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