source: tests/io/manipulatorsInput.cfa @ 8a33777

Last change on this file since 8a33777 was 8a33777, checked in by Michael Brooks <mlbrooks@…>, 6 months ago

Fix analysis error in string-input testing.

Add comments correlating .in file content with line of code that reads it.

This test's correctness expectation is bootstrapped from the actual behaviour of scanf.
A mistake in knowing "which character are we on at this point"
led to an inaccurate understanding of what scanf does on an edge case.
The test was showing that the CFA analogs behave the same as scanf.
But the test was not exercising the case that it suggested it was.
This issue is now fixed.

Old position, mistaken: case 14 begins on line ccccuuuucccc
Old position, corrected: cases 12/13 consume leading cccc; case 14 begins on uuuucccc
New positions: as commented in test .cfa

prior scanf understanding, mistaken: include skips unwanted characters before capturing
wanted characters, while exclude fails on unwanted characters

scanf understanding, corrected: include and exclude fail on unwanted characters

  • Property mode set to 100644
File size: 8.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// manipulatorsInput.cfa --
5//
6// Author           : Peter A. Buhr
7// Created On       : Sat Jun  8 17:58:54 2019
8// Last Modified By : Peter A. Buhr
9// Last Modified On : Wed Jan  3 11:15:04 2024
10// Update Count     : 103
11//
12
13#include <fstream.hfa>
14#include <stdio.h>                                      // scanf
15
16int main() {
17        {
18                // Upfront checks to ensure buffer safety.  Once these pass, the simpler `wdi(sizeof(s),s)`
19                // usage, as in the scanf alignment cases below, is justified.
20                struct {
21                        char buf[8];
22                        char canary;
23                } data;
24                static_assert( sizeof(data.buf) == 8 );
25                static_assert( &data.buf[8] == &data.canary );  // canary comes right after buf
26
27                void rep(const char* casename) {
28                        data.canary = 42;
29                        bool caught = false;
30                        try {
31                                sin | wdi( sizeof(data.buf), data.buf );
32                        } catch (cstring_length*) {
33                                caught = true;
34                        }
35                        printf( "%s \"%s\"", casename, data.buf );
36                        if ( caught ) {
37                                printf(", exception occurred");
38                        }
39                        if ( data.canary == 42 ) {
40                                printf(", canary ok");
41                        } else {
42                                printf(", canary overwritten to %d", data.canary);
43                        }
44                        printf("\n");
45                }
46
47                rep("pre1");    // 123456     |  123456
48                rep("pre2");    // 1234567    |  1234567
49                rep("pre3a");   // 12345678   |  1234567
50                rep("pre3b");   //            |  8
51                rep("pre4a");   // 123456789  |  1234567
52                rep("pre4b");   //            |  89
53
54                scanf("\n");  // next test does not start with %s so does not tolerate leading whitespace
55        }
56        {
57                char s[] = "yyyyyyyyyyyyyyyyyyyy";                                                     // Input characters consumed:
58                const char sk_fmt[] = "%*[abc]";
59                scanf( "abc " ); scanf( sk_fmt ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s );     // |abc |\ncccccb| \nxx\n|
60                scanf( "%s", s );                                                               printf( "2 %s\n", s );                 // |abcxxx|
61                scanf( "%*s" );                                                                 printf( "3 %s\n", s );                 // |\nabcyyy|
62                scanf( "%8s", s );                                                              printf( "4 %s\n", s );                 // |\naaaaaaaa|
63                scanf( "%*8s" );                                                                printf( "5 %s\n", s );                 // |xxxxxxxx|
64
65                scanf( "%[abc]", s );                                                   printf( "6 %s\n", s );                 // |aabbccbb|
66                scanf( "%[^abc]", s );                                                  printf( "7 %s\n", s );                 // |dddwww|
67                scanf( "%*[abc]" );                                                             printf( "8 %s\n", s );                 // |bbbbbbbb|
68                scanf( "%*[^abc]" );                                                    printf( "9 %s\n", s );                 // |wwwwwwww|
69                scanf( "%8[abc]", s );                                                  printf( "10 %s\n", s );                // |aaaaaaaa|
70                scanf( "%8[^abc]", s );                                                 printf( "11 %s\n", s );                // |wwwwwwww|
71                scanf( "%*8[abc]" );                                                    printf( "12 %s\n", s );                // |aaaaaaaa|
72                scanf( "%*8[^abc]" );                                                   printf( "13 %s\n", s );                // |wwwwwwww|
73                scanf( "\n" );                                                                  // must start next line                // |\n|
74
75                int rc;
76                s[0] = 'q'; s[1] = '\0'; rc = 99;
77                rc = scanf( "%[abc]", s );                                              printf( "14 rc=%d, %s\n", rc, s );     // ||
78                s[0] = 'q'; s[1] = '\0'; rc = 99;
79                rc = scanf( "%[^u]", s );                                               printf( "15 rc=%d, %s\n", rc, s );     // ||
80                scanf( "%*[u]\n" );                                                                    // |uuuuu\n|
81                scanf( "%[^\n]\n", s );                                                 printf( "16 %s\n", s );                // |get this line\n|
82                scanf( "%[^%%]%%\n", s );                                               printf( "17 %s\n", s );                // |@# this line 1)-{}%\n|
83
84                scanf( "%*[ \f\n\r\t\v]" );                                             // ignore whitespace                   // ||
85                scanf( "\"%[^\"]\"", s );                                               printf( "18 %s\n", s );                // |"abc"|
86                scanf( "%*[ \f\n\r\t\v]" );                                             // ignore whitespace                   // |\n|
87                scanf( "'%[^']'", s );                                                  printf( "19 %s\n", s );                // |'abc  '|
88                scanf( "%*[ \f\n\r\t\v]" );                                             // ignore whitespace                   // |\n|
89                scanf( "{%[^}]}", s );                                                  printf( "20 %s\n", s );                // |{ d d\n\nd }|
90                scanf( "%*[ \f\n\r\t\v]" );                                             // ignore whitespace                   // |\n|
91                scanf( "X%[^Y]Y", s );                                                  printf( "21 %s\n", s );                // |X            ZC44%Y|
92                scanf( "\n" );                                                                  // must start next line                // |\n|
93        }
94        {
95                char s[] = "yyyyyyyyyyyyyyyyyyyy";
96                char sk[] = "abc";
97                sin | "abc " | skip( sk ) | skip( 5 );                  sout | "1" | s;
98                sin | wdi( sizeof(s), s );                                              sout | "2" | s;
99                sin | ignore( s );                                                              sout | "3" | s;
100                sin | wdi( sizeof(s), 8, s );                                   sout | "4" | s;
101                sin | ignore( wdi( sizeof(s), 8, s ) );                 sout | "5" | s;
102
103                sin | incl( "abc", wdi( sizeof(s), s ) );               sout | "6" | s;
104                sin | excl( "abc", wdi( sizeof(s), s ) );               sout | "7" | s;
105                sin | ignore( incl( "abc", wdi( sizeof(s), s ) ) ); sout | "8" | s;
106                sin | ignore( excl( "abc", wdi( sizeof(s), s ) ) ); sout | "9" | s;
107                sin | incl( "abc", wdi( sizeof(s), 8, s ) );    sout | "10" | s;
108                sin | excl( "abc", wdi( sizeof(s), 8, s ) );    sout | "11" | s;
109                sin | ignore( incl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "12" | s;
110                sin | ignore( excl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "13" | s;
111                sin | "\n";
112
113                s[0] = 'q'; s[1] = '\0';
114                sin | incl( "abc", wdi( sizeof(s), s ) );               sout | "14" | s;
115                s[0] = 'q'; s[1] = '\0';
116                sin | excl( "u", wdi( sizeof(s), s ) );                 sout | "15" | s;
117                sin | skip( "u" ) | "\n";
118                sin | getline( wdi( sizeof(s), s ) );                   sout | "16" | s;
119                sin | getline( wdi( sizeof(s), s ), '%' ) | "\n"; sout | "17" | s;
120
121                sin | quoted( wdi( sizeof(s), s ) );                    sout | "18" | s;
122                sin | quoted( wdi( sizeof(s), s ), '\'' );              sout | "19" | s;
123                sin | quoted( wdi( sizeof(s), s ), '{', '}' );  sout | "20" | s;
124                sin | quoted( wdi( sizeof(s), s ), 'X', 'Y' );  sout | "21" | s;
125        }
126    // Keep harmonized with collections/string-istream-manip
127        {
128                char c;
129                sin | c;                                                                                sout | c;
130                sin | ignore( c );                                                              sout | c;
131
132                signed char sc;
133                sin | sc;                                                                               sout | sc;
134                sin | wdi( 3, sc );                                                             sout | sc;
135                sin | ignore( sc );                                                             sout | sc;
136                sin | ignore( wdi( 3, sc ) );                                   sout | sc;
137
138                unsigned char usc;
139                sin | usc;                                                                              sout | usc;
140                sin | wdi( 3, usc );                                                    sout | usc;
141                sin | ignore( usc );                                                    sout | usc;
142                sin | ignore( wdi( 3, usc ) );                                  sout | usc;
143
144                signed short int ssi;
145                sin | ssi;                                                                              sout | ssi;
146                sin | wdi( 3, ssi );                                                    sout | ssi;
147                sin | ignore( ssi );                                                    sout | ssi;
148                sin | ignore( wdi( 3, ssi ) );                                  sout | ssi;
149
150                unsigned short int usi;
151                sin | usi;                                                                              sout | usi;
152                sin | wdi( 3, usi );                                                    sout | usi;
153                sin | ignore( usi );                                                    sout | usi;
154                sin | ignore( wdi( 3, usi ) );                                  sout | usi;
155
156                signed int si;
157                sin | si;                                                                               sout | si;
158                sin | wdi( 3, si );                                                             sout | si;
159                sin | ignore( si );                                                             sout | si;
160                sin | ignore( wdi( 3, si ) );                                   sout | si;
161
162                unsigned int ui;
163                sin | ui;                                                                               sout | ui;
164                sin | wdi( 3, ui );                                                             sout | ui;
165                sin | ignore( ui );                                                             sout | ui;
166                sin | ignore( wdi( 3, ui ) );                                   sout | ui;
167
168                signed long int sli;
169                sin | sli;                                                                              sout | sli;
170                sin | wdi( 3, sli );                                                    sout | sli;
171                sin | ignore( sli );                                                    sout | sli;
172                sin | ignore( wdi( 3, sli ) );                                  sout | sli;
173
174                unsigned long int uli;
175                sin | uli;                                                                              sout | uli;
176                sin | wdi( 3, uli );                                                    sout | uli;
177                sin | ignore( uli );                                                    sout | uli;
178                sin | ignore( wdi( 3, uli ) );                                  sout | uli;
179
180                signed long long int slli;
181                sin | slli;                                                                             sout | slli;
182                sin | wdi( 3, slli );                                                   sout | slli;
183                sin | ignore( slli );                                                   sout | slli;
184                sin | ignore( wdi( 3, slli ) );                                 sout | slli;
185
186                unsigned long long int ulli;
187                sin | ulli;                                                                             sout | ulli;
188                sin | wdi( 3, ulli );                                                   sout | ulli;
189                sin | ignore( ulli );                                                   sout | ulli;
190                sin | ignore( wdi( 3, ulli ) );                                 sout | ulli;
191
192                float f;
193                sin | f;                                                                                sout | f;
194                sin | wdi( 8, f );                                                              sout | f;
195                sin | ignore( f );                                                              sout | f;
196                sin | ignore( wdi( 8, f ) );                                    sout | f;
197
198                double d;
199                sin | d;                                                                                sout | d;
200                sin | wdi( 8, d );                                                              sout | d;
201                sin | ignore( d );                                                              sout | d;
202                sin | ignore( wdi( 8, d ) );                                    sout | d;
203
204                long double ld;
205                sin | ld;                                                                               sout | ld;
206                sin | wdi( 8, ld );                                                             sout | ld;
207                sin | ignore( ld );                                                             sout | ld;
208                sin | ignore( wdi( 8, ld ) );                                   sout | ld;
209
210                float _Complex fc;
211                sin | fc;                                                                               sout | fc;
212                sin | wdi( 8, fc );                                                             sout | fc;
213                sin | ignore( fc );                                                             sout | fc;
214                sin | ignore( wdi( 8, fc ) );                                   sout | fc;
215
216                double _Complex dc;
217                sin | dc;                                                                               sout | dc;
218                sin | wdi( 8, dc );                                                             sout | dc;
219                sin | ignore( dc );                                                             sout | dc;
220                sin | ignore( wdi( 8, dc ) );                                   sout | dc;
221
222                long double _Complex ldc;
223                sin | ldc;                                                                              sout | ldc;
224                sin | wdi( 8, ldc );                                                    sout | ldc;
225                sin | ignore( ldc );                                                    sout | ldc;
226                sin | ignore( wdi( 8, ldc ) );                                  sout | ldc;
227        }
228        #if defined( __SIZEOF_INT128__ )
229        {
230                int128 val;
231                for ( 15 ) {
232                        sin | val;
233                        sout | val;
234                }
235        }
236        #endif // __SIZEOF_INT128__
237} // main
238
239// Local Variables: //
240// tab-width: 4 //
241// compile-command: "cfa -Wall -Wextra manipulatorsInput.cfa" //
242// End: //
Note: See TracBrowser for help on using the repository browser.