Mercurial > hg > nnchat
comparison th_string.c @ 11:707e35b03f89
Synced th-libs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 22 Mar 2008 02:52:01 +0000 |
parents | ecfa4e3597e3 |
children | e47955d42b55 |
comparison
equal
deleted
inserted
replaced
10:53e127854dca | 11:707e35b03f89 |
---|---|
13 #define LPREV (pNode->pPrev) | 13 #define LPREV (pNode->pPrev) |
14 #define LNEXT (pNode->pNext) | 14 #define LNEXT (pNode->pNext) |
15 | 15 |
16 /* Allocate memory for a string with given length | 16 /* Allocate memory for a string with given length |
17 */ | 17 */ |
18 char_t *th_stralloc(const size_t l) | 18 char *th_stralloc(const size_t l) |
19 { | 19 { |
20 assert(l > 0); | 20 assert(l > 0); |
21 return th_malloc(sizeof(char_t) * l); | 21 return th_malloc(sizeof(char) * l); |
22 } | 22 } |
23 | 23 |
24 | 24 |
25 char_t *th_strrealloc(char_t * s, const size_t l) | 25 char *th_strrealloc(char * s, const size_t l) |
26 { | 26 { |
27 assert(l > 0); | 27 assert(l > 0); |
28 return th_realloc(s, sizeof(char_t) * l); | 28 return th_realloc(s, sizeof(char) * l); |
29 } | |
30 | |
31 | |
32 /* Calculate the length of a string [strlen] | |
33 */ | |
34 size_t th_strlen(char_t * pStr) | |
35 { | |
36 size_t l = 0; | |
37 char_t *s = pStr; | |
38 assert(pStr); | |
39 | |
40 while (*s) { | |
41 s++; | |
42 l++; | |
43 } | |
44 | |
45 return l; | |
46 } | 29 } |
47 | 30 |
48 | 31 |
49 /* Duplicate a string [strdup] | 32 /* Duplicate a string [strdup] |
50 */ | 33 */ |
51 char_t *th_strdup(char_t * pStr) | 34 char *th_strdup(char * str) |
52 { | 35 { |
53 char_t *pResult, *s, *d; | 36 char *result, *s, *d; |
54 | 37 |
55 if (!pStr) return NULL; | 38 if (!str) return NULL; |
56 | 39 |
57 /* Allocate memory for destination */ | 40 /* Allocate memory for destination */ |
58 pResult = th_stralloc(th_strlen(pStr) + 1); | 41 result = th_stralloc(strlen(str) + 1); |
59 if (!pResult) | 42 if (!result) |
60 return NULL; | 43 return NULL; |
61 | 44 |
62 /* Copy to the destination */ | 45 /* Copy to the destination */ |
63 s = pStr; | 46 s = str; |
64 d = pResult; | 47 d = result; |
65 while (*s) { | 48 while (*s) { |
66 *(d++) = *(s++); | 49 *(d++) = *(s++); |
67 } | 50 } |
68 *d = 0; | 51 *d = 0; |
69 | 52 |
70 return pResult; | 53 return result; |
71 } | 54 } |
72 | 55 |
73 | 56 |
74 /* Concatenate a string [strcat] | 57 char *th_strncpy(char * dst, char * src, size_t n) |
75 */ | 58 { |
76 char_t *th_strcat(char_t * pDest, char_t * pSource) | 59 char *s, *d; |
77 { | |
78 char_t *s, *d; | |
79 assert(pSource); | |
80 assert(pDest); | |
81 | |
82 /* Copy to the destination */ | |
83 s = pSource; | |
84 d = pDest; | |
85 | |
86 while (*d) d++; | |
87 | |
88 while (*s) { | |
89 *(d++) = *(s++); | |
90 } | |
91 *d = 0; | |
92 | |
93 return pDest; | |
94 } | |
95 | |
96 | |
97 /* Copy a string [strcpy, strncpy] | |
98 */ | |
99 char_t *th_strcpy(char_t * pDest, char_t * pSource) | |
100 { | |
101 char_t *s, *d; | |
102 assert(pSource); | |
103 assert(pDest); | |
104 | |
105 /* Copy to the destination */ | |
106 s = pSource; | |
107 d = pDest; | |
108 | |
109 while (*s) { | |
110 *(d++) = *(s++); | |
111 } | |
112 *d = 0; | |
113 | |
114 return pDest; | |
115 } | |
116 | |
117 | |
118 char_t *th_strncpy(char_t * pDest, char_t * pSource, size_t n) | |
119 { | |
120 char_t *s, *d; | |
121 size_t i; | 60 size_t i; |
122 assert(pSource); | 61 assert(src); |
123 assert(pDest); | 62 assert(dst); |
124 | 63 |
125 /* Copy to the destination */ | 64 /* Copy to the destination */ |
126 i = n; | 65 i = n; |
127 s = pSource; | 66 s = src; |
128 d = pDest; | 67 d = dst; |
129 while (*s && (i > 0)) { | 68 while (*s && (i > 0)) { |
130 *(d++) = *(s++); | 69 *(d++) = *(s++); |
131 i--; | 70 i--; |
132 } | 71 } |
133 | 72 |
136 *(d++) = 0; | 75 *(d++) = 0; |
137 i--; | 76 i--; |
138 } | 77 } |
139 | 78 |
140 /* Ensure that last is always zero */ | 79 /* Ensure that last is always zero */ |
141 pDest[n - 1] = 0; | 80 dst[n - 1] = 0; |
142 | 81 |
143 return pDest; | 82 return dst; |
144 } | 83 } |
145 | 84 |
146 | 85 |
147 /* Compare given strings [strcmp, strncmp] | 86 int th_strncmp(char * str1, char * str2, size_t n) |
148 */ | 87 { |
149 int th_strcmp(char_t * pStr1, char_t * pStr2) | 88 char *s1, *s2; |
150 { | 89 assert(str1); |
151 char_t *s1, *s2; | 90 assert(str2); |
152 assert(pStr1); | |
153 assert(pStr2); | |
154 | 91 |
155 /* Check the string pointers */ | 92 /* Check the string pointers */ |
156 if (pStr1 == pStr2) | 93 if (str1 == str2) |
157 return 0; | 94 return 0; |
158 | 95 |
159 /* Go through the string */ | 96 /* Go through the string */ |
160 s1 = pStr1; | 97 s1 = str1; |
161 s2 = pStr2; | 98 s2 = str2; |
162 while (*s1 && *s2 && (*s1 == *s2)) { | |
163 s1++; | |
164 s2++; | |
165 } | |
166 | |
167 return ((*s1) - (*s2)); | |
168 } | |
169 | |
170 | |
171 int th_strncmp(char_t * pStr1, char_t * pStr2, size_t n) | |
172 { | |
173 char_t *s1, *s2; | |
174 assert(pStr1); | |
175 assert(pStr2); | |
176 | |
177 /* Check the string pointers */ | |
178 if (pStr1 == pStr2) | |
179 return 0; | |
180 | |
181 /* Go through the string */ | |
182 s1 = pStr1; | |
183 s2 = pStr2; | |
184 while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) { | 99 while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) { |
185 s1++; | 100 s1++; |
186 s2++; | 101 s2++; |
187 n--; | 102 n--; |
188 } | 103 } |
194 } | 109 } |
195 | 110 |
196 | 111 |
197 /* Compare two strings ignoring case [strcasecmp, strncasecmp] | 112 /* Compare two strings ignoring case [strcasecmp, strncasecmp] |
198 */ | 113 */ |
199 int th_strcasecmp(char_t * pStr1, char_t * pStr2) | 114 int th_strcasecmp(char * str1, char * str2) |
200 { | 115 { |
201 char_t *s1, *s2; | 116 char *s1 = str1, *s2 = str2; |
202 assert(pStr1); | 117 assert(str1); |
203 assert(pStr2); | 118 assert(str2); |
204 | 119 |
205 /* Check the string pointers */ | 120 /* Check the string pointers */ |
206 if (pStr1 == pStr2) | 121 if (str1 == str2) |
207 return 0; | 122 return 0; |
208 | 123 |
209 /* Go through the string */ | 124 /* Go through the string */ |
210 s1 = pStr1; | |
211 s2 = pStr2; | |
212 while (*s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { | 125 while (*s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { |
213 s1++; | 126 s1++; |
214 s2++; | 127 s2++; |
215 } | 128 } |
216 | 129 |
217 return (th_tolower(*s1) - th_tolower(*s2)); | 130 return (th_tolower(*s1) - th_tolower(*s2)); |
218 } | 131 } |
219 | 132 |
220 | 133 |
221 int th_strncasecmp(char_t * pStr1, char_t * pStr2, size_t n) | 134 int th_strncasecmp(char * str1, char * str2, size_t n) |
222 { | 135 { |
223 char_t *s1, *s2; | 136 char *s1 = str1, *s2 = str2; |
224 assert(pStr1); | 137 assert(str1); |
225 assert(pStr2); | 138 assert(str2); |
226 | 139 |
227 /* Check the string pointers */ | 140 /* Check the string pointers */ |
228 if (pStr1 == pStr2) | 141 if (str1 == str2) |
229 return 0; | 142 return 0; |
230 | 143 |
231 /* Go through the string */ | 144 /* Go through the string */ |
232 s1 = pStr1; | |
233 s2 = pStr2; | |
234 while ((n > 0) && *s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { | 145 while ((n > 0) && *s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { |
235 s1++; | 146 s1++; |
236 s2++; | 147 s2++; |
237 n--; | 148 n--; |
238 } | 149 } |
245 | 156 |
246 | 157 |
247 /* Remove all occurences of control characters, in-place. | 158 /* Remove all occurences of control characters, in-place. |
248 * Resulting string is always shorter or same length than original. | 159 * Resulting string is always shorter or same length than original. |
249 */ | 160 */ |
250 void th_strip_ctrlchars(char_t * pStr) | 161 void th_strip_ctrlchars(char * str) |
251 { | 162 { |
252 char_t *i, *j; | 163 char *i, *j; |
253 assert(pStr); | 164 assert(str); |
254 | 165 |
255 i = pStr; | 166 i = str; |
256 j = pStr; | 167 j = str; |
257 while (*i) { | 168 while (*i) { |
258 if (!th_iscntrl(*i)) | 169 if (!th_iscntrl(*i)) |
259 *(j++) = *i; | 170 *(j++) = *i; |
260 i++; | 171 i++; |
261 } | 172 } |
262 | 173 |
263 *j = 0; | 174 *j = 0; |
264 } | 175 } |
265 | 176 |
266 | 177 |
267 /* Locate a substring [strstr] | 178 /* Copy a given string over in *result. |
268 */ | 179 */ |
269 char_t *th_strstr(char_t * haystack, char_t * needle) | 180 int th_pstrcpy(char ** result, char * str) |
270 { | 181 { |
271 char_t *h, *n, *s; | 182 assert(result); |
272 assert(haystack); | |
273 assert(needle); | |
274 | |
275 /* If 'needle' is empty, we return 'haystack' */ | |
276 if (!*needle) | |
277 return haystack; | |
278 | |
279 /* Search for 'needle' in 'haystack' */ | |
280 h = haystack; | |
281 n = needle; | |
282 while (*h) { | |
283 /* Find possible start of 'needle' */ | |
284 while (*h && (*h != *n)) | |
285 h++; | |
286 | |
287 if (*h == *n) { | |
288 /* Found, check rest */ | |
289 s = h; | |
290 n = needle; | |
291 while (*h) { | |
292 if (!*n) | |
293 return s; | |
294 else | |
295 if (*h != *n) | |
296 break; | |
297 n++; | |
298 h++; | |
299 } | |
300 h = s; | |
301 h++; | |
302 } | |
303 } | |
304 | |
305 return NULL; | |
306 } | |
307 | |
308 | |
309 /* Copy a given string over in *ppResult. | |
310 */ | |
311 int th_pstrcpy(char_t ** ppResult, char_t * pStr) | |
312 { | |
313 assert(ppResult); | |
314 | 183 |
315 /* Check the string pointers */ | 184 /* Check the string pointers */ |
316 if (!pStr) | 185 if (!str) |
317 return -1; | 186 return -1; |
318 | 187 |
319 /* Allocate memory for destination */ | 188 /* Allocate memory for destination */ |
320 th_free(*ppResult); | 189 th_free(*result); |
321 *ppResult = th_stralloc(th_strlen(pStr) + 1); | 190 *result = th_stralloc(strlen(str) + 1); |
322 if (!*ppResult) | 191 if (!*result) |
323 return -2; | 192 return -2; |
324 | 193 |
325 /* Copy to the destination */ | 194 /* Copy to the destination */ |
326 th_strcpy(*ppResult, pStr); | 195 strcpy(*result, str); |
327 | 196 |
328 return 0; | 197 return 0; |
329 } | 198 } |
330 | 199 |
331 | 200 |
332 /* Concatenates a given string into string pointed by *ppResult. | 201 /* Concatenates a given string into string pointed by *result. |
333 */ | 202 */ |
334 int th_pstrcat(char_t ** ppResult, char_t * pStr) | 203 int th_pstrcat(char ** result, char * str) |
335 { | 204 { |
336 assert(ppResult); | 205 assert(result); |
337 | 206 |
338 /* Check the string pointers */ | 207 /* Check the string pointers */ |
339 if (!pStr) | 208 if (!str) |
340 return -1; | 209 return -1; |
341 | 210 |
342 if (*ppResult != NULL) { | 211 if (*result != NULL) { |
343 *ppResult = th_strrealloc(*ppResult, th_strlen(*ppResult) + th_strlen(pStr) + 1); | 212 *result = th_strrealloc(*result, strlen(*result) + strlen(str) + 1); |
344 if (*ppResult == NULL) | 213 if (*result == NULL) |
345 return -1; | 214 return -1; |
346 | 215 |
347 th_strcat(*ppResult, pStr); | 216 strcat(*result, str); |
348 } else { | 217 } else { |
349 *ppResult = th_stralloc(th_strlen(pStr) + 1); | 218 *result = th_stralloc(strlen(str) + 1); |
350 if (*ppResult == NULL) | 219 if (*result == NULL) |
351 return -1; | 220 return -1; |
352 | 221 |
353 th_strcpy(*ppResult, pStr); | 222 strcpy(*result, str); |
354 } | 223 } |
355 | 224 |
356 return 0; | 225 return 0; |
357 } | 226 } |
358 | 227 |
359 | 228 |
360 /* Find next non-whitespace character in string. | 229 /* Find next non-whitespace character in string. |
361 * Updates iPos into the position of such character and | 230 * Updates iPos into the position of such character and |
362 * returns pointer to the string. | 231 * returns pointer to the string. |
363 */ | 232 */ |
364 char_t *th_findnext(char_t * pStr, size_t * iPos) | 233 char *th_findnext(char * str, size_t * iPos) |
365 { | 234 { |
366 assert(pStr); | 235 assert(str); |
367 | 236 |
368 /* Terminating NULL-character is not whitespace! */ | 237 /* Terminating NULL-character is not whitespace! */ |
369 while (th_isspace(pStr[*iPos])) | 238 while (th_isspace(str[*iPos])) |
370 (*iPos)++; | 239 (*iPos)++; |
371 return &pStr[*iPos]; | 240 return &str[*iPos]; |
372 } | 241 } |
373 | 242 |
374 | 243 |
375 /* Find next chSep-character from string | 244 /* Find next chSep-character from string |
376 */ | 245 */ |
377 char_t *th_findsep(char_t * pStr, size_t * iPos, char_t chSep) | 246 char *th_findsep(char * str, size_t * iPos, char chSep) |
378 { | 247 { |
379 assert(pStr); | 248 assert(str); |
380 | 249 |
381 /* Terminating NULL-character is not digit! */ | 250 /* Terminating NULL-character is not digit! */ |
382 while (pStr[*iPos] && (pStr[*iPos] != chSep)) | 251 while (str[*iPos] && (str[*iPos] != chSep)) |
383 (*iPos)++; | 252 (*iPos)++; |
384 return &pStr[*iPos]; | 253 return &str[*iPos]; |
385 } | 254 } |
386 | 255 |
387 | 256 |
388 /* Find next chSep- or whitespace from string | 257 /* Find next chSep- or whitespace from string |
389 */ | 258 */ |
390 char_t *th_findseporspace(char_t * pStr, size_t * iPos, char_t chSep) | 259 char *th_findseporspace(char * str, size_t * iPos, char chSep) |
391 { | 260 { |
392 assert(pStr); | 261 assert(str); |
393 | 262 |
394 /* Terminating NULL-character is not digit! */ | 263 /* Terminating NULL-character is not digit! */ |
395 while (!th_isspace(pStr[*iPos]) && (pStr[*iPos] != chSep)) | 264 while (!th_isspace(str[*iPos]) && (str[*iPos] != chSep)) |
396 (*iPos)++; | 265 (*iPos)++; |
397 return &pStr[*iPos]; | 266 return &str[*iPos]; |
398 } | 267 } |
399 | 268 |
400 | 269 |
401 /* Compare a string to a pattern. Case-SENSITIVE version. | 270 /* Compare a string to a pattern. Case-SENSITIVE version. |
402 * The matching pattern can consist of any normal characters plus | 271 * The matching pattern can consist of any normal characters plus |
403 * wildcards ? and *. "?" matches any character and "*" matches | 272 * wildcards ? and *. "?" matches any character and "*" matches |
404 * any number of characters. | 273 * any number of characters. |
405 */ | 274 */ |
406 BOOL th_strmatch(char_t * pStr, char_t * pPattern) | 275 BOOL th_strmatch(char * str, char * pattern) |
407 { | 276 { |
408 BOOL didMatch, isAnyMode, isEnd; | 277 BOOL didMatch, isAnyMode, isEnd; |
409 char_t *tmpPattern; | 278 char *tmpPattern; |
410 | 279 |
411 /* Check given pattern and string */ | 280 /* Check given pattern and string */ |
412 if (!pStr) | 281 if (!str) |
413 return FALSE; | 282 return FALSE; |
414 if (!pPattern) | 283 if (!pattern) |
415 return FALSE; | 284 return FALSE; |
416 | 285 |
417 /* Initialize */ | 286 /* Initialize */ |
418 tmpPattern = NULL; | 287 tmpPattern = NULL; |
419 didMatch = TRUE; | 288 didMatch = TRUE; |
421 isAnyMode = FALSE; | 290 isAnyMode = FALSE; |
422 | 291 |
423 /* Start comparision */ | 292 /* Start comparision */ |
424 do { | 293 do { |
425 didMatch = FALSE; | 294 didMatch = FALSE; |
426 switch (*pPattern) { | 295 switch (*pattern) { |
427 case '?': | 296 case '?': |
428 /* Any single character matches */ | 297 /* Any single character matches */ |
429 if (*pStr) { | 298 if (*str) { |
430 didMatch = TRUE; | 299 didMatch = TRUE; |
431 pPattern++; | 300 pattern++; |
432 pStr++; | 301 str++; |
433 } | 302 } |
434 break; | 303 break; |
435 | 304 |
436 case '*': | 305 case '*': |
437 didMatch = TRUE; | 306 didMatch = TRUE; |
438 pPattern++; | 307 pattern++; |
439 if (!*pPattern) | 308 if (!*pattern) |
440 isEnd = TRUE; | 309 isEnd = TRUE; |
441 isAnyMode = TRUE; | 310 isAnyMode = TRUE; |
442 tmpPattern = pPattern; | 311 tmpPattern = pattern; |
443 break; | 312 break; |
444 | 313 |
445 case 0: | 314 case 0: |
446 if (isAnyMode) { | 315 if (isAnyMode) { |
447 if (*pStr) | 316 if (*str) |
448 pStr++; | 317 str++; |
449 else | 318 else |
450 isEnd = TRUE; | 319 isEnd = TRUE; |
451 } else { | 320 } else { |
452 if (*pStr) { | 321 if (*str) { |
453 if (tmpPattern) { | 322 if (tmpPattern) { |
454 isAnyMode = TRUE; | 323 isAnyMode = TRUE; |
455 pPattern = tmpPattern; | 324 pattern = tmpPattern; |
456 } else | 325 } else |
457 didMatch = FALSE; | 326 didMatch = FALSE; |
458 } else | 327 } else |
459 isEnd = TRUE; | 328 isEnd = TRUE; |
460 } | 329 } |
461 break; | 330 break; |
462 default: | 331 default: |
463 if (isAnyMode) { | 332 if (isAnyMode) { |
464 if ((*pPattern) == (*pStr)) { | 333 if ((*pattern) == (*str)) { |
465 isAnyMode = FALSE; | 334 isAnyMode = FALSE; |
466 didMatch = TRUE; | 335 didMatch = TRUE; |
467 } else { | 336 } else { |
468 if (*pStr) { | 337 if (*str) { |
469 didMatch = TRUE; | 338 didMatch = TRUE; |
470 pStr++; | 339 str++; |
471 } | 340 } |
472 } | 341 } |
473 } else { | 342 } else { |
474 if ((*pPattern) == (*pStr)) { | 343 if ((*pattern) == (*str)) { |
475 didMatch = TRUE; | 344 didMatch = TRUE; |
476 if (*pPattern) | 345 if (*pattern) |
477 pPattern++; | 346 pattern++; |
478 if (*pStr) | 347 if (*str) |
479 pStr++; | 348 str++; |
480 } else { | 349 } else { |
481 if (tmpPattern) { | 350 if (tmpPattern) { |
482 didMatch = TRUE; | 351 didMatch = TRUE; |
483 isAnyMode = TRUE; | 352 isAnyMode = TRUE; |
484 pPattern = tmpPattern; | 353 pattern = tmpPattern; |
485 } | 354 } |
486 } | 355 } |
487 } | 356 } |
488 | 357 |
489 if (!*pStr && !*pPattern) | 358 if (!*str && !*pattern) |
490 isEnd = TRUE; | 359 isEnd = TRUE; |
491 break; | 360 break; |
492 | 361 |
493 } /* switch */ | 362 } /* switch */ |
494 | 363 |
498 } | 367 } |
499 | 368 |
500 | 369 |
501 /* Compare a string to a pattern. Case-INSENSITIVE version. | 370 /* Compare a string to a pattern. Case-INSENSITIVE version. |
502 */ | 371 */ |
503 BOOL th_strcasematch(char_t * pStr, char_t * pPattern) | 372 BOOL th_strcasematch(char * str, char * pattern) |
504 { | 373 { |
505 BOOL didMatch, isAnyMode, isEnd; | 374 BOOL didMatch, isAnyMode, isEnd; |
506 char_t *tmpPattern; | 375 char *tmpPattern; |
507 | 376 |
508 /* Check given pattern and string */ | 377 /* Check given pattern and string */ |
509 if (!pStr) | 378 if (!str) |
510 return FALSE; | 379 return FALSE; |
511 if (!pPattern) | 380 if (!pattern) |
512 return FALSE; | 381 return FALSE; |
513 | 382 |
514 /* Initialize */ | 383 /* Initialize */ |
515 tmpPattern = NULL; | 384 tmpPattern = NULL; |
516 didMatch = TRUE; | 385 didMatch = TRUE; |
517 isEnd = FALSE; | 386 isEnd = FALSE; |
518 isAnyMode = FALSE; | 387 isAnyMode = FALSE; |
519 | 388 |
520 /* Start comparision */ | 389 /* Start comparision */ |
521 do { | 390 do { |
522 switch (*pPattern) { | 391 switch (*pattern) { |
523 case '?': | 392 case '?': |
524 /* Any single character matches */ | 393 /* Any single character matches */ |
525 if (*pStr) { | 394 if (*str) { |
526 pPattern++; | 395 pattern++; |
527 pStr++; | 396 str++; |
528 } else | 397 } else |
529 didMatch = FALSE; | 398 didMatch = FALSE; |
530 break; | 399 break; |
531 | 400 |
532 case '*': | 401 case '*': |
533 pPattern++; | 402 pattern++; |
534 if (!*pPattern || (*pPattern == '?')) | 403 if (!*pattern || (*pattern == '?')) |
535 isEnd = TRUE; | 404 isEnd = TRUE; |
536 isAnyMode = TRUE; | 405 isAnyMode = TRUE; |
537 tmpPattern = pPattern; | 406 tmpPattern = pattern; |
538 break; | 407 break; |
539 | 408 |
540 case 0: | 409 case 0: |
541 if (isAnyMode) { | 410 if (isAnyMode) { |
542 if (*pStr) | 411 if (*str) |
543 pStr++; | 412 str++; |
544 else | 413 else |
545 isEnd = TRUE; | 414 isEnd = TRUE; |
546 } else { | 415 } else { |
547 if (*pStr) { | 416 if (*str) { |
548 if (tmpPattern) { | 417 if (tmpPattern) { |
549 isAnyMode = TRUE; | 418 isAnyMode = TRUE; |
550 pPattern = tmpPattern; | 419 pattern = tmpPattern; |
551 } else | 420 } else |
552 didMatch = FALSE; | 421 didMatch = FALSE; |
553 } else | 422 } else |
554 isEnd = TRUE; | 423 isEnd = TRUE; |
555 } | 424 } |
556 break; | 425 break; |
557 | 426 |
558 default: | 427 default: |
559 if (isAnyMode) { | 428 if (isAnyMode) { |
560 if (th_tolower(*pPattern) == th_tolower(*pStr)) { | 429 if (th_tolower(*pattern) == th_tolower(*str)) { |
561 isAnyMode = FALSE; | 430 isAnyMode = FALSE; |
562 } else { | 431 } else { |
563 if (*pStr) | 432 if (*str) |
564 pStr++; | 433 str++; |
565 else | 434 else |
566 didMatch = FALSE; | 435 didMatch = FALSE; |
567 } | 436 } |
568 } else { | 437 } else { |
569 if (th_tolower(*pPattern) == th_tolower(*pStr)) { | 438 if (th_tolower(*pattern) == th_tolower(*str)) { |
570 if (*pPattern) | 439 if (*pattern) |
571 pPattern++; | 440 pattern++; |
572 if (*pStr) | 441 if (*str) |
573 pStr++; | 442 str++; |
574 } else { | 443 } else { |
575 if (tmpPattern) { | 444 if (tmpPattern) { |
576 isAnyMode = TRUE; | 445 isAnyMode = TRUE; |
577 pPattern = tmpPattern; | 446 pattern = tmpPattern; |
578 } else | 447 } else |
579 didMatch = FALSE; | 448 didMatch = FALSE; |
580 } | 449 } |
581 } | 450 } |
582 | 451 |
583 if (!*pStr && !*pPattern) | 452 if (!*str && !*pattern) |
584 isEnd = TRUE; | 453 isEnd = TRUE; |
585 break; | 454 break; |
586 | 455 |
587 } /* switch */ | 456 } /* switch */ |
588 | 457 |
589 } while ((didMatch) && (!isEnd)); | 458 } while ((didMatch) && (!isEnd)); |
590 | 459 |
591 return didMatch; | 460 return didMatch; |
592 } | 461 } |
593 | 462 |
594 | |
595 /* | |
596 * Handling of string-lists and hashes | |
597 */ | |
598 t_str_node *th_strnode_new(char_t * pcStr, ulint_t nUsed, void *pData) | |
599 { | |
600 t_str_node *pResult; | |
601 | |
602 /* Allocate memory for new node */ | |
603 pResult = (t_str_node *) th_calloc(1, sizeof(t_str_node)); | |
604 if (!pResult) | |
605 return NULL; | |
606 | |
607 /* Set fields */ | |
608 th_pstrcpy(&pResult->pcStr, pcStr); | |
609 pResult->nUsed = nUsed; | |
610 pResult->pData = pData; | |
611 | |
612 return pResult; | |
613 } | |
614 | |
615 | |
616 void th_strnode_free(t_str_node * pNode) | |
617 { | |
618 assert(pNode); | |
619 | |
620 th_free(pNode->pcStr); | |
621 th_free(pNode); | |
622 } | |
623 | |
624 | |
625 /* Insert a new node into strlist | |
626 */ | |
627 void th_strlist_insert(t_str_node ** strList, t_str_node * pNode) | |
628 { | |
629 assert(strList); | |
630 assert(pNode); | |
631 | |
632 /* Insert into linked list */ | |
633 if (*strList) { | |
634 /* The first node's pPrev points to last node */ | |
635 LPREV = (*strList)->pPrev; /* New node's prev = Previous last node */ | |
636 (*strList)->pPrev->pNext = pNode; /* Previous last node's next = New node */ | |
637 (*strList)->pPrev = pNode; /* New last node = New node */ | |
638 LNEXT = NULL; /* But next is NULL! */ | |
639 } else { | |
640 (*strList) = pNode; /* First node ... */ | |
641 LPREV = pNode; /* ... it's also last */ | |
642 LNEXT = NULL; /* But next is NULL! */ | |
643 } | |
644 | |
645 } | |
646 | |
647 | |
648 /* Free a given strlist | |
649 */ | |
650 void th_strlist_free(t_str_node * strList) | |
651 { | |
652 t_str_node *pNode, *nNode; | |
653 | |
654 pNode = strList; | |
655 while (pNode) { | |
656 nNode = pNode->pNext; | |
657 th_strnode_free(pNode); | |
658 pNode = nNode; | |
659 } | |
660 } | |
661 | |
662 | |
663 /* Create a strIndex from strlist | |
664 */ | |
665 t_str_index *th_strlist_makeindex(t_str_node * strList) | |
666 { | |
667 t_str_index *pResult; | |
668 t_str_node *pCurr; | |
669 ulint_t n; | |
670 assert(strList); | |
671 | |
672 /* Computer number of nodes */ | |
673 for (n = 0, pCurr = strList; pCurr; pCurr = pCurr->pNext) | |
674 n++; | |
675 | |
676 /* Check number of nodes */ | |
677 if (n == 0) | |
678 return NULL; | |
679 | |
680 /* Allocate memory for index */ | |
681 pResult = (t_str_index *) th_calloc(1, sizeof(t_str_index)); | |
682 if (!pResult) | |
683 return NULL; | |
684 | |
685 pResult->n = n; | |
686 pResult->ppIndex = (t_str_node **) th_calloc(n, sizeof(t_str_node *)); | |
687 if (!pResult->ppIndex) { | |
688 th_free(pResult); | |
689 return NULL; | |
690 } | |
691 | |
692 /* Create the index */ | |
693 for (n = 0, pCurr = strList; pCurr && (n < pResult->n); pCurr = pCurr->pNext) | |
694 pResult->ppIndex[n++] = pCurr; | |
695 | |
696 return pResult; | |
697 } | |
698 | |
699 | |
700 /* Insert a node into given strhash | |
701 */ | |
702 int th_strhash_insert(t_str_hash strHash, t_str_node * pNode, BOOL ignoreCase) | |
703 { | |
704 int i; | |
705 assert(strHash); | |
706 assert(pNode); | |
707 assert(pNode->pcStr); | |
708 | |
709 if (ignoreCase) | |
710 i = th_tolower(pNode->pcStr[0]); | |
711 else | |
712 i = pNode->pcStr[0]; | |
713 | |
714 /* Check the hashcode */ | |
715 if ((i < 0) && (i >= SET_HASH_MAXINDEX)) | |
716 return -1; | |
717 | |
718 if (strHash[i]) { | |
719 /* The first node's pPrev points to last node */ | |
720 pNode->pPrev = strHash[i]->pPrev; /* New node's prev = Previous last node */ | |
721 strHash[i]->pPrev->pNext = pNode; /* Previous last node's next = New node */ | |
722 strHash[i]->pPrev = pNode; /* New last node = New node */ | |
723 pNode->pNext = NULL; /* But next is NULL! */ | |
724 } else { | |
725 strHash[i] = pNode; /* First node */ | |
726 pNode->pPrev = pNode; /* But also last */ | |
727 pNode->pNext = NULL; /* But next is NULL! */ | |
728 } | |
729 | |
730 return 0; | |
731 } | |
732 | |
733 | |
734 /* Free a given strhash | |
735 */ | |
736 void th_strhash_free(t_str_hash strHash) | |
737 { | |
738 int i; | |
739 assert(strHash); | |
740 | |
741 for (i = 0; i < SET_HASH_MAXINDEX; i++) | |
742 th_strlist_free(strHash[i]); | |
743 } | |
744 | |
745 | |
746 /* Change pData for matching entries to new value | |
747 */ | |
748 void th_strhash_change_pdata(t_str_hash strHash, void *pFind, void *pNew) | |
749 { | |
750 t_str_node *pCurr; | |
751 int i; | |
752 assert(strHash); | |
753 | |
754 for (i = 0; i < SET_HASH_MAXINDEX; i++) { | |
755 /* Find from linked list */ | |
756 pCurr = strHash[i]; | |
757 while (pCurr) { | |
758 if (pCurr->pData == pFind) | |
759 pCurr->pData = pNew; | |
760 | |
761 pCurr = pCurr->pNext; | |
762 } | |
763 } | |
764 } | |
765 | |
766 | |
767 /* Search a string from a given stringhash, either case-sensitive or insensitive | |
768 */ | |
769 t_str_node *th_strhash_search(t_str_hash strHash, char_t * findStr, BOOL ignoreCase) | |
770 { | |
771 t_str_node *pCurr; | |
772 int i; | |
773 BOOL isFound; | |
774 assert(strHash); | |
775 assert(findStr); | |
776 | |
777 isFound = FALSE; | |
778 pCurr = NULL; | |
779 | |
780 /* Check hashcode */ | |
781 if (ignoreCase) | |
782 i = ((unsigned char) th_tolower(findStr[0])); | |
783 else | |
784 i = ((unsigned char) findStr[0]); | |
785 | |
786 if ((i < 0) && (i >= SET_HASH_MAXINDEX)) | |
787 return NULL; | |
788 | |
789 /* Find from linked list */ | |
790 pCurr = strHash[i]; | |
791 | |
792 if (ignoreCase) { | |
793 /* Case in-sensitive search */ | |
794 while (pCurr && !isFound) { | |
795 if (th_strcasecmp(findStr, pCurr->pcStr) == 0) | |
796 isFound = TRUE; | |
797 else | |
798 pCurr = pCurr->pNext; | |
799 } | |
800 } else { | |
801 /* Case sensitive search */ | |
802 while (pCurr && !isFound) { | |
803 if (th_strcmp(findStr, pCurr->pcStr) == 0) | |
804 isFound = TRUE; | |
805 else | |
806 pCurr = pCurr->pNext; | |
807 } | |
808 } | |
809 | |
810 /* Return result */ | |
811 if (isFound) | |
812 return pCurr; | |
813 else | |
814 return NULL; | |
815 } | |
816 | |
817 | |
818 /* Create a strIndex from strHash | |
819 */ | |
820 t_str_index *th_strhash_makeindex(t_str_hash strHash) | |
821 { | |
822 t_str_index *pResult; | |
823 t_str_node *pCurr; | |
824 unsigned int n, i; | |
825 assert(strHash); | |
826 | |
827 /* Computer number of nodes */ | |
828 for (n = i = 0; i < SET_HASH_MAXINDEX; i++) { | |
829 pCurr = strHash[i]; | |
830 while (pCurr) { | |
831 n++; | |
832 pCurr = pCurr->pNext; | |
833 } | |
834 } | |
835 | |
836 /* Check number of nodes */ | |
837 if (n <= 0) | |
838 return NULL; | |
839 | |
840 /* Allocate memory for index */ | |
841 pResult = (t_str_index *) th_calloc(1, sizeof(t_str_index)); | |
842 if (!pResult) | |
843 return NULL; | |
844 | |
845 pResult->n = n; | |
846 pResult->ppIndex = (t_str_node **) th_calloc(n, sizeof(t_str_node *)); | |
847 if (!pResult->ppIndex) { | |
848 th_free(pResult); | |
849 return NULL; | |
850 } | |
851 | |
852 /* Create the index */ | |
853 for (n = i = 0; (i < SET_HASH_MAXINDEX) && (n < pResult->n); i++) { | |
854 pCurr = strHash[i]; | |
855 while (pCurr && (n < pResult->n)) { | |
856 pResult->ppIndex[n++] = pCurr; | |
857 pCurr = pCurr->pNext; | |
858 } | |
859 } | |
860 | |
861 return pResult; | |
862 } | |
863 | |
864 | |
865 /* Free a given strIndex | |
866 */ | |
867 void th_strindex_free(t_str_index * strIndex) | |
868 { | |
869 if (strIndex) { | |
870 th_free(strIndex->ppIndex); | |
871 th_free(strIndex); | |
872 } | |
873 } | |
874 | |
875 | |
876 /* Compare two t_str_nodes by nUsed | |
877 */ | |
878 int th_strindex_cmp_used(const void *pNode1, const void *pNode2) | |
879 { | |
880 t_str_node *pStr1, *pStr2; | |
881 | |
882 pStr1 = *(t_str_node **) pNode1; | |
883 pStr2 = *(t_str_node **) pNode2; | |
884 | |
885 if (pStr1->nUsed > pStr2->nUsed) | |
886 return -1; | |
887 else if (pStr1->nUsed < pStr2->nUsed) | |
888 return 1; | |
889 else | |
890 return 0; | |
891 } | |
892 | |
893 | |
894 /* Sort an strIndex by nUsed, using th_strindex_cmp_used() | |
895 */ | |
896 void th_strindex_sort_nused(t_str_index * strIndex) | |
897 { | |
898 assert(strIndex); | |
899 assert(strIndex->ppIndex); | |
900 | |
901 qsort(strIndex->ppIndex, strIndex->n, sizeof(t_str_node *), th_strindex_cmp_used); | |
902 } | |
903 | |
904 | |
905 /* Compare two t_str_nodes via strcmp() | |
906 */ | |
907 int th_strindex_cmp_alpha(const void *pNode1, const void *pNode2) | |
908 { | |
909 t_str_node *pStr1, *pStr2; | |
910 | |
911 pStr1 = *(t_str_node **) pNode1; | |
912 pStr2 = *(t_str_node **) pNode2; | |
913 | |
914 return th_strcmp(pStr1->pcStr, pStr2->pcStr); | |
915 } | |
916 | |
917 | |
918 /* Sort an strIndex by nUsed, using th_strindex_cmp_used() | |
919 */ | |
920 void th_strindex_sort_alpha(t_str_index * strIndex) | |
921 { | |
922 assert(strIndex); | |
923 assert(strIndex->ppIndex); | |
924 | |
925 qsort(strIndex->ppIndex, strIndex->n, sizeof(t_str_node *), th_strindex_cmp_alpha); | |
926 } |