2 * "$Id: cupstestdsc.c 9384 2010-11-22 07:06:39Z mike $"
4 * DSC test program for CUPS.
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 2006 by Easy Software Products, all rights reserved.
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/".
15 * PostScript is a trademark of Adobe Systems, Inc.
17 * This file is subject to the Apple OS-Developed Software exception.
21 * main() - Main entry for test program.
22 * check() - Check a file for conformance.
23 * usage() - Show program usage.
27 * Include necessary headers...
30 #include <cups/cups-private.h>
37 static int check_file(const char *filename);
38 static void usage(void);
42 * 'main()' - Main entry for test program.
45 int /* O - Exit status */
46 main(int argc, /* I - Number of command-line args */
47 char *argv[]) /* I - Command-line arguments */
49 int i; /* Looping var */
50 int status; /* Status of tests */
51 int num_files; /* Number of files tested */
57 * Collect command-line arguments...
60 for (i = 1, num_files = 0, status = 0; i < argc; i ++)
61 if (argv[i][0] == '-')
66 * Currently the only supported option is "-h" (help)...
74 status += check_file("(stdin)");
80 status += check_file(argv[i]);
91 * 'check()' - Check a file for conformance.
94 static int /* O - 0 on success, 1 on failure */
95 check_file(const char *filename) /* I - File to read from */
97 int i; /* Looping var */
98 cups_file_t *fp; /* File */
99 char line[1024]; /* Line from file */
100 int ch; /* Current character */
101 size_t bytes; /* Length of line */
102 int status; /* Status of test */
103 int linenum; /* Line number */
104 int binary; /* File contains binary data? */
105 float version; /* DSC version */
106 int lbrt[4]; /* Bounding box */
107 char page_label[256]; /* Page label string */
108 int page_number; /* Page number */
109 int last_page_number; /* Last page number seen */
110 int level; /* Embedded document level */
111 int saw_bounding_box, /* %%BoundingBox seen? */
112 saw_pages, /* %%Pages seen? */
113 saw_end_comments, /* %%EndComments seen? */
114 saw_begin_prolog, /* %%BeginProlog seen? */
115 saw_end_prolog, /* %%EndProlog seen? */
116 saw_begin_setup, /* %%BeginSetup seen? */
117 saw_end_setup, /* %%EndSetup seen? */
118 saw_page, /* %%Page seen? */
119 saw_trailer, /* %%Trailer seen? */
120 saw_long_line; /* Saw long lines? */
127 if (!strcmp(filename, "(stdin)"))
128 fp = cupsFileStdin();
130 fp = cupsFileOpen(filename, "r");
143 last_page_number = 0;
146 saw_begin_prolog = 0;
148 saw_bounding_box = 0;
149 saw_end_comments = 0;
160 printf("%s: ", filename);
163 while ((bytes = cupsFileGetLine(fp, line, sizeof(line))) > 0)
172 _cupsLangPuts(stdout, _("FAIL"));
175 _cupsLangPrintf(stdout,
176 _(" Line %d is longer than 255 characters (%d).\n"
177 " REF: Page 25, Line Length"),
178 linenum, (int)bytes);
186 if (strncmp(line, "%!PS-Adobe-", 11))
189 _cupsLangPuts(stdout, _("FAIL"));
191 _cupsLangPuts(stdout,
192 _(" Missing %!PS-Adobe-3.0 on first line.\n"
193 " REF: Page 17, 3.1 Conforming Documents"));
198 version = atof(line + 11);
202 if (!strncmp(line, "%%BeginDocument:", 16))
204 else if (!strncmp(line, "%%EndDocument", 13))
207 else if (saw_trailer)
209 if (!strncmp(line, "%%Pages:", 8))
211 if (atoi(line + 8) <= 0)
214 _cupsLangPuts(stdout, _("FAIL"));
217 _cupsLangPrintf(stdout,
218 _(" Bad %%%%Pages: on line %d.\n"
219 " REF: Page 43, %%%%Pages:"),
225 else if (!strncmp(line, "%%BoundingBox:", 14))
227 if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2,
231 _cupsLangPuts(stdout, _("FAIL"));
234 _cupsLangPrintf(stdout, _(" Bad %%%%BoundingBox: on line %d.\n"
235 " REF: Page 39, %%%%BoundingBox:"),
239 saw_bounding_box = 1;
242 else if (!saw_end_comments)
244 if (!strncmp(line, "%%EndComments", 13))
245 saw_end_comments = 1;
246 else if (line[0] != '%')
247 saw_end_comments = -1;
248 else if (!strncmp(line, "%%Pages:", 8))
250 if (strstr(line + 8, "(atend)"))
252 else if (atoi(line + 8) <= 0)
255 _cupsLangPuts(stdout, _("FAIL"));
258 _cupsLangPrintf(stdout, _(" Bad %%%%Pages: on line %d.\n"
259 " REF: Page 43, %%%%Pages:"),
265 else if (!strncmp(line, "%%BoundingBox:", 14))
267 if (strstr(line, "(atend)"))
268 saw_bounding_box = -1;
269 else if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2,
273 _cupsLangPuts(stdout, _("FAIL"));
276 _cupsLangPrintf(stdout, _(" Bad %%%%BoundingBox: on line %d.\n"
277 " REF: Page 39, %%%%BoundingBox:"),
281 saw_bounding_box = 1;
284 else if (saw_begin_prolog && !saw_end_prolog)
286 if (!strncmp(line, "%%EndProlog", 11))
289 else if (saw_begin_setup && !saw_end_setup)
291 if (!strncmp(line, "%%EndSetup", 10))
294 else if (saw_end_comments)
296 if (!strncmp(line, "%%Page:", 7))
298 if (sscanf(line + 7, "%255s%d", page_label, &page_number) != 2 ||
299 page_number != (last_page_number + 1) || page_number < 1)
302 _cupsLangPuts(stdout, _("FAIL"));
305 _cupsLangPrintf(stdout, _(" Bad %%%%Page: on line %d.\n"
306 " REF: Page 53, %%%%Page:"),
311 last_page_number = page_number;
315 else if (!strncmp(line, "%%BeginProlog", 13))
316 saw_begin_prolog = 1;
317 else if (!strncmp(line, "%%BeginSetup", 12))
319 else if (!strncmp(line, "%%BeginDocument:", 16))
321 else if (!strncmp(line, "%%EndDocument", 13))
323 else if (!strncmp(line, "%%Trailer", 9))
327 for (i = 0; !binary && i < bytes; i ++)
331 if ((ch < ' ' || (ch & 0x80)) && ch != '\n' && ch != '\r' && ch != '\t')
336 if (saw_bounding_box <= 0)
339 _cupsLangPuts(stdout, _("FAIL"));
342 _cupsLangPuts(stdout, _(" Missing or bad %%BoundingBox: comment.\n"
343 " REF: Page 39, %%BoundingBox:"));
349 _cupsLangPuts(stdout, _("FAIL"));
352 _cupsLangPuts(stdout, _(" Missing or bad %%Pages: comment.\n"
353 " REF: Page 43, %%Pages:"));
356 if (!saw_end_comments)
359 _cupsLangPuts(stdout, _("FAIL"));
362 _cupsLangPuts(stdout, _(" Missing %%EndComments comment."
363 " REF: Page 41, %%EndComments"));
369 _cupsLangPuts(stdout, _("FAIL"));
372 _cupsLangPuts(stdout, _(" Missing or bad %%Page: comments.\n"
373 " REF: Page 53, %%Page:"));
379 _cupsLangPuts(stdout, _("FAIL"));
382 _cupsLangPuts(stdout, _(" Too many %%EndDocument comments."));
387 _cupsLangPuts(stdout, _("FAIL"));
390 _cupsLangPuts(stdout, _(" Too many %%BeginDocument comments."));
393 if (saw_long_line > 1)
394 _cupsLangPrintf(stderr,
395 _(" Saw %d lines that exceeded 255 characters."),
399 _cupsLangPuts(stdout, _("PASS"));
402 _cupsLangPuts(stdout, _(" Warning: file contains binary data."));
405 _cupsLangPrintf(stdout,
406 _(" Warning: obsolete DSC version %.1f in file."),
409 if (saw_end_comments < 0)
410 _cupsLangPuts(stdout, _(" Warning: no %%EndComments comment in file."));
419 * 'usage()' - Show program usage.
425 _cupsLangPuts(stdout, _("Usage: cupstestdsc [options] filename.ps [... "
427 _cupsLangPuts(stdout, _(" cupstestdsc [options] -"));
428 _cupsLangPuts(stdout, "");
429 _cupsLangPuts(stdout, _("Options:"));
430 _cupsLangPuts(stdout, "");
431 _cupsLangPuts(stdout, _(" -h Show program usage"));
432 _cupsLangPuts(stdout, "");
433 _cupsLangPuts(stdout, _("Note: this program only validates the DSC comments, "
434 "not the PostScript itself."));
441 * End of "$Id: cupstestdsc.c 9384 2010-11-22 07:06:39Z mike $".