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