]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/cupstestdsc.c
Fix .PHONY declaration
[thirdparty/cups.git] / systemv / cupstestdsc.c
CommitLineData
80ca4592 1/*
503b54c9 2 * DSC test program for CUPS.
80ca4592 3 *
503b54c9
MS
4 * Copyright 2007-2010 by Apple Inc.
5 * Copyright 2006 by Easy Software Products, all rights reserved.
80ca4592 6 *
503b54c9
MS
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
57b7b66b 11 * missing or damaged, see the license at "http://www.cups.org/".
80ca4592 12 *
503b54c9 13 * PostScript is a trademark of Adobe Systems, Inc.
80ca4592 14 *
503b54c9 15 * This file is subject to the Apple OS-Developed Software exception.
80ca4592 16 */
17
18/*
19 * Include necessary headers...
20 */
21
71e16022 22#include <cups/cups-private.h>
80ca4592 23
24
25/*
26 * Local functions...
27 */
28
29static int check_file(const char *filename);
85dda01c 30static void usage(void) __attribute__((noreturn));
80ca4592 31
32
33/*
34 * 'main()' - Main entry for test program.
35 */
36
37int /* O - Exit status */
38main(int argc, /* I - Number of command-line args */
39 char *argv[]) /* I - Command-line arguments */
40{
41 int i; /* Looping var */
42 int status; /* Status of tests */
43 int num_files; /* Number of files tested */
44
45
07725fee 46 _cupsSetLocale(argv);
d09495fa 47
80ca4592 48 /*
49 * Collect command-line arguments...
50 */
51
52 for (i = 1, num_files = 0, status = 0; i < argc; i ++)
53 if (argv[i][0] == '-')
54 {
55 if (argv[i][1])
56 {
57 /*
58 * Currently the only supported option is "-h" (help)...
59 */
60
61 usage();
62 }
63 else
64 {
65 num_files ++;
66 status += check_file("(stdin)");
67 }
68 }
69 else
70 {
71 num_files ++;
72 status += check_file(argv[i]);
73 }
74
75 if (!num_files)
76 usage();
77
78 return (status);
79}
80
81
82/*
89d46774 83 * 'check()' - Check a file for conformance.
80ca4592 84 */
85
86static int /* O - 0 on success, 1 on failure */
87check_file(const char *filename) /* I - File to read from */
88{
89 int i; /* Looping var */
90 cups_file_t *fp; /* File */
91 char line[1024]; /* Line from file */
92 int ch; /* Current character */
93 size_t bytes; /* Length of line */
94 int status; /* Status of test */
95 int linenum; /* Line number */
96 int binary; /* File contains binary data? */
97 float version; /* DSC version */
98 int lbrt[4]; /* Bounding box */
99 char page_label[256]; /* Page label string */
100 int page_number; /* Page number */
89d46774 101 int last_page_number; /* Last page number seen */
80ca4592 102 int level; /* Embedded document level */
103 int saw_bounding_box, /* %%BoundingBox seen? */
104 saw_pages, /* %%Pages seen? */
105 saw_end_comments, /* %%EndComments seen? */
106 saw_begin_prolog, /* %%BeginProlog seen? */
107 saw_end_prolog, /* %%EndProlog seen? */
108 saw_begin_setup, /* %%BeginSetup seen? */
109 saw_end_setup, /* %%EndSetup seen? */
110 saw_page, /* %%Page seen? */
111 saw_trailer, /* %%Trailer seen? */
80ca4592 112 saw_long_line; /* Saw long lines? */
113
114
115 /*
116 * Open the file...
117 */
118
119 if (!strcmp(filename, "(stdin)"))
120 fp = cupsFileStdin();
121 else
122 fp = cupsFileOpen(filename, "r");
123
124 if (!fp)
125 {
126 perror(filename);
127 return (1);
128 }
129
130 /*
131 * Scan the file...
132 */
133
134 binary = 0;
89d46774 135 last_page_number = 0;
80ca4592 136 level = 0;
137 linenum = 0;
138 saw_begin_prolog = 0;
139 saw_begin_setup = 0;
140 saw_bounding_box = 0;
141 saw_end_comments = 0;
142 saw_end_prolog = 0;
143 saw_end_setup = 0;
80ca4592 144 saw_long_line = 0;
145 saw_page = 0;
146 saw_pages = 0;
147 saw_trailer = 0;
148 status = 0;
149 version = 0.0f;
150
0837b7e8
MS
151 /* TODO: Fixme */
152 printf("%s: ", filename);
80ca4592 153 fflush(stdout);
154
155 while ((bytes = cupsFileGetLine(fp, line, sizeof(line))) > 0)
156 {
157 linenum ++;
158
159 if (bytes > 255)
160 {
161 if (!saw_long_line)
162 {
163 if (!status)
0837b7e8 164 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 165
166 status ++;
167 _cupsLangPrintf(stdout,
0837b7e8
MS
168 _(" Line %d is longer than 255 characters (%d).\n"
169 " REF: Page 25, Line Length"),
80ca4592 170 linenum, (int)bytes);
171 }
172
173 saw_long_line ++;
174 }
175
176 if (linenum == 1)
177 {
178 if (strncmp(line, "%!PS-Adobe-", 11))
179 {
180 if (!status)
0837b7e8 181 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 182
80ca4592 183 _cupsLangPuts(stdout,
0837b7e8
MS
184 _(" Missing %!PS-Adobe-3.0 on first line.\n"
185 " REF: Page 17, 3.1 Conforming Documents"));
80ca4592 186 cupsFileClose(fp);
187 return (1);
188 }
189 else
68c4690a 190 version = (float)atof(line + 11);
80ca4592 191 }
192 else if (level > 0)
193 {
194 if (!strncmp(line, "%%BeginDocument:", 16))
195 level ++;
196 else if (!strncmp(line, "%%EndDocument", 13))
197 level --;
198 }
199 else if (saw_trailer)
200 {
201 if (!strncmp(line, "%%Pages:", 8))
202 {
203 if (atoi(line + 8) <= 0)
204 {
205 if (!status)
0837b7e8 206 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 207
208 status ++;
209 _cupsLangPrintf(stdout,
0837b7e8
MS
210 _(" Bad %%%%Pages: on line %d.\n"
211 " REF: Page 43, %%%%Pages:"),
80ca4592 212 linenum);
213 }
214 else
215 saw_pages = 1;
216 }
217 else if (!strncmp(line, "%%BoundingBox:", 14))
218 {
219 if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2,
220 lbrt + 3) != 4)
221 {
222 if (!status)
0837b7e8 223 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 224
225 status ++;
0837b7e8
MS
226 _cupsLangPrintf(stdout, _(" Bad %%%%BoundingBox: on line %d.\n"
227 " REF: Page 39, %%%%BoundingBox:"),
80ca4592 228 linenum);
229 }
230 else
231 saw_bounding_box = 1;
232 }
233 }
234 else if (!saw_end_comments)
235 {
236 if (!strncmp(line, "%%EndComments", 13))
237 saw_end_comments = 1;
238 else if (line[0] != '%')
239 saw_end_comments = -1;
240 else if (!strncmp(line, "%%Pages:", 8))
241 {
242 if (strstr(line + 8, "(atend)"))
243 saw_pages = -1;
244 else if (atoi(line + 8) <= 0)
245 {
246 if (!status)
0837b7e8 247 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 248
249 status ++;
0837b7e8
MS
250 _cupsLangPrintf(stdout, _(" Bad %%%%Pages: on line %d.\n"
251 " REF: Page 43, %%%%Pages:"),
80ca4592 252 linenum);
253 }
254 else
255 saw_pages = 1;
256 }
257 else if (!strncmp(line, "%%BoundingBox:", 14))
258 {
259 if (strstr(line, "(atend)"))
260 saw_bounding_box = -1;
261 else if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2,
262 lbrt + 3) != 4)
263 {
264 if (!status)
0837b7e8 265 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 266
267 status ++;
0837b7e8
MS
268 _cupsLangPrintf(stdout, _(" Bad %%%%BoundingBox: on line %d.\n"
269 " REF: Page 39, %%%%BoundingBox:"),
80ca4592 270 linenum);
271 }
272 else
273 saw_bounding_box = 1;
274 }
275 }
276 else if (saw_begin_prolog && !saw_end_prolog)
277 {
278 if (!strncmp(line, "%%EndProlog", 11))
279 saw_end_prolog = 1;
280 }
281 else if (saw_begin_setup && !saw_end_setup)
282 {
283 if (!strncmp(line, "%%EndSetup", 10))
284 saw_end_setup = 1;
285 }
286 else if (saw_end_comments)
287 {
288 if (!strncmp(line, "%%Page:", 7))
289 {
89d46774 290 if (sscanf(line + 7, "%255s%d", page_label, &page_number) != 2 ||
291 page_number != (last_page_number + 1) || page_number < 1)
80ca4592 292 {
293 if (!status)
0837b7e8 294 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 295
296 status ++;
0837b7e8
MS
297 _cupsLangPrintf(stdout, _(" Bad %%%%Page: on line %d.\n"
298 " REF: Page 53, %%%%Page:"),
80ca4592 299 linenum);
300 }
301 else
89d46774 302 {
303 last_page_number = page_number;
304 saw_page = 1;
305 }
80ca4592 306 }
307 else if (!strncmp(line, "%%BeginProlog", 13))
308 saw_begin_prolog = 1;
309 else if (!strncmp(line, "%%BeginSetup", 12))
310 saw_begin_setup = 1;
311 else if (!strncmp(line, "%%BeginDocument:", 16))
312 level ++;
313 else if (!strncmp(line, "%%EndDocument", 13))
314 level --;
315 else if (!strncmp(line, "%%Trailer", 9))
316 saw_trailer = 1;
317 }
318
68c4690a 319 for (i = 0; !binary && i < (int)bytes; i ++)
80ca4592 320 {
321 ch = line[i];
322
323 if ((ch < ' ' || (ch & 0x80)) && ch != '\n' && ch != '\r' && ch != '\t')
324 binary = 1;
325 }
326 }
327
328 if (saw_bounding_box <= 0)
329 {
330 if (!status)
0837b7e8 331 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 332
333 status ++;
0837b7e8
MS
334 _cupsLangPuts(stdout, _(" Missing or bad %%BoundingBox: comment.\n"
335 " REF: Page 39, %%BoundingBox:"));
80ca4592 336 }
337
338 if (saw_pages <= 0)
339 {
340 if (!status)
0837b7e8 341 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 342
343 status ++;
0837b7e8
MS
344 _cupsLangPuts(stdout, _(" Missing or bad %%Pages: comment.\n"
345 " REF: Page 43, %%Pages:"));
80ca4592 346 }
347
348 if (!saw_end_comments)
349 {
350 if (!status)
0837b7e8 351 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 352
353 status ++;
0837b7e8
MS
354 _cupsLangPuts(stdout, _(" Missing %%EndComments comment."
355 " REF: Page 41, %%EndComments"));
80ca4592 356 }
357
358 if (!saw_page)
359 {
360 if (!status)
0837b7e8 361 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 362
363 status ++;
0837b7e8
MS
364 _cupsLangPuts(stdout, _(" Missing or bad %%Page: comments.\n"
365 " REF: Page 53, %%Page:"));
80ca4592 366 }
367
368 if (level < 0)
369 {
370 if (!status)
0837b7e8 371 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 372
373 status ++;
0837b7e8 374 _cupsLangPuts(stdout, _(" Too many %%EndDocument comments."));
80ca4592 375 }
376 else if (level > 0)
377 {
378 if (!status)
0837b7e8 379 _cupsLangPuts(stdout, _("FAIL"));
80ca4592 380
381 status ++;
0837b7e8 382 _cupsLangPuts(stdout, _(" Too many %%BeginDocument comments."));
80ca4592 383 }
384
385 if (saw_long_line > 1)
386 _cupsLangPrintf(stderr,
0837b7e8 387 _(" Saw %d lines that exceeded 255 characters."),
80ca4592 388 saw_long_line);
389
390 if (!status)
0837b7e8 391 _cupsLangPuts(stdout, _("PASS"));
80ca4592 392
393 if (binary)
0837b7e8 394 _cupsLangPuts(stdout, _(" Warning: file contains binary data."));
80ca4592 395
396 if (version < 3.0f)
397 _cupsLangPrintf(stdout,
0837b7e8 398 _(" Warning: obsolete DSC version %.1f in file."),
80ca4592 399 version);
400
401 if (saw_end_comments < 0)
0837b7e8 402 _cupsLangPuts(stdout, _(" Warning: no %%EndComments comment in file."));
80ca4592 403
404 cupsFileClose(fp);
405
406 return (status);
407}
408
409
410/*
411 * 'usage()' - Show program usage.
412 */
413
414static void
415usage(void)
416{
0837b7e8
MS
417 _cupsLangPuts(stdout, _("Usage: cupstestdsc [options] filename.ps [... "
418 "filename.ps]"));
419 _cupsLangPuts(stdout, _(" cupstestdsc [options] -"));
420 _cupsLangPuts(stdout, "");
421 _cupsLangPuts(stdout, _("Options:"));
422 _cupsLangPuts(stdout, "");
423 _cupsLangPuts(stdout, _(" -h Show program usage"));
424 _cupsLangPuts(stdout, "");
425 _cupsLangPuts(stdout, _("Note: this program only validates the DSC comments, "
426 "not the PostScript itself."));
427
80ca4592 428 exit(1);
429}