1 //-----------------------------------------------------------------------------
2 // String Utilities - based on UT_string
3 // Copyright (C) Paulo Custodio, 2011-2020
4 // License: http://www.perlfoundation.org/artistic_license_2_0
5 //-----------------------------------------------------------------------------
6
7 #include "strutil.h"
8 #include "unity.h"
9 #include "utstring.h"
10 #include "zutils.h"
11
t_strutil_cstr_toupper(void)12 void t_strutil_cstr_toupper(void)
13 {
14 char buff[10];
15 strcpy(buff, "abc1"); TEST_ASSERT_EQUAL_STRING("ABC1", strtoupper(buff));
16 strcpy(buff, "Abc1"); TEST_ASSERT_EQUAL_STRING("ABC1", strtoupper(buff));
17 strcpy(buff, "ABC1"); TEST_ASSERT_EQUAL_STRING("ABC1", strtoupper(buff));
18 }
19
t_strutil_cstr_tolower(void)20 void t_strutil_cstr_tolower(void)
21 {
22 char buff[10];
23 strcpy(buff, "abc1"); TEST_ASSERT_EQUAL_STRING("abc1", strtolower(buff));
24 strcpy(buff, "Abc1"); TEST_ASSERT_EQUAL_STRING("abc1", strtolower(buff));
25 strcpy(buff, "ABC1"); TEST_ASSERT_EQUAL_STRING("abc1", strtolower(buff));
26 }
27
t_strutil_cstr_chomp(void)28 void t_strutil_cstr_chomp(void)
29 {
30 char buff[100];
31 strcpy(buff, ""); TEST_ASSERT_EQUAL_STRING("", strchomp(buff));
32 strcpy(buff, "\r\n \t\f \r\n \t\f\v"); TEST_ASSERT_EQUAL_STRING("", strchomp(buff));
33 strcpy(buff, "\r\n \t\fx\r\n \t\f\v"); TEST_ASSERT_EQUAL_STRING("\r\n \t\fx", strchomp(buff));
34 }
35
t_strutil_cstr_strip(void)36 void t_strutil_cstr_strip(void)
37 {
38 char buff[100];
39 strcpy(buff, ""); TEST_ASSERT_EQUAL_STRING("", strstrip(buff));
40 strcpy(buff, "\r\n \t\f \r\n \t\f\v"); TEST_ASSERT_EQUAL_STRING("", strstrip(buff));
41 strcpy(buff, "\r\n \t\fx\r\n \t\f\v"); TEST_ASSERT_EQUAL_STRING("x", strstrip(buff));
42 }
43
t_strutil_cstr_strip_compress_escapes(void)44 void t_strutil_cstr_strip_compress_escapes(void)
45 {
46 UT_string *s = utstr_new();
47 char cs[100];
48
49 #define T(in, out_len, out_str) \
50 strcpy(cs, in); \
51 TEST_ASSERT_EQUAL(out_len, str_compress_escapes(cs)); \
52 TEST_ASSERT_EQUAL(0, memcmp(cs, out_str, out_len)); \
53 utstr_set(s, in); \
54 utstr_compress_escapes(s); \
55 TEST_ASSERT_EQUAL(out_len, utstr_len(s)); \
56 TEST_ASSERT_EQUAL(0, memcmp(utstr_body(s), out_str, out_len))
57
58 // trailing backslash ignored
59 T("\\", 0, "");
60
61 // escape any
62 T("\\" "?" "\\" "\"" "\\" "'",
63 3, "?\"'");
64
65 // escape chars
66 T("0" "\\a"
67 "1" "\\b"
68 "2" "\\e"
69 "3" "\\f"
70 "4" "\\n"
71 "5" "\\r"
72 "6" "\\t"
73 "7" "\\v"
74 "8",
75 17,
76 "0" "\a"
77 "1" "\b"
78 "2" "\x1B"
79 "3" "\f"
80 "4" "\n"
81 "5" "\r"
82 "6" "\t"
83 "7" "\v"
84 "8");
85
86 // octal and hexadecimal, including '\0'
87 for (int i = 0; i < 256; i++)
88 {
89 sprintf(cs, "\\%o \\x%x", i, i);
90 int len = str_compress_escapes(cs);
91 TEST_ASSERT_EQUAL(3, len);
92 TEST_ASSERT_EQUAL((char)i, cs[0]);
93 TEST_ASSERT_EQUAL(' ', cs[1]);
94 TEST_ASSERT_EQUAL((char)i, cs[2]);
95 TEST_ASSERT_EQUAL(0, cs[3]);
96 }
97
98 // octal and hexadecimal with longer digit string
99 T("\\3770\\xff0",
100 4,
101 "\xFF" "0" "\xFF" "0");
102
103 utstr_free(s);
104 #undef T
105 }
106
t_strutil_cstr_case_cmp(void)107 void t_strutil_cstr_case_cmp(void)
108 {
109 TEST_ASSERT(strcasecmp("", "") == 0);
110 TEST_ASSERT(strcasecmp("a", "") > 0);
111 TEST_ASSERT(strcasecmp("", "a") < 0);
112 TEST_ASSERT(strcasecmp("a", "a") == 0);
113 TEST_ASSERT(strcasecmp("a", "A") == 0);
114 TEST_ASSERT(strcasecmp("A", "a") == 0);
115 TEST_ASSERT(strcasecmp("ab", "a") > 0);
116 TEST_ASSERT(strcasecmp("a", "ab") < 0);
117 TEST_ASSERT(strcasecmp("ab", "ab") == 0);
118 }
119
t_strutil_cstr_case_ncmp(void)120 void t_strutil_cstr_case_ncmp(void)
121 {
122 TEST_ASSERT(strncasecmp("", "", 0) == 0);
123 TEST_ASSERT(strncasecmp("x", "y", 0) == 0);
124 TEST_ASSERT(strncasecmp("a", "", 1) > 0);
125 TEST_ASSERT(strncasecmp("", "a", 1) < 0);
126 TEST_ASSERT(strncasecmp("ax", "ay", 1) == 0);
127 TEST_ASSERT(strncasecmp("ax", "Ay", 1) == 0);
128 TEST_ASSERT(strncasecmp("Ax", "ay", 1) == 0);
129 TEST_ASSERT(strncasecmp("abx", "a", 2) > 0);
130 TEST_ASSERT(strncasecmp("a", "aby", 2) < 0);
131 TEST_ASSERT(strncasecmp("abx", "aby", 2) == 0);
132 }
133
t_strutil_str_toupper(void)134 void t_strutil_str_toupper(void)
135 {
136 UT_string *s = utstr_new();
137 utstr_set(s, "abc1"); utstr_toupper(s); TEST_ASSERT_EQUAL_STRING("ABC1", utstr_body(s));
138 utstr_set(s, "Abc1"); utstr_toupper(s); TEST_ASSERT_EQUAL_STRING("ABC1", utstr_body(s));
139 utstr_set(s, "ABC1"); utstr_toupper(s); TEST_ASSERT_EQUAL_STRING("ABC1", utstr_body(s));
140 utstr_free(s);
141 }
142
t_strutil_str_tolower(void)143 void t_strutil_str_tolower(void)
144 {
145 UT_string *s = utstr_new();
146 utstr_set(s, "abc1"); utstr_tolower(s); TEST_ASSERT_EQUAL_STRING("abc1", utstr_body(s));
147 utstr_set(s, "Abc1"); utstr_tolower(s); TEST_ASSERT_EQUAL_STRING("abc1", utstr_body(s));
148 utstr_set(s, "ABC1"); utstr_tolower(s); TEST_ASSERT_EQUAL_STRING("abc1", utstr_body(s));
149 utstr_free(s);
150 }
151
t_strutil_str_chomp(void)152 void t_strutil_str_chomp(void)
153 {
154 UT_string *s = utstr_new();
155 utstr_set(s, ""); utstr_chomp(s); TEST_ASSERT_EQUAL_STRING("", utstr_body(s));
156 utstr_set(s, "\r\n \t\f \r\n \t\f\v"); utstr_chomp(s); TEST_ASSERT_EQUAL_STRING("", utstr_body(s));
157 utstr_set(s, "\r\n \t\fx\r\n \t\f\v"); utstr_chomp(s); TEST_ASSERT_EQUAL_STRING("\r\n \t\fx", utstr_body(s));
158 utstr_free(s);
159 }
160
t_strutil_str_strip(void)161 void t_strutil_str_strip(void)
162 {
163 UT_string *s = utstr_new();
164 utstr_set(s, ""); utstr_strip(s); TEST_ASSERT_EQUAL_STRING("", utstr_body(s));
165 utstr_set(s, "\r\n \t\f \r\n \t\f\v"); utstr_strip(s); TEST_ASSERT_EQUAL_STRING("", utstr_body(s));
166 utstr_set(s, "\r\n \t\fx\r\n \t\f\v"); utstr_strip(s); TEST_ASSERT_EQUAL_STRING("x", utstr_body(s));
167 utstr_free(s);
168 }
169
t_strutil_argv_new(void)170 void t_strutil_argv_new(void)
171 {
172 argv_t *argv = argv_new();
173 TEST_ASSERT_EQUAL(0, argv_len(argv));
174 TEST_ASSERT_NULL(*argv_front(argv));
175 TEST_ASSERT_NULL(*argv_back(argv));
176 TEST_ASSERT(argv_front(argv) == argv_back(argv));
177
178 argv_push(argv, "1");
179 argv_push(argv, "2");
180 argv_push(argv, "3");
181 TEST_ASSERT_EQUAL(3, argv_len(argv));
182 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[0]);
183 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[1]);
184 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[2]);
185 TEST_ASSERT_NULL((argv_front(argv))[3]);
186 TEST_ASSERT(argv_front(argv) + 3 == argv_back(argv));
187
188 argv_unshift(argv, "0");
189 argv_unshift(argv, "-1");
190 argv_unshift(argv, "-2");
191 TEST_ASSERT_EQUAL(6, argv_len(argv));
192 TEST_ASSERT_EQUAL_STRING("-2", (argv_front(argv))[0]);
193 TEST_ASSERT_EQUAL_STRING("-1", (argv_front(argv))[1]);
194 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[2]);
195 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[3]);
196 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[4]);
197 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[5]);
198 TEST_ASSERT_NULL((argv_front(argv))[6]);
199 TEST_ASSERT(argv_front(argv) + 6 == argv_back(argv));
200
201 argv_insert(argv, 3, "0.5");
202 TEST_ASSERT_EQUAL(7, argv_len(argv));
203 TEST_ASSERT_EQUAL_STRING("-2", (argv_front(argv))[0]);
204 TEST_ASSERT_EQUAL_STRING("-1", (argv_front(argv))[1]);
205 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[2]);
206 TEST_ASSERT_EQUAL_STRING("0.5", (argv_front(argv))[3]);
207 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[4]);
208 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[5]);
209 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[6]);
210 TEST_ASSERT_NULL((argv_front(argv))[7]);
211 TEST_ASSERT(argv_front(argv) + 7 == argv_back(argv));
212
213 argv_insert(argv, 6, "2.5");
214 TEST_ASSERT_EQUAL(8, argv_len(argv));
215 TEST_ASSERT_EQUAL_STRING("-2", (argv_front(argv))[0]);
216 TEST_ASSERT_EQUAL_STRING("-1", (argv_front(argv))[1]);
217 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[2]);
218 TEST_ASSERT_EQUAL_STRING("0.5", (argv_front(argv))[3]);
219 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[4]);
220 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[5]);
221 TEST_ASSERT_EQUAL_STRING("2.5", (argv_front(argv))[6]);
222 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[7]);
223 TEST_ASSERT_NULL((argv_front(argv))[8]);
224 TEST_ASSERT(argv_front(argv) + 8 == argv_back(argv));
225
226 argv_insert(argv, 8, "3.5");
227 TEST_ASSERT_EQUAL(9, argv_len(argv));
228 TEST_ASSERT_EQUAL_STRING("-2", (argv_front(argv))[0]);
229 TEST_ASSERT_EQUAL_STRING("-1", (argv_front(argv))[1]);
230 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[2]);
231 TEST_ASSERT_EQUAL_STRING("0.5", (argv_front(argv))[3]);
232 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[4]);
233 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[5]);
234 TEST_ASSERT_EQUAL_STRING("2.5", (argv_front(argv))[6]);
235 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[7]);
236 TEST_ASSERT_EQUAL_STRING("3.5", (argv_front(argv))[8]);
237 TEST_ASSERT_NULL((argv_front(argv))[9]);
238 TEST_ASSERT(argv_front(argv) + 9 == argv_back(argv));
239
240 argv_insert(argv, 10, "4");
241 TEST_ASSERT_EQUAL(11, argv_len(argv));
242 TEST_ASSERT_EQUAL_STRING("-2", (argv_front(argv))[0]);
243 TEST_ASSERT_EQUAL_STRING("-1", (argv_front(argv))[1]);
244 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[2]);
245 TEST_ASSERT_EQUAL_STRING("0.5", (argv_front(argv))[3]);
246 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[4]);
247 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[5]);
248 TEST_ASSERT_EQUAL_STRING("2.5", (argv_front(argv))[6]);
249 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[7]);
250 TEST_ASSERT_EQUAL_STRING("3.5", (argv_front(argv))[8]);
251 TEST_ASSERT_NULL((argv_front(argv))[9]);
252 TEST_ASSERT_EQUAL_STRING("4", (argv_front(argv))[10]);
253 TEST_ASSERT_NULL((argv_front(argv))[11]);
254 TEST_ASSERT(argv_front(argv) + 11 == argv_back(argv));
255
256 argv_erase(argv, 9, 10);
257 TEST_ASSERT_EQUAL(9, argv_len(argv));
258 TEST_ASSERT_EQUAL_STRING("-2", (argv_front(argv))[0]);
259 TEST_ASSERT_EQUAL_STRING("-1", (argv_front(argv))[1]);
260 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[2]);
261 TEST_ASSERT_EQUAL_STRING("0.5", (argv_front(argv))[3]);
262 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[4]);
263 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[5]);
264 TEST_ASSERT_EQUAL_STRING("2.5", (argv_front(argv))[6]);
265 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[7]);
266 TEST_ASSERT_EQUAL_STRING("3.5", (argv_front(argv))[8]);
267 TEST_ASSERT_NULL((argv_front(argv))[9]);
268 TEST_ASSERT(argv_front(argv) + 9 == argv_back(argv));
269
270 argv_erase(argv, 0, 2);
271 TEST_ASSERT_EQUAL(7, argv_len(argv));
272 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[0]);
273 TEST_ASSERT_EQUAL_STRING("0.5", (argv_front(argv))[1]);
274 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[2]);
275 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[3]);
276 TEST_ASSERT_EQUAL_STRING("2.5", (argv_front(argv))[4]);
277 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[5]);
278 TEST_ASSERT_EQUAL_STRING("3.5", (argv_front(argv))[6]);
279 TEST_ASSERT_NULL((argv_front(argv))[7]);
280 TEST_ASSERT(argv_front(argv) + 7 == argv_back(argv));
281
282 argv_set(argv, 1, "0,5");
283 TEST_ASSERT_EQUAL(7, argv_len(argv));
284 TEST_ASSERT_EQUAL_STRING("0", (argv_front(argv))[0]);
285 TEST_ASSERT_EQUAL_STRING("0,5", (argv_front(argv))[1]);
286 TEST_ASSERT_EQUAL_STRING("1", (argv_front(argv))[2]);
287 TEST_ASSERT_EQUAL_STRING("2", (argv_front(argv))[3]);
288 TEST_ASSERT_EQUAL_STRING("2.5", (argv_front(argv))[4]);
289 TEST_ASSERT_EQUAL_STRING("3", (argv_front(argv))[5]);
290 TEST_ASSERT_EQUAL_STRING("3.5", (argv_front(argv))[6]);
291 TEST_ASSERT_NULL((argv_front(argv))[7]);
292 TEST_ASSERT(argv_front(argv) + 7 == argv_back(argv));
293
294 char **p = argv_front(argv);
295 TEST_ASSERT_EQUAL_STRING("0", *p); p++;
296 TEST_ASSERT_EQUAL_STRING("0,5", *p); p++;
297 TEST_ASSERT_EQUAL_STRING("1", *p); p++;
298 TEST_ASSERT_EQUAL_STRING("2", *p); p++;
299 TEST_ASSERT_EQUAL_STRING("2.5", *p); p++;
300 TEST_ASSERT_EQUAL_STRING("3", *p); p++;
301 TEST_ASSERT_EQUAL_STRING("3.5", *p); p++;
302 TEST_ASSERT_NULL(*p);
303
304 TEST_ASSERT_EQUAL(7, argv_len(argv));
305 TEST_ASSERT_EQUAL_STRING("0", argv_get(argv, 0));
306 TEST_ASSERT_EQUAL_STRING("0,5", argv_get(argv, 1));
307 TEST_ASSERT_EQUAL_STRING("1", argv_get(argv, 2));
308 TEST_ASSERT_EQUAL_STRING("2", argv_get(argv, 3));
309 TEST_ASSERT_EQUAL_STRING("2.5", argv_get(argv, 4));
310 TEST_ASSERT_EQUAL_STRING("3", argv_get(argv, 5));
311 TEST_ASSERT_EQUAL_STRING("3.5", argv_get(argv, 6));
312 TEST_ASSERT_NULL(argv_get(argv, 7));
313
314 argv_pop(argv);
315 TEST_ASSERT_EQUAL(6, argv_len(argv));
316 TEST_ASSERT_EQUAL_STRING("0", argv_get(argv, 0));
317 TEST_ASSERT_EQUAL_STRING("0,5", argv_get(argv, 1));
318 TEST_ASSERT_EQUAL_STRING("1", argv_get(argv, 2));
319 TEST_ASSERT_EQUAL_STRING("2", argv_get(argv, 3));
320 TEST_ASSERT_EQUAL_STRING("2.5", argv_get(argv, 4));
321 TEST_ASSERT_EQUAL_STRING("3", argv_get(argv, 5));
322 TEST_ASSERT_NULL(argv_get(argv, 6));
323
324 argv_shift(argv);
325 TEST_ASSERT_EQUAL(5, argv_len(argv));
326 TEST_ASSERT_EQUAL_STRING("0,5", argv_get(argv, 0));
327 TEST_ASSERT_EQUAL_STRING("1", argv_get(argv, 1));
328 TEST_ASSERT_EQUAL_STRING("2", argv_get(argv, 2));
329 TEST_ASSERT_EQUAL_STRING("2.5", argv_get(argv, 3));
330 TEST_ASSERT_EQUAL_STRING("3", argv_get(argv, 4));
331 TEST_ASSERT_NULL(argv_get(argv, 5));
332
333 argv_pop(argv);
334 argv_pop(argv);
335 argv_pop(argv);
336 argv_pop(argv);
337 TEST_ASSERT_EQUAL(1, argv_len(argv));
338 TEST_ASSERT_EQUAL_STRING("0,5", argv_get(argv, 0));
339 TEST_ASSERT_NULL(argv_get(argv, 1));
340
341 argv_pop(argv);
342 TEST_ASSERT_EQUAL(0, argv_len(argv));
343 TEST_ASSERT_NULL(argv_get(argv, 0));
344
345 argv_pop(argv);
346 TEST_ASSERT_EQUAL(0, argv_len(argv));
347 TEST_ASSERT_NULL(argv_get(argv, 0));
348
349 argv_push(argv, "1");
350 TEST_ASSERT_EQUAL(1, argv_len(argv));
351 TEST_ASSERT_EQUAL_STRING("1", argv_get(argv, 0));
352 TEST_ASSERT_NULL(argv_get(argv, 1));
353
354 argv_shift(argv);
355 TEST_ASSERT_EQUAL(0, argv_len(argv));
356 TEST_ASSERT_NULL(argv_get(argv, 0));
357
358 argv_shift(argv);
359 TEST_ASSERT_EQUAL(0, argv_len(argv));
360 TEST_ASSERT_NULL(argv_get(argv, 0));
361
362 argv_clear(argv);
363 TEST_ASSERT_EQUAL(0, argv_len(argv));
364
365 argv_free(argv);
366 }
367
t_strutil_argv_sort(void)368 void t_strutil_argv_sort(void)
369 {
370 argv_t *argv = argv_new();
371 argv_push(argv, "22");
372 argv_push(argv, "2");
373 argv_push(argv, "25");
374 argv_push(argv, "11");
375 argv_push(argv, "1");
376
377 argv_sort(argv);
378 char **p = argv_front(argv);
379 TEST_ASSERT_EQUAL_STRING("1", *p); p++;
380 TEST_ASSERT_EQUAL_STRING("11", *p); p++;
381 TEST_ASSERT_EQUAL_STRING("2", *p); p++;
382 TEST_ASSERT_EQUAL_STRING("22", *p); p++;
383 TEST_ASSERT_EQUAL_STRING("25", *p); p++;
384 TEST_ASSERT_NULL(*p);
385 argv_free(argv);
386 }
387
t_strutil_spool_add(void)388 void t_strutil_spool_add(void)
389 {
390 #define NUM_STRINGS 10
391 #define STRING_SIZE 5
392 struct {
393 char source[STRING_SIZE];
394 const char *pool;
395 } strings[NUM_STRINGS];
396
397 const char *pool;
398 int i;
399
400 // first run - create pool for all strings
401 for (i = 0; i < NUM_STRINGS; i++) {
402 sprintf(strings[i].source, "%d", i); // number i
403
404 pool = spool_add(strings[i].source);
405 TEST_ASSERT_NOT_NULL(pool);
406 TEST_ASSERT(pool != strings[i].source);
407 TEST_ASSERT_EQUAL_STRING(strings[i].source, pool);
408
409 strings[i].pool = pool;
410 }
411
412 // second run - check that pool did not move
413 for (i = 0; i < NUM_STRINGS; i++) {
414 pool = spool_add(strings[i].source);
415 TEST_ASSERT_NOT_NULL(pool);
416 TEST_ASSERT(pool != strings[i].source);
417 TEST_ASSERT_EQUAL_STRING(strings[i].source, pool);
418 TEST_ASSERT_EQUAL(strings[i].pool, pool);
419 }
420
421 // check NULL case
422 pool = spool_add(NULL);
423 TEST_ASSERT_NULL(pool);
424 }
425
426