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

Last change on this file since bc547d3 was c136863, checked in by Peter A. Buhr <pabuhr@…>, 6 days ago

formatting

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