source: tests/io/manipulatorsInput-uchunk.cfa@ 2e0bb92

Last change on this file since 2e0bb92 was 406c806, checked in by Michael Brooks <mlbrooks@…>, 12 months ago

Attempt to fix Promote build by naming recently added test data files in a more typical way.

  • Property mode set to 100644
File size: 5.4 KB
RevLine 
[efe697d]1/*
2uchunk - user-visible chunking: how a user's input-consuming loop experiences a presence/absence of qualifying input
3 slight generalization of "eof handling"; we called many of these cases the "eof tests" while first devising them
4
5Coverage criteria include when an input-provided chunk exactly fills a user-provided buffer,
6because the double-boundary case of "this happens just before eof" is (white-box) uchunk-relevant.
7But cases of input-provided chunks exceeding the user's buffer live under
8manipulatorsInput#pre* and ../collections/string-io-istream-manip#pre*.
9
10Test design with subprocesses and auxiliary inputs is cargo-culted from
11configs/parseconfig, configs/usage and io/many_read.
12If you're here to cargo-cult, start there.
13
14*/
15
16#ifdef __cplusplus
17 #include <iostream>
18 #include <iomanip>
19 #include <cstring>
20 using namespace std;
21 #define TRYREAD(str) tryread(sizeof(str)-1, str);
22 #define DETECT_EOF( ... ) __VA_ARGS__
23 #define POLL_EOF if ( cin.fail() ) break;
24 #define ECHO(stg, str) cout << #stg << " \"" << str << "\"" << str[sizeof(str)-1] << endl
25#elif defined __cforall
26 #include <fstream.hfa>
27 extern "C" {
28 char* strcpy(char*, const char*);
29 }
30 #define DETECT_EOF( ... ) \
31 try { \
32 __VA_ARGS__ \
33 } catch ( end_of_file * ) {}
34 #define TRYREAD(str) try { \
35 tryread(sizeof(str)-1, str); \
36 } \
37 catch ( cstring_length* ) { \
38 /* never expected; just harness robustness */ \
39 sout | "cstring_length and " | nonl; \
40 }
41 #define POLL_EOF
42 #define ECHO(stg, str) sout | #stg | " \"" | str | "\"" | str[sizeof(str)-1]
43#else
44 #error no
45#endif
46
47
48
49//
50// BEGIN: functions only used in child process
51//
52// Parent process does not use test.py-provided stdin.
53// Parent process uses test.py-provided IN_DIR, from which it explicitly opens files.
54// Each child process sees content from one such file on its stdin.
55// The functions in this section echo, from this distinct child stdin, to parent-bridged stdout.
56//
57
58void subcaseHarness( void (*tryread)(size_t, char*) ) {
59 char s[10];
60 DETECT_EOF (
61 for (bool first = true ;; ) {
62 strcpy(s, "---"); // every time: restore "---"x
63 s[9] = 'x';
64 if (first) {
65 ECHO(BGN, s); // first time: show it
66 first = false;
67 }
68
69 TRYREAD(s)
70 POLL_EOF
71 ECHO(GOT, s);
72 }
73 )
74 ECHO(END, s);
75}
76
77void tryread_default(size_t sizeof_s, char *s) {
78 #ifdef __cplusplus
79 cin >> setw( sizeof_s ) >> s;
80 #else
81 sin | wdi( sizeof_s, s );
82 #endif
83}
84
85void tryread_getline(size_t sizeof_s, char *s) {
86 #ifdef __cplusplus
87 cin.getline(s, sizeof_s);
88 #else
89 sin | getline( wdi( sizeof_s, s ) );
90 #endif
91}
92
93//
94// END: functions only used in child process
95//
96
97
98extern "C" {
99 #include <sys/types.h>
100 #include <sys/stat.h>
101 #include <fcntl.h>
102 #include <unistd.h>
103}
104
105#ifdef SUBCASE_ISOLATION
106
107 #define x(s) s
108 #define TRYREAD_FUNCTION x(tryread_ ## x(SUBCASE_ISOLATION))
109
110 #define MK_TRYREAD_FUNCTION(x) tryread_ ## x
111
112 #define _MAKEDATA(n) tryread_ ## n
113 #define MAKEDATA(n) _MAKEDATA(n)
114
115 int main() {
116 subcaseHarness( MAKEDATA(SUBCASE_ISOLATION) );
117 }
118
119#else
120 #define xstr(s) str(s)
121 #define str(s) #s
122
123 #include "../meta/fork+exec.hfa"
124
125 void forkJoinSubcase( void (*tryread)(size_t, char*), const char* subcase_name, const char* aux_in_fname ) {
126 printf("--- %s ---\n", subcase_name);
127 int aux_in_fd = open(aux_in_fname, 0);
128 if( aux_in_fd < 0 ) {
129 printf("Failed to open file: %s\n", aux_in_fname);
130 exit(1);
131 }
132 if ( pid_t child_pid = strict_fork() ) {
133 // in parent
134 do_wait(child_pid);
135 } else {
136 // in child
137 dup2(aux_in_fd, 0); // make stdin pull from aux
138 subcaseHarness( tryread );
139 exit(0);
140 }
141 }
142
[406c806]143 #define SUBCASE_( TRYREAD_FUNCTION, IN_FILE_SLUG ) forkJoinSubcase( TRYREAD_FUNCTION, (IN_FILE_SLUG), (xstr(IN_DIR) "manipulatorsInput-uchunk." IN_FILE_SLUG ".txt") )
[efe697d]144 #define SUBCASE( MANIP, IN_FILE_SUFFIX ) SUBCASE_( tryread_ ## MANIP, #MANIP "." #IN_FILE_SUFFIX )
145
146 int main() {
147
148 SUBCASE( default, 1 );
149 SUBCASE( default, 2 );
150 SUBCASE( default, 3 );
151 SUBCASE( default, 4 );
152 SUBCASE( default, 5 );
153 SUBCASE( default, 6 );
154 SUBCASE( default, 7 );
155 SUBCASE( default, 8 );
156 SUBCASE( default, 9 );
157 SUBCASE( default, 10 );
158 SUBCASE( default, 11 );
159 SUBCASE( default, 12 );
160 SUBCASE( default, 13 );
161 SUBCASE( default, 14 );
162
163 SUBCASE( getline, 1 );
164 SUBCASE( getline, 2 );
165 SUBCASE( getline, 3 );
166 SUBCASE( getline, 4 );
167 SUBCASE( getline, 5 );
168 SUBCASE( getline, 6 );
169 SUBCASE( getline, 7 );
170 SUBCASE( getline, 8 );
171 SUBCASE( getline, 9 );
172 SUBCASE( getline, 10 );
173 SUBCASE( getline, 11 );
174 SUBCASE( getline, 12 );
175 SUBCASE( getline, 13 );
176 SUBCASE( getline, 14 );
177
178 return 0;
179 }
180
181 // not used
182 static int true_main(const char * path, const char * env[]) { return 0; }
183
184
185#endif
Note: See TracBrowser for help on using the repository browser.