1 /*
2 * str_test.c
3 *
4 * Copyright (c) 2014-2021
5 *
6 * Source code released under the GPL version 2
7 */
8
9 /* Need to add tests for...
10
11 const char *str_addutf8 ( str *s, const char *p );
12 void str_fprintf ( FILE *fp, str *s );
13 int str_fget ( FILE *fp, char *buf, int bufsize, int *pbufpos,
14 str *outs );
15 int str_fgetline ( str *s, FILE *fp );
16 */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "str.h"
22
23 char progname[] = "str_test";
24 char version[] = "0.3";
25
26 int
_inconsistent_len(str * s,unsigned long numchars,const char * fn,unsigned long line)27 _inconsistent_len( str *s, unsigned long numchars, const char *fn, unsigned long line )
28 {
29 if ( s->len > s->dim ) {
30 fprintf(stdout,"%s line %lu: failed consistency check found s->len=%lu, s->max=%lu\n",fn,line,
31 s->len, s->dim );
32 }
33 if ( s->data ) {
34 if ( s->len != strlen( s->data ) ) {
35 fprintf(stdout,"%s line %lu: failed consistency check found strlen=%d, s->len=%ld\n",fn,line,(int)strlen(s->data),s->len);
36 return 1;
37 }
38 } else {
39 if ( s->len != 0 ) {
40 fprintf(stdout,"%s line %lu: failed consistency check found for unallocated string, s->len=%ld\n",fn,line,s->len);
41 return 1;
42 }
43 }
44 if ( s->len != numchars ) {
45 fprintf(stdout,"%s line %lu: failed consistency check found %d, expected %lu\n",fn,line,(int)strlen(s->data),numchars);
46 return 1;
47 }
48 return 0;
49 }
50
51 #define inconsistent_len( a, b ) _inconsistent_len( (a), (b), __FUNCTION__, __LINE__ )
52
53 int
_test_identity(str * s,const char * expected,const char * fn,unsigned long line)54 _test_identity( str *s, const char *expected, const char *fn, unsigned long line )
55 {
56 /* Unallocated strings are considered identical to empty strings */
57 if ( expected[0]=='\0' ) {
58 if ( s->data==NULL || s->data[0]=='\0' ) return 0;
59 fprintf(stdout,"%s line %lu: failed identity check found '%s', expected ''\n",fn,line,s->data);
60 return 1;
61 }
62 /* expected!="", so s->data must exist */
63 if ( !s->data ) {
64 fprintf(stdout,"%s line %lu: failed identity check, s->data unallocated, expected '%s'\n",fn,line,expected);
65 return 1;
66 }
67 if ( strcmp( s->data, expected ) == 0 ) return 0;
68 fprintf(stdout,"%s line %lu: failed identity check, found '%s', expected '%s'\n",fn,line,s->data,expected);
69 return 1;
70 }
71
72 #define test_identity( a, b ) _test_identity( (a), (b), __FUNCTION__, __LINE__ )
73
74 #define string_mismatch( a, b, c ) ( test_identity( (a), (c) ) || inconsistent_len( (a), (b) ) )
75
76 static int
test_empty(str * s)77 test_empty( str *s )
78 {
79 int failed = 0;
80 int numchars = 1000, i, j;
81
82 str_empty( s );
83 if ( string_mismatch( s, 0, "" ) ) failed++;
84
85 for ( i=0; i<numchars; ++i ) {
86 for ( j=0; j<i; ++j )
87 str_addchar( s, 'x' );
88 str_empty( s );
89 if ( string_mismatch( s, 0, "" ) ) failed++;
90 }
91
92 return failed;
93 }
94
95 static int
test_addchar(str * s)96 test_addchar( str *s )
97 {
98 int failed = 0;
99 int numshort = 5, numchars = 1000, i;
100
101 /* ...appending '\0' characters won't increase length */
102 str_empty( s );
103 for ( i=0; i<numshort; ++i )
104 str_addchar( s, '\0' );
105 if ( string_mismatch( s, 0, "" ) ) failed++;
106
107 /* ...build "11111" with str_addchar */
108 str_empty( s );
109 for ( i=0; i<numshort; ++i )
110 str_addchar( s, '1' );
111 if ( string_mismatch( s, 5, "11111" ) ) failed++;
112
113 /* ...build a bunch of random characters */
114 str_empty( s );
115 for ( i=0; i<numchars; ++i ) {
116 str_addchar( s, ( i % 64 ) + 64);
117 }
118 if ( inconsistent_len( s, numchars ) ) failed++;
119
120 return failed;
121 }
122
123 static int
test_strcatc(str * s)124 test_strcatc( str *s )
125 {
126 int failed = 0;
127 int numshort = 5, numstrings = 1000, i;
128
129 /* ...adding empty strings to an empty string shouldn't change length */
130 str_empty( s );
131 for ( i=0; i<numstrings; ++i )
132 str_strcatc( s, "" );
133 if ( string_mismatch( s, 0, "" ) ) failed++;
134
135 /* ...adding empty strings to a defined string shouldn't change string */
136 str_strcpyc( s, "1" );
137 for ( i=0; i<numstrings; ++i )
138 str_strcatc( s, "" );
139 if ( string_mismatch( s, 1, "1" ) ) failed++;
140
141 /* ...build "1111" with str_strcatc */
142 str_empty( s );
143 for ( i=0; i<numshort; ++i )
144 str_strcatc( s, "1" );
145 if ( string_mismatch( s, numshort, "11111" ) ) failed++;
146
147 /* ...build "xoxoxoxoxo" with str_strcatc */
148 str_empty( s );
149 for ( i=0; i<numshort; ++i )
150 str_strcatc( s, "xo" );
151 if ( string_mismatch( s, numshort*2, "xoxoxoxoxo" ) ) failed++;
152
153 str_empty( s );
154 for ( i=0; i<numstrings; ++i )
155 str_strcatc( s, "1" );
156 if ( inconsistent_len( s, numstrings ) ) failed++;
157
158 str_empty( s );
159 for ( i=0; i<numstrings; ++i )
160 str_strcatc( s, "XXOO" );
161 if ( inconsistent_len( s, numstrings*4 ) ) failed++;
162
163 return failed;
164 }
165
166 static int
test_strcat(str * s)167 test_strcat( str *s )
168 {
169 int numshort = 5, numstrings = 1000, i;
170 int failed = 0;
171 str t;
172
173 str_init( &t );
174
175 /* ...adding empty strings to an empty string shouldn't change length */
176 str_empty( s );
177 for ( i=0; i<numstrings; ++i )
178 str_strcat( s, &t );
179 if ( string_mismatch( s, 0, "" ) ) failed++;
180
181 /* ...adding empty strings to a defined string shouldn't change string */
182 str_strcpyc( s, "1" );
183 for ( i=0; i<numstrings; ++i )
184 str_strcat( s, &t );
185 if ( string_mismatch( s, 1, "1" ) ) failed++;
186
187 /* ...build "1111" with str_strcat */
188 str_empty( s );
189 str_strcpyc( &t, "1" );
190 for ( i=0; i<numshort; ++i )
191 str_strcat( s, &t );
192 if ( string_mismatch( s, numshort, "11111" ) ) failed++;
193
194 /* ...build "xoxoxoxoxo" with str_strcat */
195 str_empty( s );
196 str_strcpyc( &t, "xo" );
197 for ( i=0; i<numshort; ++i )
198 str_strcat( s, &t );
199 if ( string_mismatch( s, numshort*2, "xoxoxoxoxo" ) ) failed++;
200
201 str_empty( s );
202 str_strcpyc( &t, "1" );
203 for ( i=0; i<numstrings; ++i )
204 str_strcat( s, &t );
205 if ( inconsistent_len( s, numstrings ) ) failed++;
206
207 str_empty( s );
208 str_strcpyc( &t, "XXOO" );
209 for ( i=0; i<numstrings; ++i )
210 str_strcat( s, &t );
211 if ( inconsistent_len( s, numstrings*4 ) ) failed++;
212
213 str_free( &t );
214
215 return failed;
216 }
217
218 static int
test_strcpyc(str * s)219 test_strcpyc( str *s )
220 {
221 int failed = 0;
222 int numstrings = 1000, i;
223
224 /* Copying null string should reset string */
225 str_empty( s );
226 for ( i=0; i<numstrings; ++i ) {
227 str_strcpyc( s, "1" );
228 str_strcpyc( s, "" );
229 if ( string_mismatch( s, 0, "" ) ) failed++;
230 }
231
232 /* Many rounds of copying just "1" should give "1" */
233 str_empty( s );
234 for ( i=0; i<numstrings; ++i ) {
235 str_strcpyc( s, "1" );
236 if ( string_mismatch( s, 1, "1" ) ) failed++;
237 }
238
239 /* Many rounds of copying just "XXOO" should give "XXOO" */
240 str_empty( s );
241 for ( i=0; i<numstrings; ++i ) {
242 str_strcpyc( s, "XXOO" );
243 if ( string_mismatch( s, 4, "XXOO" ) ) failed++;
244 }
245
246 return failed;
247 }
248
249 static int
test_strcpy(str * s)250 test_strcpy( str *s )
251 {
252 int failed = 0;
253 int numstrings = 1000, i;
254 str t;
255
256 str_init( &t );
257
258 /* Copying null string should reset string */
259 str_empty( s );
260 for ( i=0; i<numstrings; ++i ) {
261 str_strcpyc( s, "1" );
262 str_strcpy( s, &t );
263 if ( string_mismatch( s, 0, "" ) ) failed++;
264 }
265
266 /* Many rounds of copying just "1" should give "1" */
267 str_empty( s );
268 str_strcpyc( &t, "1" );
269 for ( i=0; i<numstrings; ++i ) {
270 str_strcpy( s, &t );
271 if ( string_mismatch( s, t.len, t.data ) ) failed++;
272 }
273
274 /* Many rounds of copying just "XXOO" should give "XXOO" */
275 str_empty( s );
276 str_strcpyc( &t, "XXOO" );
277 for ( i=0; i<numstrings; ++i ) {
278 str_strcpy( s, &t );
279 if ( string_mismatch( s, t.len, t.data ) ) failed++;
280 }
281
282 str_free( &t );
283
284 return failed;
285 }
286
287 static int
test_segcpy(str * s)288 test_segcpy( str *s )
289 {
290 char segment[]="0123456789";
291 char *start=&(segment[2]), *end=&(segment[5]);
292 int numstrings = 1000, i;
293 str t, u;
294 int failed = 0;
295
296 str_init( &t );
297 str_init( &u );
298
299 str_empty( s );
300 str_segcpy( s, start, start );
301 if ( string_mismatch( s, 0, "" ) ) failed++;
302
303 str_segcpy( &t, start, start );
304 if ( string_mismatch( &t, 0, "" ) ) failed++;
305
306 str_segcpy( &u, start, end );
307 if ( string_mismatch( &u, 3, "234" ) ) failed++;
308
309 str_empty( s );
310 for ( i=0; i<numstrings; ++i ) {
311 str_segcpy( s, start, end );
312 if ( string_mismatch( s, 3, "234" ) ) failed++;
313 }
314
315 str_free( &t );
316 str_free( &u );
317
318 return failed;
319 }
320
321 static int
test_indxcpy(str * s)322 test_indxcpy( str *s )
323 {
324 char segment[]="0123456789";
325 int numstrings = 10, i;
326 str t, u;
327 int failed = 0;
328
329 str_init( &t );
330 str_init( &u );
331
332 str_empty( s );
333 str_indxcpy( s, segment, 2, 2 );
334 if ( string_mismatch( s, 0, "" ) ) failed++;
335
336 str_indxcpy( &t, segment, 2, 2 );
337 if ( string_mismatch( &t, 0, "" ) ) failed++;
338
339 str_indxcpy( &u, segment, 2, 5 );
340 if ( string_mismatch( &u, 3, "234" ) ) failed++;
341
342 str_empty( s );
343 for ( i=0; i<numstrings; ++i ) {
344 str_indxcpy( s, segment, 2, 5 );
345 if ( string_mismatch( s, 3, "234" ) ) failed++;
346 }
347
348 str_free( &t );
349 str_free( &u );
350
351 return failed;
352 }
353
354 /* void str_copyposlen ( str *s, str *in, unsigned long pos, unsigned long len ); */
355 static int
test_copyposlen(str * s)356 test_copyposlen( str *s )
357 {
358 str t;
359 int failed = 0;
360
361 str_init( &t );
362
363 str_copyposlen( s, &t, 1, 5 );
364 if ( string_mismatch( s, 0, "" ) ) failed++;
365
366 str_strcpyc( &t, "0123456789" );
367
368 str_copyposlen( s, &t, 1, 5 );
369 if ( string_mismatch( s, 5, "12345" ) ) failed++;
370
371 str_free( &t );
372
373 return failed;
374 }
375
376 static int
test_indxcat(str * s)377 test_indxcat( str *s )
378 {
379 char segment[]="0123456789";
380 int numstrings = 3, i;
381 str t, u;
382 int failed = 0;
383
384 str_init( &t );
385 str_init( &u );
386
387 str_empty( s );
388 str_indxcat( s, segment, 2, 2 );
389 if ( string_mismatch( s, 0, "" ) ) failed++;
390
391 str_indxcat( &t, segment, 2, 2 );
392 if ( string_mismatch( &t, 0, "" ) ) failed++;
393
394 str_indxcat( &u, segment, 2, 5 );
395 if ( string_mismatch( &u, 3, "234" ) ) failed++;
396
397 str_empty( s );
398 for ( i=0; i<numstrings; ++i )
399 str_indxcat( s, segment, 2, 5 );
400 if ( string_mismatch( s, 9, "234234234" ) ) failed++;
401
402 str_free( &t );
403 str_free( &u );
404
405 return failed;
406 }
407
408 static int
test_segcat(str * s)409 test_segcat( str *s )
410 {
411 char segment[]="0123456789";
412 char *start=&(segment[2]), *end=&(segment[5]);
413 int numstrings = 1000, i;
414 int failed = 0;
415 str t, u;
416
417 str_init( &t );
418 str_init( &u );
419
420 str_empty( s );
421 str_segcpy( s, start, start );
422 if ( string_mismatch( s, 0, "" ) ) failed++;
423
424 str_segcpy( &t, start, start );
425 if ( string_mismatch( &t, 0, "" ) ) failed++;
426
427 str_segcpy( &u, start, end );
428 if ( string_mismatch( &u, 3, "234" ) ) failed++;
429
430 str_empty( s );
431 for ( i=0; i<numstrings; ++i )
432 str_segcat( s, start, end );
433 if ( inconsistent_len( s, 3*numstrings ) ) failed++;
434
435 str_free( &t );
436 str_free( &u );
437
438 return failed;
439 }
440
441 static int
test_prepend(str * s)442 test_prepend( str *s )
443 {
444 int failed = 0;
445
446 str_empty( s );
447 str_prepend( s, "" );
448 if ( string_mismatch( s, 0, "" ) ) failed++;
449 str_prepend( s, "asdf" );
450 if ( string_mismatch( s, 4, "asdf" ) ) failed++;
451
452 str_strcpyc( s, "567890" );
453 str_prepend( s, "01234" );
454 if ( string_mismatch( s, 11, "01234567890" ) ) failed++;
455
456 return failed;
457 }
458
459 static int
test_pad(str * s)460 test_pad( str *s )
461 {
462 int failed = 0;
463
464 str_empty( s );
465 str_pad( s, 10, '-' );
466 if ( string_mismatch( s, 10, "----------" ) ) failed++;
467
468 str_strcpyc( s, "012" );
469 str_pad( s, 10, '-' );
470 if ( string_mismatch( s, 10, "012-------" ) ) failed++;
471
472 str_strcpyc( s, "0123456789" );
473 str_pad( s, 10, '-' );
474 if ( string_mismatch( s, 10, "0123456789" ) ) failed++;
475
476 str_strcpyc( s, "01234567890" );
477 str_pad( s, 10, '-' );
478 if ( string_mismatch( s, 11, "01234567890" ) ) failed++;
479
480 return failed;
481 }
482
483 static int
test_makepath(str * s)484 test_makepath( str *s )
485 {
486 int failed = 0;
487
488 str_empty( s );
489 str_makepath( s, "", "", '/' );
490 if ( string_mismatch( s, 0, "" ) ) failed++;
491
492 str_makepath( s, "", "file1.txt", '/' );
493 if ( string_mismatch( s, 9, "file1.txt" ) ) failed++;
494
495 str_makepath( s, "/home/user", "", '/' );
496 if ( string_mismatch( s, 11, "/home/user/" ) ) failed++;
497
498 str_makepath( s, "/home/user", "file1.txt", '/' );
499 if ( string_mismatch( s, 20, "/home/user/file1.txt" ) ) failed++;
500
501 str_makepath( s, "/home/user/", "", '/' );
502 if ( string_mismatch( s, 11, "/home/user/" ) ) failed++;
503
504 str_makepath( s, "/home/user/", "file1.txt", '/' );
505 if ( string_mismatch( s, 20, "/home/user/file1.txt" ) ) failed++;
506
507 return failed;
508 }
509
510 static int
test_findreplace(str * s)511 test_findreplace( str *s )
512 {
513 char segment[]="0123456789";
514 int numstrings = 1000, i;
515 int failed = 0;
516
517 for ( i=0; i<numstrings; ++i ) {
518 str_strcpyc( s, segment );
519 str_findreplace( s, "234", "" );
520 }
521 if ( string_mismatch( s, 7, "0156789" ) ) failed++;
522
523 for ( i=0; i<numstrings; ++i ) {
524 str_strcpyc( s, segment );
525 str_findreplace( s, "234", "223344" );
526 }
527 if ( string_mismatch( s, 13, "0122334456789" ) ) failed++;
528
529 return failed;
530 }
531
532 static int
test_mergestrs(str * s)533 test_mergestrs( str *s )
534 {
535 int failed = 0;
536
537 str_empty( s );
538
539 /* don't add any anything */
540 str_mergestrs( s, NULL );
541 if ( string_mismatch( s, 0, "" ) ) failed++;
542
543 /* add just one string */
544 str_mergestrs( s, "01", NULL );
545 if ( string_mismatch( s, 2, "01" ) ) failed++;
546
547 /* add multiple strings */
548 str_mergestrs( s, "01", "23", "45", "67", "89", NULL );
549 if ( string_mismatch( s, 10, "0123456789" ) ) failed++;
550
551 return failed;
552 }
553
554 static int
test_cpytodelim(str * s)555 test_cpytodelim( str *s )
556 {
557 char str0[]="\0";
558 char str1[]="Col1\tCol2\tCol3\n";
559 char str2[]="Col1 Col2 Col3";
560 const char *q;
561 int failed = 0;
562
563 q = str_cpytodelim( s, str0, "\t", 0 );
564 if ( string_mismatch( s, 0, "" ) ) failed++;
565 if ( *q!='\0' ) {
566 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected '\\t'\n", __FUNCTION__, __LINE__, *q );
567 failed++;
568 }
569
570 q = str_cpytodelim( s, str1, "\t", 0 );
571 if ( string_mismatch( s, 4, "Col1" ) ) failed++;
572 if ( *q!='\t' ) {
573 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected '\\t'\n", __FUNCTION__, __LINE__, *q );
574 failed++;
575 }
576
577 q = str_cpytodelim( s, str1, " \t", 0 );
578 if ( string_mismatch( s, 4, "Col1" ) ) failed++;
579 if ( *q!='\t' ) {
580 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected '\\t'\n", __FUNCTION__, __LINE__, *q );
581 failed++;
582 }
583
584 q = str_cpytodelim( s, str1, "\t", 1 );
585 if ( string_mismatch( s, 4, "Col1" ) ) failed++;
586 if ( *q!='C' ) {
587 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected 'C'\n", __FUNCTION__, __LINE__, *q );
588 failed++;
589 }
590
591 q = str_cpytodelim( s, str1, "\n", 0 );
592 if ( string_mismatch( s, strlen(str1)-1, "Col1\tCol2\tCol3" ) ) failed++;
593 if ( *q!='\n' ) {
594 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected '\\n'\n", __FUNCTION__, __LINE__, *q );
595 failed++;
596 }
597
598 q = str_cpytodelim( s, str1, "\r", 0 );
599 if ( string_mismatch( s, strlen(str1), "Col1\tCol2\tCol3\n" ) ) failed++;
600 if ( *q!='\0' ) {
601 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected '\\n'\n", __FUNCTION__, __LINE__, *q );
602 failed++;
603 }
604
605 q = str_cpytodelim( s, str2, " ", 0 );
606 if ( string_mismatch( s, 4, "Col1" ) ) failed++;
607 if ( *q!=' ' ) {
608 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected '\\t'\n", __FUNCTION__, __LINE__, *q );
609 failed++;
610 }
611
612 q = str_cpytodelim( s, str2, "\t", 0 );
613 if ( string_mismatch( s, strlen(str2), str2 ) ) failed++;
614 if ( *q!='\0' ) {
615 fprintf( stdout, "%s line %d: str_cpytodelim() returned '%c', expected '\\t'\n", __FUNCTION__, __LINE__, *q );
616 failed++;
617 }
618
619 return failed;
620 }
621
622 /* char *str_caytodelim ( str *s, char *p, const char *delim, unsigned char finalstep ); */
623 static int
test_cattodelim(str * s)624 test_cattodelim( str *s )
625 {
626 char str1[] = "1 1 1 1 1 1 1";
627 int failed = 0, i, n = 2;
628 const char *q;
629
630 str_empty( s );
631 for ( i=0; i<n; ++i ) {
632 q = str_cattodelim( s, str1, " ", 0 );
633 if ( *q!=' ' ) {
634 fprintf( stdout, "%s line %d: str_cattodelim() returned '%c', expected ' '\n", __FUNCTION__, __LINE__, *q );
635 failed++;
636 }
637 }
638 if ( string_mismatch( s, n, "11" ) ) failed++;
639
640 str_empty( s );
641 q = str1;
642 while ( *q ) {
643 q = str_cattodelim( s, q, " ", 1 );
644 if ( *q!='1' && *q!='\0' ) {
645 fprintf( stdout, "%s line %d: str_cattodelim() returned '%c', expected '1' or '\\0' \n", __FUNCTION__, __LINE__, *q );
646 failed++;
647 }
648 }
649 if ( string_mismatch( s, 7, "1111111" ) ) failed++;
650
651 return failed;
652 }
653
654 static int
test_strdup(void)655 test_strdup( void )
656 {
657 char str1[] = "In Isbel's case and mine own. Service is no heritage: and I think I shall never have the blessing of God till I have issue o' my body; for they say barnes are blessings.";
658 char str2[] = "Here once again we sit, once again crown'd, And looked upon, I hope, with cheerful eyes.";
659 int failed = 0;
660 str *dup;
661
662 dup = str_strdupc( "" );
663 if ( dup==NULL ) {
664 fprintf( stdout, "%s line %d: str_strdup() returned NULL\n", __FUNCTION__, __LINE__ );
665 failed++;
666 } else {
667 if ( string_mismatch( dup, 0, "" ) ) failed++;
668 str_delete( dup );
669 }
670
671 dup = str_strdupc( str1 );
672 if ( dup==NULL ) {
673 fprintf( stdout, "%s line %d: str_strdup() returned NULL\n", __FUNCTION__, __LINE__ );
674 failed++;
675 } else {
676 if ( string_mismatch( dup, strlen(str1), str1 ) ) failed++;
677 str_delete( dup );
678 }
679
680 dup = str_strdupc( str2 );
681 if ( dup==NULL ) {
682 fprintf( stdout, "%s line %d: str_strdup() returned NULL\n", __FUNCTION__, __LINE__ );
683 failed++;
684 } else {
685 if ( string_mismatch( dup, strlen(str2), str2 ) ) failed++;
686 str_delete( dup );
687 }
688 return failed;
689 }
690
691 static int
test_toupper(str * s)692 test_toupper( str *s )
693 {
694 char str1[] = "abcde_ABCDE_12345";
695 char str2[] = "0123456789";
696 int failed = 0;
697
698 str_empty( s );
699 str_toupper( s );
700 if ( string_mismatch( s, 0, "" ) ) failed++;
701
702 str_strcpyc( s, str1 );
703 str_toupper( s );
704 if ( string_mismatch( s, strlen(str1), "ABCDE_ABCDE_12345" ) ) failed++;
705
706 str_strcpyc( s, str2 );
707 str_toupper( s );
708 if ( string_mismatch( s, strlen(str2), str2 ) ) failed++;
709
710 return failed;
711 }
712
713 static int
test_tolower(str * s)714 test_tolower( str *s )
715 {
716 char str1[] = "abcde_ABCDE_12345";
717 char str2[] = "0123456789";
718 int failed = 0;
719
720 str_empty( s );
721 str_tolower( s );
722 if ( string_mismatch( s, 0, "" ) ) failed++;
723
724 str_strcpyc( s, str1 );
725 str_tolower( s );
726 if ( string_mismatch( s, strlen(str1), "abcde_abcde_12345" ) ) failed++;
727
728 str_strcpyc( s, str2 );
729 str_tolower( s );
730 if ( string_mismatch( s, strlen(str2), str2 ) ) failed++;
731
732 return failed;
733 }
734
735 static int
test_trimws(str * s)736 test_trimws( str *s )
737 {
738 char str1[] = " ksjadfk lajskfjds askdjflkj ";
739 char str2[] = " ";
740 int failed = 0;
741
742 str_empty( s );
743 str_trimstartingws( s );
744 if ( string_mismatch( s, 0, "" ) ) failed++;
745 str_trimendingws( s );
746 if ( string_mismatch( s, 0, "" ) ) failed++;
747
748 str_strcpyc( s, str2 );
749 str_trimstartingws( s );
750 if ( string_mismatch( s, 0, "" ) ) failed++;
751
752 str_strcpyc( s, str2 );
753 str_trimendingws( s );
754 if ( string_mismatch( s, 0, "" ) ) failed++;
755
756 str_strcpyc( s, str1 );
757 str_trimstartingws( s );
758 if ( string_mismatch( s, strlen("ksjadfk lajskfjds askdjflkj "), "ksjadfk lajskfjds askdjflkj " ) ) failed++;
759 str_trimendingws( s );
760 if ( string_mismatch( s, strlen("ksjadfk lajskfjds askdjflkj"), "ksjadfk lajskfjds askdjflkj" ) ) failed++;
761
762 str_strcpyc( s, str1 );
763 str_trimendingws( s );
764 if ( string_mismatch( s, strlen(" ksjadfk lajskfjds askdjflkj"), " ksjadfk lajskfjds askdjflkj" ) ) failed++;
765 str_trimstartingws( s );
766 if ( string_mismatch( s, strlen("ksjadfk lajskfjds askdjflkj"), "ksjadfk lajskfjds askdjflkj" ) ) failed++;
767
768 str_empty( s );
769 str_stripws( s );
770 if ( string_mismatch( s, 0, "" ) ) failed++;
771
772 str_strcpyc( s, "0123456789" );
773 str_stripws( s );
774 if ( string_mismatch( s, 10, "0123456789" ) ) failed++;
775
776 str_strcpyc( s, str1 );
777 str_stripws( s );
778 if ( string_mismatch( s, strlen("ksjadfklajskfjdsaskdjflkj"), "ksjadfklajskfjdsaskdjflkj" ) ) failed++;
779
780 return failed;
781 }
782
783 static int
test_reverse(str * s)784 test_reverse( str *s )
785 {
786 int failed = 0;
787
788 /* empty string */
789 str_strcpyc( s, "" );
790 str_reverse( s );
791 if ( string_mismatch( s, 0, "" ) ) failed++;
792
793 /* string with even number of elements */
794 str_strcpyc( s, "0123456789" );
795 str_reverse( s );
796 if ( string_mismatch( s, 10, "9876543210" ) ) failed++;
797 str_reverse( s );
798 if ( string_mismatch( s, 10, "0123456789" ) ) failed++;
799
800 /* string with odd number of elements */
801 str_strcpyc( s, "123456789" );
802 str_reverse( s );
803 if ( string_mismatch( s, 9, "987654321" ) ) failed++;
804 str_reverse( s );
805 if ( string_mismatch( s, 9, "123456789" ) ) failed++;
806
807 return failed;
808 }
809
810 static int
test_trim(str * s)811 test_trim( str *s )
812 {
813 char str1[] = "123456789";
814 char str2[] = "987654321";
815 int failed = 0;
816
817 str_strcpyc( s, str1 );
818 str_trimbegin( s, 0 );
819 if ( string_mismatch( s, 9, str1 ) ) failed++;
820 str_trimend( s, 0 );
821 if ( string_mismatch( s, 9, str1 ) ) failed++;
822
823 str_strcpyc( s, str1 );
824 str_trimbegin( s, 1 );
825 if ( string_mismatch( s, 8, "23456789" ) ) failed++;
826
827 str_strcpyc( s, str1 );
828 str_trimbegin( s, 4 );
829 if ( string_mismatch( s, 5, "56789" ) ) failed++;
830
831 str_strcpyc( s, str1 );
832 str_trimbegin( s, 9 );
833 if ( string_mismatch( s, 0, "" ) ) failed++;
834
835 str_strcpyc( s, str2 );
836 str_trimend( s, 1 );
837 if ( string_mismatch( s, 8, "98765432" ) ) failed++;
838
839 str_strcpyc( s, str2 );
840 str_trimend( s, 6 );
841 if ( string_mismatch( s, 3, "987" ) ) failed++;
842
843 str_strcpyc( s, str2 );
844 str_trimend( s, 9 );
845 if ( string_mismatch( s, 0, "" ) ) failed++;
846
847 return failed;
848 }
849
850 static int
test_case(str * s)851 test_case( str *s )
852 {
853 int failed = 0;
854
855 str_strcpyc( s, "asdfjalskjfljasdfjlsfjd" );
856 if ( !str_is_lowercase( s ) ) {
857 fprintf( stdout, "%s line %d: str_is_lowercase('%s') returned false\n", __FUNCTION__, __LINE__, s->data );
858 failed++;
859 }
860 if ( str_is_uppercase( s ) ) {
861 fprintf( stdout, "%s line %d: str_is_uppercase('%s') returned true\n", __FUNCTION__, __LINE__, s->data );
862 failed++;
863 }
864 if ( str_is_mixedcase( s ) ) {
865 fprintf( stdout, "%s line %d: str_is_mixedcase('%s') returned true\n", __FUNCTION__, __LINE__, s->data );
866 failed++;
867 }
868
869 str_strcpyc( s, "ASDFJALSKJFLJASDFJLSFJD" );
870 if ( str_is_lowercase( s ) ) {
871 fprintf( stdout, "%s line %d: str_is_lowercase('%s') returned true\n", __FUNCTION__, __LINE__, s->data );
872 failed++;
873 }
874 if ( !str_is_uppercase( s ) ) {
875 fprintf( stdout, "%s line %d: str_is_uppercase('%s') returned false\n", __FUNCTION__, __LINE__, s->data );
876 failed++;
877 }
878 if ( str_is_mixedcase( s ) ) {
879 fprintf( stdout, "%s line %d: str_is_mixedcase('%s') returned true\n", __FUNCTION__, __LINE__, s->data );
880 failed++;
881 }
882
883 str_strcpyc( s, "ASdfjalsKJFLJASdfjlsfjd" );
884 if ( str_is_lowercase( s ) ) {
885 fprintf( stdout, "%s line %d: str_is_lowercase('%s') returned true\n", __FUNCTION__, __LINE__, s->data );
886 failed++;
887 }
888 if ( str_is_uppercase( s ) ) {
889 fprintf( stdout, "%s line %d: str_is_uppercase('%s') returned true\n", __FUNCTION__, __LINE__, s->data );
890 failed++;
891 }
892 if ( !str_is_mixedcase( s ) ) {
893 fprintf( stdout, "%s line %d: str_is_mixedcase('%s') returned false\n", __FUNCTION__, __LINE__, s->data );
894 failed++;
895 }
896
897 return failed;
898 }
899
900 static int
test_strcmp(str * s)901 test_strcmp( str *s )
902 {
903 int failed = 0;
904 str t;
905
906 str_init( &t );
907
908 str_empty( s );
909 if ( str_strcmp( s, s ) ) {
910 fprintf( stdout, "%s line %d: str_strcmp(s,s) returned non-zero\n", __FUNCTION__, __LINE__ );
911 failed++;
912 }
913 if ( str_strcmp( s, &t ) ) {
914 fprintf( stdout, "%s line %d: str_strcmp(s,t) returned non-zero\n", __FUNCTION__, __LINE__ );
915 failed++;
916 }
917
918 str_strcpyc( s, "lakjsdlfjdskljfklsjf" );
919 if ( str_strcmp( s, s ) ) {
920 fprintf( stdout, "%s line %d: str_strcmp(s,s) returned non-zero\n", __FUNCTION__, __LINE__ );
921 failed++;
922 }
923 if ( !str_strcmp( s, &t ) ) {
924 fprintf( stdout, "%s line %d: str_strcmp(s,t) returned zero\n", __FUNCTION__, __LINE__ );
925 failed++;
926 }
927
928 str_strcpy( &t, s );
929 if ( str_strcmp( s, s ) ) {
930 fprintf( stdout, "%s line %d: str_strcmp(s,s) returned non-zero\n", __FUNCTION__, __LINE__ );
931 failed++;
932 }
933 if ( str_strcmp( s, &t ) ) {
934 fprintf( stdout, "%s line %d: str_strcmp(s,t) returned non-zero\n", __FUNCTION__, __LINE__ );
935 failed++;
936 }
937
938 str_free( &t );
939
940 return failed;
941 }
942
943 static int
test_match(str * s)944 test_match( str *s )
945 {
946 int failed = 0;
947
948 str_empty( s );
949 if ( str_match_first( s, '0' ) ) {
950 fprintf( stdout, "%s line %d: str_match_first() returned non-zero\n", __FUNCTION__, __LINE__ );
951 failed++;
952 }
953 str_strcpyc( s, "012345" );
954 if ( !str_match_first( s, '0' ) ) {
955 fprintf( stdout, "%s line %d: str_match_first() returned zero\n", __FUNCTION__, __LINE__ );
956 failed++;
957 }
958 if ( !str_match_end( s, '5' ) ) {
959 fprintf( stdout, "%s line %d: str_match_end() returned zero\n", __FUNCTION__, __LINE__ );
960 failed++;
961 }
962
963 return failed;
964 }
965
966 static int
test_char(str * s)967 test_char( str *s )
968 {
969 unsigned long i;
970 str t, u;
971 int failed = 0;
972
973 str_init( &t );
974 str_init( &u );
975
976 str_empty( s );
977 for ( i=0; i<5; ++i ) {
978 if ( str_char( s, i ) != '\0' ) {
979 fprintf( stdout, "%s line %d: str_char() did not return '\\0'\n", __FUNCTION__, __LINE__ );
980 failed++;
981 }
982 if ( str_revchar( s, i ) != '\0' ) {
983 fprintf( stdout, "%s line %d: str_revchar() did not return '\\0'\n", __FUNCTION__, __LINE__ );
984 failed++;
985 }
986 }
987
988 str_strcpyc( s, "0123456789" );
989 for ( i=0; i<s->len; ++i ) {
990 str_addchar( &t, str_char( s, i ) );
991 str_addchar( &u, str_revchar( s, i ) );
992 }
993
994 if ( string_mismatch( &t, s->len, s->data ) ) failed++;
995
996 str_reverse( s );
997 if ( string_mismatch( &u, s->len, s->data ) ) failed++;
998
999 str_free( &t );
1000 str_free( &u );
1001
1002 return failed;
1003 }
1004
1005 static int
test_swapstrings(str * s)1006 test_swapstrings( str *s )
1007 {
1008 int failed = 0;
1009 str t;
1010
1011 str_init( &t );
1012
1013 str_strcpyc( &t, "0123456789" );
1014 str_strcpyc( s, "abcde" );
1015
1016 str_swapstrings( s, &t );
1017 if ( string_mismatch( &t, 5, "abcde" ) ) failed++;
1018 if ( string_mismatch( s, 10, "0123456789" ) ) failed++;
1019
1020 str_swapstrings( s, &t );
1021 if ( string_mismatch( s, 5, "abcde" ) ) failed++;
1022 if ( string_mismatch( &t, 10, "0123456789" ) ) failed++;
1023
1024 str_free( &t );
1025
1026 return failed;
1027 }
1028
1029 int
main(int argc,char * argv[])1030 main ( int argc, char *argv[] )
1031 {
1032 int failed = 0;
1033 int ntest = 2;
1034 int i;
1035 str s;
1036 str_init( &s );
1037
1038 /* ...core functions */
1039 for ( i=0; i<ntest; ++i )
1040 failed += test_empty( &s );
1041
1042 /* ...adding functions */
1043 for ( i=0; i<ntest; ++i)
1044 failed += test_addchar( &s );
1045 for ( i=0; i<ntest; ++i)
1046 failed += test_strcatc( &s );
1047 for ( i=0; i<ntest; ++i )
1048 failed += test_strcat( &s );
1049 for ( i=0; i<ntest; ++i )
1050 failed += test_segcat( &s );
1051 for ( i=0; i<ntest; ++i )
1052 failed += test_indxcat( &s );
1053 for ( i=0; i<ntest; ++i )
1054 failed += test_cattodelim( &s );
1055 for ( i=0; i<ntest; ++i )
1056 failed += test_prepend( &s );
1057 for ( i=0; i<ntest; ++i )
1058 failed += test_pad( &s );
1059 for ( i=0; i<ntest; ++i )
1060 failed += test_mergestrs( &s );
1061 for ( i=0; i<ntest; ++i )
1062 failed += test_makepath( &s );
1063
1064 /* ...copying functions */
1065 for ( i=0; i<ntest; ++i)
1066 failed += test_strcpyc( &s );
1067 for ( i=0; i<ntest; ++i)
1068 failed += test_strcpy( &s );
1069 for ( i=0; i<ntest; ++i )
1070 failed += test_cpytodelim( &s );
1071 for ( i=0; i<ntest; ++i)
1072 failed += test_segcpy( &s );
1073 for ( i=0; i<ntest; ++i)
1074 failed += test_indxcpy( &s );
1075 for ( i=0; i<ntest; ++i )
1076 failed += test_copyposlen( &s );
1077 for ( i=0; i<ntest; ++i )
1078 failed += test_strdup();
1079
1080 /* ...utility functions */
1081 for ( i=0; i<ntest; ++i)
1082 failed += test_findreplace( &s );
1083 for ( i=0; i<ntest; ++i )
1084 failed += test_reverse( &s );
1085 for ( i=0; i<ntest; ++i )
1086 failed += test_toupper( &s );
1087 for ( i=0; i<ntest; ++i )
1088 failed += test_tolower( &s );
1089 for ( i=0; i<ntest; ++i )
1090 failed += test_trimws( &s );
1091 for ( i=0; i<ntest; ++i )
1092 failed += test_trim( &s );
1093 for ( i=0; i<ntest; ++i )
1094 failed += test_case( &s );
1095 for ( i=0; i<ntest; ++i )
1096 failed += test_strcmp( &s );
1097 for ( i=0; i<ntest; ++i )
1098 failed += test_char( &s );
1099 for ( i=0; i<ntest; ++i )
1100 failed += test_swapstrings( &s );
1101 for ( i=0; i<ntest; ++i )
1102 failed += test_match( &s );
1103
1104 str_free( &s );
1105
1106 if ( !failed ) {
1107 printf( "%s: PASSED\n", progname );
1108 return EXIT_SUCCESS;
1109 } else {
1110 printf( "%s: FAILED\n", progname );
1111 return EXIT_FAILURE;
1112 }
1113 return EXIT_SUCCESS;
1114 }
1115