]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/cupstestppd.c
Add list of conflicting options to cupstestppd (STR #123)
[thirdparty/cups.git] / systemv / cupstestppd.c
CommitLineData
4b0b2cf9 1/*
31e1c01a 2 * "$Id: cupstestppd.c,v 1.22 2003/05/23 15:23:46 mike Exp $"
4b0b2cf9 3 *
4 * PPD test program for the Common UNIX Printing System (CUPS).
5 *
997fbfa7 6 * Copyright 1997-2003 by Easy Software Products, all rights reserved.
4b0b2cf9 7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * PostScript is a trademark of Adobe Systems, Inc.
25 *
26 * This file is subject to the Apple OS-Developed Software exception.
27 *
28 * Contents:
29 *
31e1c01a 30 * main() - Main entry for test program.
31 * show_conflicts() - Show option conflicts in a PPD file.
32 * usage() - Show program usage...
4b0b2cf9 33 */
34
35/*
36 * Include necessary headers...
37 */
38
39#include <cups/cups.h>
40#include <cups/string.h>
41#include <errno.h>
f249be22 42#include <stdlib.h>
4b0b2cf9 43
44
45/*
46 * Error codes...
47 */
48
49#define ERROR_NONE 0
50#define ERROR_USAGE 1
51#define ERROR_FILE_OPEN 2
52#define ERROR_PPD_FORMAT 3
53#define ERROR_CONFORMANCE 4
54
55
f249be22 56/*
57 * Local functions...
58 */
59
31e1c01a 60void show_conflicts(ppd_file_t *ppd);
f249be22 61void usage(void);
62
63
4b0b2cf9 64/*
65 * 'main()' - Main entry for test program.
66 */
67
68int /* O - Exit status */
69main(int argc, /* I - Number of command-line arguments */
70 char *argv[]) /* I - Command-line arguments */
71{
5c61431a 72 int i, j, k, m, n; /* Looping vars */
73 int len; /* Length of option name */
f249be22 74 char *opt; /* Option character */
75 const char *ptr; /* Pointer into string */
1391e7cb 76 int files; /* Number of files */
4b0b2cf9 77 int verbose; /* Want verbose output? */
78 int status; /* Exit status */
79 int errors; /* Number of conformance errors */
f9d01894 80 int ppdversion; /* PPD spec version in PPD file */
1391e7cb 81 ppd_status_t error; /* Status of ppdOpen*() */
82 int line; /* Line number for error */
4b0b2cf9 83 ppd_file_t *ppd; /* PPD file record */
f0e7bfbd 84 ppd_attr_t *attr; /* PPD attribute */
4b0b2cf9 85 ppd_size_t *size; /* Size record */
86 ppd_group_t *group; /* UI group */
87 ppd_option_t *option; /* Standard UI option */
5c61431a 88 ppd_group_t *group2; /* UI group */
89 ppd_option_t *option2; /* Standard UI option */
4b0b2cf9 90 ppd_choice_t *choice; /* Standard UI option choice */
91 static char *uis[] = { "BOOLEAN", "PICKONE", "PICKMANY" };
92 static char *sections[] = { "ANY", "DOCUMENT", "EXIT",
93 "JCL", "PAGE", "PROLOG" };
94
95
96 setbuf(stdout, NULL);
97
98 /*
99 * Display PPD files for each file listed on the command-line...
100 */
101
102 verbose = 0;
103 ppd = NULL;
1391e7cb 104 files = 0;
4b0b2cf9 105 status = ERROR_NONE;
106
107 for (i = 1; i < argc; i ++)
f249be22 108 if (argv[i][0] == '-' && argv[i][1])
77f83108 109 {
f249be22 110 for (opt = argv[i] + 1; *opt; opt ++)
111 switch (*opt)
112 {
113 case 'q' :
114 if (verbose > 0)
115 {
116 fputs("cupstestppd: The -q option is incompatible with the -v option.\n",
117 stderr);
118 return (1);
119 }
77f83108 120
f249be22 121 verbose --;
122 break;
77f83108 123
f249be22 124 case 'v' :
125 if (verbose < 0)
126 {
127 fputs("cupstestppd: The -v option is incompatible with the -q option.\n",
128 stderr);
129 return (1);
130 }
131
132 verbose ++;
133 break;
134
135 default :
136 usage();
137 break;
138 }
4b0b2cf9 139 }
140 else
141 {
142 /*
143 * Open the PPD file...
144 */
145
e7848a5b 146 if (files && verbose >= 0)
5f7c946a 147 putchar('\n');
148
1391e7cb 149 files ++;
150
4b0b2cf9 151 if (argv[i][0] == '-')
152 {
153 /*
154 * Read from stdin...
155 */
156
77f83108 157 if (verbose >= 0)
f249be22 158 printf("(stdin):");
4b0b2cf9 159
160 ppd = ppdOpen(stdin);
161 }
f249be22 162 else if (strlen(argv[i]) > 3 &&
163 !strcmp(argv[i] + strlen(argv[i]) - 3, ".gz"))
164 {
165 /*
166 * Read from a gzipped file...
167 */
168
169 char command[1024]; /* Command string */
170 FILE *gunzip; /* Pipe file */
171
172
173 if (verbose >= 0)
174 printf("%s:", argv[i]);
175
ad10470c 176 snprintf(command, sizeof(command), "gunzip -c \"%s\"", argv[i]);
f249be22 177 gunzip = popen(command, "r");
178 ppd = ppdOpen(gunzip);
179
180 if (gunzip != NULL)
181 pclose(gunzip);
182 }
4b0b2cf9 183 else
184 {
185 /*
186 * Read from a file...
187 */
188
77f83108 189 if (verbose >= 0)
f249be22 190 printf("%s:", argv[i]);
4b0b2cf9 191
192 ppd = ppdOpenFile(argv[i]);
193 }
194
195 if (ppd == NULL)
196 {
1391e7cb 197 error = ppdLastError(&line);
198
8b952de6 199 if (verbose >= 0)
200 printf(" FAIL\n **FAIL** Unable to open PPD file - ");
f69d5f26 201
621b77a6 202 if (error <= PPD_ALLOC_ERROR)
4b0b2cf9 203 {
204 status = ERROR_FILE_OPEN;
77f83108 205
5f7c946a 206 if (verbose >= 0)
f69d5f26 207 puts(strerror(errno));
4b0b2cf9 208 }
209 else
210 {
211 status = ERROR_PPD_FORMAT;
77f83108 212
5f7c946a 213 if (verbose >= 0)
214 {
f69d5f26 215 printf("%s on line %d.\n", ppdErrorString(error), line);
5f7c946a 216
217 switch (error)
218 {
219 case PPD_MISSING_PPDADOBE4 :
8e524f97 220 puts(" REF: Page 42, section 5.2.");
5f7c946a 221 break;
222 case PPD_MISSING_VALUE :
8e524f97 223 puts(" REF: Page 20, section 3.4.");
5f7c946a 224 break;
225 case PPD_BAD_OPEN_GROUP :
226 case PPD_NESTED_OPEN_GROUP :
8e524f97 227 puts(" REF: Pages 45-46, section 5.2.");
5f7c946a 228 break;
229 case PPD_BAD_OPEN_UI :
230 case PPD_NESTED_OPEN_UI :
8e524f97 231 puts(" REF: Pages 42-45, section 5.2.");
5f7c946a 232 break;
233 case PPD_BAD_ORDER_DEPENDENCY :
8e524f97 234 puts(" REF: Pages 48-49, section 5.2.");
5f7c946a 235 break;
236 case PPD_BAD_UI_CONSTRAINTS :
8e524f97 237 puts(" REF: Pages 52-54, section 5.2.");
5f7c946a 238 break;
239 case PPD_MISSING_ASTERISK :
8e524f97 240 puts(" REF: Page 15, section 3.2.");
5f7c946a 241 break;
242 case PPD_LINE_TOO_LONG :
8e524f97 243 puts(" REF: Page 15, section 3.1.");
5f7c946a 244 break;
245 case PPD_ILLEGAL_CHARACTER :
8e524f97 246 puts(" REF: Page 15, section 3.1.");
5f7c946a 247 break;
248 case PPD_ILLEGAL_MAIN_KEYWORD :
8e524f97 249 puts(" REF: Pages 16-17, section 3.2.");
5f7c946a 250 break;
251 case PPD_ILLEGAL_OPTION_KEYWORD :
8e524f97 252 puts(" REF: Page 19, section 3.3.");
5f7c946a 253 break;
254 case PPD_ILLEGAL_TRANSLATION :
8e524f97 255 puts(" REF: Page 27, section 3.5.");
5f7c946a 256 break;
257 default :
258 break;
259 }
260 }
4b0b2cf9 261 }
262
263 continue;
264 }
265
266 /*
267 * Show the header and then perform basic conformance tests (limited
268 * only by what the CUPS PPD functions actually load...)
269 */
270
f9d01894 271 errors = 0;
272 ppdversion = 43;
5f7c946a 273
274 if (verbose > 0)
275 puts("\n DETAILED CONFORMANCE TEST RESULTS");
276
f0e7bfbd 277 if ((attr = ppdFindAttr(ppd, "FormatVersion", NULL)) != NULL &&
278 attr->value)
279 ppdversion = (int)(10 * atof(attr->value) + 0.5);
f9d01894 280
f249be22 281 if (ppdFindAttr(ppd, "DefaultImageableArea", NULL) != NULL)
282 {
283 if (verbose > 0)
284 puts(" PASS DefaultImageableArea");
285 }
286 else
287 {
5f7c946a 288 if (verbose >= 0)
289 {
290 if (!errors && !verbose)
291 puts(" FAIL");
f249be22 292
f249be22 293 puts(" **FAIL** REQUIRED DefaultImageableArea");
5f7c946a 294 puts(" REF: Page 102, section 5.15.");
295 }
296
297 errors ++;
f249be22 298 }
299
300 if (ppdFindAttr(ppd, "DefaultPaperDimension", NULL) != NULL)
301 {
302 if (verbose > 0)
303 puts(" PASS DefaultPaperDimension");
304 }
305 else
306 {
5f7c946a 307 if (verbose >= 0)
308 {
309 if (!errors && !verbose)
310 puts(" FAIL");
f249be22 311
f249be22 312 puts(" **FAIL** REQUIRED DefaultPaperDimension");
5f7c946a 313 puts(" REF: Page 103, section 5.15.");
314 }
315
316 errors ++;
f249be22 317 }
318
4b0b2cf9 319 for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
320 for (k = 0, option = group->options; k < group->num_options; k ++, option ++)
5c61431a 321 {
322 /*
323 * Verify that we have a default choice...
324 */
325
4b0b2cf9 326 if (option->defchoice[0])
327 {
f249be22 328 if (verbose > 0)
77f83108 329 printf(" PASS Default%s\n", option->keyword);
4b0b2cf9 330 }
331 else
332 {
5f7c946a 333 if (verbose >= 0)
334 {
335 if (!errors && !verbose)
336 puts(" FAIL");
77f83108 337
77f83108 338 printf(" **FAIL** REQUIRED Default%s\n", option->keyword);
5f7c946a 339 puts(" REF: Page 40, section 4.5.");
340 }
341
342 errors ++;
4b0b2cf9 343 }
5c61431a 344 }
345
f249be22 346 if (ppdFindAttr(ppd, "FileVersion", NULL) != NULL)
77f83108 347 {
f249be22 348 if (verbose > 0)
349 puts(" PASS FileVersion");
77f83108 350 }
4b0b2cf9 351 else
352 {
5f7c946a 353 if (verbose >= 0)
354 {
355 if (!errors && !verbose)
356 puts(" FAIL");
77f83108 357
f249be22 358 puts(" **FAIL** REQUIRED FileVersion");
5f7c946a 359 puts(" REF: Page 56, section 5.3.");
360 }
361
362 errors ++;
f249be22 363 }
364
365 if (ppdFindAttr(ppd, "FormatVersion", NULL) != NULL)
366 {
367 if (verbose > 0)
368 puts(" PASS FormatVersion");
369 }
370 else
371 {
5f7c946a 372 if (verbose >= 0)
373 {
374 if (!errors && !verbose)
375 puts(" FAIL");
f249be22 376
f249be22 377 puts(" **FAIL** REQUIRED FormatVersion");
5f7c946a 378 puts(" REF: Page 56, section 5.3.");
379 }
380
381 errors ++;
4b0b2cf9 382 }
383
384 if (ppd->lang_encoding != NULL)
77f83108 385 {
f249be22 386 if (verbose > 0)
77f83108 387 puts(" PASS LanguageEncoding");
388 }
5f7c946a 389 else if (ppdversion > 40)
4b0b2cf9 390 {
5f7c946a 391 if (verbose >= 0)
392 {
393 if (!errors && !verbose)
394 puts(" FAIL");
77f83108 395
77f83108 396 puts(" **FAIL** REQUIRED LanguageEncoding");
5f7c946a 397 puts(" REF: Pages 56-57, section 5.3.");
398 }
399
400 errors ++;
4b0b2cf9 401 }
402
403 if (ppd->lang_version != NULL)
77f83108 404 {
f249be22 405 if (verbose > 0)
77f83108 406 puts(" PASS LanguageVersion");
407 }
4b0b2cf9 408 else
409 {
5f7c946a 410 if (verbose >= 0)
411 {
412 if (!errors && !verbose)
413 puts(" FAIL");
77f83108 414
77f83108 415 puts(" **FAIL** REQUIRED LanguageVersion");
5f7c946a 416 puts(" REF: Pages 57-58, section 5.3.");
417 }
418
419 errors ++;
4b0b2cf9 420 }
421
422 if (ppd->manufacturer != NULL)
77f83108 423 {
f249be22 424 if (verbose > 0)
77f83108 425 puts(" PASS Manufacturer");
426 }
5f7c946a 427 else if (ppdversion >= 43)
4b0b2cf9 428 {
5f7c946a 429 if (verbose >= 0)
430 {
431 if (!errors && !verbose)
432 puts(" FAIL");
77f83108 433
77f83108 434 puts(" **FAIL** REQUIRED Manufacturer");
5f7c946a 435 puts(" REF: Pages 58-59, section 5.3.");
436 }
437
438 errors ++;
4b0b2cf9 439 }
440
441 if (ppd->modelname != NULL)
77f83108 442 {
f249be22 443 for (ptr = ppd->modelname; *ptr; ptr ++)
444 if (!isalnum(*ptr) && !strchr(" ./-+", *ptr))
445 break;
446
447 if (*ptr)
448 {
5f7c946a 449 if (verbose >= 0)
450 {
451 if (!errors && !verbose)
452 puts(" FAIL");
f249be22 453
5f7c946a 454 printf(" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n",
455 *ptr);
456 puts(" REF: Pages 59-60, section 5.3.");
457 }
458
459 errors ++;
f249be22 460 }
461 else if (verbose > 0)
77f83108 462 puts(" PASS ModelName");
463 }
4b0b2cf9 464 else
465 {
5f7c946a 466 if (verbose >= 0)
467 {
468 if (!errors && !verbose)
469 puts(" FAIL");
77f83108 470
77f83108 471 puts(" **FAIL** REQUIRED ModelName");
5f7c946a 472 puts(" REF: Pages 59-60, section 5.3.");
473 }
474
475 errors ++;
4b0b2cf9 476 }
477
478 if (ppd->nickname != NULL)
77f83108 479 {
f249be22 480 if (verbose > 0)
77f83108 481 puts(" PASS NickName");
482 }
4b0b2cf9 483 else
484 {
5f7c946a 485 if (verbose >= 0)
486 {
487 if (!errors && !verbose)
488 puts(" FAIL");
77f83108 489
77f83108 490 puts(" **FAIL** REQUIRED NickName");
5f7c946a 491 puts(" REF: Page 60, section 5.3.");
492 }
493
494 errors ++;
4b0b2cf9 495 }
496
497 if (ppdFindOption(ppd, "PageSize") != NULL)
77f83108 498 {
f249be22 499 if (verbose > 0)
77f83108 500 puts(" PASS PageSize");
501 }
4b0b2cf9 502 else
503 {
5f7c946a 504 if (verbose >= 0)
505 {
506 if (!errors && !verbose)
507 puts(" FAIL");
77f83108 508
77f83108 509 puts(" **FAIL** REQUIRED PageSize");
5f7c946a 510 puts(" REF: Pages 99-100, section 5.14.");
511 }
512
513 errors ++;
4b0b2cf9 514 }
515
516 if (ppdFindOption(ppd, "PageRegion") != NULL)
77f83108 517 {
f249be22 518 if (verbose > 0)
77f83108 519 puts(" PASS PageRegion");
520 }
4b0b2cf9 521 else
522 {
5f7c946a 523 if (verbose >= 0)
524 {
525 if (!errors && !verbose)
526 puts(" FAIL");
77f83108 527
77f83108 528 puts(" **FAIL** REQUIRED PageRegion");
5f7c946a 529 puts(" REF: Page 100, section 5.14.");
530 }
531
532 errors ++;
4b0b2cf9 533 }
534
23f5e659 535 if (ppd->pcfilename != NULL)
536 {
f249be22 537 if (verbose > 0)
5f7c946a 538 puts(" PASS PCFileName");
23f5e659 539 }
540 else
541 {
5f7c946a 542 if (verbose >= 0)
543 {
544 if (!errors && !verbose)
545 puts(" FAIL");
23f5e659 546
23f5e659 547 puts(" **FAIL** REQUIRED PCFileName");
5f7c946a 548 puts(" REF: Pages 61-62, section 5.3.");
549 }
550
551 errors ++;
23f5e659 552 }
553
4b0b2cf9 554 if (ppd->product != NULL)
77f83108 555 {
f249be22 556 if (ppd->product[0] != '(' ||
557 ppd->product[strlen(ppd->product) - 1] != ')')
558 {
5f7c946a 559 if (verbose >= 0)
560 {
561 if (!errors && !verbose)
562 puts(" FAIL");
563
564 puts(" **FAIL** BAD Product - not \"(string)\".");
565 puts(" REF: Page 62, section 5.3.");
566 }
f249be22 567
5f7c946a 568 errors ++;
f249be22 569 }
570 else if (verbose > 0)
77f83108 571 puts(" PASS Product");
572 }
4b0b2cf9 573 else
574 {
5f7c946a 575 if (verbose >= 0)
576 {
577 if (!errors && !verbose)
578 puts(" FAIL");
77f83108 579
77f83108 580 puts(" **FAIL** REQUIRED Product");
5f7c946a 581 puts(" REF: Page 62, section 5.3.");
582 }
583
584 errors ++;
4b0b2cf9 585 }
586
f0e7bfbd 587 if ((attr = ppdFindAttr(ppd, "PSVersion", NULL)) != NULL &&
588 attr->value != NULL)
f249be22 589 {
590 char junkstr[255]; /* Temp string */
591 int junkint; /* Temp integer */
592
593
f0e7bfbd 594 if (sscanf(attr->value, "(%[^)])%d", junkstr, &junkint) != 2)
f249be22 595 {
5f7c946a 596 if (verbose >= 0)
597 {
598 if (!errors && !verbose)
599 puts(" FAIL");
600
601 puts(" **FAIL** BAD PSVersion - not \"(string) int\".");
602 puts(" REF: Pages 62-64, section 5.3.");
603 }
f249be22 604
5f7c946a 605 errors ++;
f249be22 606 }
607 else if (verbose > 0)
608 puts(" PASS PSVersion");
609 }
610 else
611 {
5f7c946a 612 if (verbose >= 0)
613 {
614 if (!errors && !verbose)
615 puts(" FAIL");
f249be22 616
f249be22 617 puts(" **FAIL** REQUIRED PSVersion");
5f7c946a 618 puts(" REF: Pages 62-64, section 5.3.");
619 }
620
621 errors ++;
f249be22 622 }
623
4b0b2cf9 624 if (ppd->shortnickname != NULL)
77f83108 625 {
f249be22 626 if (strlen(ppd->shortnickname) > 31)
627 {
5f7c946a 628 if (verbose >= 0)
629 {
630 if (!errors && !verbose)
631 puts(" FAIL");
632
633 puts(" **FAIL** BAD ShortNickName - longer than 31 chars.");
634 puts(" REF: Pages 64-65, section 5.3.");
635 }
f249be22 636
5f7c946a 637 errors ++;
f249be22 638 }
639 else if (verbose > 0)
77f83108 640 puts(" PASS ShortNickName");
641 }
5f7c946a 642 else if (ppdversion >= 43)
f9d01894 643 {
5f7c946a 644 if (verbose >= 0)
645 {
646 if (!errors && !verbose)
647 puts(" FAIL");
77f83108 648
77f83108 649 puts(" **FAIL** REQUIRED ShortNickName");
5f7c946a 650 puts(" REF: Page 64-65, section 5.3.");
651 }
652
653 errors ++;
4b0b2cf9 654 }
655
656 if (errors)
5f7c946a 657 status = ERROR_CONFORMANCE;
658 else if (!verbose)
659 puts(" PASS");
660
661 if (verbose >= 0)
4b0b2cf9 662 {
eafe419c 663 ppdMarkDefaults(ppd);
664 if (ppdConflicts(ppd))
31e1c01a 665 {
eafe419c 666 puts(" WARN Default choices conflicting!");
667
31e1c01a 668 show_conflicts(ppd);
669 }
670
5f7c946a 671 if (ppdversion < 43)
672 {
f0e7bfbd 673 printf(" WARN Obsolete PPD version %.1f!\n",
674 0.1f * ppdversion);
5f7c946a 675 puts(" REF: Page 42, section 5.2.");
676 }
77f83108 677
6fab737b 678 if (!ppd->lang_encoding && ppdversion < 41)
5f7c946a 679 {
680 puts(" WARN LanguageEncoding required by PPD 4.3 spec.");
681 puts(" REF: Pages 56-57, section 5.3.");
682 }
683
684 if (!ppd->manufacturer && ppdversion < 43)
685 {
686 puts(" WARN Manufacturer required by PPD 4.3 spec.");
687 puts(" REF: Pages 58-59, section 5.3.");
688 }
689
690 /*
691 * Treat a PCFileName attribute longer than 12 characters as
692 * a warning and not a hard error...
693 */
694
695 if (ppd->pcfilename && strlen(ppd->pcfilename) > 12)
696 {
697 puts(" WARN PCFileName longer than 8.3 in violation of PPD spec.");
698 puts(" REF: Pages 61-62, section 5.3.");
699 }
700
701 if (!ppd->shortnickname && ppdversion < 43)
702 {
703 puts(" WARN ShortNickName required by PPD 4.3 spec.");
704 puts(" REF: Pages 64-65, section 5.3.");
705 }
b8f94d24 706
707 /*
708 * Check for options with a common prefix, e.g. Duplex and Duplexer,
709 * which are errors according to the spec but won't cause problems
710 * with CUPS specifically...
711 */
712
713 for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
714 for (k = 0, option = group->options; k < group->num_options; k ++, option ++)
715 {
716 len = strlen(option->keyword);
717
718 for (m = 0, group2 = ppd->groups;
719 m < ppd->num_groups;
720 m ++, group2 ++)
721 for (n = 0, option2 = group2->options;
722 n < group2->num_options;
723 n ++, option2 ++)
724 if (option != option2 &&
725 len < strlen(option2->keyword) &&
726 !strncmp(option->keyword, option2->keyword, len))
727 {
728 printf(" WARN %s shares a common prefix with %s\n",
729 option->keyword, option2->keyword);
730 puts(" REF: Page 15, section 3.2.");
731 }
732 }
4b0b2cf9 733 }
734
f249be22 735 if (verbose > 0)
5f7c946a 736 {
737 if (errors)
738 printf(" %d ERROR%s FOUND\n", errors, errors == 1 ? "" : "S");
739 else
740 puts(" NO ERRORS FOUND");
741 }
742
4b0b2cf9 743
744 /*
745 * Then list the options, if "-v" was provided...
746 */
747
f249be22 748 if (verbose > 1)
4b0b2cf9 749 {
750 puts("");
4b0b2cf9 751 printf(" language_level = %d\n", ppd->language_level);
752 printf(" color_device = %s\n", ppd->color_device ? "TRUE" : "FALSE");
753 printf(" variable_sizes = %s\n", ppd->variable_sizes ? "TRUE" : "FALSE");
754 printf(" landscape = %d\n", ppd->landscape);
755
756 switch (ppd->colorspace)
757 {
758 case PPD_CS_CMYK :
759 puts(" colorspace = PPD_CS_CMYK");
760 break;
761 case PPD_CS_CMY :
762 puts(" colorspace = PPD_CS_CMY");
763 break;
764 case PPD_CS_GRAY :
765 puts(" colorspace = PPD_CS_GRAY");
766 break;
767 case PPD_CS_RGB :
768 puts(" colorspace = PPD_CS_RGB");
769 break;
770 default :
771 puts(" colorspace = <unknown>");
772 break;
773 }
774
775 printf(" num_emulations = %d\n", ppd->num_emulations);
776 for (j = 0; j < ppd->num_emulations; j ++)
777 printf(" emulations[%d] = %s\n", j, ppd->emulations[j].name);
778
779 printf(" lang_encoding = %s\n", ppd->lang_encoding);
780 printf(" lang_version = %s\n", ppd->lang_version);
781 printf(" modelname = %s\n", ppd->modelname);
782 printf(" ttrasterizer = %s\n",
783 ppd->ttrasterizer == NULL ? "None" : ppd->ttrasterizer);
784 printf(" manufacturer = %s\n", ppd->manufacturer);
785 printf(" product = %s\n", ppd->product);
786 printf(" nickname = %s\n", ppd->nickname);
787 printf(" shortnickname = %s\n", ppd->shortnickname);
788 printf(" patches = %d bytes\n",
789 ppd->patches == NULL ? 0 : (int)strlen(ppd->patches));
790
791 printf(" num_groups = %d\n", ppd->num_groups);
792 for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
793 {
794 printf(" group[%d] = %s\n", j, group->text);
795
796 for (k = 0, option = group->options; k < group->num_options; k ++, option ++)
797 {
798 printf(" options[%d] = %s (%s) %s %s %.0f (%d choices)\n", k,
799 option->keyword, option->text, uis[option->ui],
800 sections[option->section], option->order,
801 option->num_choices);
802
803 if (strcmp(option->keyword, "PageSize") == 0 ||
804 strcmp(option->keyword, "PageRegion") == 0)
805 {
806 for (m = option->num_choices, choice = option->choices;
807 m > 0;
808 m --, choice ++)
809 {
810 size = ppdPageSize(ppd, choice->choice);
811
812 if (size == NULL)
813 printf(" %s (%s) = ERROR", choice->choice, choice->text);
814 else
815 printf(" %s (%s) = %.2fx%.2fin (%.1f,%.1f,%.1f,%.1f)", choice->choice,
816 choice->text, size->width / 72.0, size->length / 72.0,
817 size->left / 72.0, size->bottom / 72.0,
818 size->right / 72.0, size->top / 72.0);
819
820 if (strcmp(option->defchoice, choice->choice) == 0)
821 puts(" *");
822 else
823 putchar('\n');
824 }
825 }
826 else
827 {
828 for (m = option->num_choices, choice = option->choices;
829 m > 0;
830 m --, choice ++)
831 {
832 printf(" %s (%s)", choice->choice, choice->text);
833
834 if (strcmp(option->defchoice, choice->choice) == 0)
835 puts(" *");
836 else
837 putchar('\n');
838 }
839 }
840 }
841 }
842
843 printf(" num_profiles = %d\n", ppd->num_profiles);
844 for (j = 0; j < ppd->num_profiles; j ++)
845 printf(" profiles[%d] = %s/%s %.3f %.3f [ %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f ]\n",
846 j, ppd->profiles[j].resolution, ppd->profiles[j].media_type,
847 ppd->profiles[j].gamma, ppd->profiles[j].density,
848 ppd->profiles[j].matrix[0][0], ppd->profiles[j].matrix[0][1],
849 ppd->profiles[j].matrix[0][2], ppd->profiles[j].matrix[1][0],
850 ppd->profiles[j].matrix[1][1], ppd->profiles[j].matrix[1][2],
851 ppd->profiles[j].matrix[2][0], ppd->profiles[j].matrix[2][1],
852 ppd->profiles[j].matrix[2][2]);
853
854 printf(" num_fonts = %d\n", ppd->num_fonts);
855 for (j = 0; j < ppd->num_fonts; j ++)
856 printf(" fonts[%d] = %s\n", j, ppd->fonts[j]);
857 }
858
859 ppdClose(ppd);
860 }
861
f249be22 862 if (!files)
863 usage();
864
865 return (status);
866}
867
868
31e1c01a 869/*
870 * 'show_conflicts()' - Show option conflicts in a PPD file.
871 */
872
873void
874show_conflicts(ppd_file_t *ppd) /* I - PPD to check */
875{
876 int i, j; /* Looping variables */
877 ppd_const_t *c; /* Current constraint */
878 ppd_option_t *o1, *o2; /* Options */
879 ppd_choice_t *c1, *c2; /* Choices */
880
881
882 /*
883 * Loop through all of the UI constraints and report any options
884 * that conflict...
885 */
886
887 for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
888 {
889 /*
890 * Grab pointers to the first option...
891 */
892
893 o1 = ppdFindOption(ppd, c->option1);
894
895 if (o1 == NULL)
896 continue;
897 else if (c->choice1[0] != '\0')
898 {
899 /*
900 * This constraint maps to a specific choice.
901 */
902
903 c1 = ppdFindChoice(o1, c->choice1);
904 }
905 else
906 {
907 /*
908 * This constraint applies to any choice for this option.
909 */
910
911 for (j = o1->num_choices, c1 = o1->choices; j > 0; j --, c1 ++)
912 if (c1->marked)
913 break;
914
915 if (j == 0 ||
916 strcasecmp(c1->choice, "None") == 0 ||
917 strcasecmp(c1->choice, "Off") == 0 ||
918 strcasecmp(c1->choice, "False") == 0)
919 c1 = NULL;
920 }
921
922 /*
923 * Grab pointers to the second option...
924 */
925
926 o2 = ppdFindOption(ppd, c->option2);
927
928 if (o2 == NULL)
929 continue;
930 else if (c->choice2[0] != '\0')
931 {
932 /*
933 * This constraint maps to a specific choice.
934 */
935
936 c2 = ppdFindChoice(o2, c->choice2);
937 }
938 else
939 {
940 /*
941 * This constraint applies to any choice for this option.
942 */
943
944 for (j = o2->num_choices, c2 = o2->choices; j > 0; j --, c2 ++)
945 if (c2->marked)
946 break;
947
948 if (j == 0 ||
949 strcasecmp(c2->choice, "None") == 0 ||
950 strcasecmp(c2->choice, "Off") == 0 ||
951 strcasecmp(c2->choice, "False") == 0)
952 c2 = NULL;
953 }
954
955 /*
956 * If both options are marked then there is a conflict...
957 */
958
959 if (c1 != NULL && c1->marked && c2 != NULL && c2->marked)
960 printf(" WARN \"%s %s\" conflicts with \"%s %s\"\n"
961 " (constraint=\"%s %s %s %s\")\n",
962 o1->keyword, c1->choice, o2->keyword, c2->choice,
963 c->option1, c->choice1, c->option2, c->choice2);
964 }
965}
966
967
f249be22 968/*
969 * 'usage()' - Show program usage...
970 */
971
972void
973usage(void)
974{
975 puts("Usage: cupstestppd [-q] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[.gz]]");
976 puts(" program | cupstestppd [-q] [-v[v]] -");
4b0b2cf9 977
f249be22 978 exit(ERROR_USAGE);
4b0b2cf9 979}
980
981
982/*
31e1c01a 983 * End of "$Id: cupstestppd.c,v 1.22 2003/05/23 15:23:46 mike Exp $".
4b0b2cf9 984 */