ohmu
·
2026-10-15
1#include "common/FFstrbuf.h"
2#include "common/textModifier.h"
3
4#include <string.h>
5#include <stdlib.h>
6#include <stdio.h>
7#include <stdnoreturn.h>
8
9noreturn static void testFailed(const FFstrbuf* strbuf, const char* expression, int lineNo) {
10 fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stderr);
11 fprintf(stderr, "[%d] %s, strbuf:", lineNo, expression);
12 ffStrbufWriteTo(strbuf, stderr);
13 fputs(FASTFETCH_TEXT_MODIFIER_RESET, stderr);
14 fputc('\n', stderr);
15 exit(1);
16}
17
18#define VERIFY(expression) \
19 if (!(expression)) testFailed(&strbuf, #expression, __LINE__)
20
21int shouldNotBeCalled(int c) {
22 (void) c;
23 exit(1);
24}
25
26const FFstrbuf testCreateStatic = FF_STRBUF_STATIC("TEST");
27
28int main(void) {
29 FFstrbuf strbuf;
30
31 // destroy 0
32 ffStrbufInit(&strbuf);
33 ffStrbufDestroy(&strbuf);
34
35 // initA
36
37 ffStrbufInit(&strbuf);
38
39 VERIFY(strbuf.chars[0] == 0);
40 VERIFY(strbuf.allocated == 0);
41 VERIFY(strbuf.length == 0);
42
43 VERIFY(!ffStrbufStartsWithC(&strbuf, '0'));
44 VERIFY(!ffStrbufEndsWithC(&strbuf, '0'));
45 VERIFY(!ffStrbufStartsWithS(&strbuf, "0"));
46 VERIFY(!ffStrbufEndsWithS(&strbuf, "0"));
47 VERIFY(ffStrbufCountC(&strbuf, '0') == 0);
48
49 // Ensure following functions work with non-allocated string
50 ffStrbufAppendS(&strbuf, "");
51 ffStrbufAppendF(&strbuf, "%s", "");
52 ffStrbufAppendTransformS(&strbuf, "", shouldNotBeCalled);
53 ffStrbufPrependS(&strbuf, "");
54 ffStrbufTrim(&strbuf, ' ');
55
56 VERIFY(strbuf.chars[0] == 0);
57 VERIFY(strbuf.allocated == 0);
58 VERIFY(strbuf.length == 0);
59
60 // append(N)C
61
62 ffStrbufAppendC(&strbuf, '1');
63 VERIFY(ffStrbufEqualS(&strbuf, "1"));
64 VERIFY(strbuf.allocated >= 1);
65 ffStrbufAppendNC(&strbuf, 5, '2');
66 VERIFY(ffStrbufEqualS(&strbuf, "122222"));
67 VERIFY(strbuf.allocated >= 6);
68 ffStrbufClear(&strbuf);
69
70 // appendS
71
72 ffStrbufAppendS(&strbuf, "12345");
73 ffStrbufAppendS(&strbuf, NULL);
74
75 VERIFY(strbuf.length == 5);
76 VERIFY(strbuf.allocated >= 6);
77 VERIFY(ffStrbufEqualS(&strbuf, "12345"));
78
79 // appendNS
80
81 ffStrbufAppendNS(&strbuf, 4, "67890");
82 ffStrbufAppendNS(&strbuf, 0, NULL);
83
84 VERIFY(strbuf.length == 9);
85 VERIFY(strbuf.allocated >= 10);
86 VERIFY(ffStrbufEqualS(&strbuf, "123456789"));
87
88 // appendS long
89
90 ffStrbufAppendS(&strbuf, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
91 VERIFY(strbuf.length == 109);
92 VERIFY(strbuf.allocated >= 110);
93 VERIFY(strbuf.chars[strbuf.length] == 0);
94
95 // substr
96
97 VERIFY(ffStrbufSubstrBefore(&strbuf, 9));
98 VERIFY(strbuf.length == 9);
99 VERIFY(strbuf.allocated >= 110);
100 VERIFY(strbuf.chars[strbuf.length] == 0);
101 VERIFY(ffStrbufEqualS(&strbuf, "123456789"));
102
103 VERIFY(!ffStrbufSubstrBeforeFirstC(&strbuf, '0'));
104 VERIFY(!ffStrbufSubstrBeforeLastC(&strbuf, '0'));
105 VERIFY(!ffStrbufSubstrAfterFirstC(&strbuf, '0'));
106 VERIFY(!ffStrbufSubstrAfterLastC(&strbuf, '0'));
107 VERIFY(ffStrbufEqualS(&strbuf, "123456789"));
108
109 VERIFY(ffStrbufSubstrBeforeFirstC(&strbuf, '9'));
110 VERIFY(ffStrbufSubstrBeforeLastC(&strbuf, '8'));
111 VERIFY(ffStrbufSubstrAfterFirstC(&strbuf, '1'));
112 VERIFY(ffStrbufSubstrAfterLastC(&strbuf, '2'));
113 VERIFY(ffStrbufEqualS(&strbuf, "34567"));
114
115 ffStrbufSetS(&strbuf, "123456789");
116
117 // startsWithC
118
119 VERIFY(ffStrbufStartsWithC(&strbuf, '1'));
120 VERIFY(!ffStrbufStartsWithC(&strbuf, '2'));
121
122 // startsWithS
123
124 VERIFY(ffStrbufStartsWithS(&strbuf, "123"));
125 VERIFY(ffStrbufStartsWithS(&strbuf, "123456789"));
126 VERIFY(!ffStrbufStartsWithS(&strbuf, "1234567890123"));
127
128 // endsWithC
129 VERIFY(ffStrbufEndsWithC(&strbuf, '9'));
130 VERIFY(!ffStrbufEndsWithC(&strbuf, '1'));
131
132 // endsWithS
133
134 VERIFY(ffStrbufEndsWithS(&strbuf, "789"));
135 VERIFY(ffStrbufEndsWithS(&strbuf, "123456789"));
136 VERIFY(!ffStrbufEndsWithS(&strbuf, "1234567890123"));
137
138 // toNumber
139
140 VERIFY(ffStrbufToDouble(&strbuf, -DBL_MAX) == 123456789.0);
141 VERIFY(ffStrbufToUInt(&strbuf, 999) == 123456789);
142
143 // countC
144
145 VERIFY(ffStrbufCountC(&strbuf, '1') == 1);
146 VERIFY(ffStrbufCountC(&strbuf, '0') == 0);
147
148 // removeS
149
150 ffStrbufRemoveS(&strbuf, "78");
151
152 VERIFY(strbuf.length == 7);
153 VERIFY(strcmp(strbuf.chars, "1234569") == 0);
154
155 // removeStrings
156
157 ffStrbufRemoveStrings(&strbuf, 3, (const char*[]) { "23", "45", "9" });
158
159 VERIFY(strbuf.length == 2);
160 VERIFY(strcmp(strbuf.chars, "16") == 0);
161
162 // PrependS
163
164 ffStrbufPrependS(&strbuf, "123");
165 ffStrbufPrependS(&strbuf, NULL);
166
167 VERIFY(strbuf.length == 5);
168 VERIFY(strcmp(strbuf.chars, "12316") == 0);
169
170 // indexC
171 VERIFY(ffStrbufFirstIndexC(&strbuf, '1') == 0);
172 VERIFY(ffStrbufNextIndexC(&strbuf, 1, '1') == 3);
173 VERIFY(ffStrbufNextIndexC(&strbuf, 4, '1') == 5);
174 VERIFY(ffStrbufLastIndexC(&strbuf, '1') == 3);
175 VERIFY(ffStrbufPreviousIndexC(&strbuf, 2, '1') == 0);
176 VERIFY(ffStrbufPreviousIndexC(&strbuf, 0, '1') == 0);
177 VERIFY(ffStrbufPreviousIndexC(&strbuf, 0, '2') == 5);
178
179 // indexS
180 VERIFY(ffStrbufFirstIndexS(&strbuf, "12316") == 0);
181 VERIFY(ffStrbufNextIndexS(&strbuf, 1, "1") == 3);
182 VERIFY(ffStrbufNextIndexS(&strbuf, 4, "1") == 5);
183
184 // ignCase
185 ffStrbufSetS(&strbuf, "AbCdEfG");
186
187 VERIFY(ffStrbufIgnCaseCompS(&strbuf, "aBcDeFg") == 0);
188 VERIFY(ffStrbufStartsWithIgnCaseS(&strbuf, "ABCD"));
189 VERIFY(ffStrbufEndsWithIgnCaseS(&strbuf, "defg"));
190 VERIFY(!ffStrbufStartsWithIgnCaseS(&strbuf, "aBcDeFgH"));
191 VERIFY(!ffStrbufEndsWithIgnCaseS(&strbuf, "0aBcDeFg"));
192
193 // ensure
194 ffStrbufEnsureEndsWithC(&strbuf, '$');
195 VERIFY(ffStrbufEqualS(&strbuf, "AbCdEfG$"));
196 ffStrbufEnsureEndsWithC(&strbuf, '$');
197 VERIFY(ffStrbufEqualS(&strbuf, "AbCdEfG$"));
198
199 // trimRight
200 ffStrbufTrimRight(&strbuf, '$');
201 VERIFY(ffStrbufEqualS(&strbuf, "AbCdEfG"));
202 ffStrbufTrimRight(&strbuf, '$');
203 VERIFY(ffStrbufEqualS(&strbuf, "AbCdEfG"));
204
205 // clear
206 ffStrbufClear(&strbuf);
207 VERIFY(strbuf.allocated > 0);
208 VERIFY(strbuf.length == 0);
209 VERIFY(strbuf.chars && strbuf.chars[0] == 0);
210
211 // Destroy
212
213 ffStrbufDestroy(&strbuf);
214
215 VERIFY(strbuf.allocated == 0);
216 VERIFY(strbuf.length == 0);
217 VERIFY(strbuf.chars && strbuf.chars[0] == 0);
218
219 // initA
220 ffStrbufInitA(&strbuf, 32);
221
222 VERIFY(strbuf.allocated == 32);
223 VERIFY(strbuf.length == 0);
224 VERIFY(strbuf.chars && strbuf.chars[0] == 0);
225
226 // appendF
227 ffStrbufAppendF(&strbuf, "%s", "1234567890123456789012345678901");
228 VERIFY(strbuf.allocated == 32);
229 VERIFY(ffStrbufEqualS(&strbuf, "1234567890123456789012345678901"));
230
231 ffStrbufDestroy(&strbuf);
232
233 // initMoveS
234 {
235 char* heapStr = strdup("1234567890");
236 ffStrbufInitMoveS(&strbuf, heapStr);
237 VERIFY(ffStrbufEqualS(&strbuf, "1234567890"));
238 VERIFY(strbuf.allocated >= 11);
239 ffStrbufDestroy(&strbuf);
240 }
241
242 // initF
243 ffStrbufInitF(&strbuf, "%s", "1234567890123456789012345678901");
244 VERIFY(strbuf.allocated >= 32);
245 VERIFY(ffStrbufEqualS(&strbuf, "1234567890123456789012345678901"));
246
247 // containC
248 VERIFY(ffStrbufContainC(&strbuf, '1'));
249 VERIFY(!ffStrbufContainC(&strbuf, '-'));
250
251 // replaceAllC
252 ffStrbufReplaceAllC(&strbuf, '1', '-');
253 VERIFY(ffStrbufEqualS(&strbuf, "-234567890-234567890-234567890-"));
254 ffStrbufReplaceAllC(&strbuf, '1', '-');
255 VERIFY(ffStrbufEqualS(&strbuf, "-234567890-234567890-234567890-"));
256
257 // trim
258 ffStrbufTrim(&strbuf, '-');
259 VERIFY(ffStrbufEqualS(&strbuf, "234567890-234567890-234567890"));
260
261 ffStrbufDestroy(&strbuf);
262
263 // ffStrbufCreateS
264 {
265 FF_STRBUF_AUTO_DESTROY testCreate = ffStrbufCreateS("TEST");
266 VERIFY(ffStrbufEqualS(&testCreate, "TEST"));
267 }
268
269 // ffStrbufCreateStatic
270 ffStrbufInitStatic(&strbuf, "TEST");
271 VERIFY(ffStrbufEqualS(&strbuf, "TEST"));
272 VERIFY(strbuf.length == 4);
273 VERIFY(strbuf.allocated == 0);
274
275 ffStrbufDestroy(&strbuf);
276 VERIFY(strbuf.length == 0);
277 VERIFY(strbuf.allocated == 0);
278
279 // ffStrbufCreateStatic / Allocate
280 ffStrbufInitStatic(&strbuf, "TEST");
281 ffStrbufEnsureFree(&strbuf, 0);
282 VERIFY(ffStrbufEqualS(&strbuf, "TEST"));
283 VERIFY(strbuf.length == 4);
284 VERIFY(strbuf.allocated > 0);
285
286 // ffStrbufCreateStatic / Append
287 ffStrbufInitStatic(&strbuf, "TEST");
288 ffStrbufAppendS(&strbuf, "_TEST");
289 VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST"));
290 VERIFY(strbuf.length == 9);
291 VERIFY(strbuf.allocated >= 10);
292 ffStrbufAppendC(&strbuf, '_');
293 VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST_"));
294 ffStrbufDestroy(&strbuf);
295 VERIFY(strbuf.length == 0);
296 VERIFY(strbuf.allocated == 0);
297
298 // ffStrbufCreateStatic / Prepend
299 ffStrbufInitStatic(&strbuf, "TEST");
300 ffStrbufPrependS(&strbuf, "TEST_");
301 VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST"));
302 VERIFY(strbuf.length == 9);
303 VERIFY(strbuf.allocated >= 10);
304 ffStrbufPrependC(&strbuf, '_');
305 VERIFY(ffStrbufEqualS(&strbuf, "_TEST_TEST"));
306 ffStrbufDestroy(&strbuf);
307 VERIFY(strbuf.length == 0);
308 VERIFY(strbuf.allocated == 0);
309
310 // ffStrbufCreateStatic / Clear
311 ffStrbufInitStatic(&strbuf, "TEST");
312 ffStrbufClear(&strbuf);
313 VERIFY(strbuf.length == 0);
314 VERIFY(strbuf.allocated == 0);
315 ffStrbufDestroy(&strbuf);
316
317 // ffStrbufCreateStatic / Set
318 ffStrbufInitStatic(&strbuf, "TEST"); // static
319 ffStrbufSetStatic(&strbuf, "test");
320 VERIFY(ffStrbufEqualS(&strbuf, "test"));
321 VERIFY(strbuf.length == 4);
322 VERIFY(strbuf.allocated == 0);
323 ffStrbufDestroy(&strbuf);
324
325 // ffStrbufCreateStatic / Set
326 ffStrbufInitS(&strbuf, "TEST"); // allocated
327 ffStrbufSetStatic(&strbuf, "test");
328 VERIFY(ffStrbufEqualS(&strbuf, "test"));
329 VERIFY(strbuf.length == 4);
330 VERIFY(strbuf.allocated == 0);
331 ffStrbufDestroy(&strbuf);
332
333 // ffStrbufCreateStatic / TrimL
334 ffStrbufInitStatic(&strbuf, "_TEST_");
335 ffStrbufTrimLeft(&strbuf, '_');
336 VERIFY(ffStrbufEqualS(&strbuf, "TEST_"));
337 VERIFY(strbuf.length == 5);
338 VERIFY(strbuf.allocated == 0);
339 ffStrbufDestroy(&strbuf);
340
341 // ffStrbufCreateStatic / TrimR
342 ffStrbufInitStatic(&strbuf, "_TEST_");
343 ffStrbufTrimRight(&strbuf, ' ');
344 VERIFY(strbuf.allocated == 0);
345 VERIFY(ffStrbufEqualS(&strbuf, "_TEST_"));
346 ffStrbufTrimRight(&strbuf, '_');
347 VERIFY(ffStrbufEqualS(&strbuf, "_TEST"));
348 VERIFY(strbuf.length == 5);
349 VERIFY(strbuf.allocated > 0);
350 ffStrbufDestroy(&strbuf);
351
352 // ffStrbufCreateStatic / Substr
353 ffStrbufInitStatic(&strbuf, "__TEST__");
354 VERIFY(ffStrbufRemoveSubstr(&strbuf, 0, 6));
355 VERIFY(ffStrbufEqualS(&strbuf, "__"));
356 VERIFY(strbuf.length == 2);
357 VERIFY(strbuf.allocated > 0);
358 ffStrbufDestroy(&strbuf);
359
360 // ffStrbufCreateStatic / Substr
361 ffStrbufInitStatic(&strbuf, "__TEST__");
362 VERIFY(ffStrbufRemoveSubstr(&strbuf, 2, 8));
363 VERIFY(ffStrbufEqualS(&strbuf, "__"));
364 VERIFY(strbuf.length == 2);
365 VERIFY(strbuf.allocated > 0);
366 ffStrbufDestroy(&strbuf);
367
368 // ffStrbufCreateStatic / Substr
369 ffStrbufInitStatic(&strbuf, "__TEST__");
370 VERIFY(ffStrbufRemoveSubstr(&strbuf, 2, 6));
371 VERIFY(ffStrbufEqualS(&strbuf, "____"));
372 VERIFY(strbuf.length == 4);
373 VERIFY(strbuf.allocated > 0);
374 ffStrbufDestroy(&strbuf);
375
376 // ffStrbufCreateStatic / ReplaceAllC
377 ffStrbufInitStatic(&strbuf, "__TEST__");
378 ffStrbufReplaceAllC(&strbuf, '_', '-');
379 VERIFY(ffStrbufEqualS(&strbuf, "--TEST--"));
380 VERIFY(strbuf.length == 8);
381 VERIFY(strbuf.allocated > 0);
382 ffStrbufDestroy(&strbuf);
383
384 // ffStrbufCreateStatic / TrimSpace
385 ffStrbufInitStatic(&strbuf, "\n TEST\n ");
386 ffStrbufTrimSpace(&strbuf);
387 VERIFY(strbuf.length == 4);
388 VERIFY(strbuf.allocated > 0);
389 VERIFY(ffStrbufEqualS(&strbuf, "TEST"));
390 ffStrbufDestroy(&strbuf);
391
392 // ffStrbufCreate / TrimSpace
393 ffStrbufInitS(&strbuf, "\n TEST\n ");
394 ffStrbufTrimSpace(&strbuf);
395 VERIFY(strbuf.length == 4);
396 VERIFY(strbuf.allocated > 0);
397 VERIFY(ffStrbufEqualS(&strbuf, "TEST"));
398 ffStrbufDestroy(&strbuf);
399
400 // ffStrbufEnsureFixedLengthFree / empty buffer
401 ffStrbufInit(&strbuf);
402 ffStrbufEnsureFixedLengthFree(&strbuf, 10);
403 VERIFY(strbuf.length == 0);
404 VERIFY(strbuf.allocated == 11);
405 ffStrbufDestroy(&strbuf);
406 ffStrbufInitA(&strbuf, 10);
407 ffStrbufEnsureFixedLengthFree(&strbuf, 10);
408 VERIFY(strbuf.length == 0);
409 VERIFY(strbuf.allocated == 11);
410 ffStrbufEnsureFixedLengthFree(&strbuf, 12);
411 VERIFY(strbuf.length == 0);
412 VERIFY(strbuf.allocated == 13);
413 ffStrbufDestroy(&strbuf);
414
415 // ffStrbufEnsureFixedLengthFree / empty buffer with zero free length
416 ffStrbufInit(&strbuf);
417 ffStrbufEnsureFixedLengthFree(&strbuf, 0);
418 VERIFY(strbuf.length == 0);
419 VERIFY(strbuf.allocated == 1);
420 ffStrbufDestroy(&strbuf);
421
422 // ffStrbufEnsureFixedLengthFree / empty buffer but oldFree >= newFree
423 ffStrbufInitA(&strbuf, 11);
424 ffStrbufEnsureFixedLengthFree(&strbuf, 10);
425 VERIFY(strbuf.length == 0);
426 VERIFY(strbuf.allocated == 11);
427 ffStrbufDestroy(&strbuf);
428 ffStrbufInitA(&strbuf, 12);
429 ffStrbufEnsureFixedLengthFree(&strbuf, 10);
430 VERIFY(strbuf.length == 0);
431 VERIFY(strbuf.allocated == 12);
432 ffStrbufDestroy(&strbuf);
433
434 // ffStrbufEnsureFixedLengthFree / non empty buffer
435 ffStrbufAppendF(&strbuf, "%s", "1234567890");
436 VERIFY(strbuf.length == 10);
437 VERIFY(strbuf.allocated == 32);
438 ffStrbufEnsureFixedLengthFree(&strbuf, 0);
439 VERIFY(strbuf.length == 10);
440 VERIFY(strbuf.allocated == 32);
441 ffStrbufEnsureFixedLengthFree(&strbuf, 20); // less than oldFree (=21)
442 VERIFY(strbuf.length == 10);
443 VERIFY(strbuf.allocated == 32);
444 ffStrbufEnsureFixedLengthFree(&strbuf, 21); // equal to oldFree (=21)
445 VERIFY(strbuf.length == 10);
446 VERIFY(strbuf.allocated == 32);
447 ffStrbufEnsureFixedLengthFree(&strbuf, 22); // greater than oldFree (=21)
448 VERIFY(strbuf.length == 10);
449 VERIFY(strbuf.allocated == 33);
450 ffStrbufDestroy(&strbuf);
451
452 // ffStrbufEnsureFixedLengthFree / static buffer
453 ffStrbufInitStatic(&strbuf, "__TEST__");
454 VERIFY(strbuf.length > 0);
455 VERIFY(strbuf.allocated == 0);
456 ffStrbufEnsureFixedLengthFree(&strbuf, 10);
457 VERIFY(strbuf.length == strlen("__TEST__"));
458 VERIFY(strbuf.allocated == strlen("__TEST__") + 1 + 10);
459 VERIFY(ffStrbufEqualS(&strbuf, "__TEST__"));
460 ffStrbufDestroy(&strbuf);
461
462 // ffStrbufInsertNC
463 ffStrbufInitStatic(&strbuf, "123456");
464 ffStrbufInsertNC(&strbuf, 0, 2, 'A');
465 VERIFY(ffStrbufEqualS(&strbuf, "AA123456"));
466 ffStrbufInsertNC(&strbuf, 4, 2, 'B');
467 VERIFY(ffStrbufEqualS(&strbuf, "AA12BB3456"));
468 ffStrbufInsertNC(&strbuf, strbuf.length, 2, 'C');
469 VERIFY(ffStrbufEqualS(&strbuf, "AA12BB3456CC"));
470 ffStrbufInsertNC(&strbuf, 999, 2, 'D');
471 VERIFY(ffStrbufEqualS(&strbuf, "AA12BB3456CCDD"));
472 ffStrbufDestroy(&strbuf);
473
474 // smallest allocation test
475 {
476 FF_STRBUF_AUTO_DESTROY strbuf1 = ffStrbufCreateA(10);
477 VERIFY(strbuf1.allocated == 10);
478 ffStrbufEnsureFree(&strbuf1, 16);
479 VERIFY(strbuf1.allocated == 32);
480
481 FF_STRBUF_AUTO_DESTROY strbuf2 = ffStrbufCreate();
482 VERIFY(strbuf2.allocated == 0);
483 ffStrbufEnsureFree(&strbuf2, 16);
484 VERIFY(strbuf2.allocated == 32);
485 }
486
487 {
488 int i = 0;
489 char* lineptr = NULL;
490 size_t n = 0;
491 const char* text = "Processor\t: ARMv7\nprocessor\t: 0\nBogoMIPS\t: 38.00\n\nprocessor\t: 1\nBogoMIPS\t: 38.00";
492 ffStrbufSetS(&strbuf, text);
493
494 while (ffStrbufGetline(&lineptr, &n, &strbuf)) {
495 ++i;
496 switch (i) {
497 case 1:
498 VERIFY(strcmp(lineptr, "Processor\t: ARMv7") == 0);
499 VERIFY(n == strlen("Processor\t: ARMv7"));
500 break;
501 case 2:
502 VERIFY(strcmp(lineptr, "processor\t: 0") == 0);
503 VERIFY(n == strlen("processor\t: 0"));
504 break;
505 case 3:
506 VERIFY(strcmp(lineptr, "BogoMIPS\t: 38.00") == 0);
507 VERIFY(n == strlen("BogoMIPS\t: 38.00"));
508 break;
509 case 4:
510 VERIFY(strcmp(lineptr, "") == 0);
511 VERIFY(n == 0);
512 break;
513 case 5:
514 VERIFY(strcmp(lineptr, "processor\t: 1") == 0);
515 VERIFY(n == strlen("processor\t: 1"));
516 break;
517 case 6:
518 VERIFY(strcmp(lineptr, "BogoMIPS\t: 38.00") == 0);
519 VERIFY(n == strlen("BogoMIPS\t: 38.00"));
520 break;
521 default:
522 VERIFY(false);
523 break;
524 }
525 }
526 VERIFY(ffStrbufEqualS(&strbuf, text));
527 VERIFY(*lineptr == '\0');
528 VERIFY(i == 6);
529
530 lineptr = NULL;
531 n = 0;
532 i = 0;
533 text = "\n";
534 ffStrbufSetS(&strbuf, text);
535 while (ffStrbufGetline(&lineptr, &n, &strbuf)) {
536 ++i;
537 switch (i) {
538 case 1:
539 VERIFY(strcmp(lineptr, "") == 0);
540 VERIFY(n == 0);
541 break;
542 default:
543 VERIFY(false);
544 break;
545 }
546 }
547 VERIFY(ffStrbufEqualS(&strbuf, text));
548 VERIFY(*lineptr == '\0');
549 VERIFY(i == 1);
550
551 lineptr = NULL;
552 n = 0;
553 i = 0;
554 text = "abcd";
555 ffStrbufSetS(&strbuf, text);
556 while (ffStrbufGetline(&lineptr, &n, &strbuf)) {
557 ++i;
558 switch (i) {
559 case 1:
560 VERIFY(strcmp(lineptr, "abcd") == 0);
561 VERIFY(n == strlen("abcd"));
562 break;
563 default:
564 VERIFY(false);
565 break;
566 }
567 }
568 VERIFY(ffStrbufEqualS(&strbuf, text));
569 VERIFY(*lineptr == '\0');
570 VERIFY(i == 1);
571
572 lineptr = NULL;
573 n = 0;
574 i = 0;
575 text = "";
576 ffStrbufSetS(&strbuf, text);
577 while (ffStrbufGetline(&lineptr, &n, &strbuf)) {
578 ++i;
579 VERIFY(false);
580 }
581
582 VERIFY(ffStrbufEqualS(&strbuf, text));
583 VERIFY(*lineptr == '\0');
584 VERIFY(i == 0);
585 }
586
587 ffStrbufSetS(&strbuf, "Hello World");
588 VERIFY(ffStrbufRemoveDupWhitespaces(&strbuf) == false);
589 VERIFY(strcmp(strbuf.chars, "Hello World") == 0);
590
591 ffStrbufSetS(&strbuf, "Hello World");
592 VERIFY(ffStrbufRemoveDupWhitespaces(&strbuf) == true);
593 VERIFY(strcmp(strbuf.chars, "Hello World") == 0);
594
595 ffStrbufSetS(&strbuf, " Hello World ");
596 VERIFY(ffStrbufRemoveDupWhitespaces(&strbuf) == true);
597 VERIFY(strcmp(strbuf.chars, " Hello World ") == 0);
598
599 ffStrbufSetS(&strbuf, " Hello World ");
600 VERIFY(ffStrbufRemoveDupWhitespaces(&strbuf) == true);
601 VERIFY(strcmp(strbuf.chars, " Hello World ") == 0);
602
603 ffStrbufSetS(&strbuf, " ");
604 VERIFY(ffStrbufRemoveDupWhitespaces(&strbuf) == true);
605 VERIFY(strcmp(strbuf.chars, " ") == 0);
606
607 ffStrbufClear(&strbuf);
608 VERIFY(ffStrbufRemoveDupWhitespaces(&strbuf) == false);
609 VERIFY(strcmp(strbuf.chars, "") == 0);
610
611 ffStrbufSetStatic(&strbuf, " ");
612 VERIFY(ffStrbufRemoveDupWhitespaces(&strbuf) == false);
613 VERIFY(strcmp(strbuf.chars, " ") == 0);
614
615 {
616 ffStrbufSetStatic(&strbuf, "abcdef");
617 FF_STRBUF_AUTO_DESTROY newStr = ffStrbufCreateCopy(&strbuf);
618 VERIFY(newStr.allocated == 0);
619 VERIFY(newStr.chars == strbuf.chars);
620 }
621
622 {
623 ffStrbufSetStatic(&strbuf, "abcdef");
624 FF_STRBUF_AUTO_DESTROY newStr = ffStrbufCreateS("123456");
625 ffStrbufSet(&newStr, &strbuf);
626 VERIFY(newStr.allocated == 0);
627 VERIFY(newStr.chars == strbuf.chars);
628 VERIFY(ffStrbufEqualS(&newStr, "abcdef"));
629 }
630
631 {
632 ffStrbufClear(&strbuf);
633 FF_STRBUF_AUTO_DESTROY newStr = ffStrbufCreateS("123456");
634 uint32_t oldAlloc = newStr.allocated;
635 VERIFY(oldAlloc > newStr.length);
636 ffStrbufSet(&newStr, &strbuf);
637 VERIFY(newStr.allocated == oldAlloc);
638 VERIFY(newStr.chars != strbuf.chars);
639 VERIFY(ffStrbufEqualS(&newStr, ""));
640 }
641
642 {
643 ffStrbufSetStatic(&strbuf, "abcdefghijkl");
644 FF_STRBUF_AUTO_DESTROY newStr = ffStrbufCreateS("123456");
645 ffStrbufSet(&newStr, &strbuf);
646 VERIFY(newStr.allocated == 0);
647 VERIFY(newStr.chars == strbuf.chars);
648 VERIFY(ffStrbufEqualS(&newStr, "abcdefghijkl"));
649 }
650
651 {
652 ffStrbufClear(&strbuf);
653 FF_STRBUF_AUTO_DESTROY newStr = ffStrbufCreateCopy(&strbuf);
654 VERIFY(newStr.allocated == 0);
655 VERIFY(newStr.chars == strbuf.chars);
656 VERIFY(newStr.chars[0] == '\0');
657 }
658
659 {
660 ffStrbufClear(&strbuf);
661 FF_STRBUF_AUTO_DESTROY newStr = ffStrbufCreateS("123456");
662 ffStrbufSet(&newStr, &strbuf);
663 VERIFY(newStr.allocated > 0);
664 VERIFY(newStr.chars != strbuf.chars);
665 VERIFY(ffStrbufEqualS(&newStr, ""));
666 }
667
668 {
669 ffStrbufSetStatic(&strbuf, "abc");
670 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "abc:def:ghi", ' ') == false);
671 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "abc:def:ghi", ':') == true);
672 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "def:ghi", ' ') == false);
673 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "def:ghi", ':') == false);
674 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "def", ':') == false);
675 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "abc", ':') == true);
676 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "", ' ') == false);
677 VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":abc:", ':') == true);
678 VERIFY(ffStrbufMatchSeparatedS(&strbuf, "abc:", ':') == true);
679 VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":abc", ':') == true);
680 VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":ABC", ':') == false);
681 VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":abcdef", ':') == false);
682 }
683
684 {
685 // ffStrbufMatchSeparatedNS with explicit compLength: the length-bounded
686 // contract is load-bearing for the Linux keyboard handler, which passes
687 // a fixed-size buffer length rather than a NUL-terminated string.
688 ffStrbufSetStatic(&strbuf, "abc");
689 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 11, "abc:def:ghi", ':') == true);
690 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 3, "abc:def:ghi", ':') == true);
691 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 7, "abc:def:ghi", ':') == true); // "abc:def"
692 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 4, "abc:def:ghi", ':') == true); // "abc:"
693 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 5, "abc:def:ghi", ':') == true); // "abc:d" truncated, but "abc" is a complete segment
694 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 3, "abd:def:ghi", ':') == false);
695 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 0, "abc:def:ghi", ':') == false);
696 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 0, "", ':') == false);
697 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 11, "abc:def:ghi", ' ') == false); // no separator in bounds
698 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 12, "abc:def:ghi\0j", ':') == true); // embedded NUL inside bounds
699
700 ffStrbufClear(&strbuf);
701 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 11, "abc:def:ghi", ':') == false); // no empty segment
702 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 8, "abc::def", ':') == true); // empty segment in the middle
703 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 4, "abc:", ':') == true); // trailing empty segment
704 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 4, ":abc", ':') == true); // leading empty segment
705 VERIFY(ffStrbufMatchSeparatedNS(&strbuf, 0, "abc", ':') == true); // empty separated string itself
706 }
707
708 {
709 ffStrbufSetStatic(&strbuf, "ABC");
710 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc:def:ghi", ' ') == false);
711 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc:def:ghi", ':') == true);
712 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "def:ghi", ' ') == false);
713 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "def:ghi", ':') == false);
714 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "def", ':') == false);
715 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc", ':') == true);
716 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "", ' ') == false);
717 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":abc:", ':') == true);
718 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc:", ':') == true);
719 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":abc", ':') == true);
720 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":ABC", ':') == true);
721 VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":abcdef", ':') == false);
722 }
723
724 {
725 ffStrbufSetStatic(&strbuf, "abc:def:ghi");
726 VERIFY(ffStrbufSeparatedContainS(&strbuf, "abc", ' ') == false);
727 VERIFY(ffStrbufSeparatedContainS(&strbuf, "abc", ':') == true);
728 VERIFY(ffStrbufSeparatedContainS(&strbuf, "def", ' ') == false);
729 VERIFY(ffStrbufSeparatedContainS(&strbuf, "def", ':') == true);
730 VERIFY(ffStrbufSeparatedContainS(&strbuf, "DEF", ':') == false);
731 VERIFY(ffStrbufSeparatedContainS(&strbuf, "a", ':') == false);
732 VERIFY(ffStrbufSeparatedContainS(&strbuf, "e", ':') == false);
733 VERIFY(ffStrbufSeparatedContainS(&strbuf, "i", ':') == false);
734 }
735
736 {
737 ffStrbufSetStatic(&strbuf, "ABC:DEF:GHI");
738 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "abc", ' ') == false);
739 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "abc", ':') == true);
740 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "def", ' ') == false);
741 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "def", ':') == true);
742 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "DEF", ':') == true);
743 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "a", ':') == false);
744 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "e", ':') == false);
745 VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "i", ':') == false);
746 }
747
748 {
749 // ffStrbufSeparatedContainNS with empty strings: an empty list contains
750 // only the empty segment (symmetric to ffStrbufMatchSeparatedNS); an
751 // empty comp matches only an empty segment in the list.
752 ffStrbufClear(&strbuf);
753 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 0, "", ':') == true); // empty list contains the empty segment
754 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 3, "abc", ':') == false); // empty list contains no non-empty segment
755 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 0, "abc", ':') == true); // compLength == 0 means an empty segment
756
757 ffStrbufSetStatic(&strbuf, "abc::def");
758 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 0, "", ':') == true); // empty segment in the middle
759 ffStrbufSetStatic(&strbuf, "abc:");
760 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 0, "", ':') == true); // trailing empty segment
761 ffStrbufSetStatic(&strbuf, ":abc");
762 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 0, "", ':') == true); // leading empty segment
763 ffStrbufSetStatic(&strbuf, "abc:def");
764 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 0, "", ':') == false); // no empty segment
765 ffStrbufSetStatic(&strbuf, "abc");
766 VERIFY(ffStrbufSeparatedContainNS(&strbuf, 0, "", ':') == false); // no empty segment
767 }
768
769 {
770 ffStrbufSetStatic(&strbuf, "abc");
771 ffStrbufSubstr(&strbuf, 0, 1); // start, end
772 VERIFY(ffStrbufEqualS(&strbuf, "a"));
773
774 ffStrbufSetStatic(&strbuf, "abc");
775 ffStrbufSubstr(&strbuf, 1, 1);
776 VERIFY(ffStrbufEqualS(&strbuf, ""));
777
778 ffStrbufSetStatic(&strbuf, "abc");
779 ffStrbufSubstr(&strbuf, 2, 1);
780 VERIFY(ffStrbufEqualS(&strbuf, ""));
781
782 ffStrbufSetStatic(&strbuf, "abc");
783 ffStrbufSubstr(&strbuf, 2, 3);
784 VERIFY(ffStrbufEqualS(&strbuf, "c"));
785
786 ffStrbufSetStatic(&strbuf, "abc");
787 ffStrbufSubstr(&strbuf, 0, 3);
788 VERIFY(ffStrbufEqualS(&strbuf, "abc"));
789 }
790
791 {
792 ffStrbufSetS(&strbuf, "abc");
793 ffStrbufSubstr(&strbuf, 0, 1); // start, end
794 VERIFY(ffStrbufEqualS(&strbuf, "a"));
795
796 ffStrbufSetS(&strbuf, "abc");
797 ffStrbufSubstr(&strbuf, 1, 1);
798 VERIFY(ffStrbufEqualS(&strbuf, ""));
799
800 ffStrbufSetS(&strbuf, "abc");
801 ffStrbufSubstr(&strbuf, 2, 1);
802 VERIFY(ffStrbufEqualS(&strbuf, ""));
803
804 ffStrbufSetS(&strbuf, "abc");
805 ffStrbufSubstr(&strbuf, 2, 3);
806 VERIFY(ffStrbufEqualS(&strbuf, "c"));
807
808 ffStrbufSetS(&strbuf, "abc");
809 ffStrbufSubstr(&strbuf, 0, 3);
810 VERIFY(ffStrbufEqualS(&strbuf, "abc"));
811
812 ffStrbufDestroy(&strbuf);
813 }
814
815 {
816 ffStrbufAppendUtf32CodePoint(&strbuf, 0x6587);
817 ffStrbufAppendUtf32CodePoint(&strbuf, 0x6cc9);
818 ffStrbufAppendUtf32CodePoint(&strbuf, 0x9a7f);
819 VERIFY(ffStrbufEqualS(&strbuf, (const char*) u8"文泉驿"));
820
821 ffStrbufDestroy(&strbuf);
822 }
823
824 {
825 ffStrbufAppendSInt(&strbuf, 1234567890);
826 VERIFY(ffStrbufEqualS(&strbuf, "1234567890"));
827
828 ffStrbufClear(&strbuf);
829 ffStrbufAppendSInt(&strbuf, -1234567890);
830 VERIFY(ffStrbufEqualS(&strbuf, "-1234567890"));
831
832 ffStrbufClear(&strbuf);
833 ffStrbufAppendSInt(&strbuf, 0);
834 VERIFY(ffStrbufEqualS(&strbuf, "0"));
835
836 ffStrbufClear(&strbuf);
837 ffStrbufAppendUInt(&strbuf, 1234567890);
838 VERIFY(ffStrbufEqualS(&strbuf, "1234567890"));
839
840 ffStrbufClear(&strbuf);
841 ffStrbufAppendUInt(&strbuf, 0);
842 VERIFY(ffStrbufEqualS(&strbuf, "0"));
843
844 ffStrbufDestroy(&strbuf);
845 }
846
847 {
848 ffStrbufAppendDouble(&strbuf, 120.0, 0, true);
849 VERIFY(ffStrbufEqualS(&strbuf, "120"));
850
851 ffStrbufClear(&strbuf);
852 ffStrbufAppendDouble(&strbuf, 120.0, 1, true);
853 VERIFY(ffStrbufEqualS(&strbuf, "120.0"));
854
855 ffStrbufClear(&strbuf);
856 ffStrbufAppendDouble(&strbuf, 120.0, 5, true);
857 VERIFY(ffStrbufEqualS(&strbuf, "120.00000"));
858
859 ffStrbufClear(&strbuf);
860 ffStrbufAppendDouble(&strbuf, 120.123456789, 5, true);
861 VERIFY(ffStrbufEqualS(&strbuf, "120.12346"));
862
863 ffStrbufClear(&strbuf);
864 ffStrbufAppendDouble(&strbuf, 120.888888, 0, true);
865 VERIFY(ffStrbufEqualS(&strbuf, "121"));
866
867 ffStrbufClear(&strbuf);
868 ffStrbufAppendDouble(&strbuf, 120.999999, 2, true);
869 VERIFY(ffStrbufEqualS(&strbuf, "121.00"));
870
871 ffStrbufClear(&strbuf);
872 ffStrbufAppendDouble(&strbuf, 120.123456789, 0, true);
873 VERIFY(ffStrbufEqualS(&strbuf, "120"));
874
875 ffStrbufClear(&strbuf);
876 ffStrbufAppendDouble(&strbuf, 120.123456789, -1, true);
877 VERIFY(ffStrbufEqualS(&strbuf, "120.123456789"));
878
879 ffStrbufClear(&strbuf);
880 ffStrbufAppendDouble(&strbuf, 120.123, 5, true);
881 VERIFY(ffStrbufEqualS(&strbuf, "120.12300"));
882
883 ffStrbufClear(&strbuf);
884 ffStrbufAppendDouble(&strbuf, -120.0, 0, true);
885 VERIFY(ffStrbufEqualS(&strbuf, "-120"));
886
887 ffStrbufClear(&strbuf);
888 ffStrbufAppendDouble(&strbuf, -120.0, 1, true);
889 VERIFY(ffStrbufEqualS(&strbuf, "-120.0"));
890
891 ffStrbufClear(&strbuf);
892 ffStrbufAppendDouble(&strbuf, -120.0, 5, true);
893 VERIFY(ffStrbufEqualS(&strbuf, "-120.00000"));
894
895 ffStrbufClear(&strbuf);
896 ffStrbufAppendDouble(&strbuf, -120.123456789, 5, true);
897 VERIFY(ffStrbufEqualS(&strbuf, "-120.12346"));
898
899 ffStrbufClear(&strbuf);
900 ffStrbufAppendDouble(&strbuf, -120.123456789, 0, true);
901 VERIFY(ffStrbufEqualS(&strbuf, "-120"));
902
903 ffStrbufClear(&strbuf);
904 ffStrbufAppendDouble(&strbuf, -120.123456789, -1, true);
905 VERIFY(ffStrbufEqualS(&strbuf, "-120.123456789"));
906
907 ffStrbufClear(&strbuf);
908 ffStrbufAppendDouble(&strbuf, -120.123, 5, true);
909 VERIFY(ffStrbufEqualS(&strbuf, "-120.12300"));
910
911 ffStrbufClear(&strbuf);
912 ffStrbufAppendDouble(&strbuf, -120.888888, 0, true);
913 VERIFY(ffStrbufEqualS(&strbuf, "-121"));
914
915 ffStrbufClear(&strbuf);
916 ffStrbufAppendDouble(&strbuf, -120.999999, 2, true);
917 VERIFY(ffStrbufEqualS(&strbuf, "-121.00"));
918
919 ffStrbufClear(&strbuf);
920 ffStrbufAppendDouble(&strbuf, 1.2345e50, 1, true);
921 VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
922
923 ffStrbufClear(&strbuf);
924 ffStrbufAppendDouble(&strbuf, -1.2345e50, 1, true);
925 VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
926
927 ffStrbufClear(&strbuf);
928 ffStrbufAppendDouble(&strbuf, 1.2345e50, 0, true);
929 VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
930
931 ffStrbufClear(&strbuf);
932 ffStrbufAppendDouble(&strbuf, -1.2345e50, 0, true);
933 VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
934
935 ffStrbufClear(&strbuf);
936 ffStrbufAppendDouble(&strbuf, 1.2345e50, -1, true);
937 VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
938
939 ffStrbufClear(&strbuf);
940 ffStrbufAppendDouble(&strbuf, -1.2345e50, -1, true);
941 VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
942
943 ffStrbufClear(&strbuf);
944 ffStrbufAppendDouble(&strbuf, 1.2345e20, 1, true);
945 VERIFY(ffStrbufEqualS(&strbuf, "123450000000000000000.0"));
946
947 ffStrbufClear(&strbuf);
948 ffStrbufAppendDouble(&strbuf, -1.2345e20, 1, true);
949 VERIFY(ffStrbufEqualS(&strbuf, "-123450000000000000000.0"));
950
951 ffStrbufClear(&strbuf);
952 ffStrbufAppendDouble(&strbuf, +0.0, 0, true);
953 VERIFY(ffStrbufEqualS(&strbuf, "0"));
954
955 ffStrbufClear(&strbuf);
956 ffStrbufAppendDouble(&strbuf, -0.0, 0, true);
957 VERIFY(ffStrbufEqualS(&strbuf, "-0"));
958
959 ffStrbufDestroy(&strbuf);
960 }
961
962 {
963 ffStrbufAppendDouble(&strbuf, 120.0, 0, false);
964 VERIFY(ffStrbufEqualS(&strbuf, "120"));
965
966 ffStrbufClear(&strbuf);
967 ffStrbufAppendDouble(&strbuf, 120.0, 1, false);
968 VERIFY(ffStrbufEqualS(&strbuf, "120"));
969
970 ffStrbufClear(&strbuf);
971 ffStrbufAppendDouble(&strbuf, 120.0, 5, false);
972 VERIFY(ffStrbufEqualS(&strbuf, "120"));
973
974 ffStrbufClear(&strbuf);
975 ffStrbufAppendDouble(&strbuf, 120.123456789, 5, false);
976 VERIFY(ffStrbufEqualS(&strbuf, "120.12346"));
977
978 ffStrbufClear(&strbuf);
979 ffStrbufAppendDouble(&strbuf, 120.888888, 0, false);
980 VERIFY(ffStrbufEqualS(&strbuf, "121"));
981
982 ffStrbufClear(&strbuf);
983 ffStrbufAppendDouble(&strbuf, 120.999999, 2, false);
984 VERIFY(ffStrbufEqualS(&strbuf, "121"));
985
986 ffStrbufClear(&strbuf);
987 ffStrbufAppendDouble(&strbuf, 120.123456789, 0, false);
988 VERIFY(ffStrbufEqualS(&strbuf, "120"));
989
990 ffStrbufClear(&strbuf);
991 ffStrbufAppendDouble(&strbuf, 120.123456789, -1, false);
992 VERIFY(ffStrbufEqualS(&strbuf, "120.123456789"));
993
994 ffStrbufClear(&strbuf);
995 ffStrbufAppendDouble(&strbuf, 120.123, 5, false);
996 VERIFY(ffStrbufEqualS(&strbuf, "120.123"));
997
998 ffStrbufClear(&strbuf);
999 ffStrbufAppendDouble(&strbuf, -120.0, 0, false);
1000 VERIFY(ffStrbufEqualS(&strbuf, "-120"));
1001
1002 ffStrbufClear(&strbuf);
1003 ffStrbufAppendDouble(&strbuf, -120.0, 1, false);
1004 VERIFY(ffStrbufEqualS(&strbuf, "-120"));
1005
1006 ffStrbufClear(&strbuf);
1007 ffStrbufAppendDouble(&strbuf, -120.0, 5, false);
1008 VERIFY(ffStrbufEqualS(&strbuf, "-120"));
1009
1010 ffStrbufClear(&strbuf);
1011 ffStrbufAppendDouble(&strbuf, -120.123456789, 5, false);
1012 VERIFY(ffStrbufEqualS(&strbuf, "-120.12346"));
1013
1014 ffStrbufClear(&strbuf);
1015 ffStrbufAppendDouble(&strbuf, -120.123456789, 0, false);
1016 VERIFY(ffStrbufEqualS(&strbuf, "-120"));
1017
1018 ffStrbufClear(&strbuf);
1019 ffStrbufAppendDouble(&strbuf, -120.123456789, -1, false);
1020 VERIFY(ffStrbufEqualS(&strbuf, "-120.123456789"));
1021
1022 ffStrbufClear(&strbuf);
1023 ffStrbufAppendDouble(&strbuf, -120.123, 5, false);
1024 VERIFY(ffStrbufEqualS(&strbuf, "-120.123"));
1025
1026 ffStrbufClear(&strbuf);
1027 ffStrbufAppendDouble(&strbuf, -120.888888, 0, false);
1028 VERIFY(ffStrbufEqualS(&strbuf, "-121"));
1029
1030 ffStrbufClear(&strbuf);
1031 ffStrbufAppendDouble(&strbuf, -120.999999, 2, false);
1032 VERIFY(ffStrbufEqualS(&strbuf, "-121"));
1033
1034 ffStrbufClear(&strbuf);
1035 ffStrbufAppendDouble(&strbuf, 1.2345e50, 1, false);
1036 VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
1037
1038 ffStrbufClear(&strbuf);
1039 ffStrbufAppendDouble(&strbuf, -1.2345e50, 1, false);
1040 VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
1041
1042 ffStrbufClear(&strbuf);
1043 ffStrbufAppendDouble(&strbuf, 1.2345e50, 0, false);
1044 VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
1045
1046 ffStrbufClear(&strbuf);
1047 ffStrbufAppendDouble(&strbuf, -1.2345e50, 0, false);
1048 VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
1049
1050 ffStrbufClear(&strbuf);
1051 ffStrbufAppendDouble(&strbuf, 1.2345e50, -1, false);
1052 VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
1053
1054 ffStrbufClear(&strbuf);
1055 ffStrbufAppendDouble(&strbuf, -1.2345e50, -1, false);
1056 VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
1057
1058 ffStrbufClear(&strbuf);
1059 ffStrbufAppendDouble(&strbuf, 1.2345e20, 1, false);
1060 VERIFY(ffStrbufEqualS(&strbuf, "123450000000000000000"));
1061
1062 ffStrbufClear(&strbuf);
1063 ffStrbufAppendDouble(&strbuf, -1.2345e20, 1, false);
1064 VERIFY(ffStrbufEqualS(&strbuf, "-123450000000000000000"));
1065
1066 ffStrbufClear(&strbuf);
1067 ffStrbufAppendDouble(&strbuf, +0.0, 0, false);
1068 VERIFY(ffStrbufEqualS(&strbuf, "0"));
1069
1070 ffStrbufClear(&strbuf);
1071 ffStrbufAppendDouble(&strbuf, -0.0, 0, false);
1072 VERIFY(ffStrbufEqualS(&strbuf, "-0"));
1073
1074 ffStrbufDestroy(&strbuf);
1075 }
1076
1077 // decode hex escape sequences
1078 {
1079 ffStrbufSetS(&strbuf, "Basic\\x20data\\x20partition");
1080 VERIFY(ffStrbufDecodeHexEscapeSequences(&strbuf) == true);
1081 VERIFY(ffStrbufEqualS(&strbuf, "Basic data partition"));
1082
1083 ffStrbufSetS(&strbuf, "\\x41\\x42\\x43");
1084 VERIFY(ffStrbufDecodeHexEscapeSequences(&strbuf) == true);
1085 VERIFY(ffStrbufEqualS(&strbuf, "ABC"));
1086
1087 ffStrbufSetS(&strbuf, "abc\\x4");
1088 VERIFY(ffStrbufDecodeHexEscapeSequences(&strbuf) == false);
1089 VERIFY(ffStrbufEqualS(&strbuf, "abc\\x4"));
1090
1091 ffStrbufSetS(&strbuf, "abc\\xZZ");
1092 VERIFY(ffStrbufDecodeHexEscapeSequences(&strbuf) == false);
1093 VERIFY(ffStrbufEqualS(&strbuf, "abc\\xZZ"));
1094
1095 ffStrbufSetS(&strbuf, "abc\\x2G");
1096 VERIFY(ffStrbufDecodeHexEscapeSequences(&strbuf) == false);
1097 VERIFY(ffStrbufEqualS(&strbuf, "abc\\x2G"));
1098 }
1099
1100 // setS
1101 ffStrbufInitStatic(&strbuf, "STATIC");
1102 ffStrbufSetS(&strbuf, "DYNAMIC");
1103 VERIFY(ffStrbufEqualS(&strbuf, "DYNAMIC"));
1104 VERIFY(strbuf.allocated > 0);
1105 ffStrbufDestroy(&strbuf);
1106
1107 ffStrbufInit(&strbuf);
1108 ffStrbufSetS(&strbuf, "");
1109 VERIFY(ffStrbufEqualS(&strbuf, ""));
1110 VERIFY(strbuf.allocated == 0);
1111 ffStrbufDestroy(&strbuf);
1112
1113 ffStrbufInitStatic(&strbuf, "STATIC");
1114 ffStrbufSetS(&strbuf, "");
1115 VERIFY(ffStrbufEqualS(&strbuf, ""));
1116 VERIFY(strbuf.allocated == 0);
1117 ffStrbufDestroy(&strbuf);
1118
1119 ffStrbufInitStatic(&strbuf, "STATIC");
1120 ffStrbufSetStatic(&strbuf, "");
1121 VERIFY(ffStrbufEqualS(&strbuf, ""));
1122 VERIFY(strbuf.allocated == 0);
1123 ffStrbufDestroy(&strbuf);
1124
1125 ffStrbufInitS(&strbuf, "DYNAMIC");
1126 ffStrbufSetStatic(&strbuf, "");
1127 VERIFY(ffStrbufEqualS(&strbuf, ""));
1128 VERIFY(strbuf.allocated == 0);
1129 ffStrbufDestroy(&strbuf);
1130
1131 ffStrbufInitS(&strbuf, "DYNAMIC");
1132 ffStrbufSetS(&strbuf, "ANOTHER DYNAMIC");
1133 VERIFY(ffStrbufEqualS(&strbuf, "ANOTHER DYNAMIC"));
1134 VERIFY(strbuf.allocated > 0);
1135 ffStrbufDestroy(&strbuf);
1136
1137 ffStrbufInit(&strbuf);
1138 ffStrbufSetStatic(&strbuf, "");
1139 VERIFY(ffStrbufEqualS(&strbuf, ""));
1140 VERIFY(strbuf.allocated == 0);
1141 ffStrbufDestroy(&strbuf);
1142
1143 // set
1144 ffStrbufInitStatic(&strbuf, "STATIC");
1145 {
1146 FF_STRBUF_AUTO_DESTROY other = ffStrbufCreateS("DYNAMIC");
1147 ffStrbufSet(&strbuf, &other);
1148 }
1149 VERIFY(ffStrbufEqualS(&strbuf, "DYNAMIC"));
1150 VERIFY(strbuf.allocated > 0);
1151 ffStrbufDestroy(&strbuf);
1152
1153 ffStrbufInit(&strbuf);
1154 {
1155 FF_STRBUF_AUTO_DESTROY other = ffStrbufCreateS("");
1156 ffStrbufSet(&strbuf, &other);
1157 }
1158 VERIFY(ffStrbufEqualS(&strbuf, ""));
1159 VERIFY(strbuf.allocated == 0);
1160 ffStrbufDestroy(&strbuf);
1161
1162 ffStrbufInitStatic(&strbuf, "STATIC");
1163 {
1164 FF_STRBUF_AUTO_DESTROY other = ffStrbufCreateS("");
1165 ffStrbufSet(&strbuf, &other);
1166 }
1167 VERIFY(ffStrbufEqualS(&strbuf, ""));
1168 VERIFY(strbuf.allocated == 0);
1169 ffStrbufDestroy(&strbuf);
1170
1171 ffStrbufInitS(&strbuf, "DYNAMIC");
1172 {
1173 FF_STRBUF_AUTO_DESTROY other = ffStrbufCreateS("");
1174 ffStrbufSet(&strbuf, &other);
1175 }
1176 VERIFY(ffStrbufEqualS(&strbuf, ""));
1177 VERIFY(strbuf.allocated > 0);
1178 ffStrbufDestroy(&strbuf);
1179
1180 ffStrbufInitS(&strbuf, "DYNAMIC");
1181 {
1182 FF_STRBUF_AUTO_DESTROY other = ffStrbufCreateStatic("STATIC");
1183 ffStrbufSet(&strbuf, &other);
1184 }
1185 VERIFY(ffStrbufEqualS(&strbuf, "STATIC"));
1186 VERIFY(strbuf.allocated == 0);
1187 ffStrbufDestroy(&strbuf);
1188
1189 #if FASTFETCH_STRBUF_DEFAULT_ALLOC == 32
1190 ffStrbufEnsureFreeNoCheck(&strbuf, 1);
1191 VERIFY(strbuf.allocated == 32);
1192 ffStrbufDestroy(&strbuf);
1193
1194 ffStrbufEnsureFreeNoCheck(&strbuf, 31);
1195 VERIFY(strbuf.allocated == 32);
1196 ffStrbufDestroy(&strbuf);
1197
1198 ffStrbufEnsureFreeNoCheck(&strbuf, 32);
1199 VERIFY(strbuf.allocated == 64);
1200 ffStrbufDestroy(&strbuf);
1201
1202 ffStrbufEnsureFreeNoCheck(&strbuf, 33);
1203 VERIFY(strbuf.allocated == 64);
1204 ffStrbufDestroy(&strbuf);
1205
1206 ffStrbufEnsureFreeNoCheck(&strbuf, 63);
1207 VERIFY(strbuf.allocated == 64);
1208 ffStrbufDestroy(&strbuf);
1209
1210 ffStrbufEnsureFreeNoCheck(&strbuf, 64);
1211 VERIFY(strbuf.allocated == 128);
1212 ffStrbufDestroy(&strbuf);
1213 #endif
1214
1215 // Success
1216 puts("\e[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
1217}