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