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