]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/testppd.c
Update svn:keyword properties.
[thirdparty/cups.git] / cups / testppd.c
1 /*
2 * "$Id$"
3 *
4 * PPD test program for CUPS.
5 *
6 * Copyright 2007-2012 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 <sys/stat.h>
28 #ifdef WIN32
29 # include <io.h>
30 #else
31 # include <unistd.h>
32 # include <fcntl.h>
33 #endif /* WIN32 */
34
35
36 /*
37 * Test data...
38 */
39
40 static const char *default_code =
41 "[{\n"
42 "%%BeginFeature: *InstalledDuplexer False\n"
43 "%%EndFeature\n"
44 "} stopped cleartomark\n"
45 "[{\n"
46 "%%BeginFeature: *PageRegion Letter\n"
47 "PageRegion=Letter\n"
48 "%%EndFeature\n"
49 "} stopped cleartomark\n"
50 "[{\n"
51 "%%BeginFeature: *InputSlot Tray\n"
52 "InputSlot=Tray\n"
53 "%%EndFeature\n"
54 "} stopped cleartomark\n"
55 "[{\n"
56 "%%BeginFeature: *MediaType Plain\n"
57 "MediaType=Plain\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: *MediaType Plain\n"
81 "MediaType=Plain\n"
82 "%%EndFeature\n"
83 "} stopped cleartomark\n"
84 "[{\n"
85 "%%BeginFeature: *IntOption None\n"
86 "%%EndFeature\n"
87 "} stopped cleartomark\n"
88 "[{\n"
89 "%%BeginFeature: *CustomStringOption True\n"
90 "(value\\0502\\051)\n"
91 "(value 1)\n"
92 "StringOption=Custom\n"
93 "%%EndFeature\n"
94 "} stopped cleartomark\n"
95 "[{\n"
96 "%%BeginFeature: *CustomPageSize True\n"
97 "400\n"
98 "500\n"
99 "0\n"
100 "0\n"
101 "0\n"
102 "PageSize=Custom\n"
103 "%%EndFeature\n"
104 "} stopped cleartomark\n";
105
106 static const char *default2_code =
107 "[{\n"
108 "%%BeginFeature: *InstalledDuplexer False\n"
109 "%%EndFeature\n"
110 "} stopped cleartomark\n"
111 "[{\n"
112 "%%BeginFeature: *InputSlot Tray\n"
113 "InputSlot=Tray\n"
114 "%%EndFeature\n"
115 "} stopped cleartomark\n"
116 "[{\n"
117 "%%BeginFeature: *Quality Normal\n"
118 "Quality=Normal\n"
119 "%%EndFeature\n"
120 "} stopped cleartomark\n"
121 "[{\n"
122 "%%BeginFeature: *IntOption None\n"
123 "%%EndFeature\n"
124 "} stopped cleartomark\n"
125 "[{\n"
126 "%%BeginFeature: *StringOption None\n"
127 "%%EndFeature\n"
128 "} stopped cleartomark\n";
129
130
131 /*
132 * 'main()' - Main entry.
133 */
134
135 int /* O - Exit status */
136 main(int argc, /* I - Number of command-line arguments */
137 char *argv[]) /* I - Command-line arguments */
138 {
139 int i; /* Looping var */
140 ppd_file_t *ppd; /* PPD file loaded from disk */
141 int status; /* Status of tests (0 = success, 1 = fail) */
142 int conflicts; /* Number of conflicts */
143 char *s; /* String */
144 char buffer[8192]; /* String buffer */
145 const char *text, /* Localized text */
146 *val; /* Option value */
147 int num_options; /* Number of options */
148 cups_option_t *options; /* Options */
149 ppd_size_t minsize, /* Minimum size */
150 maxsize, /* Maximum size */
151 *size; /* Current size */
152 ppd_attr_t *attr; /* Current attribute */
153 _ppd_cache_t *pc; /* PPD cache */
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", _PPD_LOCALIZATION_ALL)) != 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 _cups_strcasecmp(val, "Letter") ||
306 (val = cupsGetOption("PageSize", num_options, options)) == NULL ||
307 _cups_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 && !_cups_strcasecmp(options[0].name, "InputSlot") &&
357 !_cups_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 fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout);
446 num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
447 &options);
448 cupsMarkOptions(ppd, num_options, options);
449 cupsFreeOptions(num_options, options);
450
451 size = ppdPageSize(ppd, NULL);
452 if (!size || strcmp(size->name, "Letter.Fullbleed"))
453 {
454 printf("FAIL (%s)\n", size ? size->name : "unknown");
455 status ++;
456 }
457 else
458 puts("PASS");
459
460 fputs("cupsMarkOptions(media=A4): ", stdout);
461 num_options = cupsAddOption("media", "A4", 0, &options);
462 cupsMarkOptions(ppd, num_options, options);
463 cupsFreeOptions(num_options, options);
464
465 size = ppdPageSize(ppd, NULL);
466 if (!size || strcmp(size->name, "A4"))
467 {
468 printf("FAIL (%s)\n", size ? size->name : "unknown");
469 status ++;
470 }
471 else
472 puts("PASS");
473
474 /*
475 * Custom sizes...
476 */
477
478 fputs("cupsMarkOptions(media=Custom.8x10in): ", stdout);
479 num_options = cupsAddOption("media", "Custom.8x10in", 0, &options);
480 cupsMarkOptions(ppd, num_options, options);
481 cupsFreeOptions(num_options, options);
482
483 size = ppdPageSize(ppd, NULL);
484 if (!size || strcmp(size->name, "Custom") ||
485 size->width != 576 || size->length != 720)
486 {
487 printf("FAIL (%s - %gx%g)\n", size ? size->name : "unknown",
488 size ? size->width : 0.0, size ? size->length : 0.0);
489 status ++;
490 }
491 else
492 puts("PASS");
493
494 /*
495 * Test localization...
496 */
497
498 fputs("ppdLocalizeIPPReason(text): ", stdout);
499 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
500 !strcmp(buffer, "Foo Reason"))
501 puts("PASS");
502 else
503 {
504 status ++;
505 printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer);
506 }
507
508 fputs("ppdLocalizeIPPReason(http): ", stdout);
509 if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) &&
510 !strcmp(buffer, "http://foo/bar.html"))
511 puts("PASS");
512 else
513 {
514 status ++;
515 printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer);
516 }
517
518 fputs("ppdLocalizeIPPReason(help): ", stdout);
519 if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) &&
520 !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help"))
521 puts("PASS");
522 else
523 {
524 status ++;
525 printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer);
526 }
527
528 fputs("ppdLocalizeIPPReason(file): ", stdout);
529 if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) &&
530 !strcmp(buffer, "/help/foo/bar.html"))
531 puts("PASS");
532 else
533 {
534 status ++;
535 printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer);
536 }
537
538 putenv("LANG=fr");
539 putenv("LC_ALL=fr");
540 putenv("LC_CTYPE=fr");
541 putenv("LC_MESSAGES=fr");
542
543 fputs("ppdLocalizeIPPReason(fr text): ", stdout);
544 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
545 !strcmp(buffer, "La Long Foo Reason"))
546 puts("PASS");
547 else
548 {
549 status ++;
550 printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer);
551 }
552
553 putenv("LANG=zh_TW");
554 putenv("LC_ALL=zh_TW");
555 putenv("LC_CTYPE=zh_TW");
556 putenv("LC_MESSAGES=zh_TW");
557
558 fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout);
559 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
560 !strcmp(buffer, "Number 1 Foo Reason"))
561 puts("PASS");
562 else
563 {
564 status ++;
565 printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
566 }
567
568 /*
569 * cupsMarkerName localization...
570 */
571
572 putenv("LANG=en");
573 putenv("LC_ALL=en");
574 putenv("LC_CTYPE=en");
575 putenv("LC_MESSAGES=en");
576
577 fputs("ppdLocalizeMarkerName(bogus): ", stdout);
578
579 if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
580 {
581 status ++;
582 printf("FAIL (\"%s\" instead of NULL)\n", text);
583 }
584 else
585 puts("PASS");
586
587 fputs("ppdLocalizeMarkerName(cyan): ", stdout);
588
589 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
590 !strcmp(text, "Cyan Toner"))
591 puts("PASS");
592 else
593 {
594 status ++;
595 printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
596 text ? text : "(null)");
597 }
598
599 putenv("LANG=fr");
600 putenv("LC_ALL=fr");
601 putenv("LC_CTYPE=fr");
602 putenv("LC_MESSAGES=fr");
603
604 fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
605 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
606 !strcmp(text, "La Toner Cyan"))
607 puts("PASS");
608 else
609 {
610 status ++;
611 printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
612 text ? text : "(null)");
613 }
614
615 putenv("LANG=zh_TW");
616 putenv("LC_ALL=zh_TW");
617 putenv("LC_CTYPE=zh_TW");
618 putenv("LC_MESSAGES=zh_TW");
619
620 fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
621 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
622 !strcmp(text, "Number 1 Cyan Toner"))
623 puts("PASS");
624 else
625 {
626 status ++;
627 printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
628 text ? text : "(null)");
629 }
630
631 ppdClose(ppd);
632
633 /*
634 * Test new constraints...
635 */
636
637 fputs("ppdOpenFile(test2.ppd): ", stdout);
638
639 if ((ppd = ppdOpenFile("test2.ppd")) != NULL)
640 puts("PASS");
641 else
642 {
643 ppd_status_t err; /* Last error in file */
644 int line; /* Line number in file */
645
646
647 status ++;
648 err = ppdLastError(&line);
649
650 printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
651 }
652
653 fputs("ppdMarkDefaults: ", stdout);
654 ppdMarkDefaults(ppd);
655
656 if ((conflicts = ppdConflicts(ppd)) == 0)
657 puts("PASS");
658 else
659 {
660 status ++;
661 printf("FAIL (%d conflicts)\n", conflicts);
662 }
663
664 fputs("ppdEmitString (defaults): ", stdout);
665 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
666 !strcmp(s, default2_code))
667 puts("PASS");
668 else
669 {
670 status ++;
671 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
672 (int)strlen(default2_code));
673
674 if (s)
675 puts(s);
676 }
677
678 if (s)
679 free(s);
680
681 fputs("ppdConflicts(): ", stdout);
682 ppdMarkOption(ppd, "PageSize", "Env10");
683 ppdMarkOption(ppd, "InputSlot", "Envelope");
684 ppdMarkOption(ppd, "Quality", "Photo");
685
686 if ((conflicts = ppdConflicts(ppd)) == 1)
687 puts("PASS (1)");
688 else
689 {
690 printf("FAIL (%d)\n", conflicts);
691 status ++;
692 }
693
694 fputs("cupsResolveConflicts(Quality=Photo): ", stdout);
695 num_options = 0;
696 options = NULL;
697 if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
698 &options))
699 {
700 printf("FAIL (%d options:", num_options);
701 for (i = 0; i < num_options; i ++)
702 printf(" %s=%s", options[i].name, options[i].value);
703 puts(")");
704 status ++;
705 }
706 else
707 puts("PASS (Unable to resolve)");
708 cupsFreeOptions(num_options, options);
709
710 fputs("cupsResolveConflicts(No option/choice): ", stdout);
711 num_options = 0;
712 options = NULL;
713 if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
714 num_options == 1 && !_cups_strcasecmp(options->name, "Quality") &&
715 !_cups_strcasecmp(options->value, "Normal"))
716 puts("PASS");
717 else if (num_options > 0)
718 {
719 printf("FAIL (%d options:", num_options);
720 for (i = 0; i < num_options; i ++)
721 printf(" %s=%s", options[i].name, options[i].value);
722 puts(")");
723 status ++;
724 }
725 else
726 {
727 puts("FAIL (Unable to resolve!)");
728 status ++;
729 }
730 cupsFreeOptions(num_options, options);
731
732 fputs("cupsResolveConflicts(loop test): ", stdout);
733 ppdMarkOption(ppd, "PageSize", "A4");
734 ppdMarkOption(ppd, "InputSlot", "Tray");
735 ppdMarkOption(ppd, "Quality", "Photo");
736 num_options = 0;
737 options = NULL;
738 if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
739 puts("PASS");
740 else if (num_options > 0)
741 {
742 printf("FAIL (%d options:", num_options);
743 for (i = 0; i < num_options; i ++)
744 printf(" %s=%s", options[i].name, options[i].value);
745 puts(")");
746 }
747 else
748 puts("FAIL (No conflicts!)");
749
750 fputs("ppdInstallableConflict(): ", stdout);
751 if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
752 !ppdInstallableConflict(ppd, "Duplex", "None"))
753 puts("PASS");
754 else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
755 {
756 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
757 status ++;
758 }
759 else
760 {
761 puts("FAIL (Duplex=None conflicted)");
762 status ++;
763 }
764
765 /*
766 * ppdPageSizeLimits
767 */
768
769 ppdMarkDefaults(ppd);
770
771 fputs("ppdPageSizeLimits(default): ", stdout);
772 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
773 {
774 if (minsize.width != 36 || minsize.length != 36 ||
775 maxsize.width != 1080 || maxsize.length != 86400)
776 {
777 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
778 "expected min=36x36, max=1080x86400)\n", minsize.width,
779 minsize.length, maxsize.width, maxsize.length);
780 status ++;
781 }
782 else
783 puts("PASS");
784 }
785 else
786 {
787 puts("FAIL (returned 0)");
788 status ++;
789 }
790
791 ppdMarkOption(ppd, "InputSlot", "Manual");
792
793 fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout);
794 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
795 {
796 if (minsize.width != 100 || minsize.length != 100 ||
797 maxsize.width != 1000 || maxsize.length != 1000)
798 {
799 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
800 "expected min=100x100, max=1000x1000)\n", minsize.width,
801 minsize.length, maxsize.width, maxsize.length);
802 status ++;
803 }
804 else
805 puts("PASS");
806 }
807 else
808 {
809 puts("FAIL (returned 0)");
810 status ++;
811 }
812
813 ppdMarkOption(ppd, "Quality", "Photo");
814
815 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
816 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
817 {
818 if (minsize.width != 200 || minsize.length != 200 ||
819 maxsize.width != 1000 || maxsize.length != 1000)
820 {
821 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
822 "expected min=200x200, max=1000x1000)\n", minsize.width,
823 minsize.length, maxsize.width, maxsize.length);
824 status ++;
825 }
826 else
827 puts("PASS");
828 }
829 else
830 {
831 puts("FAIL (returned 0)");
832 status ++;
833 }
834
835 ppdMarkOption(ppd, "InputSlot", "Tray");
836
837 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
838 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
839 {
840 if (minsize.width != 300 || minsize.length != 300 ||
841 maxsize.width != 1080 || maxsize.length != 86400)
842 {
843 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
844 "expected min=300x300, max=1080x86400)\n", minsize.width,
845 minsize.length, maxsize.width, maxsize.length);
846 status ++;
847 }
848 else
849 puts("PASS");
850 }
851 else
852 {
853 puts("FAIL (returned 0)");
854 status ++;
855 }
856 }
857 else
858 {
859 const char *filename; /* PPD filename */
860 struct stat fileinfo; /* File information */
861
862
863 if (!strncmp(argv[1], "-d", 2))
864 {
865 const char *printer; /* Printer name */
866
867 if (argv[1][2])
868 printer = argv[1] + 2;
869 else if (argv[2])
870 printer = argv[2];
871 else
872 {
873 puts("Usage: ./testppd -d printer");
874 return (1);
875 }
876
877 filename = cupsGetPPD(printer);
878
879 if (!filename)
880 {
881 printf("%s: %s\n", printer, cupsLastErrorString());
882 return (1);
883 }
884 }
885 else
886 filename = argv[1];
887
888 if (lstat(filename, &fileinfo))
889 {
890 printf("%s: %s\n", filename, strerror(errno));
891 return (1);
892 }
893
894 if (S_ISLNK(fileinfo.st_mode))
895 {
896 char realfile[1024]; /* Real file path */
897 ssize_t realsize; /* Size of real file path */
898
899
900 if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0)
901 strlcpy(realfile, "Unknown", sizeof(realfile));
902 else
903 realfile[realsize] = '\0';
904
905 if (stat(realfile, &fileinfo))
906 printf("%s: symlink to \"%s\", %s\n", filename, realfile,
907 strerror(errno));
908 else
909 printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile,
910 (long)fileinfo.st_size);
911 }
912 else
913 printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size);
914
915 if ((ppd = ppdOpenFile(filename)) == NULL)
916 {
917 ppd_status_t err; /* Last error in file */
918 int line; /* Line number in file */
919
920
921 status ++;
922 err = ppdLastError(&line);
923
924 printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
925 }
926 else
927 {
928 int j, k; /* Looping vars */
929 ppd_group_t *group; /* Option group */
930 ppd_option_t *option; /* Option */
931 ppd_coption_t *coption; /* Custom option */
932 ppd_cparam_t *cparam; /* Custom parameter */
933 ppd_const_t *c; /* UIConstraints */
934 char lang[255], /* LANG environment variable */
935 lc_all[255], /* LC_ALL environment variable */
936 lc_ctype[255], /* LC_CTYPE environment variable */
937 lc_messages[255];/* LC_MESSAGES environment variable */
938
939
940 if (argc > 2)
941 {
942 snprintf(lang, sizeof(lang), "LANG=%s", argv[2]);
943 putenv(lang);
944 snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]);
945 putenv(lc_all);
946 snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]);
947 putenv(lc_ctype);
948 snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]);
949 putenv(lc_messages);
950 }
951
952 ppdLocalize(ppd);
953 ppdMarkDefaults(ppd);
954
955 if (argc > 3)
956 {
957 text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer));
958 printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3],
959 text ? text : "(null)");
960 return (text == NULL);
961 }
962
963 for (i = ppd->num_groups, group = ppd->groups;
964 i > 0;
965 i --, group ++)
966 {
967 printf("%s (%s):\n", group->name, group->text);
968
969 for (j = group->num_options, option = group->options;
970 j > 0;
971 j --, option ++)
972 {
973 printf(" %s (%s):\n", option->keyword, option->text);
974
975 for (k = 0; k < option->num_choices; k ++)
976 printf(" - %s%s (%s)\n",
977 option->choices[k].marked ? "*" : "",
978 option->choices[k].choice, option->choices[k].text);
979
980 if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
981 {
982 for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
983 cparam;
984 cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
985 {
986 switch (cparam->type)
987 {
988 case PPD_CUSTOM_CURVE :
989 printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
990 cparam->name, cparam->text,
991 cparam->minimum.custom_curve,
992 cparam->maximum.custom_curve);
993 break;
994
995 case PPD_CUSTOM_INT :
996 printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
997 cparam->name, cparam->text,
998 cparam->minimum.custom_int,
999 cparam->maximum.custom_int);
1000 break;
1001
1002 case PPD_CUSTOM_INVCURVE :
1003 printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
1004 cparam->name, cparam->text,
1005 cparam->minimum.custom_invcurve,
1006 cparam->maximum.custom_invcurve);
1007 break;
1008
1009 case PPD_CUSTOM_PASSCODE :
1010 printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
1011 cparam->name, cparam->text,
1012 cparam->minimum.custom_passcode,
1013 cparam->maximum.custom_passcode);
1014 break;
1015
1016 case PPD_CUSTOM_PASSWORD :
1017 printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
1018 cparam->name, cparam->text,
1019 cparam->minimum.custom_password,
1020 cparam->maximum.custom_password);
1021 break;
1022
1023 case PPD_CUSTOM_POINTS :
1024 printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
1025 cparam->name, cparam->text,
1026 cparam->minimum.custom_points,
1027 cparam->maximum.custom_points);
1028 break;
1029
1030 case PPD_CUSTOM_REAL :
1031 printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
1032 cparam->name, cparam->text,
1033 cparam->minimum.custom_real,
1034 cparam->maximum.custom_real);
1035 break;
1036
1037 case PPD_CUSTOM_STRING :
1038 printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
1039 cparam->name, cparam->text,
1040 cparam->minimum.custom_string,
1041 cparam->maximum.custom_string);
1042 break;
1043 }
1044 }
1045 }
1046 }
1047 }
1048
1049 puts("\nSizes:");
1050 for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
1051 printf(" %s = %gx%g, [%g %g %g %g]\n", size->name, size->width,
1052 size->length, size->left, size->bottom, size->right, size->top);
1053
1054 puts("\nConstraints:");
1055
1056 for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
1057 printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
1058 c->option2, c->choice2);
1059 if (ppd->num_consts == 0)
1060 puts(" NO CONSTRAINTS");
1061
1062 puts("\nFilters:");
1063
1064 for (i = 0; i < ppd->num_filters; i ++)
1065 printf(" %s\n", ppd->filters[i]);
1066
1067 if (ppd->num_filters == 0)
1068 puts(" NO FILTERS");
1069
1070 puts("\nAttributes:");
1071
1072 for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
1073 attr;
1074 attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
1075 printf(" *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
1076 attr->text, attr->value ? attr->value : "");
1077
1078 puts("\nPPD Cache:");
1079 if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
1080 printf(" Unable to create: %s\n", cupsLastErrorString());
1081 else
1082 {
1083 _ppdCacheWriteFile(pc, "t.cache", NULL);
1084 puts(" Wrote t.cache.");
1085 }
1086 }
1087
1088 if (!strncmp(argv[1], "-d", 2))
1089 unlink(filename);
1090 }
1091
1092 #ifdef __APPLE__
1093 if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
1094 {
1095 char command[1024]; /* malloc_history command */
1096
1097 snprintf(command, sizeof(command), "malloc_history %d -all_by_size",
1098 getpid());
1099 fflush(stdout);
1100 system(command);
1101 }
1102 #endif /* __APPLE__ */
1103
1104 ppdClose(ppd);
1105
1106 return (status);
1107 }
1108
1109
1110 /*
1111 * End of "$Id$".
1112 */