comparison th_string.c @ 14:e5e6370217ef

Various cleanups, additions and removals.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 30 Oct 2010 17:47:41 +0300
parents a25f5d22483e
children 1f7d8693fda8
comparison
equal deleted inserted replaced
13:adcbcac66125 14:e5e6370217ef
7 */ 7 */
8 #ifdef HAVE_CONFIG_H 8 #ifdef HAVE_CONFIG_H
9 #include "config.h" 9 #include "config.h"
10 #endif 10 #endif
11 #include "th_string.h" 11 #include "th_string.h"
12
13 #define LPREV (pNode->pPrev)
14 #define LNEXT (pNode->pNext)
15
16 12
17 /* strdup with a NULL check 13 /* strdup with a NULL check
18 */ 14 */
19 char *th_strdup(const char *s) 15 char *th_strdup(const char *s)
20 { 16 {
28 strcpy(res, s); 24 strcpy(res, s);
29 return res; 25 return res;
30 } 26 }
31 27
32 28
33 /* Allocate memory for a string with given length 29 char *th_strncpy(char * dst, const char * src, const size_t n)
34 */
35 char *th_stralloc(const size_t l)
36 {
37 assert(l > 0);
38 return th_malloc(sizeof(char) * l);
39 }
40
41
42 char *th_strrealloc(char * s, const size_t l)
43 {
44 assert(l > 0);
45 return th_realloc(s, sizeof(char) * l);
46 }
47
48
49 char *th_strncpy(char * dst, const char * src, size_t n)
50 { 30 {
51 const char *s = src; 31 const char *s = src;
52 char *d = dst; 32 char *d = dst;
53 size_t i; 33 size_t i;
54 assert(src != NULL); 34 assert(src != NULL);
55 assert(dst != NULL); 35 assert(dst != NULL);
56 36
57 /* Copy to the destination */ 37 /* Copy to the destination */
58 i = n; 38 i = n;
59 while (*s && (i > 0)) { 39 while (*s && i > 0) {
60 *(d++) = *(s++); 40 *(d++) = *(s++);
61 i--; 41 i--;
62 } 42 }
63 43
64 /* Fill rest of space with zeros */ 44 /* Fill rest of space with zeros */
72 52
73 return dst; 53 return dst;
74 } 54 }
75 55
76 56
77 int th_strncmp(char * str1, char * str2, size_t n) 57 /* Simulate a sprintf() that allocates memory
78 { 58 */
79 char *s1, *s2; 59 char * th_strdup_vprintf(const char *fmt, va_list args)
60 {
61 int size = 100;
62 char *buf, *nbuf = NULL;
63
64 if ((buf = th_malloc(size)) == NULL)
65 return NULL;
66
67 while (1) {
68 int n = vsnprintf(buf, size, fmt, args);
69 if (n > -1 && n < size)
70 return buf;
71 if (n > -1)
72 size = n + 1;
73 else
74 size *= 2;
75
76 if ((nbuf = th_realloc(nbuf, size)) == NULL) {
77 th_free(buf);
78 return NULL;
79 }
80
81 buf = nbuf;
82 }
83 }
84
85
86 char * th_strdup_printf(const char *fmt, ...)
87 {
88 char *res;
89 va_list ap;
90
91 va_start(ap, fmt);
92 res = th_strdup_vprintf(fmt, ap);
93 va_end(ap);
94
95 return res;
96 }
97
98
99 /* Compare two strings ignoring case [strcasecmp, strncasecmp]
100 */
101 int th_strcasecmp(const char * str1, const char * str2)
102 {
103 const char *s1 = str1, *s2 = str2;
80 assert(str1 != NULL); 104 assert(str1 != NULL);
81 assert(str2 != NULL); 105 assert(str2 != NULL);
82 106
83 /* Check the string pointers */
84 if (str1 == str2) 107 if (str1 == str2)
85 return 0; 108 return 0;
86 109
87 /* Go through the string */ 110 while (*s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) {
88 s1 = str1; 111 s1++;
89 s2 = str2; 112 s2++;
90 while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) { 113 }
114
115 return (th_tolower(*s1) - th_tolower(*s2));
116 }
117
118
119 int th_strncasecmp(const char * str1, const char * str2, size_t n)
120 {
121 const char *s1 = str1, *s2 = str2;
122 assert(str1 != NULL);
123 assert(str2 != NULL);
124
125 if (str1 == str2)
126 return 0;
127
128 while (n > 0 && *s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) {
91 s1++; 129 s1++;
92 s2++; 130 s2++;
93 n--; 131 n--;
94 } 132 }
95 133
96 if (n > 0) 134 return n > 0 ? (th_tolower(*s1) - th_tolower(*s2)) : 0;
97 return ((*s1) - (*s2));
98 else
99 return 0;
100 }
101
102
103 /* Compare two strings ignoring case [strcasecmp, strncasecmp]
104 */
105 int th_strcasecmp(char * str1, char * str2)
106 {
107 char *s1 = str1, *s2 = str2;
108 assert(str1 != NULL);
109 assert(str2 != NULL);
110
111 /* Check the string pointers */
112 if (str1 == str2)
113 return 0;
114
115 /* Go through the string */
116 while (*s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) {
117 s1++;
118 s2++;
119 }
120
121 return (th_tolower(*s1) - th_tolower(*s2));
122 }
123
124
125 int th_strncasecmp(char * str1, char * str2, size_t n)
126 {
127 char *s1 = str1, *s2 = str2;
128 assert(str1 != NULL);
129 assert(str2 != NULL);
130
131 /* Check the string pointers */
132 if (str1 == str2)
133 return 0;
134
135 /* Go through the string */
136 while ((n > 0) && *s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) {
137 s1++;
138 s2++;
139 n--;
140 }
141
142 if (n > 0)
143 return (th_tolower(*s1) - th_tolower(*s2));
144 else
145 return 0;
146 } 135 }
147 136
148 137
149 /* Remove all occurences of control characters, in-place. 138 /* Remove all occurences of control characters, in-place.
150 * Resulting string is always shorter or same length than original. 139 * Resulting string is always shorter or same length than original.
166 } 155 }
167 156
168 157
169 /* Copy a given string over in *result. 158 /* Copy a given string over in *result.
170 */ 159 */
171 int th_pstrcpy(char ** result, char * str) 160 int th_pstrcpy(char ** result, const char * str)
172 { 161 {
173 assert(result != NULL); 162 assert(result != NULL);
174 163
175 /* Check the string pointers */
176 if (str == NULL) 164 if (str == NULL)
177 return -1; 165 return -1;
178 166
179 /* Allocate memory for destination */
180 th_free(*result); 167 th_free(*result);
181 *result = th_stralloc(strlen(str) + 1); 168 if ((*result = th_malloc(strlen(str) + 1)) == NULL)
182 if (!*result)
183 return -2; 169 return -2;
184 170
185 /* Copy to the destination */
186 strcpy(*result, str); 171 strcpy(*result, str);
187
188 return 0; 172 return 0;
189 } 173 }
190 174
191 175
192 /* Concatenates a given string into string pointed by *result. 176 /* Concatenates a given string into string pointed by *result.
193 */ 177 */
194 int th_pstrcat(char ** result, char * str) 178 int th_pstrcat(char ** result, const char * str)
195 { 179 {
196 assert(result != NULL); 180 assert(result != NULL);
197 181
198 /* Check the string pointers */
199 if (str == NULL) 182 if (str == NULL)
200 return -1; 183 return -1;
201 184
202 if (*result != NULL) { 185 if (*result != NULL) {
203 *result = th_strrealloc(*result, strlen(*result) + strlen(str) + 1); 186 *result = th_realloc(*result, strlen(*result) + strlen(str) + 1);
204 if (*result == NULL) 187 if (*result == NULL)
205 return -1; 188 return -1;
206 189
207 strcat(*result, str); 190 strcat(*result, str);
208 } else { 191 } else {
209 *result = th_stralloc(strlen(str) + 1); 192 *result = th_malloc(strlen(str) + 1);
210 if (*result == NULL) 193 if (*result == NULL)
211 return -1; 194 return -1;
212 195
213 strcpy(*result, str); 196 strcpy(*result, str);
214 } 197 }
219 202
220 /* Find next non-whitespace character in string. 203 /* Find next non-whitespace character in string.
221 * Updates iPos into the position of such character and 204 * Updates iPos into the position of such character and
222 * returns pointer to the string. 205 * returns pointer to the string.
223 */ 206 */
224 char *th_findnext(char * str, size_t * iPos) 207 const char *th_findnext(const char * str, size_t * pos)
225 { 208 {
226 assert(str != NULL); 209 assert(str != NULL);
227 210
228 /* Terminating NULL-character is not whitespace! */ 211 /* Terminating NULL-character is not whitespace! */
229 while (th_isspace(str[*iPos])) 212 while (th_isspace(str[*pos]))
230 (*iPos)++; 213 (*pos)++;
231 return &str[*iPos]; 214 return &str[*pos];
232 } 215 }
233 216
234 217
235 /* Find next chSep-character from string 218 /* Find next sep-character from string
236 */ 219 */
237 char *th_findsep(char * str, size_t * iPos, char chSep) 220 const char *th_findsep(const char * str, size_t * pos, char sep)
238 { 221 {
239 assert(str != NULL); 222 assert(str != NULL);
240 223
241 /* Terminating NULL-character is not digit! */ 224 while (str[*pos] && str[*pos] != sep)
242 while (str[*iPos] && (str[*iPos] != chSep)) 225 (*pos)++;
243 (*iPos)++; 226
244 return &str[*iPos]; 227 return &str[*pos];
245 } 228 }
246 229
247 230
248 /* Find next chSep- or whitespace from string 231 /* Find next sep- or whitespace from string
249 */ 232 */
250 char *th_findseporspace(char * str, size_t * iPos, char chSep) 233 const char *th_findseporspace(const char * str, size_t * pos, char sep)
251 { 234 {
252 assert(str != NULL); 235 assert(str != NULL);
253 236
254 /* Terminating NULL-character is not digit! */ 237 while (!th_isspace(str[*pos]) && str[*pos] != sep)
255 while (!th_isspace(str[*iPos]) && (str[*iPos] != chSep)) 238 (*pos)++;
256 (*iPos)++; 239
257 return &str[*iPos]; 240 return &str[*pos];
258 } 241 }
259 242
260 243
261 /* Compare a string to a pattern. Case-SENSITIVE version. 244 /* Compare a string to a pattern. Case-SENSITIVE version.
262 * The matching pattern can consist of any normal characters plus 245 * The matching pattern can consist of any normal characters plus
263 * wildcards ? and *. "?" matches any character and "*" matches 246 * wildcards ? and *. "?" matches any character and "*" matches
264 * any number of characters. 247 * any number of characters.
265 */ 248 */
266 BOOL th_strmatch(char * str, char * pattern) 249 BOOL th_strmatch(const char * str, const char * pattern)
267 { 250 {
268 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; 251 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE;
269 char *tmpPattern = NULL; 252 const char *tmpPattern = NULL;
270 253
271 /* Check given pattern and string */ 254 /* Check given pattern and string */
272 if (str == NULL || pattern == NULL) 255 if (str == NULL || pattern == NULL)
273 return FALSE; 256 return FALSE;
274 257
350 } 333 }
351 334
352 335
353 /* Compare a string to a pattern. Case-INSENSITIVE version. 336 /* Compare a string to a pattern. Case-INSENSITIVE version.
354 */ 337 */
355 BOOL th_strcasematch(char * str, char * pattern) 338 BOOL th_strcasematch(const char * str, const char * pattern)
356 { 339 {
357 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; 340 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE;
358 char *tmpPattern = NULL; 341 const char *tmpPattern = NULL;
359 342
360 /* Check given pattern and string */ 343 /* Check given pattern and string */
361 if (str == NULL || pattern == NULL) 344 if (str == NULL || pattern == NULL)
362 return FALSE; 345 return FALSE;
363 346
433 } while (didMatch && !isEnd); 416 } while (didMatch && !isEnd);
434 417
435 return didMatch; 418 return didMatch;
436 } 419 }
437 420
421
422 int th_get_hex_triplet(const char *str)
423 {
424 const char *p = str;
425 int len, val = 0;
426
427 for (len = 0; *p && len < 6; p++, len++) {
428 if (*p >= '0' && *p <= '9') {
429 val *= 16; val += (*p - '0');
430 } else if (*p >= 'A' && *p <= 'F') {
431 val *= 16; val += (*p - 'A') + 10;
432 } else if (*p >= 'a' && *p <= 'f') {
433 val *= 16; val += (*p - 'a') + 10;
434 } else
435 return -1;
436 }
437
438 return (len == 6) ? val : -1;
439 }
440
441