tomwalters@0
|
1 /***************************************************************************
|
tomwalters@0
|
2
|
tomwalters@0
|
3 strmatch.c String matching routines to supplement those defined in
|
tomwalters@0
|
4 ---------- <strings.h>.
|
tomwalters@0
|
5
|
tomwalters@0
|
6
|
tomwalters@0
|
7 Character classification macros defined in <ctype.h>
|
tomwalters@0
|
8 These return truth values [0,1].
|
tomwalters@0
|
9
|
tomwalters@0
|
10
|
tomwalters@0
|
11 int isalpha(c) c is a letter
|
tomwalters@0
|
12 int c;
|
tomwalters@0
|
13
|
tomwalters@0
|
14 int isupper(c) c is an uppercase letter
|
tomwalters@0
|
15 int c;
|
tomwalters@0
|
16
|
tomwalters@0
|
17 int islower(c) c is a lowercase letter
|
tomwalters@0
|
18 int c;
|
tomwalters@0
|
19
|
tomwalters@0
|
20 int isdigit(c) c is a digit
|
tomwalters@0
|
21 int c;
|
tomwalters@0
|
22
|
tomwalters@0
|
23 int isxdigit(c) c is a hexadecimal digit, by default [0-9], [A-F], or
|
tomwalters@0
|
24 int c; [a-f].
|
tomwalters@0
|
25
|
tomwalters@0
|
26 int isalnum(c) c is an alphanumeric character
|
tomwalters@0
|
27 int c;
|
tomwalters@0
|
28
|
tomwalters@0
|
29 int isspace(c) c is a space, tab, carriage return, new line, or form
|
tomwalters@0
|
30 int c; feed.
|
tomwalters@0
|
31
|
tomwalters@0
|
32 int ispunct(c) c is a punctuation character (neither control,
|
tomwalters@0
|
33 int c; alphanumeric, nor space)
|
tomwalters@0
|
34
|
tomwalters@0
|
35
|
tomwalters@0
|
36 int isprint(c) c is a printing character, by default code 040(8)
|
tomwalters@0
|
37 int c; (space) through 0176 (tilde)
|
tomwalters@0
|
38
|
tomwalters@0
|
39
|
tomwalters@0
|
40 int isgraph(c) c is a printing character, like isprint except false
|
tomwalters@0
|
41 int c; for space.
|
tomwalters@0
|
42
|
tomwalters@0
|
43 int iscntrl(c) c is a delete character (0177) or ordinary control
|
tomwalters@0
|
44 int c; character (less than 040) except for space characters
|
tomwalters@0
|
45
|
tomwalters@0
|
46
|
tomwalters@0
|
47 int isascii(c) c is an ASCII character, code less than 0200
|
tomwalters@0
|
48 int c;
|
tomwalters@0
|
49
|
tomwalters@0
|
50
|
tomwalters@0
|
51 Character translation macros defined in <ctype.h>
|
tomwalters@0
|
52
|
tomwalters@0
|
53
|
tomwalters@0
|
54 int toupper(c) return upper-case letter corresponding to c.
|
tomwalters@0
|
55 int c;
|
tomwalters@0
|
56
|
tomwalters@0
|
57 int tolower(c) return lower-case letter corresponding to c.
|
tomwalters@0
|
58 int c;
|
tomwalters@0
|
59
|
tomwalters@0
|
60 int toascii(c) return ascii value corresponding to c.
|
tomwalters@0
|
61 int c;
|
tomwalters@0
|
62
|
tomwalters@0
|
63
|
tomwalters@0
|
64 String handling routines defined in <strings.h>
|
tomwalters@0
|
65 A `span' is the length of a segment of a string, ie a number of characters.
|
tomwalters@0
|
66
|
tomwalters@0
|
67
|
tomwalters@0
|
68 char *strcat(s1, s2) Append a copy of string s2 to the end of
|
tomwalters@0
|
69 char *s1, *s2; string s1. Return a ptr to s1.
|
tomwalters@0
|
70
|
tomwalters@0
|
71 char *strncat(s1, s2, n) Append n chars of s2 to the end of string s1.
|
tomwalters@0
|
72 char *s1, *s2; Return a ptr to s1.
|
tomwalters@0
|
73
|
tomwalters@0
|
74 int strcmp(s1, s2) Compare strings. Return 0 if equal.
|
tomwalters@0
|
75 unsigned char *s1, *s2; Otherwise return difference number of chars.
|
tomwalters@0
|
76
|
tomwalters@0
|
77 int strncmp(s1, s2, n) Compare n chars of strings. Return 0 if equal.
|
tomwalters@0
|
78 unsigned char *s1, *s2; Otherwise return difference number of chars.
|
tomwalters@0
|
79 int n
|
tomwalters@0
|
80
|
tomwalters@0
|
81 strcasecmp(s1, s2) As strcmp, but case insensitive.
|
tomwalters@0
|
82 char *s1, *s2;
|
tomwalters@0
|
83
|
tomwalters@0
|
84 strncasecmp(s1, s2, n) As strncmp, but case insensitive.
|
tomwalters@0
|
85 char *s1, *s2;
|
tomwalters@0
|
86
|
tomwalters@0
|
87 char *strcpy(s1, s2) Copy s2 to s1, including null char.
|
tomwalters@0
|
88 char *s1, *s2;
|
tomwalters@0
|
89
|
tomwalters@0
|
90 char *strncpy(s1, s2, n) Copy n chars of s2 to s1. Truncate or pad s2
|
tomwalters@0
|
91 char *s1, *s2; with nulls to make up n chars. If s2 needs to
|
tomwalters@0
|
92 int n be truncated, s1 will not be null terminated.
|
tomwalters@0
|
93
|
tomwalters@0
|
94 int strlen(s) Return number of chars in s, not including
|
tomwalters@0
|
95 char *s; the terminating null character.
|
tomwalters@0
|
96
|
tomwalters@0
|
97 char *strstr(s1, s2) Return a ptr to the first occurrence of s2
|
tomwalters@0
|
98 char *s1, *s2; in s1. Otherwise return a null ptr.
|
tomwalters@0
|
99
|
tomwalters@0
|
100 char *strchr(s, c) Return a ptr to the first occurrence of c
|
tomwalters@0
|
101 char *s; in s. Otherwise return a null ptr.
|
tomwalters@0
|
102 int c;
|
tomwalters@0
|
103
|
tomwalters@0
|
104 char *strrchr(s, c) Return a ptr to the last occurrence of c
|
tomwalters@0
|
105 char *s; in s. Otherwise return a null ptr.
|
tomwalters@0
|
106 int c;
|
tomwalters@0
|
107
|
tomwalters@0
|
108 char *strpbrk(s1, s2) Return a ptr to the first occurrence of any
|
tomwalters@0
|
109 char *s1, *s2; char in s2 in s1. Otherwise return a null ptr.
|
tomwalters@0
|
110
|
tomwalters@0
|
111 int strspn(s1, s2) Return the span from the head of s1 which
|
tomwalters@0
|
112 char *s1, *s2; consists of chars which are in s2.
|
tomwalters@0
|
113
|
tomwalters@0
|
114 int strcspn(s1, s2) Return the span from the head of s1 which
|
tomwalters@0
|
115 char *s1, *s2; consists of chars which are not in s2.
|
tomwalters@0
|
116
|
tomwalters@0
|
117 char *strtok(s1, s2) See below:
|
tomwalters@0
|
118 char *s1, *s2;
|
tomwalters@0
|
119
|
tomwalters@0
|
120 The strtok subroutine considers the string s1 to consist of a sequence
|
tomwalters@0
|
121 of zero or more text tokens separated by spans of one or more characters
|
tomwalters@0
|
122 from the separator string s2. The first call (with pointer s1 speci-
|
tomwalters@0
|
123 fied) returns a pointer to the first character of the first token, and
|
tomwalters@0
|
124 will have written a null character into s1 immediately following the
|
tomwalters@0
|
125 returned token. The function keeps track of its position in the string
|
tomwalters@0
|
126 between separate calls, so that subsequent calls (which must be made
|
tomwalters@0
|
127 with the first argument a NULL pointer) will work through the string s1
|
tomwalters@0
|
128 immediately following that token. In this way, subsequent calls will
|
tomwalters@0
|
129 work through the string s1 until no tokens remain. The separator string
|
tomwalters@0
|
130 s2 may be different from call to call. When no token remains in s1, a
|
tomwalters@0
|
131 NULL pointer is returned.
|
tomwalters@0
|
132
|
tomwalters@0
|
133
|
tomwalters@0
|
134 ***************************************************************************/
|
tomwalters@0
|
135
|
tomwalters@0
|
136
|
tomwalters@0
|
137
|
tomwalters@0
|
138 #include <math.h>
|
tomwalters@0
|
139 #include "strmatch.h"
|
tomwalters@0
|
140
|
tomwalters@0
|
141
|
tomwalters@0
|
142 /*
|
tomwalters@0
|
143 Test for a NULL pointer to a character or string
|
tomwalters@0
|
144 */
|
tomwalters@0
|
145
|
tomwalters@0
|
146 int isnull( s )
|
tomwalters@0
|
147 char *s ;
|
tomwalters@0
|
148 {
|
tomwalters@0
|
149 if ( s == (char *)0 ) return 1 ;
|
tomwalters@0
|
150 else return 0 ;
|
tomwalters@0
|
151 }
|
tomwalters@0
|
152
|
tomwalters@0
|
153 /*
|
tomwalters@0
|
154 Test for an empty string
|
tomwalters@0
|
155 */
|
tomwalters@0
|
156
|
tomwalters@0
|
157
|
tomwalters@0
|
158 int isempty( s )
|
tomwalters@0
|
159 char *s ;
|
tomwalters@0
|
160 {
|
tomwalters@0
|
161 if ( *s == '\0' ) return 1 ;
|
tomwalters@0
|
162 else return 0 ;
|
tomwalters@0
|
163 }
|
tomwalters@0
|
164
|
tomwalters@0
|
165 /*
|
tomwalters@0
|
166 Test for NULL string pointer or empty string
|
tomwalters@0
|
167 */
|
tomwalters@0
|
168
|
tomwalters@0
|
169 int isnullorempty( s )
|
tomwalters@0
|
170 char *s ;
|
tomwalters@0
|
171 {
|
tomwalters@0
|
172 if ( s == (char *)0 || *s == '\0' ) return 1 ;
|
tomwalters@0
|
173 else return 0 ;
|
tomwalters@0
|
174 }
|
tomwalters@0
|
175
|
tomwalters@0
|
176
|
tomwalters@0
|
177 /*
|
tomwalters@0
|
178 Return a pointer to the terminator '\0' at the tail of string `s'.
|
tomwalters@0
|
179 */
|
tomwalters@0
|
180
|
tomwalters@0
|
181 char *terminator( s )
|
tomwalters@0
|
182 char *s ;
|
tomwalters@0
|
183 {
|
tomwalters@0
|
184 return ( s + strlen( s ) ) ;
|
tomwalters@0
|
185 }
|
tomwalters@0
|
186
|
tomwalters@0
|
187
|
tomwalters@0
|
188 /*
|
tomwalters@0
|
189 Test strings s1==s2. Return 1 if true, 0 otherwise.
|
tomwalters@0
|
190 */
|
tomwalters@0
|
191
|
tomwalters@0
|
192 int isstr( s1, s2 )
|
tomwalters@0
|
193 char *s1, *s2 ;
|
tomwalters@0
|
194 {
|
tomwalters@0
|
195 return ( strcmp( s1, s2 ) == 0 ) ;
|
tomwalters@0
|
196 }
|
tomwalters@0
|
197
|
tomwalters@0
|
198
|
tomwalters@0
|
199 /*
|
tomwalters@0
|
200 Test strings s1==s2 up to the length of string s1 (ie allowing truncation).
|
tomwalters@0
|
201 Return 1 if true, 0 otherwise.
|
tomwalters@0
|
202 */
|
tomwalters@0
|
203
|
tomwalters@0
|
204 int iststr( s1, s2 )
|
tomwalters@0
|
205 char *s1, *s2 ;
|
tomwalters@0
|
206 {
|
tomwalters@0
|
207 return ( strncmp( s1, s2, strlen( s1 ) ) == 0 ) ;
|
tomwalters@0
|
208 }
|
tomwalters@0
|
209
|
tomwalters@0
|
210
|
tomwalters@0
|
211 /*
|
tomwalters@0
|
212 Copy s2 to s1 up to (but not including) the first occurrence of character c
|
tomwalters@0
|
213 in s2. Ensure s1 is then null terminated.
|
tomwalters@0
|
214 Return s1 or a null ptr if c is not found in s2.
|
tomwalters@0
|
215 */
|
tomwalters@0
|
216
|
tomwalters@0
|
217 char *strccpy( s1, s2, c )
|
tomwalters@0
|
218 char *s1, *s2 ;
|
tomwalters@0
|
219 char c ;
|
tomwalters@0
|
220 {
|
tomwalters@0
|
221 char *s ;
|
tomwalters@0
|
222
|
tomwalters@0
|
223 if ( ( s = strchr( s2, c ) ) == (char *)0 ) return (char *)0 ;
|
tomwalters@0
|
224 strncpy( s1, s2, (int)( s - s2 ) ) ;
|
tomwalters@0
|
225 *( s1 + ( s - s2 ) ) == '\0' ;
|
tomwalters@0
|
226 return ( s1 ) ;
|
tomwalters@0
|
227 }
|
tomwalters@0
|
228
|
tomwalters@0
|
229
|
tomwalters@0
|
230 /*
|
tomwalters@0
|
231 Return a ptr to the first occurrence of any char in s1 which is not in s2.
|
tomwalters@0
|
232 Otherwise return a null ptr. (This complements strpbrk() in the Unix string
|
tomwalters@0
|
233 library).
|
tomwalters@0
|
234 */
|
tomwalters@0
|
235
|
tomwalters@0
|
236 char *strcbrk(s1, s2)
|
tomwalters@0
|
237 char *s1, *s2;
|
tomwalters@0
|
238 {
|
tomwalters@0
|
239 int spn ;
|
tomwalters@0
|
240
|
tomwalters@0
|
241 if ( ( spn = strspn( s1, s2 ) ) == strlen( s1 ) )
|
tomwalters@0
|
242 return ( (char *)0 ) ;
|
tomwalters@0
|
243 return ( (char *)( s1 + spn ) ) ;
|
tomwalters@0
|
244 }
|
tomwalters@0
|
245
|
tomwalters@0
|
246
|
tomwalters@0
|
247
|
tomwalters@0
|
248 /*
|
tomwalters@0
|
249 Return the span from the head of s1 to the first occurrence of any char in s2.
|
tomwalters@0
|
250 Otherwise (if no such char found) return -1.
|
tomwalters@0
|
251 */
|
tomwalters@0
|
252
|
tomwalters@0
|
253 int strspnbrk(s1, s2)
|
tomwalters@0
|
254 char *s1, *s2;
|
tomwalters@0
|
255 {
|
tomwalters@0
|
256 int spn ;
|
tomwalters@0
|
257
|
tomwalters@0
|
258 if ( ( spn = strcspn( s1, s2 ) ) == strlen( s1 ) )
|
tomwalters@0
|
259 return ( -1 ) ;
|
tomwalters@0
|
260 return ( spn ) ;
|
tomwalters@0
|
261 }
|
tomwalters@0
|
262
|
tomwalters@0
|
263
|
tomwalters@0
|
264 /*
|
tomwalters@0
|
265 Return the span from the head of s1 to the first occurrence of any char not
|
tomwalters@0
|
266 in s2. Otherwise (if no such char found) return -1.
|
tomwalters@0
|
267 */
|
tomwalters@0
|
268
|
tomwalters@0
|
269 int strcspnbrk(s1, s2)
|
tomwalters@0
|
270 char *s1, *s2;
|
tomwalters@0
|
271 {
|
tomwalters@0
|
272 int spn ;
|
tomwalters@0
|
273
|
tomwalters@0
|
274 if ( ( spn = strspn( s1, s2 ) ) == strlen( s1 ) )
|
tomwalters@0
|
275 return ( -1 ) ;
|
tomwalters@0
|
276 return ( spn ) ;
|
tomwalters@0
|
277 }
|
tomwalters@0
|
278
|
tomwalters@0
|
279
|
tomwalters@0
|
280
|
tomwalters@0
|
281 /*
|
tomwalters@0
|
282 Compare the heads of strings s1 and s2 up to the length of string s1.
|
tomwalters@0
|
283 Return 0 if equal, otherwise return difference number of chars.
|
tomwalters@0
|
284 */
|
tomwalters@0
|
285
|
tomwalters@0
|
286 int strtcmp( s1, s2 )
|
tomwalters@0
|
287 char *s1, *s2 ;
|
tomwalters@0
|
288 {
|
tomwalters@0
|
289 return ( strncmp( s1, s2, strlen( s1 ) ) ) ;
|
tomwalters@0
|
290 }
|
tomwalters@0
|
291
|
tomwalters@0
|
292
|
tomwalters@0
|
293 /*
|
tomwalters@0
|
294 Compare the tails of strings s1 and s2 back to the length of string s2.
|
tomwalters@0
|
295 Return 0 if equal, otherwise return difference number of chars.
|
tomwalters@0
|
296 */
|
tomwalters@0
|
297
|
tomwalters@0
|
298 int strtrcmp( s1, s2 )
|
tomwalters@0
|
299 char *s1, *s2 ;
|
tomwalters@0
|
300 {
|
tomwalters@0
|
301 int i, j ;
|
tomwalters@0
|
302
|
tomwalters@0
|
303 if ( ( i = strlen( s1 ) ) >= ( j = strlen( s2 ) ) )
|
tomwalters@0
|
304 return ( strcmp( s1+i-j, s2 ) ) ;
|
tomwalters@0
|
305 return ( i-j ) ;
|
tomwalters@0
|
306 }
|
tomwalters@0
|
307
|
tomwalters@0
|
308
|
tomwalters@0
|
309 /*
|
tomwalters@0
|
310 Return the span (number of chars) over which the head of string s1 equals the
|
tomwalters@0
|
311 head of string s2.
|
tomwalters@0
|
312 */
|
tomwalters@0
|
313
|
tomwalters@0
|
314 int streqspn( s1, s2 )
|
tomwalters@0
|
315 char *s1, *s2 ;
|
tomwalters@0
|
316 {
|
tomwalters@0
|
317 int spn=0 ;
|
tomwalters@0
|
318
|
tomwalters@0
|
319 while ( !isempty(s1) && *s1++ == *s2++ ) spn++ ;
|
tomwalters@0
|
320 return spn ;
|
tomwalters@0
|
321 }
|
tomwalters@0
|
322
|
tomwalters@0
|
323
|
tomwalters@0
|
324 /*
|
tomwalters@0
|
325 Return the span (number of chars) of a <number> at the head of string s.
|
tomwalters@0
|
326 <number> = [-]<digits>[.]<digits>
|
tomwalters@0
|
327 where either, but not both, of the digit strings may be empty.
|
tomwalters@0
|
328 */
|
tomwalters@0
|
329
|
tomwalters@0
|
330 int strnumspn( s )
|
tomwalters@0
|
331 char *s ;
|
tomwalters@0
|
332 {
|
tomwalters@0
|
333 int j0=0, j1, j2 ;
|
tomwalters@0
|
334
|
tomwalters@0
|
335 if ( *s == '-' ) j0++ ; /* span of '-' */
|
tomwalters@0
|
336 j1 = strspn( s+j0, "0123456789" ) ; /* span of digits left of point */
|
tomwalters@0
|
337 if ( *( s+j0+j1 ) == '.' ) j1++ ; /* span of '.' */
|
tomwalters@0
|
338 j2 = strspn( s+j0+j1, "0123456789" ) ; /* span of digits right of point */
|
tomwalters@0
|
339 if ( *( s+j0+j1+j2 ) == '.' ) j2++ ;
|
tomwalters@0
|
340
|
tomwalters@0
|
341 if ( j1>0 || j2>0 )
|
tomwalters@0
|
342 return ( j0+j1+j2 ) ;
|
tomwalters@0
|
343 return 0 ; /* zero span means no number */
|
tomwalters@0
|
344 }
|
tomwalters@0
|
345
|
tomwalters@0
|
346
|
tomwalters@0
|
347 /*
|
tomwalters@0
|
348 Test for a <number>.
|
tomwalters@0
|
349 */
|
tomwalters@0
|
350
|
tomwalters@0
|
351 int isnumber( s )
|
tomwalters@0
|
352 char *s ;
|
tomwalters@0
|
353 {
|
tomwalters@0
|
354 if ( strnumspn( s ) > 0 ) return 1 ;
|
tomwalters@0
|
355 else return 0 ;
|
tomwalters@0
|
356 }
|
tomwalters@0
|
357
|
tomwalters@0
|
358
|
tomwalters@0
|
359 /*
|
tomwalters@0
|
360 Return a ptr to the first char after a <number> at the head of string s.
|
tomwalters@0
|
361 */
|
tomwalters@0
|
362
|
tomwalters@0
|
363 char *strnumptr( s )
|
tomwalters@0
|
364 char *s ;
|
tomwalters@0
|
365 {
|
tomwalters@0
|
366 return ( s + strnumspn( s ) ) ;
|
tomwalters@0
|
367 }
|
tomwalters@0
|
368
|
tomwalters@0
|
369
|
tomwalters@0
|
370 /*
|
tomwalters@0
|
371 Return a ptr to the first occurrence of any number char in s.
|
tomwalters@0
|
372 (where a number char includes '-' and '.' as well as any digit).
|
tomwalters@0
|
373 */
|
tomwalters@0
|
374
|
tomwalters@0
|
375 char *strpnum(s)
|
tomwalters@0
|
376 char *s ;
|
tomwalters@0
|
377 {
|
tomwalters@0
|
378 return ( strpbrk( s, "-.0123456789" ) ) ;
|
tomwalters@0
|
379 }
|
tomwalters@0
|
380
|
tomwalters@0
|
381 /*
|
tomwalters@0
|
382 Return a ptr to the first occurrence of any char in s not a number char.
|
tomwalters@0
|
383 (where a number char includes '-' and '.' as well as any digit).
|
tomwalters@0
|
384 */
|
tomwalters@0
|
385
|
tomwalters@0
|
386 char *strcnum(s)
|
tomwalters@0
|
387 char *s ;
|
tomwalters@0
|
388 {
|
tomwalters@0
|
389 return ( strcbrk( s, "-.0123456789" ) ) ;
|
tomwalters@0
|
390 }
|
tomwalters@0
|
391
|
tomwalters@0
|
392
|
tomwalters@0
|
393 /*
|
tomwalters@0
|
394 Separate string `s1' into two string tokens at the first occurrence of a
|
tomwalters@0
|
395 separator character `s2'. (Given as a string of one char).
|
tomwalters@0
|
396 Numbers at the head of `s1' are skipped. (This skips leading hyphens or points
|
tomwalters@0
|
397 which are part of a number, and so allows negative numbers with splitting
|
tomwalters@0
|
398 hyphens, real numbers with splitting decimal point, etc.).
|
tomwalters@0
|
399 Four possible outcomes, depending upon form of `s1':
|
tomwalters@0
|
400 1. Null or empty. - return NULL ptr, (missing 1st and 2nd tokens).
|
tomwalters@0
|
401 2. No separator char. - return ptr to empty string, (empty 2nd token).
|
tomwalters@0
|
402 3. Separator is last char. - return NULL ptr, (missing 2nd token).
|
tomwalters@0
|
403 4. Separator within `s1'. - return ptr to 2nd token, (two correct tokens).
|
tomwalters@0
|
404 String `s1' is unchanged at the end.
|
tomwalters@0
|
405 */
|
tomwalters@0
|
406
|
tomwalters@0
|
407 char *strpsep( s1, s2 )
|
tomwalters@0
|
408 char *s1, *s2 ;
|
tomwalters@0
|
409 {
|
tomwalters@0
|
410 char *s ;
|
tomwalters@0
|
411
|
tomwalters@0
|
412 if ( isnullorempty( s1 ) )
|
tomwalters@0
|
413 return ( (char *)0 ) ;
|
tomwalters@0
|
414
|
tomwalters@0
|
415 s1 = strnumptr( s1 ) ; /* skip leading numbers */
|
tomwalters@0
|
416
|
tomwalters@0
|
417 if ( ( s = strpbrk( s1, s2 ) ) == (char *)0 )
|
tomwalters@0
|
418 return ( s1 + strlen( s1 ) ) ; /* ptr to empty string at end s1 */
|
tomwalters@0
|
419
|
tomwalters@0
|
420 if ( isempty( ( s2 = s+1 ) ) )
|
tomwalters@0
|
421 return ( (char *)0 ) ; /* separator is last char */
|
tomwalters@0
|
422
|
tomwalters@0
|
423 return ( s2 ) ;
|
tomwalters@0
|
424 }
|
tomwalters@0
|
425
|
tomwalters@0
|
426 /* Replace above last 4 lines of routine, and also mod strsep, to get proper
|
tomwalters@0
|
427 string separator
|
tomwalters@0
|
428 if ( ( s2 = strcbrk( s, s2 ) ) == (char *)0 )
|
tomwalters@0
|
429 return ( (char *)0 ) ;
|
tomwalters@0
|
430 while ( --s2 > s && isnumber( s2 ) ) ;
|
tomwalters@0
|
431 return ( ++s2 ) ;
|
tomwalters@0
|
432 */
|
tomwalters@0
|
433
|
tomwalters@0
|
434 /*
|
tomwalters@0
|
435 Separate string `s1' into two string tokens.
|
tomwalters@0
|
436 strsep() is the same as strpsep() except that, in the event of two correct
|
tomwalters@0
|
437 tokens, insert '\0' at the separator.
|
tomwalters@0
|
438 String `s1' is thus separated and becomes the first token.
|
tomwalters@0
|
439 */
|
tomwalters@0
|
440
|
tomwalters@0
|
441 char *strsep( s1, s2 )
|
tomwalters@0
|
442 char *s1, *s2 ;
|
tomwalters@0
|
443 {
|
tomwalters@0
|
444 char *s = strpsep( s1, s2 ) ; /* ptr to 2nd token */
|
tomwalters@0
|
445
|
tomwalters@0
|
446 if ( isnullorempty( s ) )
|
tomwalters@0
|
447 return s ;
|
tomwalters@0
|
448
|
tomwalters@0
|
449 *(s-1) = '\0' ; /* insert '\0' and return 2nd token */
|
tomwalters@0
|
450 return ( s ) ;
|
tomwalters@0
|
451 }
|
tomwalters@0
|
452
|
tomwalters@0
|
453
|
tomwalters@0
|
454 /*
|
tomwalters@0
|
455 Compare the head of string `s' with null-terminated list of strings `list'.
|
tomwalters@0
|
456 Return the longest matching string from `list'.
|
tomwalters@0
|
457 Return a NULL pointer if no match is found, or if the (possibly abbreviated)
|
tomwalters@0
|
458 head of string `s' is ambiguous (ie. matches more than once in the list).
|
tomwalters@0
|
459 */
|
tomwalters@0
|
460
|
tomwalters@0
|
461 char *listcmp( list, s )
|
tomwalters@0
|
462 char **list ;
|
tomwalters@0
|
463 char *s ;
|
tomwalters@0
|
464 {
|
tomwalters@0
|
465 int i, j = (-1) ;
|
tomwalters@0
|
466
|
tomwalters@0
|
467 for ( i=0; list[i] != (char *)0 ; i++)
|
tomwalters@0
|
468 if ( strtcmp( s, list[i] ) == 0 ) {
|
tomwalters@0
|
469 if ( j >= 0 ) return (char *)0 ; /* ambiguous match */
|
tomwalters@0
|
470 else j = i;
|
tomwalters@0
|
471 }
|
tomwalters@0
|
472 if ( j < 0 ) return (char *)0 ; /* match not found */
|
tomwalters@0
|
473 return ( list[j] ) ;
|
tomwalters@0
|
474 }
|
tomwalters@0
|
475
|
tomwalters@0
|
476
|
tomwalters@0
|
477 /*
|
tomwalters@0
|
478 Compare the tail of string `s' with null-terminated list of strings `list'.
|
tomwalters@0
|
479 Return the longest matching string from `list'.
|
tomwalters@0
|
480 Return a NULL pointer if no match is found, or if the (possibly abbreviated)
|
tomwalters@0
|
481 tail of string `s' is ambiguous (ie. matches more than once in the list).
|
tomwalters@0
|
482 */
|
tomwalters@0
|
483
|
tomwalters@0
|
484 char *listrcmp( list, s )
|
tomwalters@0
|
485 char **list ;
|
tomwalters@0
|
486 char *s ;
|
tomwalters@0
|
487 {
|
tomwalters@0
|
488 int i, j = (-1), k, maxlen = 0 ;
|
tomwalters@0
|
489
|
tomwalters@0
|
490 for ( i=0; list[i] != (char *)0 ; i++)
|
tomwalters@0
|
491 if ( strtrcmp( s, list[i] ) == 0 && ( k = strlen( list[i] ) ) > maxlen ) {
|
tomwalters@0
|
492 maxlen = k ;
|
tomwalters@0
|
493 j = i ;
|
tomwalters@0
|
494 }
|
tomwalters@0
|
495 if ( j < 0 ) return (char *)0 ; /* match not found */
|
tomwalters@0
|
496 return ( list[j] ) ;
|
tomwalters@0
|
497 }
|
tomwalters@0
|
498
|
tomwalters@0
|
499
|
tomwalters@0
|
500 /*
|
tomwalters@0
|
501 Compare the head of string `s' with null-terminated list of strings `list'.
|
tomwalters@0
|
502 Find the string in `list' having the longest matching span with the head of
|
tomwalters@0
|
503 `s' (which is possibly abbreviated).
|
tomwalters@0
|
504 Return the list index of the matching string.
|
tomwalters@0
|
505 Return (-1) if there is no match in the list (all spans are zero).
|
tomwalters@0
|
506 Return (-2) if the longest matching span is ambiguous (ie occurs more
|
tomwalters@0
|
507 than once in the list).
|
tomwalters@0
|
508 */
|
tomwalters@0
|
509
|
tomwalters@0
|
510 int listindex( list, s )
|
tomwalters@0
|
511 char **list ;
|
tomwalters@0
|
512 char *s ;
|
tomwalters@0
|
513 {
|
tomwalters@0
|
514 int i, j, jmax = 0, index = (-1) ;
|
tomwalters@0
|
515
|
tomwalters@0
|
516 for ( i=0; list[i] != (char *)0 ; i++) {
|
tomwalters@0
|
517 if ( ( j = streqspn( s, list[i] ) ) > jmax ) {
|
tomwalters@0
|
518 jmax = j ;
|
tomwalters@0
|
519 index = i ;
|
tomwalters@0
|
520 }
|
tomwalters@0
|
521 else if ( j > 0 && j == jmax )
|
tomwalters@0
|
522 index = (-2) ;
|
tomwalters@0
|
523 }
|
tomwalters@0
|
524 return index ;
|
tomwalters@0
|
525 }
|
tomwalters@0
|
526
|
tomwalters@0
|
527
|
tomwalters@0
|
528 /*
|
tomwalters@0
|
529 Return the length of the null-terminated list of strings `list', ie. the
|
tomwalters@0
|
530 number of strings it contains.
|
tomwalters@0
|
531 */
|
tomwalters@0
|
532
|
tomwalters@0
|
533 listsize( list )
|
tomwalters@0
|
534 char **list ;
|
tomwalters@0
|
535 {
|
tomwalters@0
|
536 int i ;
|
tomwalters@0
|
537
|
tomwalters@0
|
538 for ( i = 0 ; list[i] != (char *)0 ; i++ )
|
tomwalters@0
|
539 ;
|
tomwalters@0
|
540 return i ;
|
tomwalters@0
|
541 }
|
tomwalters@0
|
542
|
tomwalters@0
|
543
|
tomwalters@0
|
544 /*
|
tomwalters@0
|
545 For each string in list1, find the index of the matching string in list2
|
tomwalters@0
|
546 and store it in the index array, (which must be at least the size of list1).
|
tomwalters@0
|
547 The string match allows for abbreviations in the list1 strings.
|
tomwalters@0
|
548 Return the number of matching strings found. (If this is less than the size
|
tomwalters@0
|
549 of list1 then list1 contains an unknown or an ambiguous string).
|
tomwalters@0
|
550 */
|
tomwalters@0
|
551
|
tomwalters@0
|
552 mapindices( list1, list2, index )
|
tomwalters@0
|
553 char **list1, **list2 ;
|
tomwalters@0
|
554 int *index ;
|
tomwalters@0
|
555 {
|
tomwalters@0
|
556 int i, j, n = 0 ;
|
tomwalters@0
|
557
|
tomwalters@0
|
558 for ( i = 0 ; list1[i] != (char *)0 ; i++ )
|
tomwalters@0
|
559 if ( ( j = listindex( list2, list1[i] ) ) >= 0 )
|
tomwalters@0
|
560 index[n++] = j ;
|
tomwalters@0
|
561
|
tomwalters@0
|
562 return n ;
|
tomwalters@0
|
563 }
|
tomwalters@0
|
564
|
tomwalters@0
|
565
|
tomwalters@0
|
566 /*
|
tomwalters@0
|
567 Split the given string `str' into tokens at occurrences of separator char c.
|
tomwalters@0
|
568 Store pointers to each token in `list', and null-terminate each token
|
tomwalters@0
|
569 by overwriting the separator char with null.
|
tomwalters@0
|
570 The list must contain at most n pointers.
|
tomwalters@0
|
571 Return the number of tokens, or 0 if an error.
|
tomwalters@0
|
572 */
|
tomwalters@0
|
573
|
tomwalters@0
|
574 tokens( str, list, n, c )
|
tomwalters@0
|
575 char *str ;
|
tomwalters@0
|
576 char **list ;
|
tomwalters@0
|
577 int n ;
|
tomwalters@0
|
578 char c ;
|
tomwalters@0
|
579 {
|
tomwalters@0
|
580 int i ;
|
tomwalters@0
|
581 char *s ;
|
tomwalters@0
|
582
|
tomwalters@0
|
583 if ( isempty( str ) || *str == c || n <= 0 ) return 0 ;
|
tomwalters@0
|
584 list[0] = str ;
|
tomwalters@0
|
585
|
tomwalters@0
|
586 for ( i = 1 ; i < n && ( s = strchr( str, c ) ) != (char *)0 ; i++ ) {
|
tomwalters@0
|
587 *s = '\0' ;
|
tomwalters@0
|
588 str = s + 1 ;
|
tomwalters@0
|
589 if ( isempty( str ) || *str == c ) return 0 ;
|
tomwalters@0
|
590 list[i] = str ;
|
tomwalters@0
|
591 }
|
tomwalters@0
|
592
|
tomwalters@0
|
593 if ( i == n && strchr( str, c ) != (char *)0 ) return 0 ;
|
tomwalters@0
|
594
|
tomwalters@0
|
595 return i ;
|
tomwalters@0
|
596 }
|
tomwalters@0
|
597
|
tomwalters@0
|
598
|
tomwalters@0
|
599
|
tomwalters@0
|
600 /*
|
tomwalters@0
|
601 Return ASCII string of integer i. (Inverse of atoi()).
|
tomwalters@0
|
602 */
|
tomwalters@0
|
603
|
tomwalters@0
|
604 char *itoa( i )
|
tomwalters@0
|
605 int i ;
|
tomwalters@0
|
606 {
|
tomwalters@0
|
607 char s[64], *s1 ;
|
tomwalters@0
|
608
|
tomwalters@0
|
609 sprintf( s, "%d", i ) ;
|
tomwalters@0
|
610 s1 = (char *)malloc( strlen( s ) + 1 ) ;
|
tomwalters@0
|
611 strcpy( s1, s ) ;
|
tomwalters@0
|
612 return s1 ;
|
tomwalters@0
|
613 }
|