Home | History | Annotate | Download | only in libiberty
      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 }
    193