Home | History | Annotate | Line # | Download | only in libopts
streqvcmp.c revision 1.2
      1  1.2  christos /*	$NetBSD: streqvcmp.c,v 1.2 2012/02/03 21:36:40 christos Exp $	*/
      2  1.1    kardel 
      3  1.1    kardel 
      4  1.2  christos /**
      5  1.2  christos  * \file streqvcmp.c
      6  1.2  christos  *
      7  1.2  christos  * Time-stamp:      "2010-07-17 10:16:24 bkorb"
      8  1.1    kardel  *
      9  1.1    kardel  *  String Equivalence Comparison
     10  1.1    kardel  *
     11  1.1    kardel  *  These routines allow any character to be mapped to any other
     12  1.1    kardel  *  character before comparison.  In processing long option names,
     13  1.1    kardel  *  the characters "-", "_" and "^" all need to be equivalent
     14  1.1    kardel  *  (because they are treated so by different development environments).
     15  1.1    kardel  *
     16  1.1    kardel  *  This file is part of AutoOpts, a companion to AutoGen.
     17  1.1    kardel  *  AutoOpts is free software.
     18  1.2  christos  *  AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
     19  1.1    kardel  *
     20  1.1    kardel  *  AutoOpts is available under any one of two licenses.  The license
     21  1.1    kardel  *  in use must be one of these two and the choice is under the control
     22  1.1    kardel  *  of the user of the license.
     23  1.1    kardel  *
     24  1.1    kardel  *   The GNU Lesser General Public License, version 3 or later
     25  1.1    kardel  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
     26  1.1    kardel  *
     27  1.1    kardel  *   The Modified Berkeley Software Distribution License
     28  1.1    kardel  *      See the file "COPYING.mbsd"
     29  1.1    kardel  *
     30  1.1    kardel  *  These files have the following md5sums:
     31  1.1    kardel  *
     32  1.1    kardel  *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
     33  1.1    kardel  *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
     34  1.1    kardel  *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
     35  1.1    kardel  *
     36  1.1    kardel  * This array is designed for mapping upper and lower case letter
     37  1.1    kardel  * together for a case independent comparison.  The mappings are
     38  1.1    kardel  * based upon ascii character sequences.
     39  1.1    kardel  */
     40  1.1    kardel static unsigned char charmap[] = {
     41  1.1    kardel     0x00, 0x01, 0x02, 0x03,  0x04, 0x05, 0x06, '\a',
     42  1.1    kardel     '\b', '\t', '\n', '\v',  '\f', '\r', 0x0E, 0x0F,
     43  1.1    kardel     0x10, 0x11, 0x12, 0x13,  0x14, 0x15, 0x16, 0x17,
     44  1.1    kardel     0x18, 0x19, 0x1A, 0x1B,  0x1C, 0x1D, 0x1E, 0x1F,
     45  1.1    kardel 
     46  1.1    kardel     ' ',  '!',  '"',  '#',   '$',  '%',  '&',  '\'',
     47  1.1    kardel     '(',  ')',  '*',  '+',   ',',  '-',  '.',  '/',
     48  1.1    kardel     '0',  '1',  '2',  '3',   '4',  '5',  '6',  '7',
     49  1.1    kardel     '8',  '9',  ':',  ';',   '<',  '=',  '>',  '?',
     50  1.1    kardel 
     51  1.1    kardel     '@',  'a',  'b',  'c',   'd',  'e',  'f',  'g',
     52  1.1    kardel     'h',  'i',  'j',  'k',   'l',  'm',  'n',  'o',
     53  1.1    kardel     'p',  'q',  'r',  's',   't',  'u',  'v',  'w',
     54  1.1    kardel     'x',  'y',  'z',  '[',   '\\', ']',  '^',  '_',
     55  1.1    kardel     '`',  'a',  'b',  'c',   'd',  'e',  'f',  'g',
     56  1.1    kardel     'h',  'i',  'j',  'k',   'l',  'm',  'n',  'o',
     57  1.1    kardel     'p',  'q',  'r',  's',   't',  'u',  'v',  'w',
     58  1.1    kardel     'x',  'y',  'z',  '{',   '|',  '}',  '~',  0x7f,
     59  1.1    kardel 
     60  1.1    kardel     0x80, 0x81, 0x82, 0x83,  0x84, 0x85, 0x86, 0x87,
     61  1.1    kardel     0x88, 0x89, 0x8A, 0x8B,  0x8C, 0x8D, 0x8E, 0x8F,
     62  1.1    kardel     0x90, 0x91, 0x92, 0x93,  0x94, 0x95, 0x96, 0x97,
     63  1.1    kardel     0x98, 0x99, 0x9A, 0x9B,  0x9C, 0x9D, 0x9E, 0x9F,
     64  1.1    kardel     0xA0, 0xA1, 0xA2, 0xA3,  0xA4, 0xA5, 0xA6, 0xA7,
     65  1.1    kardel     0xA8, 0xA9, 0xAA, 0xAB,  0xAC, 0xAD, 0xAE, 0xAF,
     66  1.1    kardel     0xB0, 0xB1, 0xB2, 0xB3,  0xB4, 0xB5, 0xB6, 0xB7,
     67  1.1    kardel     0xB8, 0xB9, 0xBA, 0xBB,  0xBC, 0xBD, 0xBE, 0xBF,
     68  1.1    kardel 
     69  1.1    kardel     0xC0, 0xC1, 0xC2, 0xC3,  0xC4, 0xC5, 0xC6, 0xC7,
     70  1.1    kardel     0xC8, 0xC9, 0xCA, 0xCB,  0xCC, 0xCD, 0xCE, 0xCF,
     71  1.1    kardel     0xD0, 0xD1, 0xD2, 0xD3,  0xD4, 0xD5, 0xD6, 0xD7,
     72  1.1    kardel     0xD8, 0xD9, 0xDA, 0xDB,  0xDC, 0xDD, 0xDE, 0xDF,
     73  1.1    kardel     0xE0, 0xE1, 0xE2, 0xE3,  0xE4, 0xE5, 0xE6, 0xE7,
     74  1.1    kardel     0xE8, 0xE9, 0xEA, 0xEB,  0xEC, 0xED, 0xEE, 0xEF,
     75  1.1    kardel     0xF0, 0xF1, 0xF2, 0xF3,  0xF4, 0xF5, 0xF6, 0xF7,
     76  1.1    kardel     0xF8, 0xF9, 0xFA, 0xFB,  0xFC, 0xFD, 0xFE, 0xFF,
     77  1.1    kardel };
     78  1.1    kardel 
     79  1.1    kardel 
     80  1.1    kardel /*=export_func strneqvcmp
     81  1.1    kardel  *
     82  1.1    kardel  * what: compare two strings with an equivalence mapping
     83  1.1    kardel  *
     84  1.1    kardel  * arg:  + char const* + str1 + first string +
     85  1.1    kardel  * arg:  + char const* + str2 + second string +
     86  1.1    kardel  * arg:  + int         + ct   + compare length +
     87  1.1    kardel  *
     88  1.1    kardel  * ret_type:  int
     89  1.1    kardel  * ret_desc:  the difference between two differing characters
     90  1.1    kardel  *
     91  1.1    kardel  * doc:
     92  1.1    kardel  *
     93  1.1    kardel  * Using a character mapping, two strings are compared for "equivalence".
     94  1.1    kardel  * Each input character is mapped to a comparison character and the
     95  1.1    kardel  * mapped-to characters are compared for the two NUL terminated input strings.
     96  1.1    kardel  * The comparison is limited to @code{ct} bytes.
     97  1.1    kardel  * This function name is mapped to option_strneqvcmp so as to not conflict
     98  1.1    kardel  * with the POSIX name space.
     99  1.1    kardel  *
    100  1.1    kardel  * err:  none checked.  Caller responsible for seg faults.
    101  1.1    kardel =*/
    102  1.1    kardel int
    103  1.2  christos strneqvcmp(tCC* s1, tCC* s2, int ct)
    104  1.1    kardel {
    105  1.1    kardel     for (; ct > 0; --ct) {
    106  1.1    kardel         unsigned char u1 = (unsigned char) *s1++;
    107  1.1    kardel         unsigned char u2 = (unsigned char) *s2++;
    108  1.1    kardel         int dif = charmap[ u1 ] - charmap[ u2 ];
    109  1.1    kardel 
    110  1.1    kardel         if (dif != 0)
    111  1.1    kardel             return dif;
    112  1.1    kardel 
    113  1.1    kardel         if (u1 == NUL)
    114  1.1    kardel             return 0;
    115  1.1    kardel     }
    116  1.1    kardel 
    117  1.1    kardel     return 0;
    118  1.1    kardel }
    119  1.1    kardel 
    120  1.1    kardel 
    121  1.1    kardel /*=export_func streqvcmp
    122  1.1    kardel  *
    123  1.1    kardel  * what: compare two strings with an equivalence mapping
    124  1.1    kardel  *
    125  1.1    kardel  * arg:  + char const* + str1 + first string +
    126  1.1    kardel  * arg:  + char const* + str2 + second string +
    127  1.1    kardel  *
    128  1.1    kardel  * ret_type:  int
    129  1.1    kardel  * ret_desc:  the difference between two differing characters
    130  1.1    kardel  *
    131  1.1    kardel  * doc:
    132  1.1    kardel  *
    133  1.1    kardel  * Using a character mapping, two strings are compared for "equivalence".
    134  1.1    kardel  * Each input character is mapped to a comparison character and the
    135  1.1    kardel  * mapped-to characters are compared for the two NUL terminated input strings.
    136  1.1    kardel  * This function name is mapped to option_streqvcmp so as to not conflict
    137  1.1    kardel  * with the POSIX name space.
    138  1.1    kardel  *
    139  1.1    kardel  * err:  none checked.  Caller responsible for seg faults.
    140  1.1    kardel =*/
    141  1.1    kardel int
    142  1.2  christos streqvcmp(tCC* s1, tCC* s2)
    143  1.1    kardel {
    144  1.1    kardel     for (;;) {
    145  1.1    kardel         unsigned char u1 = (unsigned char) *s1++;
    146  1.1    kardel         unsigned char u2 = (unsigned char) *s2++;
    147  1.1    kardel         int dif = charmap[ u1 ] - charmap[ u2 ];
    148  1.1    kardel 
    149  1.1    kardel         if (dif != 0)
    150  1.1    kardel             return dif;
    151  1.1    kardel 
    152  1.1    kardel         if (u1 == NUL)
    153  1.1    kardel             return 0;
    154  1.1    kardel     }
    155  1.1    kardel }
    156  1.1    kardel 
    157  1.1    kardel 
    158  1.1    kardel /*=export_func streqvmap
    159  1.1    kardel  *
    160  1.1    kardel  * what: Set the character mappings for the streqv functions
    161  1.1    kardel  *
    162  1.1    kardel  * arg:  + char + From + Input character +
    163  1.1    kardel  * arg:  + char + To   + Mapped-to character +
    164  1.1    kardel  * arg:  + int  + ct   + compare length +
    165  1.1    kardel  *
    166  1.1    kardel  * doc:
    167  1.1    kardel  *
    168  1.1    kardel  * Set the character mapping.  If the count (@code{ct}) is set to zero, then
    169  1.1    kardel  * the map is cleared by setting all entries in the map to their index
    170  1.1    kardel  * value.  Otherwise, the "@code{From}" character is mapped to the "@code{To}"
    171  1.1    kardel  * character.  If @code{ct} is greater than 1, then @code{From} and @code{To}
    172  1.1    kardel  * are incremented and the process repeated until @code{ct} entries have been
    173  1.1    kardel  * set. For example,
    174  1.1    kardel  * @example
    175  1.2  christos  *    streqvmap('a', 'A', 26);
    176  1.1    kardel  * @end example
    177  1.1    kardel  * @noindent
    178  1.1    kardel  * will alter the mapping so that all English lower case letters
    179  1.1    kardel  * will map to upper case.
    180  1.1    kardel  *
    181  1.1    kardel  * This function name is mapped to option_streqvmap so as to not conflict
    182  1.1    kardel  * with the POSIX name space.
    183  1.1    kardel  *
    184  1.1    kardel  * err:  none.
    185  1.1    kardel =*/
    186  1.1    kardel void
    187  1.2  christos streqvmap(char From, char To, int ct)
    188  1.1    kardel {
    189  1.1    kardel     if (ct == 0) {
    190  1.2  christos         ct = sizeof(charmap) - 1;
    191  1.1    kardel         do  {
    192  1.1    kardel             charmap[ ct ] = ct;
    193  1.1    kardel         } while (--ct >= 0);
    194  1.1    kardel     }
    195  1.1    kardel 
    196  1.1    kardel     else {
    197  1.2  christos         size_t  chTo   = (int)To   & 0xFF;
    198  1.2  christos         size_t  chFrom = (int)From & 0xFF;
    199  1.1    kardel 
    200  1.1    kardel         do  {
    201  1.1    kardel             charmap[ chFrom ] = (unsigned)chTo;
    202  1.1    kardel             chFrom++;
    203  1.1    kardel             chTo++;
    204  1.2  christos             if ((chFrom >= sizeof(charmap)) || (chTo >= sizeof(charmap)))
    205  1.1    kardel                 break;
    206  1.1    kardel         } while (--ct > 0);
    207  1.1    kardel     }
    208  1.1    kardel }
    209  1.1    kardel 
    210  1.1    kardel 
    211  1.1    kardel /*=export_func strequate
    212  1.1    kardel  *
    213  1.1    kardel  * what: map a list of characters to the same value
    214  1.1    kardel  *
    215  1.1    kardel  * arg:  + char const* + ch_list + characters to equivalence +
    216  1.1    kardel  *
    217  1.1    kardel  * doc:
    218  1.1    kardel  *
    219  1.1    kardel  * Each character in the input string get mapped to the first character
    220  1.1    kardel  * in the string.
    221  1.1    kardel  * This function name is mapped to option_strequate so as to not conflict
    222  1.1    kardel  * with the POSIX name space.
    223  1.1    kardel  *
    224  1.1    kardel  * err:  none.
    225  1.1    kardel =*/
    226  1.1    kardel void
    227  1.2  christos strequate(char const* s)
    228  1.1    kardel {
    229  1.1    kardel     if ((s != NULL) && (*s != NUL)) {
    230  1.1    kardel         unsigned char equiv = (unsigned)*s;
    231  1.1    kardel         while (*s != NUL)
    232  1.1    kardel             charmap[ (unsigned)*(s++) ] = equiv;
    233  1.1    kardel     }
    234  1.1    kardel }
    235  1.1    kardel 
    236  1.1    kardel 
    237  1.1    kardel /*=export_func strtransform
    238  1.1    kardel  *
    239  1.1    kardel  * what: convert a string into its mapped-to value
    240  1.1    kardel  *
    241  1.1    kardel  * arg:  + char*       + dest + output string +
    242  1.1    kardel  * arg:  + char const* + src  + input string +
    243  1.1    kardel  *
    244  1.1    kardel  * doc:
    245  1.1    kardel  *
    246  1.1    kardel  * Each character in the input string is mapped and the mapped-to
    247  1.1    kardel  * character is put into the output.
    248  1.1    kardel  * This function name is mapped to option_strtransform so as to not conflict
    249  1.1    kardel  * with the POSIX name space.
    250  1.1    kardel  *
    251  1.1    kardel  * The source and destination may be the same.
    252  1.1    kardel  *
    253  1.1    kardel  * err:  none.
    254  1.1    kardel =*/
    255  1.1    kardel void
    256  1.2  christos strtransform(char* d, char const* s)
    257  1.1    kardel {
    258  1.1    kardel     do  {
    259  1.1    kardel         *(d++) = (char)charmap[ (unsigned)*s ];
    260  1.1    kardel     } while (*(s++) != NUL);
    261  1.1    kardel }
    262  1.1    kardel 
    263  1.1    kardel /*
    264  1.1    kardel  * Local Variables:
    265  1.1    kardel  * mode: C
    266  1.1    kardel  * c-file-style: "stroustrup"
    267  1.1    kardel  * indent-tabs-mode: nil
    268  1.1    kardel  * End:
    269  1.1    kardel  * end of autoopts/streqvcmp.c */
    270