streqvcmp.c revision 1.5 1 1.5 christos /* $NetBSD: streqvcmp.c,v 1.5 2015/07/10 14:20:35 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.5 christos * AutoOpts is Copyright (C) 1992-2015 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.1 kardel 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