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

Last change on this file since 9d5eacb was 75e2286, checked in by Peter A. Buhr <pabuhr@…>, 9 months ago

add tests for getline and quoted input manipulators

  • 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.