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