streqvcmp.c revision 280849
1181834Sroberto 2280849Scy/** 3280849Scy * \file streqvcmp.c 4181834Sroberto * 5181834Sroberto * String Equivalence Comparison 6181834Sroberto * 7181834Sroberto * These routines allow any character to be mapped to any other 8181834Sroberto * character before comparison. In processing long option names, 9181834Sroberto * the characters "-", "_" and "^" all need to be equivalent 10181834Sroberto * (because they are treated so by different development environments). 11280849Scy * 12280849Scy * @addtogroup autoopts 13280849Scy * @{ 14181834Sroberto */ 15181834Sroberto/* 16280849Scy * This file is part of AutoOpts, a companion to AutoGen. 17280849Scy * AutoOpts is free software. 18280849Scy * AutoOpts is Copyright (C) 1992-2014 by Bruce Korb - all rights reserved 19181834Sroberto * 20280849Scy * AutoOpts is available under any one of two licenses. The license 21280849Scy * in use must be one of these two and the choice is under the control 22280849Scy * of the user of the license. 23181834Sroberto * 24280849Scy * The GNU Lesser General Public License, version 3 or later 25280849Scy * See the files "COPYING.lgplv3" and "COPYING.gplv3" 26181834Sroberto * 27280849Scy * The Modified Berkeley Software Distribution License 28280849Scy * See the file "COPYING.mbsd" 29181834Sroberto * 30280849Scy * These files have the following sha256 sums: 31181834Sroberto * 32280849Scy * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 33280849Scy * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 34280849Scy * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 35181834Sroberto * 36181834Sroberto * This array is designed for mapping upper and lower case letter 37181834Sroberto * together for a case independent comparison. The mappings are 38181834Sroberto * based upon ascii character sequences. 39181834Sroberto */ 40181834Srobertostatic unsigned char charmap[] = { 41280849Scy NUL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a', 42280849Scy '\b', '\t', NL, '\v', '\f', '\r', 0x0E, 0x0F, 43181834Sroberto 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 44181834Sroberto 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 45181834Sroberto 46181834Sroberto ' ', '!', '"', '#', '$', '%', '&', '\'', 47181834Sroberto '(', ')', '*', '+', ',', '-', '.', '/', 48181834Sroberto '0', '1', '2', '3', '4', '5', '6', '7', 49181834Sroberto '8', '9', ':', ';', '<', '=', '>', '?', 50181834Sroberto 51181834Sroberto '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 52181834Sroberto 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 53181834Sroberto 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 54181834Sroberto 'x', 'y', 'z', '[', '\\', ']', '^', '_', 55181834Sroberto '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 56181834Sroberto 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 57181834Sroberto 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 58181834Sroberto 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, 59181834Sroberto 60181834Sroberto 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 61181834Sroberto 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 62181834Sroberto 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 63181834Sroberto 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 64181834Sroberto 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 65181834Sroberto 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 66181834Sroberto 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 67181834Sroberto 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 68181834Sroberto 69181834Sroberto 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 70181834Sroberto 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 71181834Sroberto 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 72181834Sroberto 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 73181834Sroberto 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 74181834Sroberto 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 75181834Sroberto 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 76181834Sroberto 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 77181834Sroberto}; 78181834Sroberto 79181834Sroberto 80181834Sroberto/*=export_func strneqvcmp 81181834Sroberto * 82181834Sroberto * what: compare two strings with an equivalence mapping 83181834Sroberto * 84181834Sroberto * arg: + char const* + str1 + first string + 85181834Sroberto * arg: + char const* + str2 + second string + 86181834Sroberto * arg: + int + ct + compare length + 87181834Sroberto * 88181834Sroberto * ret_type: int 89181834Sroberto * ret_desc: the difference between two differing characters 90181834Sroberto * 91181834Sroberto * doc: 92181834Sroberto * 93181834Sroberto * Using a character mapping, two strings are compared for "equivalence". 94181834Sroberto * Each input character is mapped to a comparison character and the 95181834Sroberto * mapped-to characters are compared for the two NUL terminated input strings. 96181834Sroberto * The comparison is limited to @code{ct} bytes. 97181834Sroberto * This function name is mapped to option_strneqvcmp so as to not conflict 98181834Sroberto * with the POSIX name space. 99181834Sroberto * 100181834Sroberto * err: none checked. Caller responsible for seg faults. 101181834Sroberto=*/ 102181834Srobertoint 103280849Scystrneqvcmp(char const * s1, char const * s2, int ct) 104181834Sroberto{ 105181834Sroberto for (; ct > 0; --ct) { 106181834Sroberto unsigned char u1 = (unsigned char) *s1++; 107181834Sroberto unsigned char u2 = (unsigned char) *s2++; 108280849Scy int dif; 109280849Scy if (u1 == u2) { 110280849Scy if (u1 == NUL) 111280849Scy return 0; 112280849Scy continue; 113280849Scy } 114181834Sroberto 115280849Scy dif = charmap[ u1 ] - charmap[ u2 ]; 116280849Scy 117181834Sroberto if (dif != 0) 118181834Sroberto return dif; 119181834Sroberto 120181834Sroberto if (u1 == NUL) 121181834Sroberto return 0; 122181834Sroberto } 123181834Sroberto 124181834Sroberto return 0; 125181834Sroberto} 126181834Sroberto 127181834Sroberto 128181834Sroberto/*=export_func streqvcmp 129181834Sroberto * 130181834Sroberto * what: compare two strings with an equivalence mapping 131181834Sroberto * 132181834Sroberto * arg: + char const* + str1 + first string + 133181834Sroberto * arg: + char const* + str2 + second string + 134181834Sroberto * 135181834Sroberto * ret_type: int 136181834Sroberto * ret_desc: the difference between two differing characters 137181834Sroberto * 138181834Sroberto * doc: 139181834Sroberto * 140181834Sroberto * Using a character mapping, two strings are compared for "equivalence". 141181834Sroberto * Each input character is mapped to a comparison character and the 142181834Sroberto * mapped-to characters are compared for the two NUL terminated input strings. 143181834Sroberto * This function name is mapped to option_streqvcmp so as to not conflict 144181834Sroberto * with the POSIX name space. 145181834Sroberto * 146181834Sroberto * err: none checked. Caller responsible for seg faults. 147181834Sroberto=*/ 148181834Srobertoint 149280849Scystreqvcmp(char const * s1, char const * s2) 150181834Sroberto{ 151181834Sroberto for (;;) { 152181834Sroberto unsigned char u1 = (unsigned char) *s1++; 153181834Sroberto unsigned char u2 = (unsigned char) *s2++; 154280849Scy int dif; 155280849Scy if (u1 == u2) { 156280849Scy if (u1 == NUL) 157280849Scy return 0; 158280849Scy continue; 159280849Scy } 160181834Sroberto 161280849Scy dif = charmap[ u1 ] - charmap[ u2 ]; 162280849Scy 163181834Sroberto if (dif != 0) 164181834Sroberto return dif; 165181834Sroberto 166181834Sroberto if (u1 == NUL) 167181834Sroberto return 0; 168181834Sroberto } 169181834Sroberto} 170181834Sroberto 171181834Sroberto 172181834Sroberto/*=export_func streqvmap 173181834Sroberto * 174181834Sroberto * what: Set the character mappings for the streqv functions 175181834Sroberto * 176280849Scy * arg: + char + from + Input character + 177280849Scy * arg: + char + to + Mapped-to character + 178181834Sroberto * arg: + int + ct + compare length + 179181834Sroberto * 180181834Sroberto * doc: 181181834Sroberto * 182181834Sroberto * Set the character mapping. If the count (@code{ct}) is set to zero, then 183181834Sroberto * the map is cleared by setting all entries in the map to their index 184181834Sroberto * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" 185181834Sroberto * character. If @code{ct} is greater than 1, then @code{From} and @code{To} 186181834Sroberto * are incremented and the process repeated until @code{ct} entries have been 187181834Sroberto * set. For example, 188181834Sroberto * @example 189280849Scy * streqvmap('a', 'A', 26); 190181834Sroberto * @end example 191181834Sroberto * @noindent 192181834Sroberto * will alter the mapping so that all English lower case letters 193181834Sroberto * will map to upper case. 194181834Sroberto * 195181834Sroberto * This function name is mapped to option_streqvmap so as to not conflict 196181834Sroberto * with the POSIX name space. 197181834Sroberto * 198181834Sroberto * err: none. 199181834Sroberto=*/ 200181834Srobertovoid 201280849Scystreqvmap(char from, char to, int ct) 202181834Sroberto{ 203181834Sroberto if (ct == 0) { 204280849Scy ct = sizeof(charmap) - 1; 205181834Sroberto do { 206280849Scy charmap[ct] = (unsigned char)ct; 207181834Sroberto } while (--ct >= 0); 208181834Sroberto } 209181834Sroberto 210181834Sroberto else { 211280849Scy unsigned int i_to = (int)to & 0xFF; 212280849Scy unsigned int i_from = (int)from & 0xFF; 213181834Sroberto 214181834Sroberto do { 215280849Scy charmap[i_from] = (unsigned char)i_to; 216280849Scy i_from++; 217280849Scy i_to++; 218280849Scy if ((i_from >= sizeof(charmap)) || (i_to >= sizeof(charmap))) 219181834Sroberto break; 220181834Sroberto } while (--ct > 0); 221181834Sroberto } 222181834Sroberto} 223181834Sroberto 224181834Sroberto 225181834Sroberto/*=export_func strequate 226181834Sroberto * 227181834Sroberto * what: map a list of characters to the same value 228181834Sroberto * 229181834Sroberto * arg: + char const* + ch_list + characters to equivalence + 230181834Sroberto * 231181834Sroberto * doc: 232181834Sroberto * 233181834Sroberto * Each character in the input string get mapped to the first character 234181834Sroberto * in the string. 235181834Sroberto * This function name is mapped to option_strequate so as to not conflict 236181834Sroberto * with the POSIX name space. 237181834Sroberto * 238181834Sroberto * err: none. 239181834Sroberto=*/ 240181834Srobertovoid 241280849Scystrequate(char const* s) 242181834Sroberto{ 243181834Sroberto if ((s != NULL) && (*s != NUL)) { 244280849Scy unsigned char equiv = (unsigned char)*s; 245181834Sroberto while (*s != NUL) 246280849Scy charmap[(unsigned char)*(s++)] = equiv; 247181834Sroberto } 248181834Sroberto} 249181834Sroberto 250181834Sroberto 251181834Sroberto/*=export_func strtransform 252181834Sroberto * 253181834Sroberto * what: convert a string into its mapped-to value 254181834Sroberto * 255181834Sroberto * arg: + char* + dest + output string + 256181834Sroberto * arg: + char const* + src + input string + 257181834Sroberto * 258181834Sroberto * doc: 259181834Sroberto * 260181834Sroberto * Each character in the input string is mapped and the mapped-to 261181834Sroberto * character is put into the output. 262181834Sroberto * This function name is mapped to option_strtransform so as to not conflict 263181834Sroberto * with the POSIX name space. 264181834Sroberto * 265280849Scy * The source and destination may be the same. 266280849Scy * 267181834Sroberto * err: none. 268181834Sroberto=*/ 269181834Srobertovoid 270280849Scystrtransform(char* d, char const* s) 271181834Sroberto{ 272181834Sroberto do { 273280849Scy *(d++) = (char)charmap[(unsigned char)*s]; 274181834Sroberto } while (*(s++) != NUL); 275181834Sroberto} 276181834Sroberto 277280849Scy/** @} 278280849Scy * 279181834Sroberto * Local Variables: 280181834Sroberto * mode: C 281181834Sroberto * c-file-style: "stroustrup" 282181834Sroberto * indent-tabs-mode: nil 283181834Sroberto * End: 284181834Sroberto * end of autoopts/streqvcmp.c */ 285