198b9484cSchristos /* Hex character manipulation support. 2*5173eb0aSchristos Copyright (C) 1995-2024 Free Software Foundation, Inc. 398b9484cSchristos 498b9484cSchristos This file is part of the libiberty library. 598b9484cSchristos Libiberty is free software; you can redistribute it and/or 698b9484cSchristos modify it under the terms of the GNU Library General Public 798b9484cSchristos License as published by the Free Software Foundation; either 898b9484cSchristos version 2 of the License, or (at your option) any later version. 998b9484cSchristos 1098b9484cSchristos Libiberty is distributed in the hope that it will be useful, 1198b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1298b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1398b9484cSchristos Library General Public License for more details. 1498b9484cSchristos 1598b9484cSchristos You should have received a copy of the GNU Library General Public 1698b9484cSchristos License along with libiberty; see the file COPYING.LIB. If 1798b9484cSchristos not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 1898b9484cSchristos Boston, MA 02110-1301, USA. */ 1998b9484cSchristos 2098b9484cSchristos #include <stdio.h> /* for EOF */ 2198b9484cSchristos #ifdef HAVE_CONFIG_H 2298b9484cSchristos #include "config.h" 2398b9484cSchristos #endif 2498b9484cSchristos #include "libiberty.h" 2598b9484cSchristos #include "safe-ctype.h" /* for HOST_CHARSET_ASCII */ 2698b9484cSchristos 2798b9484cSchristos #if EOF != -1 2898b9484cSchristos #error "hex.c requires EOF == -1" 2998b9484cSchristos #endif 3098b9484cSchristos 3198b9484cSchristos /* 3298b9484cSchristos 3398b9484cSchristos @deftypefn Extension void hex_init (void) 3498b9484cSchristos 3598b9484cSchristos Initializes the array mapping the current character set to 3698b9484cSchristos corresponding hex values. This function must be called before any 3798b9484cSchristos call to @code{hex_p} or @code{hex_value}. If you fail to call it, a 3898b9484cSchristos default ASCII-based table will normally be used on ASCII systems. 3998b9484cSchristos 4098b9484cSchristos @end deftypefn 4198b9484cSchristos 4298b9484cSchristos @deftypefn Extension int hex_p (int @var{c}) 4398b9484cSchristos 4498b9484cSchristos Evaluates to non-zero if the given character is a valid hex character, 4598b9484cSchristos or zero if it is not. Note that the value you pass will be cast to 4698b9484cSchristos @code{unsigned char} within the macro. 4798b9484cSchristos 4898b9484cSchristos @end deftypefn 4998b9484cSchristos 5098b9484cSchristos @deftypefn Extension {unsigned int} hex_value (int @var{c}) 5198b9484cSchristos 5298b9484cSchristos Returns the numeric equivalent of the given character when interpreted 5398b9484cSchristos as a hexadecimal digit. The result is undefined if you pass an 5498b9484cSchristos invalid hex digit. Note that the value you pass will be cast to 5598b9484cSchristos @code{unsigned char} within the macro. 5698b9484cSchristos 5798b9484cSchristos The @code{hex_value} macro returns @code{unsigned int}, rather than 5898b9484cSchristos signed @code{int}, to make it easier to use in parsing addresses from 5998b9484cSchristos hex dump files: a signed @code{int} would be sign-extended when 6098b9484cSchristos converted to a wider unsigned type --- like @code{bfd_vma}, on some 6198b9484cSchristos systems. 6298b9484cSchristos 6398b9484cSchristos @end deftypefn 6498b9484cSchristos 6598b9484cSchristos @undocumented _hex_array_size 6698b9484cSchristos @undocumented _hex_bad 6798b9484cSchristos @undocumented _hex_value 6898b9484cSchristos 6998b9484cSchristos */ 7098b9484cSchristos 7198b9484cSchristos 7298b9484cSchristos /* Are we ASCII? */ 7398b9484cSchristos #if HOST_CHARSET == HOST_CHARSET_ASCII 7498b9484cSchristos 7598b9484cSchristos const unsigned char _hex_value[_hex_array_size] = 7698b9484cSchristos { 7798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* NUL SOH STX ETX */ 7898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* EOT ENQ ACK BEL */ 7998b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* BS HT LF VT */ 8098b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* FF CR SO SI */ 8198b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* DLE DC1 DC2 DC3 */ 8298b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* DC4 NAK SYN ETB */ 8398b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* CAN EM SUB ESC */ 8498b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* FS GS RS US */ 8598b9484cSchristos 8698b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* SP ! " # */ 8798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* $ % & ' */ 8898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* ( ) * + */ 8998b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* , - . / */ 9098b9484cSchristos 0, 1, 2, 3, /* 0 1 2 3 */ 9198b9484cSchristos 4, 5, 6, 7, /* 4 5 6 7 */ 9298b9484cSchristos 8, 9, _hex_bad, _hex_bad, /* 8 9 : ; */ 9398b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* < = > ? */ 9498b9484cSchristos 9598b9484cSchristos _hex_bad, 10, 11, 12, /* @ A B C */ 9698b9484cSchristos 13, 14, 15, _hex_bad, /* D E F G */ 9798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* H I J K */ 9898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* L M N O */ 9998b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* P Q R S */ 10098b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* T U V W */ 10198b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* X Y Z [ */ 10298b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* \ ] ^ _ */ 10398b9484cSchristos 10498b9484cSchristos _hex_bad, 10, 11, 12, /* ` a b c */ 10598b9484cSchristos 13, 14, 15, _hex_bad, /* d e f g */ 10698b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* h i j k */ 10798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* l m n o */ 10898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* p q r s */ 10998b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* t u v w */ 11098b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* x y z { */ 11198b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* | } ~ DEL */ 11298b9484cSchristos 11398b9484cSchristos /* The high half of unsigned char, all values are _hex_bad. */ 11498b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 11598b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 11698b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 11798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 11898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 11998b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12098b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12198b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12298b9484cSchristos 12398b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12498b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12598b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12698b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 12998b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13098b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13198b9484cSchristos 13298b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13398b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13498b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13598b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13698b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 13998b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14098b9484cSchristos 14198b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14298b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14398b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14498b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14598b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14698b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14798b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14898b9484cSchristos _hex_bad, _hex_bad, _hex_bad, _hex_bad, 14998b9484cSchristos }; 15098b9484cSchristos #define HEX_TABLE_INITIALIZED 15198b9484cSchristos 15298b9484cSchristos #else 15398b9484cSchristos 15498b9484cSchristos unsigned char _hex_value[_hex_array_size]; 15598b9484cSchristos 15698b9484cSchristos #endif /* not ASCII */ 15798b9484cSchristos 15898b9484cSchristos void 15998b9484cSchristos hex_init (void) 16098b9484cSchristos { 16198b9484cSchristos #ifndef HEX_TABLE_INITIALIZED 16298b9484cSchristos int i; 16398b9484cSchristos 16498b9484cSchristos for (i=0; i<_hex_array_size; i++) 16598b9484cSchristos { 16698b9484cSchristos switch (i) 16798b9484cSchristos { 16898b9484cSchristos case '0': _hex_value[i] = 0; break; 16998b9484cSchristos case '1': _hex_value[i] = 1; break; 17098b9484cSchristos case '2': _hex_value[i] = 2; break; 17198b9484cSchristos case '3': _hex_value[i] = 3; break; 17298b9484cSchristos case '4': _hex_value[i] = 4; break; 17398b9484cSchristos case '5': _hex_value[i] = 5; break; 17498b9484cSchristos case '6': _hex_value[i] = 6; break; 17598b9484cSchristos case '7': _hex_value[i] = 7; break; 17698b9484cSchristos case '8': _hex_value[i] = 8; break; 17798b9484cSchristos case '9': _hex_value[i] = 9; break; 17898b9484cSchristos 17998b9484cSchristos case 'a': case 'A': _hex_value[i] = 10; break; 18098b9484cSchristos case 'b': case 'B': _hex_value[i] = 11; break; 18198b9484cSchristos case 'c': case 'C': _hex_value[i] = 12; break; 18298b9484cSchristos case 'd': case 'D': _hex_value[i] = 13; break; 18398b9484cSchristos case 'e': case 'E': _hex_value[i] = 14; break; 18498b9484cSchristos case 'f': case 'F': _hex_value[i] = 15; break; 18598b9484cSchristos 18698b9484cSchristos default: 18798b9484cSchristos _hex_value[i] = _hex_bad; 18898b9484cSchristos break; 18998b9484cSchristos } 19098b9484cSchristos } 19198b9484cSchristos #endif 19298b9484cSchristos } 193