186d7f5d3SJohn Marino /* Hex character manipulation support.
286d7f5d3SJohn Marino Copyright (C) 1995, 2001 Free Software Foundation, Inc.
386d7f5d3SJohn Marino
486d7f5d3SJohn Marino This file is part of the libiberty library.
586d7f5d3SJohn Marino Libiberty is free software; you can redistribute it and/or
686d7f5d3SJohn Marino modify it under the terms of the GNU Library General Public
786d7f5d3SJohn Marino License as published by the Free Software Foundation; either
886d7f5d3SJohn Marino version 2 of the License, or (at your option) any later version.
986d7f5d3SJohn Marino
1086d7f5d3SJohn Marino Libiberty is distributed in the hope that it will be useful,
1186d7f5d3SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
1286d7f5d3SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1386d7f5d3SJohn Marino Library General Public License for more details.
1486d7f5d3SJohn Marino
1586d7f5d3SJohn Marino You should have received a copy of the GNU Library General Public
1686d7f5d3SJohn Marino License along with libiberty; see the file COPYING.LIB. If
1786d7f5d3SJohn Marino not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
1886d7f5d3SJohn Marino Boston, MA 02110-1301, USA. */
1986d7f5d3SJohn Marino
2086d7f5d3SJohn Marino #include <stdio.h> /* for EOF */
2186d7f5d3SJohn Marino #ifdef HAVE_CONFIG_H
2286d7f5d3SJohn Marino #include "config.h"
2386d7f5d3SJohn Marino #endif
2486d7f5d3SJohn Marino #include "libiberty.h"
2586d7f5d3SJohn Marino #include "safe-ctype.h" /* for HOST_CHARSET_ASCII */
2686d7f5d3SJohn Marino
2786d7f5d3SJohn Marino #if EOF != -1
2886d7f5d3SJohn Marino #error "hex.c requires EOF == -1"
2986d7f5d3SJohn Marino #endif
3086d7f5d3SJohn Marino
3186d7f5d3SJohn Marino /*
3286d7f5d3SJohn Marino
3386d7f5d3SJohn Marino @deftypefn Extension void hex_init (void)
3486d7f5d3SJohn Marino
3586d7f5d3SJohn Marino Initializes the array mapping the current character set to
3686d7f5d3SJohn Marino corresponding hex values. This function must be called before any
3786d7f5d3SJohn Marino call to @code{hex_p} or @code{hex_value}. If you fail to call it, a
3886d7f5d3SJohn Marino default ASCII-based table will normally be used on ASCII systems.
3986d7f5d3SJohn Marino
4086d7f5d3SJohn Marino @end deftypefn
4186d7f5d3SJohn Marino
4286d7f5d3SJohn Marino @deftypefn Extension int hex_p (int @var{c})
4386d7f5d3SJohn Marino
4486d7f5d3SJohn Marino Evaluates to non-zero if the given character is a valid hex character,
4586d7f5d3SJohn Marino or zero if it is not. Note that the value you pass will be cast to
4686d7f5d3SJohn Marino @code{unsigned char} within the macro.
4786d7f5d3SJohn Marino
4886d7f5d3SJohn Marino @end deftypefn
4986d7f5d3SJohn Marino
5086d7f5d3SJohn Marino @deftypefn Extension {unsigned int} hex_value (int @var{c})
5186d7f5d3SJohn Marino
5286d7f5d3SJohn Marino Returns the numeric equivalent of the given character when interpreted
5386d7f5d3SJohn Marino as a hexadecimal digit. The result is undefined if you pass an
5486d7f5d3SJohn Marino invalid hex digit. Note that the value you pass will be cast to
5586d7f5d3SJohn Marino @code{unsigned char} within the macro.
5686d7f5d3SJohn Marino
5786d7f5d3SJohn Marino The @code{hex_value} macro returns @code{unsigned int}, rather than
5886d7f5d3SJohn Marino signed @code{int}, to make it easier to use in parsing addresses from
5986d7f5d3SJohn Marino hex dump files: a signed @code{int} would be sign-extended when
6086d7f5d3SJohn Marino converted to a wider unsigned type --- like @code{bfd_vma}, on some
6186d7f5d3SJohn Marino systems.
6286d7f5d3SJohn Marino
6386d7f5d3SJohn Marino @end deftypefn
6486d7f5d3SJohn Marino
6586d7f5d3SJohn Marino @undocumented _hex_array_size
6686d7f5d3SJohn Marino @undocumented _hex_bad
6786d7f5d3SJohn Marino @undocumented _hex_value
6886d7f5d3SJohn Marino
6986d7f5d3SJohn Marino */
7086d7f5d3SJohn Marino
7186d7f5d3SJohn Marino
7286d7f5d3SJohn Marino /* Are we ASCII? */
7386d7f5d3SJohn Marino #if HOST_CHARSET == HOST_CHARSET_ASCII
7486d7f5d3SJohn Marino
7586d7f5d3SJohn Marino const unsigned char _hex_value[_hex_array_size] =
7686d7f5d3SJohn Marino {
7786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* NUL SOH STX ETX */
7886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* EOT ENQ ACK BEL */
7986d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* BS HT LF VT */
8086d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* FF CR SO SI */
8186d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* DLE DC1 DC2 DC3 */
8286d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* DC4 NAK SYN ETB */
8386d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* CAN EM SUB ESC */
8486d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* FS GS RS US */
8586d7f5d3SJohn Marino
8686d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* SP ! " # */
8786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* $ % & ' */
8886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* ( ) * + */
8986d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* , - . / */
9086d7f5d3SJohn Marino 0, 1, 2, 3, /* 0 1 2 3 */
9186d7f5d3SJohn Marino 4, 5, 6, 7, /* 4 5 6 7 */
9286d7f5d3SJohn Marino 8, 9, _hex_bad, _hex_bad, /* 8 9 : ; */
9386d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* < = > ? */
9486d7f5d3SJohn Marino
9586d7f5d3SJohn Marino _hex_bad, 10, 11, 12, /* @ A B C */
9686d7f5d3SJohn Marino 13, 14, 15, _hex_bad, /* D E F G */
9786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* H I J K */
9886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* L M N O */
9986d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* P Q R S */
10086d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* T U V W */
10186d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* X Y Z [ */
10286d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* \ ] ^ _ */
10386d7f5d3SJohn Marino
10486d7f5d3SJohn Marino _hex_bad, 10, 11, 12, /* ` a b c */
10586d7f5d3SJohn Marino 13, 14, 15, _hex_bad, /* d e f g */
10686d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* h i j k */
10786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* l m n o */
10886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* p q r s */
10986d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* t u v w */
11086d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* x y z { */
11186d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* | } ~ DEL */
11286d7f5d3SJohn Marino
11386d7f5d3SJohn Marino /* The high half of unsigned char, all values are _hex_bad. */
11486d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
11586d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
11686d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
11786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
11886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
11986d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12086d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12186d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12286d7f5d3SJohn Marino
12386d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12486d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12586d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12686d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
12986d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13086d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13186d7f5d3SJohn Marino
13286d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13386d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13486d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13586d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13686d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
13986d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14086d7f5d3SJohn Marino
14186d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14286d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14386d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14486d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14586d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14686d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14786d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14886d7f5d3SJohn Marino _hex_bad, _hex_bad, _hex_bad, _hex_bad,
14986d7f5d3SJohn Marino };
15086d7f5d3SJohn Marino #define HEX_TABLE_INITIALIZED
15186d7f5d3SJohn Marino
15286d7f5d3SJohn Marino #else
15386d7f5d3SJohn Marino
15486d7f5d3SJohn Marino unsigned char _hex_value[_hex_array_size];
15586d7f5d3SJohn Marino
15686d7f5d3SJohn Marino #endif /* not ASCII */
15786d7f5d3SJohn Marino
15886d7f5d3SJohn Marino void
hex_init(void)15986d7f5d3SJohn Marino hex_init (void)
16086d7f5d3SJohn Marino {
16186d7f5d3SJohn Marino #ifndef HEX_TABLE_INITIALIZED
16286d7f5d3SJohn Marino int i;
16386d7f5d3SJohn Marino
16486d7f5d3SJohn Marino for (i=0; i<_hex_array_size; i++)
16586d7f5d3SJohn Marino {
16686d7f5d3SJohn Marino switch (i)
16786d7f5d3SJohn Marino {
16886d7f5d3SJohn Marino case '0': _hex_value[i] = 0; break;
16986d7f5d3SJohn Marino case '1': _hex_value[i] = 1; break;
17086d7f5d3SJohn Marino case '2': _hex_value[i] = 2; break;
17186d7f5d3SJohn Marino case '3': _hex_value[i] = 3; break;
17286d7f5d3SJohn Marino case '4': _hex_value[i] = 4; break;
17386d7f5d3SJohn Marino case '5': _hex_value[i] = 5; break;
17486d7f5d3SJohn Marino case '6': _hex_value[i] = 6; break;
17586d7f5d3SJohn Marino case '7': _hex_value[i] = 7; break;
17686d7f5d3SJohn Marino case '8': _hex_value[i] = 8; break;
17786d7f5d3SJohn Marino case '9': _hex_value[i] = 9; break;
17886d7f5d3SJohn Marino
17986d7f5d3SJohn Marino case 'a': case 'A': _hex_value[i] = 10; break;
18086d7f5d3SJohn Marino case 'b': case 'B': _hex_value[i] = 11; break;
18186d7f5d3SJohn Marino case 'c': case 'C': _hex_value[i] = 12; break;
18286d7f5d3SJohn Marino case 'd': case 'D': _hex_value[i] = 13; break;
18386d7f5d3SJohn Marino case 'e': case 'E': _hex_value[i] = 14; break;
18486d7f5d3SJohn Marino case 'f': case 'F': _hex_value[i] = 15; break;
18586d7f5d3SJohn Marino
18686d7f5d3SJohn Marino default:
18786d7f5d3SJohn Marino _hex_value[i] = _hex_bad;
18886d7f5d3SJohn Marino break;
18986d7f5d3SJohn Marino }
19086d7f5d3SJohn Marino }
19186d7f5d3SJohn Marino #endif
19286d7f5d3SJohn Marino }
193