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