]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testfile.c
Full sweep of all Clang warnings, plus some bug fixes for incorrect memcpy usage.
[thirdparty/cups.git] / cups / testfile.c
CommitLineData
ef416fc2 1/*
f2d18633 2 * "$Id$"
ef416fc2 3 *
7e86f2f6 4 * File test program for CUPS.
ef416fc2 5 *
7e86f2f6
MS
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products.
ef416fc2 8 *
7e86f2f6
MS
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
7e86f2f6 15 * This file is subject to the Apple OS-Developed Software exception.
ef416fc2 16 */
17
18/*
19 * Include necessary headers...
20 */
21
71e16022
MS
22#include "string-private.h"
23#include "debug-private.h"
24#include "file.h"
ef416fc2 25#include <stdlib.h>
ef416fc2 26#include <time.h>
b423cd4c 27#ifdef HAVE_LIBZ
28# include <zlib.h>
29#endif /* HAVE_LIBZ */
536bc2c6
MS
30#ifdef WIN32
31# include <io.h>
32#else
33# include <unistd.h>
34#endif /* WIN32 */
ae71f5de 35#include <fcntl.h>
ef416fc2 36
37
38/*
39 * Local functions...
40 */
41
c9fc04c6 42static int count_lines(cups_file_t *fp);
634763e8 43static int random_tests(void);
ef416fc2 44static int read_write_tests(int compression);
45
46
47/*
48 * 'main()' - Main entry.
49 */
50
51int /* O - Exit status */
52main(int argc, /* I - Number of command-line arguments */
53 char *argv[]) /* I - Command-line arguments */
54{
ae71f5de
MS
55 int status; /* Exit status */
56 char filename[1024]; /* Filename buffer */
c9fc04c6 57 cups_file_t *fp; /* File pointer */
7a0cbd5e 58#ifndef WIN32
ae71f5de
MS
59 int fds[2]; /* Open file descriptors */
60 cups_file_t *fdfile; /* File opened with cupsFileOpenFd() */
7a0cbd5e 61#endif /* !WIN32 */
c9fc04c6 62 int count; /* Number of lines in file */
ef416fc2 63
64
fa73b229 65 if (argc == 1)
66 {
67 /*
68 * Do uncompressed file tests...
69 */
ef416fc2 70
fa73b229 71 status = read_write_tests(0);
ef416fc2 72
73#ifdef HAVE_LIBZ
fa73b229 74 /*
75 * Do compressed file tests...
76 */
ef416fc2 77
fa73b229 78 putchar('\n');
ef416fc2 79
fa73b229 80 status += read_write_tests(1);
ef416fc2 81#endif /* HAVE_LIBZ */
82
634763e8
MS
83 /*
84 * Do uncompressed random I/O tests...
85 */
86
1f0275e3 87 status += random_tests();
634763e8 88
7a0cbd5e 89#ifndef WIN32
ae71f5de
MS
90 /*
91 * Test fdopen and close without reading...
92 */
93
94 pipe(fds);
95 close(fds[1]);
96
634763e8 97 fputs("\ncupsFileOpenFd(fd, \"r\"): ", stdout);
ae71f5de
MS
98 fflush(stdout);
99
100 if ((fdfile = cupsFileOpenFd(fds[0], "r")) == NULL)
101 {
102 puts("FAIL");
103 status ++;
104 }
105 else
106 {
107 /*
108 * Able to open file, now close without reading. If we don't return
109 * before the alarm fires, that is a failure and we will crash on the
110 * alarm signal...
111 */
112
113 puts("PASS");
114 fputs("cupsFileClose(no read): ", stdout);
115 fflush(stdout);
116
117 alarm(5);
118 cupsFileClose(fdfile);
119 alarm(0);
120
121 puts("PASS");
122 }
7a0cbd5e 123#endif /* !WIN32 */
ae71f5de 124
c9fc04c6 125 /*
c7017ecc 126 * Count lines in psglyphs, rewind, then count again.
c9fc04c6
MS
127 */
128
a4845881 129 fputs("\ncupsFileOpen(\"../data/media.defs\", \"r\"): ", stdout);
c9fc04c6 130
a4845881 131 if ((fp = cupsFileOpen("../data/media.defs", "r")) == NULL)
c9fc04c6
MS
132 {
133 puts("FAIL");
134 status ++;
135 }
136 else
137 {
138 puts("PASS");
139 fputs("cupsFileGets: ", stdout);
140
a4845881 141 if ((count = count_lines(fp)) != 208)
c9fc04c6 142 {
a4845881 143 printf("FAIL (got %d lines, expected 208)\n", count);
c9fc04c6
MS
144 status ++;
145 }
146 else
147 {
148 puts("PASS");
149 fputs("cupsFileRewind: ", stdout);
150
151 if (cupsFileRewind(fp) != 0)
152 {
153 puts("FAIL");
154 status ++;
155 }
156 else
157 {
158 puts("PASS");
159 fputs("cupsFileGets: ", stdout);
160
a4845881 161 if ((count = count_lines(fp)) != 208)
c9fc04c6 162 {
a4845881 163 printf("FAIL (got %d lines, expected 208)\n", count);
c9fc04c6
MS
164 status ++;
165 }
166 else
167 puts("PASS");
168 }
169 }
170
171 cupsFileClose(fp);
172 }
173
fa73b229 174 /*
175 * Test path functions...
176 */
177
634763e8 178 fputs("\ncupsFileFind: ", stdout);
b86bc4cf 179#ifdef WIN32
180 if (cupsFileFind("notepad.exe", "C:/WINDOWS", 1, filename, sizeof(filename)) &&
181 cupsFileFind("notepad.exe", "C:/WINDOWS;C:/WINDOWS/SYSTEM32", 1, filename, sizeof(filename)))
182#else
4400e98d 183 if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) &&
184 cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename)))
b86bc4cf 185#endif /* WIN32 */
fa73b229 186 printf("PASS (%s)\n", filename);
187 else
188 {
189 puts("FAIL");
190 status ++;
191 }
ef416fc2 192
fa73b229 193 /*
194 * Summarize the results and return...
195 */
196
197 if (!status)
198 puts("\nALL TESTS PASSED!");
199 else
200 printf("\n%d TEST(S) FAILED!\n", status);
201 }
ef416fc2 202 else
fa73b229 203 {
204 /*
205 * Cat the filename on the command-line...
206 */
207
fa73b229 208 char line[1024]; /* Line from file */
209
fa73b229 210 if ((fp = cupsFileOpen(argv[1], "r")) == NULL)
211 {
212 perror(argv[1]);
213 status = 1;
214 }
215 else
216 {
217 status = 0;
218
219 while (cupsFileGets(fp, line, sizeof(line)))
220 puts(line);
221
222 if (!cupsFileEOF(fp))
223 perror(argv[1]);
224
225 cupsFileClose(fp);
226 }
227 }
ef416fc2 228
229 return (status);
230}
231
232
c9fc04c6
MS
233/*
234 * 'count_lines()' - Count the number of lines in a file.
235 */
236
237static int /* O - Number of lines */
238count_lines(cups_file_t *fp) /* I - File to read from */
239{
240 int count; /* Number of lines */
241 char line[1024]; /* Line buffer */
242
243
244 for (count = 0; cupsFileGets(fp, line, sizeof(line)); count ++);
245
246 return (count);
247}
248
249
634763e8
MS
250/*
251 * 'random_tests()' - Do random access tests.
252 */
253
254static int /* O - Status */
255random_tests(void)
256{
257 int status, /* Status of tests */
258 pass, /* Current pass */
259 count, /* Number of records read */
260 record, /* Current record */
261 num_records; /* Number of records */
7e86f2f6
MS
262 off_t pos; /* Position in file */
263 ssize_t expected; /* Expected position in file */
634763e8
MS
264 cups_file_t *fp; /* File */
265 char buffer[512]; /* Data buffer */
266
267
268 /*
269 * Run 4 passes, each time appending to a data file and then reopening the
270 * file for reading to validate random records in the file.
271 */
272
273 for (status = 0, pass = 0; pass < 4; pass ++)
274 {
275 /*
276 * cupsFileOpen(append)
277 */
278
279 printf("\ncupsFileOpen(append %d): ", pass);
280
281 if ((fp = cupsFileOpen("testfile.dat", "a")) == NULL)
282 {
283 printf("FAIL (%s)\n", strerror(errno));
284 status ++;
285 break;
286 }
287 else
288 puts("PASS");
289
290 /*
291 * cupsFileTell()
292 */
293
7e86f2f6 294 expected = 256 * (ssize_t)sizeof(buffer) * pass;
634763e8
MS
295
296 fputs("cupsFileTell(): ", stdout);
7e86f2f6 297 if ((pos = cupsFileTell(fp)) != (off_t)expected)
634763e8
MS
298 {
299 printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n",
300 CUPS_LLCAST pos, CUPS_LLCAST expected);
301 status ++;
302 break;
303 }
304 else
305 puts("PASS");
306
307 /*
308 * cupsFileWrite()
309 */
310
311 fputs("cupsFileWrite(256 512-byte records): ", stdout);
312 for (record = 0; record < 256; record ++)
313 {
314 memset(buffer, record, sizeof(buffer));
7e86f2f6 315 if (cupsFileWrite(fp, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer))
634763e8
MS
316 break;
317 }
318
319 if (record < 256)
320 {
321 printf("FAIL (%d: %s)\n", record, strerror(errno));
322 status ++;
323 break;
324 }
325 else
326 puts("PASS");
327
328 /*
329 * cupsFileTell()
330 */
331
7e86f2f6 332 expected += 256 * (ssize_t)sizeof(buffer);
634763e8
MS
333
334 fputs("cupsFileTell(): ", stdout);
7e86f2f6 335 if ((pos = cupsFileTell(fp)) != (off_t)expected)
634763e8
MS
336 {
337 printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n",
338 CUPS_LLCAST pos, CUPS_LLCAST expected);
339 status ++;
340 break;
341 }
342 else
343 puts("PASS");
344
345 cupsFileClose(fp);
346
347 /*
348 * cupsFileOpen(read)
349 */
350
351 printf("\ncupsFileOpen(read %d): ", pass);
352
353 if ((fp = cupsFileOpen("testfile.dat", "r")) == NULL)
354 {
355 printf("FAIL (%s)\n", strerror(errno));
356 status ++;
357 break;
358 }
359 else
360 puts("PASS");
361
362 /*
363 * cupsFileSeek, cupsFileRead
364 */
365
366 fputs("cupsFileSeek(), cupsFileRead(): ", stdout);
367
7e86f2f6 368 for (num_records = (pass + 1) * 256, count = (pass + 1) * 256, record = ((int)CUPS_RAND() & 65535) % num_records;
634763e8 369 count > 0;
7e86f2f6 370 count --, record = (record + ((int)CUPS_RAND() & 31) - 16 + num_records) % num_records)
634763e8
MS
371 {
372 /*
373 * The last record is always the first...
374 */
375
376 if (count == 1)
377 record = 0;
378
379 /*
380 * Try reading the data for the specified record, and validate the
381 * contents...
382 */
383
7e86f2f6 384 expected = (ssize_t)sizeof(buffer) * record;
634763e8
MS
385
386 if ((pos = cupsFileSeek(fp, expected)) != expected)
387 {
388 printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n",
389 CUPS_LLCAST pos, CUPS_LLCAST expected);
390 status ++;
391 break;
392 }
393 else
394 {
395 if (cupsFileRead(fp, buffer, sizeof(buffer)) != sizeof(buffer))
396 {
397 printf("FAIL (%s)\n", strerror(errno));
398 status ++;
399 break;
400 }
401 else if ((buffer[0] & 255) != (record & 255) ||
402 memcmp(buffer, buffer + 1, sizeof(buffer) - 1))
403 {
404 printf("FAIL (Bad Data - %d instead of %d)\n", buffer[0] & 255,
405 record & 255);
406 status ++;
407 break;
408 }
409 }
410 }
411
412 if (count == 0)
413 puts("PASS");
414
415 cupsFileClose(fp);
416 }
417
418 /*
419 * Remove the test file...
420 */
421
422 unlink("testfile.dat");
88f9aafc 423
634763e8
MS
424 /*
425 * Return the test status...
426 */
427
428 return (status);
429}
430
431
ef416fc2 432/*
433 * 'read_write_tests()' - Perform read/write tests.
434 */
435
436static int /* O - Status */
437read_write_tests(int compression) /* I - Use compression? */
438{
439 int i; /* Looping var */
634763e8 440 cups_file_t *fp; /* File */
ef416fc2 441 int status; /* Exit status */
442 char line[1024], /* Line from file */
443 *value; /* Directive value from line */
444 int linenum; /* Line number */
445 unsigned char readbuf[8192], /* Read buffer */
446 writebuf[8192]; /* Write buffer */
447 int byte; /* Byte from file */
7e86f2f6 448 ssize_t bytes; /* Number of bytes read/written */
634763e8 449 off_t length; /* Length of file */
c277e2f8
MS
450 static const char *partial_line = "partial line";
451 /* Partial line */
ef416fc2 452
453
454 /*
455 * No errors so far...
456 */
457
458 status = 0;
459
460 /*
461 * Initialize the write buffer with random data...
462 */
463
7cf5915e 464 CUPS_SRAND((unsigned)time(NULL));
b86bc4cf 465
ef416fc2 466 for (i = 0; i < (int)sizeof(writebuf); i ++)
7e86f2f6 467 writebuf[i] = (unsigned char)CUPS_RAND();
ef416fc2 468
469 /*
470 * cupsFileOpen(write)
471 */
472
473 printf("cupsFileOpen(write%s): ", compression ? " compressed" : "");
474
475 fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat",
476 compression ? "w9" : "w");
477 if (fp)
478 {
479 puts("PASS");
480
481 /*
482 * cupsFileCompression()
483 */
484
485 fputs("cupsFileCompression(): ", stdout);
486
487 if (cupsFileCompression(fp) == compression)
488 puts("PASS");
489 else
490 {
491 printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp),
492 compression);
493 status ++;
494 }
495
496 /*
497 * cupsFilePuts()
498 */
499
500 fputs("cupsFilePuts(): ", stdout);
501
502 if (cupsFilePuts(fp, "# Hello, World\n") > 0)
503 puts("PASS");
504 else
505 {
506 printf("FAIL (%s)\n", strerror(errno));
507 status ++;
508 }
509
510 /*
511 * cupsFilePrintf()
512 */
513
514 fputs("cupsFilePrintf(): ", stdout);
515
516 for (i = 0; i < 1000; i ++)
634763e8 517 if (cupsFilePrintf(fp, "TestLine %03d\n", i) < 0)
ef416fc2 518 break;
519
520 if (i >= 1000)
521 puts("PASS");
522 else
523 {
524 printf("FAIL (%s)\n", strerror(errno));
525 status ++;
526 }
527
528 /*
529 * cupsFilePutChar()
530 */
531
532 fputs("cupsFilePutChar(): ", stdout);
533
534 for (i = 0; i < 256; i ++)
535 if (cupsFilePutChar(fp, i) < 0)
536 break;
537
538 if (i >= 256)
539 puts("PASS");
540 else
541 {
542 printf("FAIL (%s)\n", strerror(errno));
543 status ++;
544 }
545
546 /*
547 * cupsFileWrite()
548 */
549
550 fputs("cupsFileWrite(): ", stdout);
551
c277e2f8 552 for (i = 0; i < 10000; i ++)
ef416fc2 553 if (cupsFileWrite(fp, (char *)writebuf, sizeof(writebuf)) < 0)
554 break;
555
c277e2f8
MS
556 if (i >= 10000)
557 puts("PASS");
558 else
559 {
560 printf("FAIL (%s)\n", strerror(errno));
561 status ++;
562 }
563
564 /*
565 * cupsFilePuts() with partial line...
566 */
567
568 fputs("cupsFilePuts(\"partial line\"): ", stdout);
569
570 if (cupsFilePuts(fp, partial_line) > 0)
ef416fc2 571 puts("PASS");
572 else
573 {
574 printf("FAIL (%s)\n", strerror(errno));
575 status ++;
576 }
577
634763e8
MS
578 /*
579 * cupsFileTell()
580 */
581
582 fputs("cupsFileTell(): ", stdout);
583
584 if ((length = cupsFileTell(fp)) == 81933283)
585 puts("PASS");
586 else
587 {
588 printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length);
589 status ++;
590 }
591
ef416fc2 592 /*
593 * cupsFileClose()
594 */
595
596 fputs("cupsFileClose(): ", stdout);
597
598 if (!cupsFileClose(fp))
599 puts("PASS");
600 else
601 {
602 printf("FAIL (%s)\n", strerror(errno));
603 status ++;
604 }
605 }
606 else
607 {
608 printf("FAIL (%s)\n", strerror(errno));
609 status ++;
610 }
611
612 /*
613 * cupsFileOpen(read)
614 */
615
634763e8 616 fputs("\ncupsFileOpen(read): ", stdout);
ef416fc2 617
618 fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat", "r");
619 if (fp)
620 {
621 puts("PASS");
622
623 /*
624 * cupsFileGets()
625 */
626
627 fputs("cupsFileGets(): ", stdout);
628
629 if (cupsFileGets(fp, line, sizeof(line)))
630 {
631 if (line[0] == '#')
632 puts("PASS");
633 else
634 {
635 printf("FAIL (Got line \"%s\", expected comment line)\n", line);
636 status ++;
637 }
638 }
639 else
640 {
641 printf("FAIL (%s)\n", strerror(errno));
642 status ++;
643 }
644
645 /*
646 * cupsFileCompression()
647 */
648
649 fputs("cupsFileCompression(): ", stdout);
650
651 if (cupsFileCompression(fp) == compression)
652 puts("PASS");
653 else
654 {
655 printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp),
656 compression);
657 status ++;
658 }
659
660 /*
661 * cupsFileGetConf()
662 */
663
664 linenum = 1;
665
666 fputs("cupsFileGetConf(): ", stdout);
667
7e86f2f6 668 for (i = 0, value = NULL; i < 1000; i ++)
ef416fc2 669 if (!cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
670 break;
88f9aafc 671 else if (_cups_strcasecmp(line, "TestLine") || !value || atoi(value) != i ||
ef416fc2 672 linenum != (i + 2))
673 break;
674
675 if (i >= 1000)
676 puts("PASS");
677 else if (line[0])
678 {
679 printf("FAIL (Line %d, directive \"%s\", value \"%s\")\n", linenum,
680 line, value ? value : "(null)");
681 status ++;
682 }
683 else
684 {
685 printf("FAIL (%s)\n", strerror(errno));
686 status ++;
687 }
688
689 /*
b86bc4cf 690 * cupsFileGetChar()
ef416fc2 691 */
692
b86bc4cf 693 fputs("cupsFileGetChar(): ", stdout);
694
7e86f2f6 695 for (i = 0, byte = 0; i < 256; i ++)
ef416fc2 696 if ((byte = cupsFileGetChar(fp)) != i)
697 break;
698
699 if (i >= 256)
700 puts("PASS");
701 else if (byte >= 0)
702 {
703 printf("FAIL (Got %d, expected %d)\n", byte, i);
704 status ++;
705 }
706 else
707 {
708 printf("FAIL (%s)\n", strerror(errno));
709 status ++;
710 }
711
712 /*
713 * cupsFileRead()
714 */
715
716 fputs("cupsFileRead(): ", stdout);
717
7e86f2f6
MS
718 for (i = 0, bytes = 0; i < 10000; i ++)
719 if ((bytes = cupsFileRead(fp, (char *)readbuf, sizeof(readbuf))) < 0)
ef416fc2 720 break;
721 else if (memcmp(readbuf, writebuf, sizeof(readbuf)))
722 break;
723
c277e2f8 724 if (i >= 10000)
ef416fc2 725 puts("PASS");
7e86f2f6 726 else if (bytes > 0)
ef416fc2 727 {
728 printf("FAIL (Pass %d, ", i);
729
730 for (i = 0; i < (int)sizeof(readbuf); i ++)
731 if (readbuf[i] != writebuf[i])
732 break;
733
734 printf("match failed at offset %d - got %02X, expected %02X)\n",
735 i, readbuf[i], writebuf[i]);
736 }
737 else
738 {
739 printf("FAIL (%s)\n", strerror(errno));
740 status ++;
741 }
742
c277e2f8
MS
743 /*
744 * cupsFileGetChar() with partial line...
745 */
746
747 fputs("cupsFileGetChar(partial line): ", stdout);
748
7a0cbd5e 749 for (i = 0; i < (int)strlen(partial_line); i ++)
c277e2f8
MS
750 if ((byte = cupsFileGetChar(fp)) < 0)
751 break;
752 else if (byte != partial_line[i])
753 break;
754
755 if (!partial_line[i])
756 puts("PASS");
757 else
758 {
759 printf("FAIL (got '%c', expected '%c')\n", byte, partial_line[i]);
760 status ++;
761 }
762
634763e8
MS
763 /*
764 * cupsFileTell()
765 */
766
767 fputs("cupsFileTell(): ", stdout);
768
769 if ((length = cupsFileTell(fp)) == 81933283)
770 puts("PASS");
771 else
772 {
773 printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length);
774 status ++;
775 }
776
ef416fc2 777 /*
778 * cupsFileClose()
779 */
780
781 fputs("cupsFileClose(): ", stdout);
782
783 if (!cupsFileClose(fp))
784 puts("PASS");
785 else
786 {
787 printf("FAIL (%s)\n", strerror(errno));
788 status ++;
789 }
790 }
791 else
792 {
793 printf("FAIL (%s)\n", strerror(errno));
794 status ++;
795 }
796
634763e8
MS
797 /*
798 * Remove the test file...
799 */
800
801 unlink(compression ? "testfile.dat.gz" : "testfile.dat");
88f9aafc 802
ef416fc2 803 /*
804 * Return the test status...
805 */
806
807 return (status);
808}
809
810
811/*
f2d18633 812 * End of "$Id$".
ef416fc2 813 */