1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#include "test.h"
/* all optional */
#define SP_MALLOC mallocc
#define SP_REALLOC reallocc
#define SP_FREE free
#include <conts/sp.h>
/* including default name is fine */
#include <conts/sp.h>
/* separate string type, can be defined in addition to the default type. The
* default type can be included multiple times, but specially-named types
* cannot. */
#define SP_NAME second
#define SP_MALLOC mallocc
#define SP_REALLOC reallocc
#define SP_FREE free
#include <conts/sp.h>
int main()
{
#if defined(COVERAGE)
assert(!covsrv_init());
atexit(covsrv_destroy);
#endif
struct sp sp = sp_create();
/* should be in static buffer, cannot fail
* (though the user should probably assume that appending can always
* fail) */
assert(!sp_append_str(&sp, "123"));
/* don't use sp.b directly, prefer sp_str, but this is fine for testing */
assert(strcmp(sp.b, "123") == 0);
/* test static iteration */
foreach(sp, c, &sp) {
switch (c.i) {
case 0: assert(*c.p == '1'); break;
case 1: assert(*c.p == '2'); break;
case 2: assert(*c.p == '3'); break;
default: assert(0 && "weird iteration");
}
}
/* now we should switch over to the dynamic buffer, as we have more
* characters than can fit in any regular pointer type (3 for 32bit, 7
* for 64 bit, 15 for stuff like Cheri), might fail */
if (sp_append_str(&sp, "4567890ABCDEFGH")) {
fprintf(stderr, "failed appending to string buffer");
sp_destroy(&sp);
return -1;
}
/* same deal, check that we're using the dynamic buffer */
assert(strcmp(sp.p, "1234567890ABCDEFGH") == 0);
/* test dynamic iteration */
foreach(sp, c, &sp) {
switch (c.i) {
case 0: assert(*c.p == '1'); break;
case 1: assert(*c.p == '2'); break;
case 2: assert(*c.p == '3'); break;
case 3: assert(*c.p == '4'); break;
case 4: assert(*c.p == '5'); break;
case 5: assert(*c.p == '6'); break;
case 6: assert(*c.p == '7'); break;
case 7: assert(*c.p == '8'); break;
case 8: assert(*c.p == '9'); break;
case 9: assert(*c.p == '0'); break;
case 10: assert(*c.p == 'A'); break;
case 11: assert(*c.p == 'B'); break;
case 12: assert(*c.p == 'C'); break;
case 13: assert(*c.p == 'D'); break;
case 14: assert(*c.p == 'E'); break;
case 15: assert(*c.p == 'F'); break;
case 16: assert(*c.p == 'G'); break;
case 17: assert(*c.p == 'H'); break;
default: assert(0 && "weird iteration");
}
}
/* 'reset' string */
sp_destroy(&sp);
/* test formatting functions */
sp = sp_create();
/* static formatting */
for (int i = 1; i < 4; ++i)
assert(!sp_append_fmt(&sp, "%d", i));
assert(strcmp(sp.b, "123") == 0);
/* dynamic formatting */
for (int i = 4; i < 15; ++i)
if (sp_append_fmt(&sp, "%d", i)) {
fprintf(stderr, "failed formatting input\n");
sp_destroy(&sp);
return -1;
}
assert(strcmp(sp.p, "1234567891011121314") == 0);
sp_destroy(&sp);
/* do some benchmarking, oh yeah! */
struct second sec = second_create();
for (int i = 0; i < ITER; ++i)
if (second_append_str(&sec, "BENCHMARK, FUCK YEAH\n")) {
fprintf(stderr, "failed when stressing append\n");
second_destroy(&sec);
return -1;
}
/* hmm, come to think of it, foreach_line or something along those lines
* might be pretty neat? */
second_destroy(&sec);
sec = second_create();
for (int i = 0; i < ITER; ++i)
if (second_append_fmt(&sec, "I'm in iteration %d!\n", i)) {
fprintf(stderr, "failed when stressing fmt\n");
second_destroy(&sec);
return -1;
}
second_destroy(&sec);
/* all done! */
return 0;
}
|