]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/testppd.c
Merge changes from CUPS 1.5svn-r9041.
[thirdparty/cups.git] / cups / testppd.c
1 /*
2 * "$Id: testppd.c 7897 2008-09-02 19:33:19Z mike $"
3 *
4 * PPD test program for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
8 *
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/".
14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
19 * main() - Main entry.
20 */
21
22 /*
23 * Include necessary headers...
24 */
25
26 #include <cups/cups.h>
27 #include <cups/string.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #ifdef WIN32
33 # include <io.h>
34 #else
35 # include <unistd.h>
36 # include <fcntl.h>
37 #endif /* WIN32 */
38
39
40 /*
41 * Test data...
42 */
43
44 static const char *default_code =
45 "[{\n"
46 "%%BeginFeature: *InstalledDuplexer False\n"
47 "%%EndFeature\n"
48 "} stopped cleartomark\n"
49 "[{\n"
50 "%%BeginFeature: *PageRegion Letter\n"
51 "PageRegion=Letter\n"
52 "%%EndFeature\n"
53 "} stopped cleartomark\n"
54 "[{\n"
55 "%%BeginFeature: *InputSlot Tray\n"
56 "InputSlot=Tray\n"
57 "%%EndFeature\n"
58 "} stopped cleartomark\n"
59 "[{\n"
60 "%%BeginFeature: *MediaType Plain\n"
61 "MediaType=Plain\n"
62 "%%EndFeature\n"
63 "} stopped cleartomark\n"
64 "[{\n"
65 "%%BeginFeature: *IntOption None\n"
66 "%%EndFeature\n"
67 "} stopped cleartomark\n"
68 "[{\n"
69 "%%BeginFeature: *StringOption None\n"
70 "%%EndFeature\n"
71 "} stopped cleartomark\n";
72
73 static const char *custom_code =
74 "[{\n"
75 "%%BeginFeature: *InstalledDuplexer False\n"
76 "%%EndFeature\n"
77 "} stopped cleartomark\n"
78 "[{\n"
79 "%%BeginFeature: *InputSlot Tray\n"
80 "InputSlot=Tray\n"
81 "%%EndFeature\n"
82 "} stopped cleartomark\n"
83 "[{\n"
84 "%%BeginFeature: *MediaType Plain\n"
85 "MediaType=Plain\n"
86 "%%EndFeature\n"
87 "} stopped cleartomark\n"
88 "[{\n"
89 "%%BeginFeature: *IntOption None\n"
90 "%%EndFeature\n"
91 "} stopped cleartomark\n"
92 "[{\n"
93 "%%BeginFeature: *CustomStringOption True\n"
94 "(value\\0502\\051)\n"
95 "(value 1)\n"
96 "StringOption=Custom\n"
97 "%%EndFeature\n"
98 "} stopped cleartomark\n"
99 "[{\n"
100 "%%BeginFeature: *CustomPageSize True\n"
101 "400\n"
102 "500\n"
103 "0\n"
104 "0\n"
105 "0\n"
106 "PageSize=Custom\n"
107 "%%EndFeature\n"
108 "} stopped cleartomark\n";
109
110 static const char *default2_code =
111 "[{\n"
112 "%%BeginFeature: *InstalledDuplexer False\n"
113 "%%EndFeature\n"
114 "} stopped cleartomark\n"
115 "[{\n"
116 "%%BeginFeature: *InputSlot Tray\n"
117 "InputSlot=Tray\n"
118 "%%EndFeature\n"
119 "} stopped cleartomark\n"
120 "[{\n"
121 "%%BeginFeature: *Quality Normal\n"
122 "Quality=Normal\n"
123 "%%EndFeature\n"
124 "} stopped cleartomark\n"
125 "[{\n"
126 "%%BeginFeature: *IntOption None\n"
127 "%%EndFeature\n"
128 "} stopped cleartomark\n"
129 "[{\n"
130 "%%BeginFeature: *StringOption None\n"
131 "%%EndFeature\n"
132 "} stopped cleartomark\n";
133
134
135 /*
136 * 'main()' - Main entry.
137 */
138
139 int /* O - Exit status */
140 main(int argc, /* I - Number of command-line arguments */
141 char *argv[]) /* I - Command-line arguments */
142 {
143 int i; /* Looping var */
144 ppd_file_t *ppd; /* PPD file loaded from disk */
145 int status; /* Status of tests (0 = success, 1 = fail) */
146 int conflicts; /* Number of conflicts */
147 char *s; /* String */
148 char buffer[8192]; /* String buffer */
149 const char *text, /* Localized text */
150 *val; /* Option value */
151 int num_options; /* Number of options */
152 cups_option_t *options; /* Options */
153 ppd_size_t minsize, /* Minimum size */
154 maxsize, /* Maximum size */
155 *size; /* Current size */
156 ppd_attr_t *attr; /* Current attribute */
157
158
159 status = 0;
160
161 if (argc == 1)
162 {
163 /*
164 * Setup directories for locale stuff...
165 */
166
167 if (access("locale", 0))
168 {
169 mkdir("locale", 0777);
170 mkdir("locale/fr", 0777);
171 symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
172 mkdir("locale/zh_TW", 0777);
173 symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
174 }
175
176 putenv("LOCALEDIR=locale");
177 putenv("SOFTWARE=CUPS");
178
179 /*
180 * Do tests with test.ppd...
181 */
182
183 fputs("ppdOpenFile(test.ppd): ", stdout);
184
185 if ((ppd = ppdOpenFile("test.ppd")) != NULL)
186 puts("PASS");
187 else
188 {
189 ppd_status_t err; /* Last error in file */
190 int line; /* Line number in file */
191
192
193 status ++;
194 err = ppdLastError(&line);
195
196 printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
197 }
198
199 fputs("ppdFindAttr(wildcard): ", stdout);
200 if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL)
201 {
202 status ++;
203 puts("FAIL (not found)");
204 }
205 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
206 {
207 status ++;
208 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
209 }
210 else
211 puts("PASS");
212
213 fputs("ppdFindNextAttr(wildcard): ", stdout);
214 if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL)
215 {
216 status ++;
217 puts("FAIL (not found)");
218 }
219 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar"))
220 {
221 status ++;
222 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
223 }
224 else
225 puts("PASS");
226
227 fputs("ppdFindAttr(Foo): ", stdout);
228 if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL)
229 {
230 status ++;
231 puts("FAIL (not found)");
232 }
233 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
234 {
235 status ++;
236 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
237 }
238 else
239 puts("PASS");
240
241 fputs("ppdFindNextAttr(Foo): ", stdout);
242 if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL)
243 {
244 status ++;
245 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
246 }
247 else
248 puts("PASS");
249
250 fputs("ppdMarkDefaults: ", stdout);
251 ppdMarkDefaults(ppd);
252
253 if ((conflicts = ppdConflicts(ppd)) == 0)
254 puts("PASS");
255 else
256 {
257 status ++;
258 printf("FAIL (%d conflicts)\n", conflicts);
259 }
260
261 fputs("ppdEmitString (defaults): ", stdout);
262 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
263 !strcmp(s, default_code))
264 puts("PASS");
265 else
266 {
267 status ++;
268 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
269 (int)strlen(default_code));
270
271 if (s)
272 puts(s);
273 }
274
275 if (s)
276 free(s);
277
278 fputs("ppdEmitString (custom size and string): ", stdout);
279 ppdMarkOption(ppd, "PageSize", "Custom.400x500");
280 ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}");
281
282 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
283 !strcmp(s, custom_code))
284 puts("PASS");
285 else
286 {
287 status ++;
288 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
289 (int)strlen(custom_code));
290
291 if (s)
292 puts(s);
293 }
294
295 if (s)
296 free(s);
297
298 /*
299 * Test constraints...
300 */
301
302 fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout);
303 ppdMarkOption(ppd, "PageSize", "Letter");
304
305 num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options);
306 if (num_options != 2 ||
307 (val = cupsGetOption("PageRegion", num_options, options)) == NULL ||
308 strcasecmp(val, "Letter") ||
309 (val = cupsGetOption("PageSize", num_options, options)) == NULL ||
310 strcasecmp(val, "Letter"))
311 {
312 printf("FAIL (%d options:", num_options);
313 for (i = 0; i < num_options; i ++)
314 printf(" %s=%s", options[i].name, options[i].value);
315 puts(")");
316 status ++;
317 }
318 else
319 puts("PASS");
320
321 fputs("ppdConflicts(): ", stdout);
322 ppdMarkOption(ppd, "InputSlot", "Envelope");
323
324 if ((conflicts = ppdConflicts(ppd)) == 2)
325 puts("PASS (2)");
326 else
327 {
328 printf("FAIL (%d)\n", conflicts);
329 status ++;
330 }
331
332 fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout);
333 num_options = 0;
334 options = NULL;
335 if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options,
336 &options))
337 {
338 puts("FAIL (Unable to resolve)");
339 status ++;
340 }
341 else if (num_options != 2 ||
342 !cupsGetOption("PageSize", num_options, options))
343 {
344 printf("FAIL (%d options:", num_options);
345 for (i = 0; i < num_options; i ++)
346 printf(" %s=%s", options[i].name, options[i].value);
347 puts(")");
348 status ++;
349 }
350 else
351 puts("PASS (Resolved by changing PageSize)");
352
353 cupsFreeOptions(num_options, options);
354
355 fputs("cupsResolveConflicts(No option/choice): ", stdout);
356 num_options = 0;
357 options = NULL;
358 if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
359 num_options == 1 && !strcasecmp(options[0].name, "InputSlot") &&
360 !strcasecmp(options[0].value, "Tray"))
361 puts("PASS (Resolved by changing InputSlot)");
362 else if (num_options > 0)
363 {
364 printf("FAIL (%d options:", num_options);
365 for (i = 0; i < num_options; i ++)
366 printf(" %s=%s", options[i].name, options[i].value);
367 puts(")");
368 status ++;
369 }
370 else
371 {
372 puts("FAIL (Unable to resolve)");
373 status ++;
374 }
375 cupsFreeOptions(num_options, options);
376
377 fputs("ppdInstallableConflict(): ", stdout);
378 if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
379 !ppdInstallableConflict(ppd, "Duplex", "None"))
380 puts("PASS");
381 else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
382 {
383 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
384 status ++;
385 }
386 else
387 {
388 puts("FAIL (Duplex=None conflicted)");
389 status ++;
390 }
391
392 /*
393 * ppdPageSizeLimits
394 */
395
396 fputs("ppdPageSizeLimits: ", stdout);
397 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
398 {
399 if (minsize.width != 36 || minsize.length != 36 ||
400 maxsize.width != 1080 || maxsize.length != 86400)
401 {
402 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
403 "expected min=36x36, max=1080x86400)\n", minsize.width,
404 minsize.length, maxsize.width, maxsize.length);
405 status ++;
406 }
407 else
408 puts("PASS");
409 }
410 else
411 {
412 puts("FAIL (returned 0)");
413 status ++;
414 }
415
416 /*
417 * cupsMarkOptions with PWG and IPP size names.
418 */
419
420 fputs("cupsMarkOptions(media=iso-a4): ", stdout);
421 num_options = cupsAddOption("media", "iso-a4", 0, &options);
422 cupsMarkOptions(ppd, num_options, options);
423 cupsFreeOptions(num_options, options);
424
425 size = ppdPageSize(ppd, NULL);
426 if (!size || strcmp(size->name, "A4"))
427 {
428 printf("FAIL (%s)\n", size ? size->name : "unknown");
429 status ++;
430 }
431 else
432 puts("PASS");
433
434 fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout);
435 num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options);
436 cupsMarkOptions(ppd, num_options, options);
437 cupsFreeOptions(num_options, options);
438
439 size = ppdPageSize(ppd, NULL);
440 if (!size || strcmp(size->name, "Letter"))
441 {
442 printf("FAIL (%s)\n", size ? size->name : "unknown");
443 status ++;
444 }
445 else
446 puts("PASS");
447
448 /*
449 * Test localization...
450 */
451
452 fputs("ppdLocalizeIPPReason(text): ", stdout);
453 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
454 !strcmp(buffer, "Foo Reason"))
455 puts("PASS");
456 else
457 {
458 status ++;
459 printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer);
460 }
461
462 fputs("ppdLocalizeIPPReason(http): ", stdout);
463 if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) &&
464 !strcmp(buffer, "http://foo/bar.html"))
465 puts("PASS");
466 else
467 {
468 status ++;
469 printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer);
470 }
471
472 fputs("ppdLocalizeIPPReason(help): ", stdout);
473 if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) &&
474 !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help"))
475 puts("PASS");
476 else
477 {
478 status ++;
479 printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer);
480 }
481
482 fputs("ppdLocalizeIPPReason(file): ", stdout);
483 if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) &&
484 !strcmp(buffer, "/help/foo/bar.html"))
485 puts("PASS");
486 else
487 {
488 status ++;
489 printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer);
490 }
491
492 putenv("LANG=fr");
493 putenv("LC_ALL=fr");
494 putenv("LC_CTYPE=fr");
495 putenv("LC_MESSAGES=fr");
496
497 fputs("ppdLocalizeIPPReason(fr text): ", stdout);
498 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
499 !strcmp(buffer, "La Long Foo Reason"))
500 puts("PASS");
501 else
502 {
503 status ++;
504 printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer);
505 }
506
507 putenv("LANG=zh_TW");
508 putenv("LC_ALL=zh_TW");
509 putenv("LC_CTYPE=zh_TW");
510 putenv("LC_MESSAGES=zh_TW");
511
512 fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout);
513 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
514 !strcmp(buffer, "Number 1 Foo Reason"))
515 puts("PASS");
516 else
517 {
518 status ++;
519 printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
520 }
521
522 /*
523 * cupsMarkerName localization...
524 */
525
526 putenv("LANG=en");
527 putenv("LC_ALL=en");
528 putenv("LC_CTYPE=en");
529 putenv("LC_MESSAGES=en");
530
531 fputs("ppdLocalizeMarkerName(bogus): ", stdout);
532
533 if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
534 {
535 status ++;
536 printf("FAIL (\"%s\" instead of NULL)\n", text);
537 }
538 else
539 puts("PASS");
540
541 fputs("ppdLocalizeMarkerName(cyan): ", stdout);
542
543 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
544 !strcmp(text, "Cyan Toner"))
545 puts("PASS");
546 else
547 {
548 status ++;
549 printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
550 text ? text : "(null)");
551 }
552
553 putenv("LANG=fr");
554 putenv("LC_ALL=fr");
555 putenv("LC_CTYPE=fr");
556 putenv("LC_MESSAGES=fr");
557
558 fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
559 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
560 !strcmp(text, "La Toner Cyan"))
561 puts("PASS");
562 else
563 {
564 status ++;
565 printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
566 text ? text : "(null)");
567 }
568
569 putenv("LANG=zh_TW");
570 putenv("LC_ALL=zh_TW");
571 putenv("LC_CTYPE=zh_TW");
572 putenv("LC_MESSAGES=zh_TW");
573
574 fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
575 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
576 !strcmp(text, "Number 1 Cyan Toner"))
577 puts("PASS");
578 else
579 {
580 status ++;
581 printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
582 text ? text : "(null)");
583 }
584
585 ppdClose(ppd);
586
587 /*
588 * Test new constraints...
589 */
590
591 fputs("ppdOpenFile(test2.ppd): ", stdout);
592
593 if ((ppd = ppdOpenFile("test2.ppd")) != NULL)
594 puts("PASS");
595 else
596 {
597 ppd_status_t err; /* Last error in file */
598 int line; /* Line number in file */
599
600
601 status ++;
602 err = ppdLastError(&line);
603
604 printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
605 }
606
607 fputs("ppdMarkDefaults: ", stdout);
608 ppdMarkDefaults(ppd);
609
610 if ((conflicts = ppdConflicts(ppd)) == 0)
611 puts("PASS");
612 else
613 {
614 status ++;
615 printf("FAIL (%d conflicts)\n", conflicts);
616 }
617
618 fputs("ppdEmitString (defaults): ", stdout);
619 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
620 !strcmp(s, default2_code))
621 puts("PASS");
622 else
623 {
624 status ++;
625 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
626 (int)strlen(default2_code));
627
628 if (s)
629 puts(s);
630 }
631
632 if (s)
633 free(s);
634
635 fputs("ppdConflicts(): ", stdout);
636 ppdMarkOption(ppd, "PageSize", "Env10");
637 ppdMarkOption(ppd, "InputSlot", "Envelope");
638 ppdMarkOption(ppd, "Quality", "Photo");
639
640 if ((conflicts = ppdConflicts(ppd)) == 1)
641 puts("PASS (1)");
642 else
643 {
644 printf("FAIL (%d)\n", conflicts);
645 status ++;
646 }
647
648 fputs("cupsResolveConflicts(Quality=Photo): ", stdout);
649 num_options = 0;
650 options = NULL;
651 if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
652 &options))
653 {
654 printf("FAIL (%d options:", num_options);
655 for (i = 0; i < num_options; i ++)
656 printf(" %s=%s", options[i].name, options[i].value);
657 puts(")");
658 status ++;
659 }
660 else
661 puts("PASS (Unable to resolve)");
662 cupsFreeOptions(num_options, options);
663
664 fputs("cupsResolveConflicts(No option/choice): ", stdout);
665 num_options = 0;
666 options = NULL;
667 if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
668 num_options == 1 && !strcasecmp(options->name, "Quality") &&
669 !strcasecmp(options->value, "Normal"))
670 puts("PASS");
671 else if (num_options > 0)
672 {
673 printf("FAIL (%d options:", num_options);
674 for (i = 0; i < num_options; i ++)
675 printf(" %s=%s", options[i].name, options[i].value);
676 puts(")");
677 status ++;
678 }
679 else
680 {
681 puts("FAIL (Unable to resolve!)");
682 status ++;
683 }
684 cupsFreeOptions(num_options, options);
685
686 fputs("cupsResolveConflicts(loop test): ", stdout);
687 ppdMarkOption(ppd, "PageSize", "A4");
688 ppdMarkOption(ppd, "InputSlot", "Tray");
689 ppdMarkOption(ppd, "Quality", "Photo");
690 num_options = 0;
691 options = NULL;
692 if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
693 puts("PASS");
694 else if (num_options > 0)
695 {
696 printf("FAIL (%d options:", num_options);
697 for (i = 0; i < num_options; i ++)
698 printf(" %s=%s", options[i].name, options[i].value);
699 puts(")");
700 }
701 else
702 puts("FAIL (No conflicts!)");
703
704 fputs("ppdInstallableConflict(): ", stdout);
705 if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
706 !ppdInstallableConflict(ppd, "Duplex", "None"))
707 puts("PASS");
708 else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
709 {
710 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
711 status ++;
712 }
713 else
714 {
715 puts("FAIL (Duplex=None conflicted)");
716 status ++;
717 }
718
719 /*
720 * ppdPageSizeLimits
721 */
722
723 ppdMarkDefaults(ppd);
724
725 fputs("ppdPageSizeLimits(default): ", stdout);
726 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
727 {
728 if (minsize.width != 36 || minsize.length != 36 ||
729 maxsize.width != 1080 || maxsize.length != 86400)
730 {
731 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
732 "expected min=36x36, max=1080x86400)\n", minsize.width,
733 minsize.length, maxsize.width, maxsize.length);
734 status ++;
735 }
736 else
737 puts("PASS");
738 }
739 else
740 {
741 puts("FAIL (returned 0)");
742 status ++;
743 }
744
745 ppdMarkOption(ppd, "InputSlot", "Manual");
746
747 fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout);
748 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
749 {
750 if (minsize.width != 100 || minsize.length != 100 ||
751 maxsize.width != 1000 || maxsize.length != 1000)
752 {
753 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
754 "expected min=100x100, max=1000x1000)\n", minsize.width,
755 minsize.length, maxsize.width, maxsize.length);
756 status ++;
757 }
758 else
759 puts("PASS");
760 }
761 else
762 {
763 puts("FAIL (returned 0)");
764 status ++;
765 }
766
767 ppdMarkOption(ppd, "Quality", "Photo");
768
769 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
770 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
771 {
772 if (minsize.width != 200 || minsize.length != 200 ||
773 maxsize.width != 1000 || maxsize.length != 1000)
774 {
775 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
776 "expected min=200x200, max=1000x1000)\n", minsize.width,
777 minsize.length, maxsize.width, maxsize.length);
778 status ++;
779 }
780 else
781 puts("PASS");
782 }
783 else
784 {
785 puts("FAIL (returned 0)");
786 status ++;
787 }
788
789 ppdMarkOption(ppd, "InputSlot", "Tray");
790
791 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
792 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
793 {
794 if (minsize.width != 300 || minsize.length != 300 ||
795 maxsize.width != 1080 || maxsize.length != 86400)
796 {
797 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
798 "expected min=300x300, max=1080x86400)\n", minsize.width,
799 minsize.length, maxsize.width, maxsize.length);
800 status ++;
801 }
802 else
803 puts("PASS");
804 }
805 else
806 {
807 puts("FAIL (returned 0)");
808 status ++;
809 }
810 }
811 else
812 {
813 const char *filename; /* PPD filename */
814 struct stat fileinfo; /* File information */
815
816
817 if (!strncmp(argv[1], "-d", 2))
818 {
819 filename = cupsGetPPD(argv[1] + 2);
820 if (!filename)
821 {
822 printf("%s: %s\n", argv[1], cupsLastErrorString());
823 return (1);
824 }
825 }
826 else
827 filename = argv[1];
828
829 if (lstat(filename, &fileinfo))
830 {
831 printf("%s: %s\n", filename, strerror(errno));
832 return (1);
833 }
834
835 if (S_ISLNK(fileinfo.st_mode))
836 {
837 char realfile[1024]; /* Real file path */
838 ssize_t realsize; /* Size of real file path */
839
840
841 if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0)
842 strcpy(realfile, "Unknown");
843 else
844 realfile[realsize] = '\0';
845
846 if (stat(realfile, &fileinfo))
847 printf("%s: symlink to \"%s\", %s\n", filename, realfile,
848 strerror(errno));
849 else
850 printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile,
851 (long)fileinfo.st_size);
852 }
853 else
854 printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size);
855
856 if ((ppd = ppdOpenFile(filename)) == NULL)
857 {
858 ppd_status_t err; /* Last error in file */
859 int line; /* Line number in file */
860
861
862 status ++;
863 err = ppdLastError(&line);
864
865 printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
866 }
867 else
868 {
869 int j, k; /* Looping vars */
870 ppd_group_t *group; /* Option group */
871 ppd_option_t *option; /* Option */
872 ppd_coption_t *coption; /* Custom option */
873 ppd_cparam_t *cparam; /* Custom parameter */
874 ppd_const_t *c; /* UIConstraints */
875 char lang[255], /* LANG environment variable */
876 lc_all[255], /* LC_ALL environment variable */
877 lc_ctype[255], /* LC_CTYPE environment variable */
878 lc_messages[255];/* LC_MESSAGES environment variable */
879
880
881 if (argc > 2)
882 {
883 snprintf(lang, sizeof(lang), "LANG=%s", argv[2]);
884 putenv(lang);
885 snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]);
886 putenv(lc_all);
887 snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]);
888 putenv(lc_ctype);
889 snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]);
890 putenv(lc_messages);
891 }
892
893 ppdLocalize(ppd);
894 ppdMarkDefaults(ppd);
895
896 if (argc > 3)
897 {
898 text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer));
899 printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3],
900 text ? text : "(null)");
901 return (text == NULL);
902 }
903
904 for (i = ppd->num_groups, group = ppd->groups;
905 i > 0;
906 i --, group ++)
907 {
908 printf("%s (%s):\n", group->name, group->text);
909
910 for (j = group->num_options, option = group->options;
911 j > 0;
912 j --, option ++)
913 {
914 printf(" %s (%s):\n", option->keyword, option->text);
915
916 for (k = 0; k < option->num_choices; k ++)
917 printf(" - %s%s (%s)\n",
918 option->choices[k].marked ? "*" : "",
919 option->choices[k].choice, option->choices[k].text);
920
921 if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
922 {
923 for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
924 cparam;
925 cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
926 {
927 switch (cparam->type)
928 {
929 case PPD_CUSTOM_CURVE :
930 printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
931 cparam->name, cparam->text,
932 cparam->minimum.custom_curve,
933 cparam->maximum.custom_curve);
934 break;
935
936 case PPD_CUSTOM_INT :
937 printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
938 cparam->name, cparam->text,
939 cparam->minimum.custom_int,
940 cparam->maximum.custom_int);
941 break;
942
943 case PPD_CUSTOM_INVCURVE :
944 printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
945 cparam->name, cparam->text,
946 cparam->minimum.custom_invcurve,
947 cparam->maximum.custom_invcurve);
948 break;
949
950 case PPD_CUSTOM_PASSCODE :
951 printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
952 cparam->name, cparam->text,
953 cparam->minimum.custom_passcode,
954 cparam->maximum.custom_passcode);
955 break;
956
957 case PPD_CUSTOM_PASSWORD :
958 printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
959 cparam->name, cparam->text,
960 cparam->minimum.custom_password,
961 cparam->maximum.custom_password);
962 break;
963
964 case PPD_CUSTOM_POINTS :
965 printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
966 cparam->name, cparam->text,
967 cparam->minimum.custom_points,
968 cparam->maximum.custom_points);
969 break;
970
971 case PPD_CUSTOM_REAL :
972 printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
973 cparam->name, cparam->text,
974 cparam->minimum.custom_real,
975 cparam->maximum.custom_real);
976 break;
977
978 case PPD_CUSTOM_STRING :
979 printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
980 cparam->name, cparam->text,
981 cparam->minimum.custom_string,
982 cparam->maximum.custom_string);
983 break;
984 }
985 }
986 }
987 }
988 }
989
990 puts("\nConstraints:");
991
992 for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
993 printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
994 c->option2, c->choice2);
995 if (ppd->num_consts == 0)
996 puts(" NO CONSTRAINTS");
997
998 puts("\nFilters:");
999
1000 for (i = 0; i < ppd->num_filters; i ++)
1001 printf(" %s\n", ppd->filters[i]);
1002
1003 if (ppd->num_filters == 0)
1004 puts(" NO FILTERS");
1005
1006 puts("\nAttributes:");
1007
1008 for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
1009 attr;
1010 attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
1011 printf(" *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
1012 attr->text, attr->value ? attr->value : "");
1013 }
1014
1015 if (!strncmp(argv[1], "-d", 2))
1016 unlink(filename);
1017 }
1018
1019 #ifdef __APPLE__
1020 if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
1021 {
1022 char command[1024]; /* malloc_history command */
1023
1024 snprintf(command, sizeof(command), "malloc_history %d -all_by_size",
1025 getpid());
1026 fflush(stdout);
1027 system(command);
1028 }
1029 #endif /* __APPLE__ */
1030
1031 ppdClose(ppd);
1032
1033 return (status);
1034 }
1035
1036
1037 /*
1038 * End of "$Id: testppd.c 7897 2008-09-02 19:33:19Z mike $".
1039 */