hex.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* Hex character manipulation support.
  2. Copyright (C) 1995-2022 Free Software Foundation, Inc.
  3. This file is part of the libiberty library.
  4. Libiberty is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. Libiberty is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with libiberty; see the file COPYING.LIB. If
  14. not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
  15. Boston, MA 02110-1301, USA. */
  16. #include <stdio.h> /* for EOF */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include "libiberty.h"
  21. #include "safe-ctype.h" /* for HOST_CHARSET_ASCII */
  22. #if EOF != -1
  23. #error "hex.c requires EOF == -1"
  24. #endif
  25. /*
  26. @deftypefn Extension void hex_init (void)
  27. Initializes the array mapping the current character set to
  28. corresponding hex values. This function must be called before any
  29. call to @code{hex_p} or @code{hex_value}. If you fail to call it, a
  30. default ASCII-based table will normally be used on ASCII systems.
  31. @end deftypefn
  32. @deftypefn Extension int hex_p (int @var{c})
  33. Evaluates to non-zero if the given character is a valid hex character,
  34. or zero if it is not. Note that the value you pass will be cast to
  35. @code{unsigned char} within the macro.
  36. @end deftypefn
  37. @deftypefn Extension {unsigned int} hex_value (int @var{c})
  38. Returns the numeric equivalent of the given character when interpreted
  39. as a hexadecimal digit. The result is undefined if you pass an
  40. invalid hex digit. Note that the value you pass will be cast to
  41. @code{unsigned char} within the macro.
  42. The @code{hex_value} macro returns @code{unsigned int}, rather than
  43. signed @code{int}, to make it easier to use in parsing addresses from
  44. hex dump files: a signed @code{int} would be sign-extended when
  45. converted to a wider unsigned type --- like @code{bfd_vma}, on some
  46. systems.
  47. @end deftypefn
  48. @undocumented _hex_array_size
  49. @undocumented _hex_bad
  50. @undocumented _hex_value
  51. */
  52. /* Are we ASCII? */
  53. #if HOST_CHARSET == HOST_CHARSET_ASCII
  54. const unsigned char _hex_value[_hex_array_size] =
  55. {
  56. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* NUL SOH STX ETX */
  57. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* EOT ENQ ACK BEL */
  58. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* BS HT LF VT */
  59. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* FF CR SO SI */
  60. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* DLE DC1 DC2 DC3 */
  61. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* DC4 NAK SYN ETB */
  62. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* CAN EM SUB ESC */
  63. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* FS GS RS US */
  64. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* SP ! " # */
  65. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* $ % & ' */
  66. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* ( ) * + */
  67. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* , - . / */
  68. 0, 1, 2, 3, /* 0 1 2 3 */
  69. 4, 5, 6, 7, /* 4 5 6 7 */
  70. 8, 9, _hex_bad, _hex_bad, /* 8 9 : ; */
  71. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* < = > ? */
  72. _hex_bad, 10, 11, 12, /* @ A B C */
  73. 13, 14, 15, _hex_bad, /* D E F G */
  74. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* H I J K */
  75. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* L M N O */
  76. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* P Q R S */
  77. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* T U V W */
  78. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* X Y Z [ */
  79. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* \ ] ^ _ */
  80. _hex_bad, 10, 11, 12, /* ` a b c */
  81. 13, 14, 15, _hex_bad, /* d e f g */
  82. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* h i j k */
  83. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* l m n o */
  84. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* p q r s */
  85. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* t u v w */
  86. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* x y z { */
  87. _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* | } ~ DEL */
  88. /* The high half of unsigned char, all values are _hex_bad. */
  89. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  90. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  91. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  92. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  93. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  94. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  95. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  96. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  97. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  98. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  99. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  100. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  101. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  102. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  103. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  104. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  105. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  106. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  107. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  108. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  109. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  110. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  111. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  112. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  113. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  114. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  115. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  116. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  117. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  118. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  119. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  120. _hex_bad, _hex_bad, _hex_bad, _hex_bad,
  121. };
  122. #define HEX_TABLE_INITIALIZED
  123. #else
  124. unsigned char _hex_value[_hex_array_size];
  125. #endif /* not ASCII */
  126. void
  127. hex_init (void)
  128. {
  129. #ifndef HEX_TABLE_INITIALIZED
  130. int i;
  131. for (i=0; i<_hex_array_size; i++)
  132. {
  133. switch (i)
  134. {
  135. case '0': _hex_value[i] = 0; break;
  136. case '1': _hex_value[i] = 1; break;
  137. case '2': _hex_value[i] = 2; break;
  138. case '3': _hex_value[i] = 3; break;
  139. case '4': _hex_value[i] = 4; break;
  140. case '5': _hex_value[i] = 5; break;
  141. case '6': _hex_value[i] = 6; break;
  142. case '7': _hex_value[i] = 7; break;
  143. case '8': _hex_value[i] = 8; break;
  144. case '9': _hex_value[i] = 9; break;
  145. case 'a': case 'A': _hex_value[i] = 10; break;
  146. case 'b': case 'B': _hex_value[i] = 11; break;
  147. case 'c': case 'C': _hex_value[i] = 12; break;
  148. case 'd': case 'D': _hex_value[i] = 13; break;
  149. case 'e': case 'E': _hex_value[i] = 14; break;
  150. case 'f': case 'F': _hex_value[i] = 15; break;
  151. default:
  152. _hex_value[i] = _hex_bad;
  153. break;
  154. }
  155. }
  156. #endif
  157. }