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