source: trunk/src/sh_string.c@ 169

Last change on this file since 169 was 169, checked in by katerina, 16 years ago

Fixes for tickes #93 to #104 (yes, big commit, bad, bad,...).

File size: 20.7 KB
Line 
1
2#include "config_xor.h"
3
4#include <string.h>
5#include <stdio.h>
6
7#include "sh_string.h"
8#include "sh_mem.h"
9
10#undef FIL__
11#define FIL__ _("sh_string.c")
12
13extern int sl_ok_adds (size_t a, size_t b);
14#define SL_TRUE 1
15#define SL_FALSE 0
16
17#include <ctype.h>
18/* Split array at delim in at most nfields fields.
19 * Empty fields are returned as empty (zero-length) strings.
20 * Leading and trailing WS are removed from token.
21 * The number of fields is returned in 'nfields', their
22 * lengths in 'lengths'.
23 * A single delimiter will return two empty fields.
24 */
25char ** split_array(char *line, unsigned int * nfields,
26 char delim, size_t * lengths)
27{
28 char *a, *e, *s;
29 unsigned int i = 0;
30 int flag = 0;
31 char **arr;
32 unsigned int maxfields = (*nfields);
33
34 arr = SH_ALLOC((maxfields+1) * sizeof (char*));
35
36 e = line;
37
38 do
39 {
40 /* skip leading WS
41 */
42 for (s=e; *s && isspace(*s); ++s) /* nothing */;
43
44 if (*s)
45 {
46 a = s;
47
48 /* move a to next delim
49 */
50 for (a=s; *a && *a != delim; ++a) /* nothing */;
51
52 /* set e to next after delim
53 */
54 if (*a == delim)
55 {
56 e = a+1;
57 flag = 1;
58 }
59 else /* (!*a) */
60 {
61 e = a;
62 flag = 0;
63 }
64
65 if (a != line)
66 {
67 /* chop off trailing WS
68 */
69 for (a--; isspace(*a) && a > s; a--) /* do nothing */;
70
71 /* terminate string
72 */
73 ++a; *a = '\0';
74 }
75 else
76 {
77 *a = '\0';
78 }
79 }
80 else /* (!*s) */
81 {
82 a = s;
83 /* (i == 0) handles the special case of splitting the empty string */
84 if (flag || i == 0)
85 {
86 flag = 0;
87 goto setnext;
88 }
89 break;
90 }
91
92 setnext:
93 lengths[i] = (a-s);
94 arr[i] = s;
95 ++i;
96
97 } while (i < maxfields);
98
99 *nfields = i;
100 arr[i] = NULL;
101
102 return arr;
103}
104
105/* Split array at whitespace in at most nfields fields.
106 * Multiple whitespaces are collapsed.
107 * Empty fields are returned as empty (zero-length) strings.
108 * The number of fields is returned in nfields.
109 * An empty string will return zero fields.
110 * If nfields < actual fields, last string will be remainder.
111 */
112char ** split_array_ws(char *line, unsigned int * nfields, size_t * lengths)
113{
114 char *a, *e, *s;
115 unsigned int i = 0;
116 char **arr;
117 unsigned int maxfields = (*nfields);
118
119 arr = SH_ALLOC((maxfields+1) * sizeof (char*));
120
121 e = line;
122
123 do
124 {
125 s = e;
126
127 /* skip leading WS
128 */
129 if ( *s && isspace(*s) )
130 {
131 do {
132 ++s;
133 } while ( *s && isspace(*s) );
134 }
135
136 if (*s)
137 {
138
139 /* s is at non-ws, move a to next ws
140 */
141 a = s;
142 do {
143 a++;
144 } while ( *a && (!isspace(*a)) );
145
146 /* next token, *a is either ws or '\0'
147 */
148 e = ( (*a) ? a+1 : a);
149
150 /* terminate and set arr[i]
151 */
152 if (i < (maxfields-1))
153 {
154 *a = '\0';
155 }
156 else
157 {
158 /* If nfields < actual fields, last
159 * string will be remainder. Therefore
160 * skip to end.
161 */
162 if ( *a )
163 {
164 do {
165 a++;
166 } while ( *a );
167 }
168 }
169 lengths[i] = (a-s);
170 arr[i] = s;
171 ++i;
172 }
173 else /* if (!*s) */
174 {
175 break;
176 }
177
178 } while (i < maxfields);
179
180 *nfields = i;
181 arr[i] = NULL;
182
183 return arr;
184}
185
186
187#define SH_STRING_PARCEL 120
188
189size_t sh_string_read(sh_string * s, FILE * fp, size_t maxlen)
190{
191
192 /* case 1) EOF or error
193 */
194 if (fgets(s->str, s->siz, fp) == NULL)
195 {
196 sh_string_truncate(s, 0);
197 if (ferror(fp))
198 return -1;
199 return 0;
200 }
201
202 /* case 2) end of line reached. strlen should always be > 0
203 * because of the '\n', but we check.
204 */
205 s->len = strlen(s->str);
206 if (s->len > 0 && (s->str)[s->len-1] == '\n')
207 {
208 (s->str)[s->len-1] = '\0';
209 --(s->len);
210 return (s->len + 1);
211 }
212
213 /* case 3) incomplete string
214 */
215 for (;;) {
216
217 if (maxlen > 0 && (s->siz+SH_STRING_PARCEL) > maxlen)
218 {
219 if (s->siz < maxlen)
220 sh_string_grow(s, (maxlen-s->siz));
221 else
222 return -2;
223 }
224 else
225 {
226 sh_string_grow(s, 0);
227 }
228
229 if (fgets(&(s->str[s->len]), (s->siz - s->len), fp) == NULL)
230 {
231 if (ferror(fp))
232 {
233 sh_string_truncate(s, 0);
234 return -1;
235 }
236 return s->len;
237 }
238
239 s->len += strlen( &(s->str[s->len]) );
240 if (s->len > 0 && s->str[s->len-1] == '\n')
241 {
242 (s->str)[s->len-1] = '\0';
243 --(s->len);
244 return (s->len + 1);
245 }
246 }
247
248 /* notreached */
249}
250
251sh_string * sh_string_cat_lchar(sh_string * s, char * str, size_t len)
252{
253 if (sl_ok_adds(len, s->siz) == SL_TRUE)
254 {
255 if ((len + 1 + s->len) > s->siz)
256 {
257 sh_string_grow(s, ((len+1+s->len) - s->siz) );
258 }
259 memcpy(&(s->str[s->len]), str, len);
260 s->len += len;
261 s->str[s->len] = '\0';
262 return s;
263 }
264
265 return NULL;
266}
267
268sh_string * sh_string_set_from_char(sh_string * s, char * str)
269{
270 size_t len = strlen(str);
271
272 if ((len+1) > s->siz)
273 {
274 sh_string_grow(s, ((len+1) - s->siz) );
275 }
276 memcpy(s->str, str, (len+1));
277 return s;
278}
279
280sh_string * sh_string_new_from_lchar(char * str, size_t len)
281{
282 sh_string * s;
283 s = SH_ALLOC(sizeof(sh_string));
284 s->str = SH_ALLOC(len+1);
285 memcpy(s->str, str, len);
286 s->str[len] = '\0';
287 s->siz = len+1;
288 s->len = len;
289 return s;
290}
291
292sh_string * sh_string_new_from_lchar3(char * str1, size_t len1,
293 char * str2, size_t len2,
294 char * str3, size_t len3)
295{
296 sh_string * s;
297 size_t len = 0;
298
299 if (sl_ok_adds(len1, len2) == SL_TRUE)
300 len = len1 + len2;
301 else
302 return NULL;
303 if (sl_ok_adds( len, len3) == SL_TRUE)
304 len = len + len3;
305 else
306 return NULL;
307
308 s = SH_ALLOC(sizeof(sh_string));
309 s->str = SH_ALLOC(len+1);
310
311 memcpy(s->str, str1, len1);
312 memcpy(&s->str[len1], str2, len2);
313 memcpy(&s->str[len1+len2], str3, len3);
314
315 s->str[len] = '\0';
316 s->siz = len+1;
317 s->len = len;
318 return s;
319}
320
321sh_string * sh_string_grow(sh_string * s, size_t increase)
322{
323 char * new;
324
325 if (increase == 0)
326 increase = SH_STRING_PARCEL;
327
328 if (s && sl_ok_adds(s->siz, increase) == SL_TRUE)
329 {
330 new = SH_ALLOC(s->siz + increase);
331
332 if (s->str)
333 {
334 memcpy(new, s->str, s->len+1);
335 SH_FREE(s->str);
336 }
337 else
338 {
339 new[0] = '\0';
340 }
341 s->str = new;
342 s->siz += increase;
343 return s;
344 }
345 return NULL;
346}
347
348sh_string * sh_string_truncate(sh_string * s, size_t len)
349{
350 if (s)
351 {
352 if (s->str && (s->len > len) )
353 {
354 s->len = len;
355 (s->str)[len] = '\0';
356 }
357 return s;
358 }
359 return NULL;
360}
361
362void sh_string_destroy(sh_string ** s)
363{
364 if (s)
365 {
366 if ((*s) && (*s)->str)
367 SH_FREE ((*s)->str);
368 SH_FREE(*s);
369 *s = NULL;
370 }
371 return;
372}
373
374sh_string * sh_string_new(size_t size)
375{
376 sh_string * s;
377 s = SH_ALLOC (sizeof(sh_string));
378 if (size == 0)
379 size = SH_STRING_PARCEL;
380 s->str = SH_ALLOC (size);
381 s->str[0] = '\0';
382 s->siz = size;
383 s->len = 0;
384 return s;
385}
386
387/* Replaces fields in s with 'replacement'. Fields are given
388 * in the ordered array ovector, comprising ovecnum pairs
389 * ovector[i], ovector[i+1] which list offset of first char
390 * of field, offset of first char after field (this is how
391 * the pcre library does it).
392 */
393sh_string * sh_string_replace(const sh_string * s,
394 const int * ovector, int ovecnum,
395 const char * replacement, size_t rlen)
396{
397 sh_string * r = NULL;
398 char * p;
399 size_t len;
400 int end = 0;
401 int start = 0;
402 size_t oldlen = 0;
403 size_t newlen = 0;
404 long diff;
405 int i;
406
407
408 for (i = 0; i < ovecnum; ++i)
409 {
410 start = ovector[2*i]; /* offset of first char of substring */
411 if (start >= end)
412 {
413 end = ovector[2*i+1]; /* offset of first char after substring end*/
414
415 if (end > start && (unsigned int)end <= (s->len + 1))
416 {
417 oldlen += (end - start);
418 newlen += rlen;
419 }
420 else /* inconsistency detected */
421 {
422 return NULL;
423 }
424 }
425 else /* overlap detected */
426 {
427 return NULL;
428 }
429 }
430
431 diff = newlen - oldlen;
432
433 if ((diff > 0) && ((s->len + 1 + diff) > s->siz))
434 {
435 r = sh_string_new_from_lchar(sh_string_str(s),
436 sh_string_len(s));
437 r = sh_string_grow(r, diff);
438 }
439 else
440 {
441 r = sh_string_new_from_lchar(sh_string_str(s),
442 sh_string_len(s));
443 }
444
445 if (r && ovecnum > 0)
446 {
447 r->len = 0; r->str[0] = '\0'; p = r->str;
448
449 /* First part, until start of first replacement
450 */
451 memcpy(p, s->str, ovector[0]); p += ovector[0];
452 memcpy(p, replacement, rlen); p += rlen;
453 *p = '\0'; r->len += (ovector[0] + rlen);
454
455 for (i = 1; i < ovecnum; ++i)
456 {
457 /* From end of last replacement to start of this */
458 len = ovector[2*i] - ovector[2*i -1];
459 memcpy(p, &(s->str[ovector[2*i -1]]), len);
460 p += len;
461
462 /* The replacement */
463 memcpy(p, replacement, rlen);
464 p += rlen;
465
466 /* null terminate */
467 *p = '\0'; r->len += (len + rlen);
468 }
469
470 /* Last part, after last replacement; includes terminating null
471 */
472 len = (s->len + 1) - ovector[2*i -1];
473 memcpy(p, &(s->str[ovector[2*i -1]]), len);
474 p += len; *p = '\0'; r->len += (len - 1);
475 }
476 return r;
477}
478
479
480#ifdef SH_CUTEST
481#include <stdlib.h>
482#include "CuTest.h"
483
484void Test_string (CuTest *tc) {
485 int status, i, max = 120;
486 FILE * fp;
487 sh_string * s = NULL;
488 sh_string * t;
489 static char template[] = "/tmp/xtest.XXXXXX";
490 char ** array;
491 char test[128];
492 size_t lengths[16];
493 unsigned int iarr;
494 int ovector[16];
495 int ovecnum;
496
497 s = sh_string_new(0);
498 CuAssertPtrNotNull(tc, s);
499 sh_string_destroy(&s);
500 CuAssertTrue(tc, s == NULL);
501
502 s = sh_string_new(0);
503 CuAssertPtrNotNull(tc, s);
504
505 status = mkstemp(template);
506 CuAssertTrue(tc, status >= 0);
507
508 fp = fdopen(status, "r+");
509 CuAssertPtrNotNull(tc, fp);
510
511 for (i = 0; i < 80; ++i) { fputc ('a', fp); } fputc ('\n', fp); // 0
512 for (i = 0; i < 118; ++i) { fputc ('a', fp); } fputc ('\n', fp); // 1
513 for (i = 0; i < 119; ++i) { fputc ('a', fp); } fputc ('\n', fp); // 2
514 for (i = 0; i < 120; ++i) { fputc ('a', fp); } fputc ('\n', fp); // 3
515 for (i = 0; i < 121; ++i) { fputc ('a', fp); } fputc ('\n', fp); // 4
516 for (i = 0; i < 238; ++i) { fputc ('a', fp); } fputc ('\n', fp);
517 for (i = 0; i < 239; ++i) { fputc ('a', fp); } fputc ('\n', fp);
518 for (i = 0; i < 240; ++i) { fputc ('a', fp); } fputc ('\n', fp);
519 for (i = 0; i < 241; ++i) { fputc ('a', fp); } fputc ('\n', fp);
520
521 rewind(fp);
522
523 for (i = 0; i < 9; ++i)
524 {
525 status = sh_string_read(s, fp, max);
526
527 switch (i) {
528 case 0:
529 CuAssertTrue(tc, s->len == 80);
530 CuAssertTrue(tc, s->siz == 120);
531 CuAssertTrue(tc, status == 81);
532 break;
533 case 1:
534 CuAssertTrue(tc, s->len == 118);
535 CuAssertTrue(tc, s->siz == 120);
536 CuAssertTrue(tc, status == 119);
537 break;
538 case 2:
539 CuAssertTrue(tc, s->len == 119);
540 CuAssertTrue(tc, s->siz == 120);
541 CuAssertTrue(tc, status == -2); /* no terminating '\n', truncated */
542 break;
543 case 3:
544 CuAssertTrue(tc, s->len == 120);
545 CuAssertTrue(tc, s->siz == 240);
546 CuAssertTrue(tc, status == 121);
547 break;
548 case 4:
549 CuAssertTrue(tc, s->len == 121);
550 CuAssertTrue(tc, s->siz == 240);
551 CuAssertTrue(tc, status == 122);
552 break;
553 case 5:
554 CuAssertTrue(tc, s->len == 238);
555 CuAssertTrue(tc, s->siz == 240);
556 CuAssertTrue(tc, status == 239);
557 break;
558 case 6:
559 CuAssertTrue(tc, s->len == 239);
560 CuAssertTrue(tc, s->siz == 240);
561 CuAssertTrue(tc, status == -2); /* no terminating '\n', truncated */
562 break;
563 default:
564 CuAssertTrue(tc, s->len == 239);
565 CuAssertTrue(tc, s->siz == 240);
566 CuAssertTrue(tc, status == -2);
567 }
568 if (status == -2) /* read in rest of string */
569 { max = 240; sh_string_read(s, fp, max); }
570 }
571
572 rewind(fp);
573
574 sh_string_truncate(s, 0);
575 CuAssertTrue(tc, s->len == 0);
576
577 for (i = 0; i < 9; ++i)
578 {
579 status = sh_string_read(s, fp, 240);
580 if (status == -2)
581 sh_string_read(s, fp, 240);
582 else
583 {
584 for (status = 0; status < (int)s->len; ++status)
585 {
586 if (s->str[status] != 'a')
587 {
588 CuFail(tc, "unexpected character");
589 }
590 }
591 }
592 }
593
594 status = fclose(fp);
595 CuAssertTrue(tc, status == 0);
596 status = remove(template);
597 CuAssertTrue(tc, status == 0);
598
599 iarr = 10; strcpy(test, "|a1|| a2| |a3 |a4|a5|");
600 array = split_array(test, &iarr, '|', lengths);
601 CuAssertIntEquals(tc,9,(int)iarr);
602 CuAssertStrEquals(tc,"", array[0]);
603 CuAssertStrEquals(tc,"a1", array[1]);
604 CuAssertStrEquals(tc,"", array[2]);
605 CuAssertStrEquals(tc,"a2", array[3]);
606 CuAssertStrEquals(tc,"", array[4]);
607 CuAssertStrEquals(tc,"a3", array[5]);
608 CuAssertStrEquals(tc,"a4", array[6]);
609 CuAssertStrEquals(tc,"a5", array[7]);
610 CuAssertStrEquals(tc,"", array[8]);
611
612 CuAssertIntEquals(tc, 0, (int)lengths[0]);
613 CuAssertIntEquals(tc, 2, (int)lengths[1]);
614 CuAssertIntEquals(tc, 0, (int)lengths[2]);
615 CuAssertIntEquals(tc, 2, (int)lengths[3]);
616 CuAssertIntEquals(tc, 0, (int)lengths[4]);
617 CuAssertIntEquals(tc, 2, (int)lengths[5]);
618 CuAssertIntEquals(tc, 2, (int)lengths[6]);
619 CuAssertIntEquals(tc, 2, (int)lengths[7]);
620 CuAssertIntEquals(tc, 0, (int)lengths[8]);
621
622 iarr = 10; strcpy(test, "a1|| a2| |a3 |a4|a5|");
623 array = split_array(test, &iarr, '|', lengths);
624 CuAssertIntEquals(tc,8,(int)iarr);
625 CuAssertStrEquals(tc,"a1", array[0]);
626 CuAssertStrEquals(tc,"", array[1]);
627 CuAssertStrEquals(tc,"a2", array[2]);
628 CuAssertStrEquals(tc,"", array[3]);
629 CuAssertStrEquals(tc,"a3", array[4]);
630 CuAssertStrEquals(tc,"a4", array[5]);
631 CuAssertStrEquals(tc,"a5", array[6]);
632 CuAssertStrEquals(tc,"", array[7]);
633
634 CuAssertIntEquals(tc, 2, (int)lengths[0]);
635 CuAssertIntEquals(tc, 0, (int)lengths[1]);
636 CuAssertIntEquals(tc, 2, (int)lengths[2]);
637 CuAssertIntEquals(tc, 0, (int)lengths[3]);
638 CuAssertIntEquals(tc, 2, (int)lengths[4]);
639 CuAssertIntEquals(tc, 2, (int)lengths[5]);
640 CuAssertIntEquals(tc, 2, (int)lengths[6]);
641 CuAssertIntEquals(tc, 0, (int)lengths[7]);
642
643 iarr = 10; strcpy(test, " a1|| a2 | |a3 |a4|a5");
644 array = split_array(test, &iarr, '|', lengths);
645 CuAssertIntEquals(tc,7,(int)iarr);
646 CuAssertStrEquals(tc,"a1", array[0]);
647 CuAssertStrEquals(tc,"", array[1]);
648 CuAssertStrEquals(tc,"a2", array[2]);
649 CuAssertStrEquals(tc,"", array[3]);
650 CuAssertStrEquals(tc,"a3", array[4]);
651 CuAssertStrEquals(tc,"a4", array[5]);
652 CuAssertStrEquals(tc,"a5", array[6]);
653
654 CuAssertIntEquals(tc, 2, (int)lengths[0]);
655 CuAssertIntEquals(tc, 0, (int)lengths[1]);
656 CuAssertIntEquals(tc, 2, (int)lengths[2]);
657 CuAssertIntEquals(tc, 0, (int)lengths[3]);
658 CuAssertIntEquals(tc, 2, (int)lengths[4]);
659 CuAssertIntEquals(tc, 2, (int)lengths[5]);
660 CuAssertIntEquals(tc, 2, (int)lengths[6]);
661
662 iarr = 10; strcpy(test, "a1|| a2 | |a3 |a4|a5 ");
663 array = split_array(test, &iarr, '|', lengths);
664 CuAssertIntEquals(tc,7,(int)iarr);
665 CuAssertStrEquals(tc,"a1", array[0]);
666 CuAssertStrEquals(tc,"", array[1]);
667 CuAssertStrEquals(tc,"a2", array[2]);
668 CuAssertStrEquals(tc,"", array[3]);
669 CuAssertStrEquals(tc,"a3", array[4]);
670 CuAssertStrEquals(tc,"a4", array[5]);
671 CuAssertStrEquals(tc,"a5", array[6]);
672
673 CuAssertIntEquals(tc, 2, (int)lengths[0]);
674 CuAssertIntEquals(tc, 0, (int)lengths[1]);
675 CuAssertIntEquals(tc, 2, (int)lengths[2]);
676 CuAssertIntEquals(tc, 0, (int)lengths[3]);
677 CuAssertIntEquals(tc, 2, (int)lengths[4]);
678 CuAssertIntEquals(tc, 2, (int)lengths[5]);
679 CuAssertIntEquals(tc, 2, (int)lengths[6]);
680
681 iarr = 10; strcpy(test, "|");
682 array = split_array(test, &iarr, '|', lengths);
683 CuAssertIntEquals(tc,2,(int)iarr);
684 CuAssertStrEquals(tc,"", array[0]);
685 CuAssertStrEquals(tc,"", array[1]);
686
687 CuAssertIntEquals(tc, 0, (int)lengths[0]);
688 CuAssertIntEquals(tc, 0, (int)lengths[1]);
689
690 iarr = 10; strcpy(test, "|||");
691 array = split_array(test, &iarr, '|', lengths);
692 CuAssertIntEquals(tc,4,(int)iarr);
693 CuAssertStrEquals(tc,"", array[0]);
694 CuAssertStrEquals(tc,"", array[1]);
695 CuAssertStrEquals(tc,"", array[2]);
696 CuAssertStrEquals(tc,"", array[3]);
697
698 CuAssertIntEquals(tc, 0, (int)lengths[0]);
699 CuAssertIntEquals(tc, 0, (int)lengths[1]);
700 CuAssertIntEquals(tc, 0, (int)lengths[2]);
701 CuAssertIntEquals(tc, 0, (int)lengths[3]);
702
703 iarr = 10; strcpy(test, " a1 ");
704 array = split_array(test, &iarr, '|', lengths);
705 CuAssertIntEquals(tc,1,(int)iarr);
706 CuAssertStrEquals(tc,"a1", array[0]);
707
708 CuAssertIntEquals(tc, 2, (int)lengths[0]);
709
710 iarr = 10; strcpy(test, "");
711 array = split_array(test, &iarr, '|', lengths);
712 CuAssertIntEquals(tc,1,(int)iarr);
713 CuAssertStrEquals(tc,"", array[0]);
714
715 CuAssertIntEquals(tc, 0, (int)lengths[0]);
716
717 /* WS separated */
718
719 iarr = 10; strcpy(test, "a1");
720 array = split_array_ws (test, &iarr, lengths);
721 CuAssertIntEquals(tc,1,(int)iarr);
722 CuAssertStrEquals(tc,"a1", array[0]);
723
724 CuAssertIntEquals(tc, 2, (int)lengths[0]);
725
726 iarr = 10; strcpy(test, " a1");
727 array = split_array_ws (test, &iarr, lengths);
728 CuAssertIntEquals(tc,1,(int)iarr);
729 CuAssertStrEquals(tc,"a1", array[0]);
730
731 CuAssertIntEquals(tc, 2, (int)lengths[0]);
732
733 iarr = 10; strcpy(test, " a1 ");
734 array = split_array_ws (test, &iarr, lengths);
735 CuAssertIntEquals(tc,1,(int)iarr);
736 CuAssertStrEquals(tc,"a1", array[0]);
737
738 CuAssertIntEquals(tc, 2, (int)lengths[0]);
739
740 iarr = 10; strcpy(test, " ");
741 array = split_array_ws (test, &iarr, lengths);
742 CuAssertIntEquals(tc,0,(int)iarr);
743 CuAssertTrue(tc, array[0] == NULL);
744
745 iarr = 10; strcpy(test, " a1 a2");
746 array = split_array_ws (test, &iarr, lengths);
747 CuAssertIntEquals(tc,2,(int)iarr);
748 CuAssertStrEquals(tc,"a1", array[0]);
749 CuAssertStrEquals(tc,"a2", array[1]);
750
751 CuAssertIntEquals(tc, 2, (int)lengths[0]);
752 CuAssertIntEquals(tc, 2, (int)lengths[1]);
753
754 iarr = 10; strcpy(test, " a1 a2 ");
755 array = split_array_ws (test, &iarr, lengths);
756 CuAssertIntEquals(tc,2,(int)iarr);
757 CuAssertStrEquals(tc,"a1", array[0]);
758 CuAssertStrEquals(tc,"a2", array[1]);
759
760 CuAssertIntEquals(tc, 2, (int)lengths[0]);
761 CuAssertIntEquals(tc, 2, (int)lengths[1]);
762
763 iarr = 10; strcpy(test, "");
764 array = split_array_ws (test, &iarr, lengths);
765 CuAssertIntEquals(tc,0,(int)iarr);
766 CuAssertTrue(tc, array[0] == NULL);
767
768 iarr = 3; strcpy(test, " this is a test for remainder");
769 array = split_array_ws (test, &iarr, lengths);
770 CuAssertIntEquals(tc,3,(int)iarr);
771 CuAssertStrEquals(tc,"this", array[0]);
772 CuAssertStrEquals(tc,"is", array[1]);
773 CuAssertStrEquals(tc,"a test for remainder", array[2]);
774 for (i = 0; i < 3; ++i)
775 {
776 CuAssertIntEquals(tc, (int)strlen(array[i]), lengths[i] );
777 }
778
779 /* string replace */
780 s = sh_string_new_from_lchar3 ("abc ", 4, "def ", 4, "ghi ", 4);
781 ovecnum = 2;
782 ovector[0] = 0; ovector[1] = 2;
783 ovector[2] = 4; ovector[3] = 11;
784
785 t = sh_string_replace(s, ovector, ovecnum,
786 "___", 3);
787 CuAssertStrEquals(tc, "___c ___ ", t->str);
788 CuAssertIntEquals(tc, 9, (int)t->len);
789
790 ovector[0] = 0; ovector[1] = 2;
791 ovector[2] = 4; ovector[3] = 12;
792 t = sh_string_replace(s, ovector, ovecnum,
793 "___", 3);
794 CuAssertStrEquals(tc, "___c ___", t->str);
795 CuAssertIntEquals(tc, 8, (int)t->len);
796
797 ovector[0] = 0; ovector[1] = 0;
798 ovector[2] = 0; ovector[3] = 0;
799 t = sh_string_replace(s, ovector, ovecnum,
800 "___", 3);
801 CuAssertTrue(tc, t == NULL);
802
803 ovector[0] = 0; ovector[1] = 3;
804 ovector[2] = 3; ovector[3] = 6;
805 t = sh_string_replace(s, ovector, ovecnum,
806 "___", 3);
807
808 CuAssertStrEquals(tc, "______f ghi ", t->str);
809 CuAssertIntEquals(tc, 12, (int)t->len);
810
811 ovector[0] = 4; ovector[1] = 5;
812 ovector[2] = 11; ovector[3] = 12;
813 t = sh_string_replace(s, ovector, ovecnum,
814 "___", 3);
815 CuAssertStrEquals(tc, "abc ___ef ghi___", t->str);
816 CuAssertIntEquals(tc, 16, (int)t->len);
817
818 t = sh_string_replace(s, ovector, 0,
819 "___", 3);
820 CuAssertStrEquals(tc, s->str, t->str);
821 CuAssertIntEquals(tc, (int)s->len, (int)t->len);
822
823}
824
825#endif
Note: See TracBrowser for help on using the repository browser.