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