]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/testppd.c
2 * "$Id: testppd.c 7897 2008-09-02 19:33:19Z mike $"
4 * PPD test program for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
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/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * main() - Main entry.
23 * Include necessary headers...
28 #include <cups/string.h>
44 static const char *default_code
=
46 "%%BeginFeature: *InstalledDuplexer False\n"
48 "} stopped cleartomark\n"
50 "%%BeginFeature: *PageRegion Letter\n"
53 "} stopped cleartomark\n"
55 "%%BeginFeature: *InputSlot Tray\n"
58 "} stopped cleartomark\n"
60 "%%BeginFeature: *IntOption None\n"
62 "} stopped cleartomark\n"
64 "%%BeginFeature: *StringOption None\n"
66 "} stopped cleartomark\n";
68 static const char *custom_code
=
70 "%%BeginFeature: *InstalledDuplexer False\n"
72 "} stopped cleartomark\n"
74 "%%BeginFeature: *InputSlot Tray\n"
77 "} stopped cleartomark\n"
79 "%%BeginFeature: *IntOption None\n"
81 "} stopped cleartomark\n"
83 "%%BeginFeature: *CustomStringOption True\n"
84 "(value\\0502\\051)\n"
86 "StringOption=Custom\n"
88 "} stopped cleartomark\n"
90 "%%BeginFeature: *CustomPageSize True\n"
98 "} stopped cleartomark\n";
102 * 'main()' - Main entry.
105 int /* O - Exit status */
106 main(int argc
, /* I - Number of command-line arguments */
107 char *argv
[]) /* I - Command-line arguments */
109 int i
; /* Looping var */
110 ppd_file_t
*ppd
; /* PPD file loaded from disk */
111 int status
; /* Status of tests (0 = success, 1 = fail) */
112 int conflicts
; /* Number of conflicts */
113 char *s
; /* String */
114 char buffer
[8192]; /* String buffer */
115 const char *text
; /* Localized text */
116 int num_options
; /* Number of options */
117 cups_option_t
*options
; /* Options */
118 ppd_size_t minsize
, /* Minimum size */
119 maxsize
; /* Maximum size */
120 ppd_attr_t
*attr
; /* Current attribute */
128 * Setup directories for locale stuff...
131 if (access("locale", 0))
133 mkdir("locale", 0777);
134 mkdir("locale/fr", 0777);
135 symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
136 mkdir("locale/zh_TW", 0777);
137 symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
140 putenv("LOCALEDIR=locale");
143 * Do tests with test.ppd...
146 fputs("ppdOpenFile(test.ppd): ", stdout
);
148 if ((ppd
= ppdOpenFile("test.ppd")) != NULL
)
152 ppd_status_t err
; /* Last error in file */
153 int line
; /* Line number in file */
157 err
= ppdLastError(&line
);
159 printf("FAIL (%s on line %d)\n", ppdErrorString(err
), line
);
162 fputs("ppdFindAttr(wildcard): ", stdout
);
163 if ((attr
= ppdFindAttr(ppd
, "cupsTest", NULL
)) == NULL
)
166 puts("FAIL (not found)");
168 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Foo"))
171 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
176 fputs("ppdFindNextAttr(wildcard): ", stdout
);
177 if ((attr
= ppdFindNextAttr(ppd
, "cupsTest", NULL
)) == NULL
)
180 puts("FAIL (not found)");
182 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Bar"))
185 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
190 fputs("ppdFindAttr(Foo): ", stdout
);
191 if ((attr
= ppdFindAttr(ppd
, "cupsTest", "Foo")) == NULL
)
194 puts("FAIL (not found)");
196 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Foo"))
199 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
204 fputs("ppdFindNextAttr(Foo): ", stdout
);
205 if ((attr
= ppdFindNextAttr(ppd
, "cupsTest", "Foo")) != NULL
)
208 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
213 fputs("ppdMarkDefaults: ", stdout
);
214 ppdMarkDefaults(ppd
);
216 if ((conflicts
= ppdConflicts(ppd
)) == 0)
221 printf("FAIL (%d conflicts)\n", conflicts
);
224 fputs("ppdEmitString (defaults): ", stdout
);
225 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
226 !strcmp(s
, default_code
))
231 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
232 (int)strlen(default_code
));
241 fputs("ppdEmitString (custom size and string): ", stdout
);
242 ppdMarkOption(ppd
, "PageSize", "Custom.400x500");
243 ppdMarkOption(ppd
, "StringOption", "{String1=\"value 1\" String2=value(2)}");
245 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
246 !strcmp(s
, custom_code
))
251 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
252 (int)strlen(custom_code
));
262 * Test constraints...
265 fputs("ppdConflicts(): ", stdout
);
266 ppdMarkOption(ppd
, "PageSize", "Letter");
267 ppdMarkOption(ppd
, "InputSlot", "Envelope");
269 if ((conflicts
= ppdConflicts(ppd
)) == 2)
273 printf("FAIL (%d)\n", conflicts
);
277 fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout
);
280 if (cupsResolveConflicts(ppd
, "InputSlot", "Envelope", &num_options
,
283 puts("FAIL (Resolved but shouldn't be able to!)");
287 puts("PASS (Unable to resolve)");
288 cupsFreeOptions(num_options
, options
);
290 fputs("cupsResolveConflicts(No option/choice): ", stdout
);
293 if (cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
) &&
294 num_options
== 1 && !strcasecmp(options
[0].name
, "InputSlot") &&
295 !strcasecmp(options
[0].value
, "Manual"))
296 puts("PASS (Resolved)");
297 else if (num_options
> 0)
299 printf("FAIL (%d options:", num_options
);
300 for (i
= 0; i
< num_options
; i
++)
301 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
307 puts("FAIL (Unable to resolve)");
310 cupsFreeOptions(num_options
, options
);
312 fputs("ppdInstallableConflict(): ", stdout
);
313 if (ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble") &&
314 !ppdInstallableConflict(ppd
, "Duplex", "None"))
316 else if (!ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble"))
318 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
323 puts("FAIL (Duplex=None conflicted)");
331 fputs("ppdPageSizeLimits: ", stdout
);
332 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
334 if (minsize
.width
!= 36 || minsize
.length
!= 36 ||
335 maxsize
.width
!= 1080 || maxsize
.length
!= 86400)
337 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
338 "expected min=36x36, max=1080x86400)\n", minsize
.width
,
339 minsize
.length
, maxsize
.width
, maxsize
.length
);
347 puts("FAIL (returned 0)");
352 * Test localization...
355 fputs("ppdLocalizeIPPReason(text): ", stdout
);
356 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
357 !strcmp(buffer
, "Foo Reason"))
362 printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer
);
365 fputs("ppdLocalizeIPPReason(http): ", stdout
);
366 if (ppdLocalizeIPPReason(ppd
, "foo", "http", buffer
, sizeof(buffer
)) &&
367 !strcmp(buffer
, "http://foo/bar.html"))
372 printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer
);
375 fputs("ppdLocalizeIPPReason(help): ", stdout
);
376 if (ppdLocalizeIPPReason(ppd
, "foo", "help", buffer
, sizeof(buffer
)) &&
377 !strcmp(buffer
, "help:anchor='foo'%20bookID=Vendor%20Help"))
382 printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer
);
385 fputs("ppdLocalizeIPPReason(file): ", stdout
);
386 if (ppdLocalizeIPPReason(ppd
, "foo", "file", buffer
, sizeof(buffer
)) &&
387 !strcmp(buffer
, "/help/foo/bar.html"))
392 printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer
);
397 putenv("LC_CTYPE=fr");
398 putenv("LC_MESSAGES=fr");
400 fputs("ppdLocalizeIPPReason(fr text): ", stdout
);
401 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
402 !strcmp(buffer
, "La Long Foo Reason"))
407 printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer
);
410 putenv("LANG=zh_TW");
411 putenv("LC_ALL=zh_TW");
412 putenv("LC_CTYPE=zh_TW");
413 putenv("LC_MESSAGES=zh_TW");
415 fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout
);
416 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
417 !strcmp(buffer
, "Number 1 Foo Reason"))
422 printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer
);
426 * cupsMarkerName localization...
431 putenv("LC_CTYPE=en");
432 putenv("LC_MESSAGES=en");
434 fputs("ppdLocalizeMarkerName(bogus): ", stdout
);
436 if ((text
= ppdLocalizeMarkerName(ppd
, "bogus")) != NULL
)
439 printf("FAIL (\"%s\" instead of NULL)\n", text
);
444 fputs("ppdLocalizeMarkerName(cyan): ", stdout
);
446 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
447 !strcmp(text
, "Cyan Toner"))
452 printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
453 text
? text
: "(null)");
458 putenv("LC_CTYPE=fr");
459 putenv("LC_MESSAGES=fr");
461 fputs("ppdLocalizeMarkerName(fr cyan): ", stdout
);
462 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
463 !strcmp(text
, "La Toner Cyan"))
468 printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
469 text
? text
: "(null)");
472 putenv("LANG=zh_TW");
473 putenv("LC_ALL=zh_TW");
474 putenv("LC_CTYPE=zh_TW");
475 putenv("LC_MESSAGES=zh_TW");
477 fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout
);
478 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
479 !strcmp(text
, "Number 1 Cyan Toner"))
484 printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
485 text
? text
: "(null)");
491 * Test new constraints...
494 fputs("ppdOpenFile(test2.ppd): ", stdout
);
496 if ((ppd
= ppdOpenFile("test2.ppd")) != NULL
)
500 ppd_status_t err
; /* Last error in file */
501 int line
; /* Line number in file */
505 err
= ppdLastError(&line
);
507 printf("FAIL (%s on line %d)\n", ppdErrorString(err
), line
);
510 fputs("ppdMarkDefaults: ", stdout
);
511 ppdMarkDefaults(ppd
);
513 if ((conflicts
= ppdConflicts(ppd
)) == 0)
518 printf("FAIL (%d conflicts)\n", conflicts
);
521 fputs("ppdConflicts(): ", stdout
);
522 ppdMarkOption(ppd
, "PageSize", "Env10");
523 ppdMarkOption(ppd
, "InputSlot", "Envelope");
524 ppdMarkOption(ppd
, "Quality", "Photo");
526 if ((conflicts
= ppdConflicts(ppd
)) == 2)
530 printf("FAIL (%d)\n", conflicts
);
534 fputs("cupsResolveConflicts(Quality=Photo): ", stdout
);
537 if (cupsResolveConflicts(ppd
, "Quality", "Photo", &num_options
,
540 printf("FAIL (%d options:", num_options
);
541 for (i
= 0; i
< num_options
; i
++)
542 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
547 puts("PASS (Unable to resolve)");
548 cupsFreeOptions(num_options
, options
);
550 fputs("cupsResolveConflicts(No option/choice): ", stdout
);
553 if (cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
) &&
554 num_options
== 1 && !strcasecmp(options
->name
, "Quality") &&
555 !strcasecmp(options
->value
, "Normal"))
557 else if (num_options
> 0)
559 printf("FAIL (%d options:", num_options
);
560 for (i
= 0; i
< num_options
; i
++)
561 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
567 puts("FAIL (Unable to resolve!)");
570 cupsFreeOptions(num_options
, options
);
572 fputs("cupsResolveConflicts(loop test): ", stdout
);
573 ppdMarkOption(ppd
, "PageSize", "A4");
574 ppdMarkOption(ppd
, "Quality", "Photo");
577 if (!cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
))
579 else if (num_options
> 0)
581 printf("FAIL (%d options:", num_options
);
582 for (i
= 0; i
< num_options
; i
++)
583 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
587 puts("FAIL (No conflicts!)");
589 fputs("ppdInstallableConflict(): ", stdout
);
590 if (ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble") &&
591 !ppdInstallableConflict(ppd
, "Duplex", "None"))
593 else if (!ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble"))
595 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
600 puts("FAIL (Duplex=None conflicted)");
608 ppdMarkDefaults(ppd
);
610 fputs("ppdPageSizeLimits(default): ", stdout
);
611 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
613 if (minsize
.width
!= 36 || minsize
.length
!= 36 ||
614 maxsize
.width
!= 1080 || maxsize
.length
!= 86400)
616 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
617 "expected min=36x36, max=1080x86400)\n", minsize
.width
,
618 minsize
.length
, maxsize
.width
, maxsize
.length
);
626 puts("FAIL (returned 0)");
630 ppdMarkOption(ppd
, "InputSlot", "Manual");
632 fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout
);
633 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
635 if (minsize
.width
!= 100 || minsize
.length
!= 100 ||
636 maxsize
.width
!= 1000 || maxsize
.length
!= 1000)
638 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
639 "expected min=100x100, max=1000x1000)\n", minsize
.width
,
640 minsize
.length
, maxsize
.width
, maxsize
.length
);
648 puts("FAIL (returned 0)");
652 ppdMarkOption(ppd
, "Quality", "Photo");
654 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout
);
655 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
657 if (minsize
.width
!= 200 || minsize
.length
!= 200 ||
658 maxsize
.width
!= 1000 || maxsize
.length
!= 1000)
660 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
661 "expected min=200x200, max=1000x1000)\n", minsize
.width
,
662 minsize
.length
, maxsize
.width
, maxsize
.length
);
670 puts("FAIL (returned 0)");
674 ppdMarkOption(ppd
, "InputSlot", "Tray");
676 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout
);
677 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
679 if (minsize
.width
!= 300 || minsize
.length
!= 300 ||
680 maxsize
.width
!= 1080 || maxsize
.length
!= 86400)
682 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
683 "expected min=300x300, max=1080x86400)\n", minsize
.width
,
684 minsize
.length
, maxsize
.width
, maxsize
.length
);
692 puts("FAIL (returned 0)");
698 const char *filename
; /* PPD filename */
701 if (!strncmp(argv
[1], "-d", 2))
703 filename
= cupsGetPPD(argv
[1] + 2);
706 printf("%s: %s\n", argv
[1], cupsLastErrorString());
713 if ((ppd
= ppdOpenFile(filename
)) == NULL
)
715 ppd_status_t err
; /* Last error in file */
716 int line
; /* Line number in file */
720 err
= ppdLastError(&line
);
722 printf("%s: %s on line %d\n", argv
[1], ppdErrorString(err
), line
);
726 int j
, k
; /* Looping vars */
727 ppd_group_t
*group
; /* Option group */
728 ppd_option_t
*option
; /* Option */
729 ppd_coption_t
*coption
; /* Custom option */
730 ppd_cparam_t
*cparam
; /* Custom parameter */
731 ppd_const_t
*c
; /* UIConstraints */
732 char lang
[255], /* LANG environment variable */
733 lc_all
[255], /* LC_ALL environment variable */
734 lc_ctype
[255], /* LC_CTYPE environment variable */
735 lc_messages
[255];/* LC_MESSAGES environment variable */
740 snprintf(lang
, sizeof(lang
), "LANG=%s", argv
[2]);
742 snprintf(lc_all
, sizeof(lc_all
), "LC_ALL=%s", argv
[2]);
744 snprintf(lc_ctype
, sizeof(lc_ctype
), "LC_CTYPE=%s", argv
[2]);
746 snprintf(lc_messages
, sizeof(lc_messages
), "LC_MESSAGES=%s", argv
[2]);
754 text
= ppdLocalizeIPPReason(ppd
, argv
[3], NULL
, buffer
, sizeof(buffer
));
755 printf("ppdLocalizeIPPReason(%s)=%s\n", argv
[3],
756 text
? text
: "(null)");
757 return (text
== NULL
);
760 for (i
= ppd
->num_groups
, group
= ppd
->groups
;
764 printf("%s (%s):\n", group
->name
, group
->text
);
766 for (j
= group
->num_options
, option
= group
->options
;
770 printf(" %s (%s):\n", option
->keyword
, option
->text
);
772 for (k
= 0; k
< option
->num_choices
; k
++)
773 printf(" - %s (%s)\n", option
->choices
[k
].choice
,
774 option
->choices
[k
].text
);
776 if ((coption
= ppdFindCustomOption(ppd
, option
->keyword
)) != NULL
)
778 for (cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
);
780 cparam
= (ppd_cparam_t
*)cupsArrayNext(coption
->params
))
782 switch (cparam
->type
)
784 case PPD_CUSTOM_CURVE
:
785 printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
786 cparam
->name
, cparam
->text
,
787 cparam
->minimum
.custom_curve
,
788 cparam
->maximum
.custom_curve
);
791 case PPD_CUSTOM_INT
:
792 printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
793 cparam
->name
, cparam
->text
,
794 cparam
->minimum
.custom_int
,
795 cparam
->maximum
.custom_int
);
798 case PPD_CUSTOM_INVCURVE
:
799 printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
800 cparam
->name
, cparam
->text
,
801 cparam
->minimum
.custom_invcurve
,
802 cparam
->maximum
.custom_invcurve
);
805 case PPD_CUSTOM_PASSCODE
:
806 printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
807 cparam
->name
, cparam
->text
,
808 cparam
->minimum
.custom_passcode
,
809 cparam
->maximum
.custom_passcode
);
812 case PPD_CUSTOM_PASSWORD
:
813 printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
814 cparam
->name
, cparam
->text
,
815 cparam
->minimum
.custom_password
,
816 cparam
->maximum
.custom_password
);
819 case PPD_CUSTOM_POINTS
:
820 printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
821 cparam
->name
, cparam
->text
,
822 cparam
->minimum
.custom_points
,
823 cparam
->maximum
.custom_points
);
826 case PPD_CUSTOM_REAL
:
827 printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
828 cparam
->name
, cparam
->text
,
829 cparam
->minimum
.custom_real
,
830 cparam
->maximum
.custom_real
);
833 case PPD_CUSTOM_STRING
:
834 printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
835 cparam
->name
, cparam
->text
,
836 cparam
->minimum
.custom_string
,
837 cparam
->maximum
.custom_string
);
845 puts("Constraints:");
847 for (i
= ppd
->num_consts
, c
= ppd
->consts
; i
> 0; i
--, c
++)
848 printf(" *UIConstraints: *%s %s *%s %s\n", c
->option1
, c
->choice1
,
849 c
->option2
, c
->choice2
);
853 for (attr
= (ppd_attr_t
*)cupsArrayFirst(ppd
->sorted_attrs
);
855 attr
= (ppd_attr_t
*)cupsArrayNext(ppd
->sorted_attrs
))
856 printf(" *%s %s/%s: \"%s\"\n", attr
->name
, attr
->spec
,
857 attr
->text
, attr
->value
? attr
->value
: "");
860 if (!strncmp(argv
[1], "-d", 2))
865 if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
867 char command
[1024]; /* malloc_history command */
869 snprintf(command
, sizeof(command
), "malloc_history %d -all_by_size",
874 #endif /* __APPLE__ */
883 * End of "$Id: testppd.c 7897 2008-09-02 19:33:19Z mike $".