Mercurial > hg > nnchat
comparison th_string.c @ 124:fe4d5f3b486c
Sync.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 29 Oct 2010 16:41:08 +0300 |
parents | 69aed051f84d |
children | 9ae3d87a686f |
comparison
equal
deleted
inserted
replaced
123:0a07138e75bc | 124:fe4d5f3b486c |
---|---|
28 strcpy(res, s); | 28 strcpy(res, s); |
29 return res; | 29 return res; |
30 } | 30 } |
31 | 31 |
32 | 32 |
33 /* Allocate memory for a string with given length | 33 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 { | 34 { |
51 const char *s = src; | 35 const char *s = src; |
52 char *d = dst; | 36 char *d = dst; |
53 size_t i; | 37 size_t i; |
54 assert(src != NULL); | 38 assert(src != NULL); |
55 assert(dst != NULL); | 39 assert(dst != NULL); |
56 | 40 |
57 /* Copy to the destination */ | 41 /* Copy to the destination */ |
58 i = n; | 42 i = n; |
59 while (*s && (i > 0)) { | 43 while (*s && i > 0) { |
60 *(d++) = *(s++); | 44 *(d++) = *(s++); |
61 i--; | 45 i--; |
62 } | 46 } |
63 | 47 |
64 /* Fill rest of space with zeros */ | 48 /* Fill rest of space with zeros */ |
72 | 56 |
73 return dst; | 57 return dst; |
74 } | 58 } |
75 | 59 |
76 | 60 |
77 int th_strncmp(char * str1, char * str2, size_t n) | 61 #ifdef STRDUP_PRINTF |
78 { | 62 /* |
79 char *s1, *s2; | 63 */ |
64 enum { | |
65 TH_PAD_RIGHT = 1, | |
66 TH_PAD_ZERO = 2 | |
67 }; | |
68 | |
69 | |
70 static size_t th_printbuf_str(char **buf, const char *str, size_t width, int flags) | |
71 { | |
72 size_t len = strlen(str); | |
73 char *out = (buf != NULL) ? *buf : NULL; | |
74 char pad = ' '; | |
75 | |
76 if (width > 0) { | |
77 width = (len >= width) ? 0 : width - len; | |
78 if (flags & TH_PAD_ZERO) | |
79 pad = '0'; | |
80 } | |
81 | |
82 if ((flags & TH_PAD_RIGHT) == 0 && out != NULL) { | |
83 while (width-- > 0) | |
84 *out++ = pad; | |
85 } | |
86 | |
87 if (out != NULL) { | |
88 while (*str) | |
89 *out++ = *str++; | |
90 } | |
91 | |
92 if (flags & TH_PAD_RIGHT && out != NULL) { | |
93 while (width-- > 0) | |
94 *out++ = pad; | |
95 } | |
96 | |
97 if (buf != NULL) | |
98 *buf = out; | |
99 | |
100 return len + width; | |
101 } | |
102 | |
103 #define TH_INTBUF_LEN (32) | |
104 | |
105 static size_t th_printbuf_int(char **buf, int i, int b, int sg, int width, int pad, int letbase) | |
106 { | |
107 char tmpbuf[TH_INTBUF_LEN], *s; | |
108 int t, neg = 0, pc = 0; | |
109 unsigned int u = i; | |
110 | |
111 if (i == 0) { | |
112 tmpbuf[0] = '0'; | |
113 tmpbuf[1] = 0; | |
114 return th_printbuf_str(buf, tmpbuf, width, pad); | |
115 } | |
116 | |
117 if (sg && b == 10 && i < 0) { | |
118 neg = 1; | |
119 u = -i; | |
120 } | |
121 | |
122 s = tmpbuf + TH_INTBUF_LEN - 1; | |
123 *s = 0; | |
124 | |
125 while (u) { | |
126 t = u % b; | |
127 if (t >= 10) | |
128 t += letbase - '0' - 10; | |
129 | |
130 *--s = t + '0'; | |
131 u /= b; | |
132 } | |
133 | |
134 if (neg) { | |
135 if (width && (pad & PAD_ZERO)) { | |
136 printchar (out, '-'); | |
137 ++pc; | |
138 --width; | |
139 } else { | |
140 *--s = '-'; | |
141 } | |
142 } | |
143 | |
144 return pc + th_printbuf_str(buf, s, width, pad); | |
145 } | |
146 | |
147 | |
148 char * th_strdup_vprintf(const char *fmt, va_list args) | |
149 { | |
150 const char *s = fmt; | |
151 char *res; | |
152 size_t len = 0; | |
153 | |
154 /* 1. Determine required space for final string */ | |
155 while (*s) { | |
156 if (*s == '%') { | |
157 s++; | |
158 } else { | |
159 s++; | |
160 len++; | |
161 } | |
162 } | |
163 | |
164 /* 2. Allocate space */ | |
165 | |
166 /* 3. Create final string */ | |
167 | |
168 return res; | |
169 } | |
170 | |
171 | |
172 char * th_strdup_printf(const char *fmt, ...) | |
173 { | |
174 char *res; | |
175 va_list ap; | |
176 | |
177 va_start(ap, fmt); | |
178 res = th_strdup_vprintf(fmt, ap); | |
179 va_end(ap); | |
180 | |
181 return res; | |
182 } | |
183 #endif | |
184 | |
185 /* Compare two strings ignoring case [strcasecmp, strncasecmp] | |
186 */ | |
187 int th_strcasecmp(const char * str1, const char * str2) | |
188 { | |
189 const char *s1 = str1, *s2 = str2; | |
80 assert(str1 != NULL); | 190 assert(str1 != NULL); |
81 assert(str2 != NULL); | 191 assert(str2 != NULL); |
82 | 192 |
83 /* Check the string pointers */ | |
84 if (str1 == str2) | 193 if (str1 == str2) |
85 return 0; | 194 return 0; |
86 | 195 |
87 /* Go through the string */ | 196 while (*s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { |
88 s1 = str1; | 197 s1++; |
89 s2 = str2; | 198 s2++; |
90 while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) { | 199 } |
200 | |
201 return (th_tolower(*s1) - th_tolower(*s2)); | |
202 } | |
203 | |
204 | |
205 int th_strncasecmp(const char * str1, const char * str2, size_t n) | |
206 { | |
207 const char *s1 = str1, *s2 = str2; | |
208 assert(str1 != NULL); | |
209 assert(str2 != NULL); | |
210 | |
211 if (str1 == str2) | |
212 return 0; | |
213 | |
214 while (n > 0 && *s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { | |
91 s1++; | 215 s1++; |
92 s2++; | 216 s2++; |
93 n--; | 217 n--; |
94 } | 218 } |
95 | 219 |
96 if (n > 0) | 220 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 } | 221 } |
147 | 222 |
148 | 223 |
149 /* Remove all occurences of control characters, in-place. | 224 /* Remove all occurences of control characters, in-place. |
150 * Resulting string is always shorter or same length than original. | 225 * Resulting string is always shorter or same length than original. |
166 } | 241 } |
167 | 242 |
168 | 243 |
169 /* Copy a given string over in *result. | 244 /* Copy a given string over in *result. |
170 */ | 245 */ |
171 int th_pstrcpy(char ** result, char * str) | 246 int th_pstrcpy(char ** result, const char * str) |
172 { | 247 { |
173 assert(result != NULL); | 248 assert(result != NULL); |
174 | 249 |
175 /* Check the string pointers */ | |
176 if (str == NULL) | 250 if (str == NULL) |
177 return -1; | 251 return -1; |
178 | 252 |
179 /* Allocate memory for destination */ | |
180 th_free(*result); | 253 th_free(*result); |
181 *result = th_stralloc(strlen(str) + 1); | 254 if ((*result = th_malloc(strlen(str) + 1)) == NULL) |
182 if (!*result) | |
183 return -2; | 255 return -2; |
184 | 256 |
185 /* Copy to the destination */ | |
186 strcpy(*result, str); | 257 strcpy(*result, str); |
187 | |
188 return 0; | 258 return 0; |
189 } | 259 } |
190 | 260 |
191 | 261 |
192 /* Concatenates a given string into string pointed by *result. | 262 /* Concatenates a given string into string pointed by *result. |
193 */ | 263 */ |
194 int th_pstrcat(char ** result, char * str) | 264 int th_pstrcat(char ** result, const char * str) |
195 { | 265 { |
196 assert(result != NULL); | 266 assert(result != NULL); |
197 | 267 |
198 /* Check the string pointers */ | |
199 if (str == NULL) | 268 if (str == NULL) |
200 return -1; | 269 return -1; |
201 | 270 |
202 if (*result != NULL) { | 271 if (*result != NULL) { |
203 *result = th_strrealloc(*result, strlen(*result) + strlen(str) + 1); | 272 *result = th_realloc(*result, strlen(*result) + strlen(str) + 1); |
204 if (*result == NULL) | 273 if (*result == NULL) |
205 return -1; | 274 return -1; |
206 | 275 |
207 strcat(*result, str); | 276 strcat(*result, str); |
208 } else { | 277 } else { |
209 *result = th_stralloc(strlen(str) + 1); | 278 *result = th_malloc(strlen(str) + 1); |
210 if (*result == NULL) | 279 if (*result == NULL) |
211 return -1; | 280 return -1; |
212 | 281 |
213 strcpy(*result, str); | 282 strcpy(*result, str); |
214 } | 283 } |
219 | 288 |
220 /* Find next non-whitespace character in string. | 289 /* Find next non-whitespace character in string. |
221 * Updates iPos into the position of such character and | 290 * Updates iPos into the position of such character and |
222 * returns pointer to the string. | 291 * returns pointer to the string. |
223 */ | 292 */ |
224 char *th_findnext(char * str, size_t * iPos) | 293 const char *th_findnext(const char * str, size_t * pos) |
225 { | 294 { |
226 assert(str != NULL); | 295 assert(str != NULL); |
227 | 296 |
228 /* Terminating NULL-character is not whitespace! */ | 297 /* Terminating NULL-character is not whitespace! */ |
229 while (th_isspace(str[*iPos])) | 298 while (th_isspace(str[*pos])) |
230 (*iPos)++; | 299 (*pos)++; |
231 return &str[*iPos]; | 300 return &str[*pos]; |
232 } | 301 } |
233 | 302 |
234 | 303 |
235 /* Find next chSep-character from string | 304 /* Find next sep-character from string |
236 */ | 305 */ |
237 char *th_findsep(char * str, size_t * iPos, char chSep) | 306 const char *th_findsep(const char * str, size_t * pos, char sep) |
238 { | 307 { |
239 assert(str != NULL); | 308 assert(str != NULL); |
240 | 309 |
241 /* Terminating NULL-character is not digit! */ | 310 while (str[*pos] && str[*pos] != sep) |
242 while (str[*iPos] && (str[*iPos] != chSep)) | 311 (*pos)++; |
243 (*iPos)++; | 312 |
244 return &str[*iPos]; | 313 return &str[*pos]; |
245 } | 314 } |
246 | 315 |
247 | 316 |
248 /* Find next chSep- or whitespace from string | 317 /* Find next sep- or whitespace from string |
249 */ | 318 */ |
250 char *th_findseporspace(char * str, size_t * iPos, char chSep) | 319 const char *th_findseporspace(const char * str, size_t * pos, char sep) |
251 { | 320 { |
252 assert(str != NULL); | 321 assert(str != NULL); |
253 | 322 |
254 /* Terminating NULL-character is not digit! */ | 323 while (!th_isspace(str[*pos]) && str[*pos] != sep) |
255 while (!th_isspace(str[*iPos]) && (str[*iPos] != chSep)) | 324 (*pos)++; |
256 (*iPos)++; | 325 |
257 return &str[*iPos]; | 326 return &str[*pos]; |
258 } | 327 } |
259 | 328 |
260 | 329 |
261 /* Compare a string to a pattern. Case-SENSITIVE version. | 330 /* Compare a string to a pattern. Case-SENSITIVE version. |
262 * The matching pattern can consist of any normal characters plus | 331 * The matching pattern can consist of any normal characters plus |
263 * wildcards ? and *. "?" matches any character and "*" matches | 332 * wildcards ? and *. "?" matches any character and "*" matches |
264 * any number of characters. | 333 * any number of characters. |
265 */ | 334 */ |
266 BOOL th_strmatch(char * str, char * pattern) | 335 BOOL th_strmatch(const char * str, const char * pattern) |
267 { | 336 { |
268 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; | 337 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
269 char *tmpPattern = NULL; | 338 const char *tmpPattern = NULL; |
270 | 339 |
271 /* Check given pattern and string */ | 340 /* Check given pattern and string */ |
272 if (str == NULL || pattern == NULL) | 341 if (str == NULL || pattern == NULL) |
273 return FALSE; | 342 return FALSE; |
274 | 343 |
350 } | 419 } |
351 | 420 |
352 | 421 |
353 /* Compare a string to a pattern. Case-INSENSITIVE version. | 422 /* Compare a string to a pattern. Case-INSENSITIVE version. |
354 */ | 423 */ |
355 BOOL th_strcasematch(char * str, char * pattern) | 424 BOOL th_strcasematch(const char * str, const char * pattern) |
356 { | 425 { |
357 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; | 426 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
358 char *tmpPattern = NULL; | 427 const char *tmpPattern = NULL; |
359 | 428 |
360 /* Check given pattern and string */ | 429 /* Check given pattern and string */ |
361 if (str == NULL || pattern == NULL) | 430 if (str == NULL || pattern == NULL) |
362 return FALSE; | 431 return FALSE; |
363 | 432 |