source: tests/collections/string-istream-manip.cfa@ 283fbdd

Last change on this file since 283fbdd was c565d68, checked in by Peter A. Buhr <pabuhr@…>, 11 months ago

change CFA tests to use C designator syntax

  • Property mode set to 100644
File size: 7.0 KB
Line 
1
2#include <fstream.hfa>
3#include <collections/string.hfa>
4#include <collections/string_res.hfa>
5#include <stdio.h>
6
7// No-op manipulators.
8// Temporary hack while there are two code paths in the string implementation.
9// (One for reading plain strings, the other for reading via a manipulator.)
10// The test cases that use plainjane(-) are exercising the via-manipulator code path,
11// just with trivial manipulation.
12static _Istream_Sstr plainjane( string & s ) { return (_Istream_Sstr)@{ s, {{0p}, -1, {.flags.rwd = false}} }; }
13static _Istream_Rstr plainjane( string_res & s ) { return (_Istream_Rstr)@{ &s, {{0p}, -1, {.flags.rwd = false}} }; }
14
15static void forceStringHeapFreeSpaceTo(int desiredSize) {
16 for (1_000_000) {
17 string x = "a";
18 (void)x;
19 if (desiredSize == DEBUG_string_bytes_avail_until_gc(DEBUG_string_heap())) return;
20 }
21 sout | "Unable to force size" | desiredSize | "in 1,000,000 tries";
22}
23
24int main() {
25 // These "pre" cases deal with issues analogous to the "pre" cases of io/manipulatorsInput.
26 // The acceptance criterion is simpler but driving the cases is harder.
27 // The tests just read strings and echo what they read; acceptance of simple echoing assures
28 // no spurious splitting merging.
29 // The lengths of the strings are chosen to match white-box knowledge of when the string layer
30 // has tor drive the cstring layer through a second iteration:
31 // - for no-manip, lengths are near the room at end of string heap
32 // (chosen target size of 9 showed the original bug on preS2, aligned with the other cases)
33 // - for manip, lengths are near the auxiliary buffer size of 128
34 // Only first case repeats for string_res; rest run only from the passthru string layer.
35 // Similarly, the manipulator breadth isn't checked at the cstring layer either.
36 {
37 // S: string, no manipulator
38 void echoTillX(const char * casename) {
39 string s;
40 // loop assumes behaviour not tested until main-case #15:
41 // on reading nothing, the prior string value is left alone
42 do {
43 s = "";
44 forceStringHeapFreeSpaceTo(9);
45 sin | s;
46 sout | casename | s;
47 } while ( size(s) > 0 && s[size(s)-1] != 'x' );
48 }
49 echoTillX("preS1");
50 echoTillX("preS2");
51 echoTillX("preS3");
52 echoTillX("preS4");
53 }
54 {
55 // SMN: string, manipulator for no-op
56 void echoTillX(const char * casename) {
57 string s;
58 do {
59 s = "";
60 sin | plainjane( s );
61 sout | casename | s;
62 } while ( size(s) > 0 && s[size(s)-1] != 'x' );
63 }
64 echoTillX("preSMN1");
65 echoTillX("preSMN2");
66 echoTillX("preSMN3");
67 echoTillX("preSMN4");
68 }
69 {
70 // RMN: string_res, manipulator for no-op
71 void echoTillX(const char * casename) {
72 string_res s;
73 do {
74 s = "";
75 sin | plainjane( s );
76 sout | casename | s;
77 } while ( size(s) > 0 && s[size(s)-1] != 'x' );
78 }
79 echoTillX("preRMN1");
80 echoTillX("preRMN2");
81 echoTillX("preRMN3");
82 echoTillX("preRMN4");
83 }
84 {
85 // SMI: string, manipulator `incl`
86 void echoTillX(const char * casename) {
87 string s;
88 do {
89 s = "";
90 sin | skip("-\n");
91 sin | incl( ".:|# x", s );
92 sout | casename | " \"" | s | "\"";
93 } while ( size(s) > 0 && s[size(s)-1] != 'x' );
94 }
95 echoTillX("preSMI1");
96 echoTillX("preSMI2");
97 echoTillX("preSMI3");
98 echoTillX("preSMI4");
99 }
100 {
101 // SME: string, manipulator `excl`
102 void echoTillX(const char * casename) {
103 string s;
104 do {
105 s = "";
106 sin | skip("-\n");
107 sin | excl( "-\n", s );
108 sout | casename | " \"" | s | "\"";
109 } while ( size(s) > 0 && s[size(s)-1] != 'x' );
110 }
111 echoTillX("preSME1");
112 echoTillX("preSME2");
113 echoTillX("preSME3");
114 echoTillX("preSME4");
115 }
116 sin | skip("-\n");
117 {
118 // SMG: string, manipulator `getline`
119 void echoTillX(const char * casename) {
120 string s;
121 do {
122 s = "";
123 sin | getline( s );
124 sout | casename | s;
125 } while ( size(s) > 0 && s[size(s)-1] != 'x' );
126 }
127 echoTillX("preSMG1");
128 echoTillX("preSMG2");
129 echoTillX("preSMG3");
130 echoTillX("preSMG4");
131 }
132 {
133 // SMD: string, manipulator (`getline` with custom) delimiter
134 void echoTillX(const char * casename) {
135 string s;
136 do {
137 s = "";
138 sin | getline( s, '@' );
139 sout | casename | s;
140 } while ( size(s) > 0 && s[size(s)-1] != 'x' );
141 sin | skip(" \n");
142 }
143 echoTillX("preSMD1");
144 echoTillX("preSMD2");
145 echoTillX("preSMD3");
146 echoTillX("preSMD4");
147 }
148 // Keep harmonized with io/manipulatorsInput.
149 {
150 string s = "yyyyyyyyyyyyyyyyyyyy";
151 char sk[] = "abc";
152 sin | "abc " | skip( sk ) | skip( 5 ); sout | "1" | s;
153 sin | s; sout | "2" | s;
154 sin | ignore( s ); sout | "3" | s;
155 sin | wdi( 8, s ); sout | "4" | s;
156 sin | ignore( wdi( 8, s ) ); sout | "5" | s;
157
158 sin | incl( "abc", s ); sout | "6" | s;
159 sin | excl( "abc", s ); sout | "7" | s;
160 sin | ignore( incl( "abc", s ) ); sout | "8" | s;
161 sin | ignore( excl( "abc", s ) ); sout | "9" | s;
162 sin | incl( "abc", wdi( 8, s ) ); sout | "10" | s;
163 sin | excl( "abc", wdi( 8, s ) ); sout | "11" | s;
164 sin | ignore( incl( "abc", wdi( 8, s ) ) ); sout | "12" | s;
165 sin | ignore( excl( "abc", wdi( 8, s ) ) ); sout | "13" | s;
166 sin | nl;
167
168 s = "q";
169 sin | incl( "abc", s ); sout | "14" | s;
170 s = "q";
171 sin | excl( "u", s ); sout | "15" | s;
172 sin | skip( "u" ) | nl;
173
174 sin | getline( s ); sout | "16" | s;
175 sin | getline( s, '%' ) | nl; sout | "17" | s;
176 sin | ignore( getline( s, '%' ) ) | nl; sout | "18" | s;
177
178 sin | quoted( s ); sout | "19" | s;
179 sin | quoted( s, '\'' ); sout | "20" | s;
180 sin | quoted( s, '{', '}' ); sout | "21" | s;
181 sin | quoted( s, 'X', 'Y' ); sout | "22" | s;
182 sin | ignore( quoted( s, 'X', 'Y' ) ); sout | "23" | s;
183 sin | nl;
184 }
185 // Full repeat on string_res layer assures the full manipulator vocabulary is supported there.
186 {
187 string_res s = "yyyyyyyyyyyyyyyyyyyy";
188 char sk[] = "abc";
189 sin | "abc " | skip( sk ) | skip( 5 ); sout | "1" | s;
190 sin | s; sout | "2" | s;
191 sin | ignore( s ); sout | "3" | s;
192 sin | wdi( 8, s ); sout | "4" | s;
193 sin | ignore( wdi( 8, s ) ); sout | "5" | s;
194
195 sin | incl( "abc", s ); sout | "6" | s;
196 sin | excl( "abc", s ); sout | "7" | s;
197 sin | ignore( incl( "abc", s ) ); sout | "8" | s;
198 sin | ignore( excl( "abc", s ) ); sout | "9" | s;
199 sin | incl( "abc", wdi( 8, s ) ); sout | "10" | s;
200 sin | excl( "abc", wdi( 8, s ) ); sout | "11" | s;
201 sin | ignore( incl( "abc", wdi( 8, s ) ) ); sout | "12" | s;
202 sin | ignore( excl( "abc", wdi( 8, s ) ) ); sout | "13" | s;
203 sin | "\n";
204
205 s = "q";
206 sin | incl( "abc", s ); sout | "14" | s;
207 s = "q";
208 sin | excl( "u", s ); sout | "15" | s;
209 sin | skip( "u" );
210 sin | "\n";
211 sin | getline( s ); sout | "16" | s;
212 sin | getline( s, '%' ) | nl; sout | "17" | s;
213 sin | ignore( getline( s, '%' ) ) | nl; sout | "18" | s;
214
215 sin | quoted( s ); sout | "19" | s;
216 sin | quoted( s, '\'' ); sout | "20" | s;
217 sin | quoted( s, '{', '}' ); sout | "21" | s;
218 sin | quoted( s, 'X', 'Y' ); sout | "22" | s;
219 sin | ignore( quoted( s, 'X', 'Y' ) ); sout | "23" | s;
220 }
221}
Note: See TracBrowser for help on using the repository browser.