Updated test program.
[reactos.git] / reactos / apps / testsets / msvcrt / fileio / _tfileio.c
1 /*
2 * ReactOS test program -
3 *
4 * _tfileio.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #define WIN32_LEAN_AND_MEAN
24 #include <windows.h>
25 #include <tchar.h>
26 #include <wchar.h>
27 #include <stdio.h>
28
29
30 #ifdef UNICODE
31 #define _tfopen _wfopen
32 #define _tunlink _wunlink
33 #define _TEOF WEOF
34 #define _gettchar getwchar
35 #define _puttchar putwchar
36 #define _THEX_FORMAT _T("0x%04x ")
37 #else /*UNICODE*/
38 #define _tfopen fopen
39 #define _tunlink _unlink
40 #define _TEOF EOF
41 #define _gettchar getchar
42 #define _puttchar putchar
43 #define _THEX_FORMAT "0x%02x "
44 #endif /*UNICODE*/
45
46
47 #define TEST_BUFFER_SIZE 200
48 #define TEST_FILE_LINES 4
49
50 extern BOOL verbose_flagged;
51 extern BOOL status_flagged;
52
53 static TCHAR test_buffer[TEST_BUFFER_SIZE];
54
55 static TCHAR dos_data[] = _T("line1: this is a bunch of readable text.\r\n")\
56 _T("line2: some more printable text and punctuation !@#$%^&*()\r\n")\
57 _T("line3: followed up with some numerals 1234567890\r\n")\
58 _T("line4: done.\r\n");
59
60 static TCHAR nix_data[] = _T("line1: this is a bunch of readable text.\n")\
61 _T("line2: some more printable text and punctuation !@#$%^&*()\n")\
62 _T("line3: followed up with some numerals 1234567890\n")\
63 _T("line4: done.\n");
64
65 #ifdef UNICODE
66 #define TEST_B1_FILE_SIZE ((((sizeof(dos_data)/2)-1)+TEST_FILE_LINES)/2) // (166+4)/2=85
67 #define TEST_B2_FILE_SIZE (((sizeof(dos_data)/2)-1)*2) // (166*2) =332
68 #define TEST_B3_FILE_SIZE ((((sizeof(nix_data)/2)-1)+TEST_FILE_LINES)/2) // (162+4)/2=83
69 #define TEST_B4_FILE_SIZE (((sizeof(nix_data)/2)-1)*2) // (162*2) =324
70 #else /*UNICODE*/
71 #define TEST_B1_FILE_SIZE (sizeof(dos_data)-1+TEST_FILE_LINES) // (166+4)=170
72 #define TEST_B2_FILE_SIZE (sizeof(dos_data)-1-TEST_FILE_LINES) // (166-4)=162
73 #define TEST_B3_FILE_SIZE (sizeof(nix_data)-1+TEST_FILE_LINES) // (162+4)=166
74 #define TEST_B4_FILE_SIZE (sizeof(nix_data)-1) // (162) =162
75 #endif /*UNICODE*/
76
77
78 static BOOL create_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data)
79 {
80 BOOL result = FALSE;
81 FILE *file = _tfopen(file_name, file_mode);
82 if (file != NULL) {
83 if (_fputts(file_data, file) != _TEOF) {
84 result = TRUE;
85 } else {
86 _tprintf(_T("ERROR: failed to write data to file \"%s\"\n"), file_name);
87 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
88 }
89 fclose(file);
90 } else {
91 _tprintf(_T("ERROR: failed to open/create file \"%s\" for output\n"), file_name);
92 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
93 }
94 return result;
95 }
96
97 static BOOL verify_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data)
98 {
99 int error_code;
100 int offset = 0;
101 int line_num = 0;
102 BOOL result = FALSE;
103 BOOL error_flagged = FALSE;
104 FILE* file = _tfopen(file_name, file_mode);
105 if (file == NULL) {
106 _tprintf(_T("ERROR: (%s) Can't open file for reading\n"), file_name);
107 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file));
108 return FALSE;
109 } else if (status_flagged) {
110 _tprintf(_T("STATUS: (%s) opened file for reading\n"), file_name);
111 }
112 while (_fgetts(test_buffer, TEST_BUFFER_SIZE, file)) {
113 int length = _tcslen(test_buffer);
114 int req_len = _tcschr(file_data+offset, _T('\n')) - (file_data+offset) + 1;
115
116 ++line_num;
117 if (length > req_len) {
118 _tprintf(_T("ERROR: read excess bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len);
119 error_flagged = TRUE;
120 break;
121 }
122 if (length < req_len) {
123 _tprintf(_T("ERROR: read to few bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len);
124 error_flagged = TRUE;
125 break;
126 }
127 if (status_flagged) {
128 _tprintf(_T("STATUS: Verifying %d bytes read from line %d\n"), length, line_num);
129 }
130 if (_tcsncmp(test_buffer, file_data+offset, length - 1) == 0) {
131 result = TRUE;
132 } else {
133 if (status_flagged) {
134 int i;
135 _tprintf(_T("WARNING: (%s) failed to verify file\n"), file_name);
136 for (i = 0; i < length; i++) {
137 if (file_data[offset+i] != test_buffer[i]) {
138 _tprintf(_T("line %d, offset %d expected: 0x%04x found: 0x%04x\n"), line_num, i, (int)file_data[offset+i], (int)test_buffer[i]);
139 }
140 }
141 _tprintf(_T("\n"));
142 } else {
143 error_flagged = TRUE;
144 }
145 }
146 offset += length;
147 }
148 error_code = ferror(file);
149 if (error_code) {
150 _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code);
151 perror("Read error");
152 }
153 if (!line_num) {
154 _tprintf(_T("ERROR: (%s) failed to read from file\n"), file_name);
155 }
156 if (error_flagged == TRUE) {
157 _tprintf(_T("ERROR: (%s) failed to verify file\n"), file_name);
158 result = FALSE;
159 }
160 fclose(file);
161 return result;
162 }
163
164 static int create_test_file(TCHAR* file_name, TCHAR* write_mode, TCHAR* read_mode, TCHAR* file_data)
165 {
166 if (status_flagged) {
167 _tprintf(_T("STATUS: Attempting to create output file %s\n"), file_name);
168 }
169 if (create_output_file(file_name, write_mode, file_data)) {
170 if (status_flagged) {
171 _tprintf(_T("STATUS: Attempting to verify output file %s\n"), file_name);
172 }
173 if (verify_output_file(file_name, read_mode, file_data)) {
174 if (status_flagged) {
175 _tprintf(_T("SUCCESS: %s verified ok\n"), file_name);
176 }
177 } else {
178 //_tprintf(_T("ERROR: failed to verify file %s\n"), file_name);
179 return 2;
180 }
181 } else {
182 _tprintf(_T("ERROR: failed to create file %s\n"), file_name);
183 return 1;
184 }
185 return 0;
186 }
187
188 static int check_file_size(TCHAR* file_name, TCHAR* file_mode, int expected)
189 {
190 int count = 0;
191 FILE* file;
192 TCHAR ch;
193 int error_code;
194
195 if (status_flagged) {
196 //_tprintf(_T("STATUS: (%s) checking for %d bytes in %s mode\n"), file_name, expected, _tcschr(file_mode, _T('b')) ? _T("binary") : _T("text"));
197 _tprintf(_T("STATUS: (%s) checking for %d bytes with mode %s\n"), file_name, expected, file_mode);
198 }
199 file = _tfopen(file_name, file_mode);
200 if (file == NULL) {
201 _tprintf(_T("ERROR: (%s) failed to open file for reading\n"), file_name);
202 return 1;
203 }
204 while ((ch = _fgettc(file)) != _TEOF) {
205 if (verbose_flagged) {
206 _tprintf(_THEX_FORMAT, ch);
207 }
208 ++count;
209 }
210 error_code = ferror(file);
211 if (error_code) {
212 _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code);
213 perror("Read error");
214 }
215
216 if (verbose_flagged) {
217 // _puttc(_T('\n'), stdout);
218 }
219 fclose(file);
220 if (count == expected) {
221 if (status_flagged) {
222 _tprintf(_T("PASSED: (%s) read %d bytes\n"), file_name, count);
223 }
224 } else {
225 _tprintf(_T("FAILED: (%s) read %d bytes but expected %d using mode \"%s\"\n"), file_name, count, expected, file_mode);
226 }
227 return (count == expected) ? 0 : -1;
228 }
229
230 static int test_console_io(void)
231 {
232 TCHAR buffer[81];
233 TCHAR ch;
234 int i, j;
235
236 _tprintf(_T("Enter a line for echoing:\n"));
237
238 //for (i = 0; (i < 80) && ((ch = _gettchar()) != _TEOF) && (ch != _T('\n')); i++) {
239 for (i = 0; (i < 80) && ((ch = _gettc(stdin)) != _TEOF) && (ch != _T('\n')); i++) {
240 buffer[i] = (TCHAR)ch;
241 }
242 buffer[i] = _T('\0');
243 for (j = 0; j < i; j++) {
244 _puttc(buffer[j], stdout);
245 }
246 _puttc(_T('\n'), stdout);
247 _tprintf(_T("%s\n"), buffer);
248 return 0;
249 }
250
251 static int test_console_getchar(void)
252 {
253 int result = 0;
254 TCHAR ch;
255
256 _tprintf(_T("Enter lines for dumping or <ctrl-z><nl> to finish:\n"));
257
258 //while ((ch = _gettchar()) != _TEOF) {
259 while ((ch = _gettc(stdin)) != _TEOF) {
260 _tprintf(_THEX_FORMAT, ch);
261 //printf("0x%04x ", ch);
262 }
263 return result;
264 }
265
266 static int test_console_putch(void)
267 {
268 int result = 0;
269
270 _putch('1');
271 _putch('@');
272 _putch('3');
273 _putch(':');
274 _putch('\n');
275 _putch('a');
276 _putch('B');
277 _putch('c');
278 _putch(':');
279 _putch('\n');
280 return result;
281 }
282
283 static int test_unlink_files(void)
284 {
285 int result = 0;
286
287 //printf("sizeof dos_data: %d\n", sizeof(dos_data));
288 //printf("sizeof nix_data: %d\n", sizeof(nix_data));
289
290 result |= _tunlink(_T("binary.dos"));
291 result |= _tunlink(_T("binary.nix"));
292 result |= _tunlink(_T("text.dos"));
293 result |= _tunlink(_T("text.nix"));
294 return result;
295 }
296
297 static int test_text_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize)
298 {
299 int result = 0;
300
301 result = create_test_file(file_name, _T("w"), _T("r"), file_data);
302 result = check_file_size(file_name, _T("r"), tsize);
303 result = check_file_size(file_name, _T("rb"), bsize);
304 return result;
305 }
306
307 static int test_binary_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize)
308 {
309 int result = 0;
310
311 result = create_test_file(file_name, _T("wb"), _T("rb"), file_data);
312 result = check_file_size(file_name, _T("r"), tsize);
313 result = check_file_size(file_name, _T("rb"), bsize);
314 return result;
315 }
316
317 static int test_files(int test_num, char* type)
318 {
319 int result = 0;
320
321 printf("performing test: %d (%s)\n", test_num, type);
322
323 switch (test_num) {
324 case 1:
325 result = test_text_fileio(_T("text.dos"), dos_data, 166, TEST_B1_FILE_SIZE);
326 break;
327 case 2:
328 result = test_binary_fileio(_T("binary.dos"), dos_data, TEST_B2_FILE_SIZE, 166);
329 break;
330 case 3:
331 result = test_text_fileio(_T("text.nix"), nix_data, 162, TEST_B3_FILE_SIZE);
332 break;
333 case 4:
334 result = test_binary_fileio(_T("binary.nix"), nix_data, TEST_B4_FILE_SIZE, 162);
335 break;
336 case 5:
337 result = test_console_io();
338 break;
339 case 6:
340 result = test_console_getchar();
341 break;
342 case 7:
343 result = test_console_putch();
344 break;
345 case -1:
346 result = test_unlink_files();
347 break;
348 default:
349 _tprintf(_T("no test number selected\n"));
350 break;
351 }
352 return result;
353 }