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