2 * PPD test program for CUPS.
4 * Copyright 2007-2015 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products.
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
11 * file is missing or damaged, see the license at "http://www.cups.org/".
13 * This file is subject to the Apple OS-Developed Software exception.
17 * Include necessary headers...
20 #undef _CUPS_NO_DEPRECATED
21 #include "cups-private.h"
22 #include "ppd-private.h"
37 static const char *default_code
=
39 "%%BeginFeature: *InstalledDuplexer False\n"
41 "} stopped cleartomark\n"
43 "%%BeginFeature: *PageRegion Letter\n"
46 "} stopped cleartomark\n"
48 "%%BeginFeature: *InputSlot Tray\n"
51 "} stopped cleartomark\n"
53 "%%BeginFeature: *OutputBin Tray1\n"
56 "} stopped cleartomark\n"
58 "%%BeginFeature: *MediaType Plain\n"
61 "} stopped cleartomark\n"
63 "%%BeginFeature: *IntOption None\n"
65 "} stopped cleartomark\n"
67 "%%BeginFeature: *StringOption None\n"
69 "} stopped cleartomark\n";
71 static const char *custom_code
=
73 "%%BeginFeature: *InstalledDuplexer False\n"
75 "} stopped cleartomark\n"
77 "%%BeginFeature: *InputSlot Tray\n"
80 "} stopped cleartomark\n"
82 "%%BeginFeature: *MediaType Plain\n"
85 "} stopped cleartomark\n"
87 "%%BeginFeature: *OutputBin Tray1\n"
90 "} stopped cleartomark\n"
92 "%%BeginFeature: *IntOption None\n"
94 "} stopped cleartomark\n"
96 "%%BeginFeature: *CustomStringOption True\n"
97 "(value\\0502\\051)\n"
99 "StringOption=Custom\n"
101 "} stopped cleartomark\n"
103 "%%BeginFeature: *CustomPageSize True\n"
111 "} stopped cleartomark\n";
113 static const char *default2_code
=
115 "%%BeginFeature: *InstalledDuplexer False\n"
117 "} stopped cleartomark\n"
119 "%%BeginFeature: *InputSlot Tray\n"
122 "} stopped cleartomark\n"
124 "%%BeginFeature: *Quality Normal\n"
127 "} stopped cleartomark\n"
129 "%%BeginFeature: *IntOption None\n"
131 "} stopped cleartomark\n"
133 "%%BeginFeature: *StringOption None\n"
135 "} stopped cleartomark\n";
139 * 'main()' - Main entry.
142 int /* O - Exit status */
143 main(int argc
, /* I - Number of command-line arguments */
144 char *argv
[]) /* I - Command-line arguments */
146 int i
; /* Looping var */
147 ppd_file_t
*ppd
; /* PPD file loaded from disk */
148 int status
; /* Status of tests (0 = success, 1 = fail) */
149 int conflicts
; /* Number of conflicts */
150 char *s
; /* String */
151 char buffer
[8192]; /* String buffer */
152 const char *text
, /* Localized text */
153 *val
; /* Option value */
154 int num_options
; /* Number of options */
155 cups_option_t
*options
; /* Options */
156 ppd_size_t minsize
, /* Minimum size */
157 maxsize
, /* Maximum size */
158 *size
; /* Current size */
159 ppd_attr_t
*attr
; /* Current attribute */
160 _ppd_cache_t
*pc
; /* PPD cache */
168 * Setup directories for locale stuff...
171 if (access("locale", 0))
173 mkdir("locale", 0777);
174 mkdir("locale/fr", 0777);
175 symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
176 mkdir("locale/zh_TW", 0777);
177 symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
180 putenv("LOCALEDIR=locale");
181 putenv("SOFTWARE=CUPS");
184 * Do tests with test.ppd...
187 fputs("ppdOpenFile(test.ppd): ", stdout
);
189 if ((ppd
= _ppdOpenFile("test.ppd", _PPD_LOCALIZATION_ALL
)) != NULL
)
193 ppd_status_t err
; /* Last error in file */
194 int line
; /* Line number in file */
198 err
= ppdLastError(&line
);
200 printf("FAIL (%s on line %d)\n", ppdErrorString(err
), line
);
203 fputs("ppdFindAttr(wildcard): ", stdout
);
204 if ((attr
= ppdFindAttr(ppd
, "cupsTest", NULL
)) == NULL
)
207 puts("FAIL (not found)");
209 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Foo"))
212 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
217 fputs("ppdFindNextAttr(wildcard): ", stdout
);
218 if ((attr
= ppdFindNextAttr(ppd
, "cupsTest", NULL
)) == NULL
)
221 puts("FAIL (not found)");
223 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Bar"))
226 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
231 fputs("ppdFindAttr(Foo): ", stdout
);
232 if ((attr
= ppdFindAttr(ppd
, "cupsTest", "Foo")) == NULL
)
235 puts("FAIL (not found)");
237 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Foo"))
240 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
245 fputs("ppdFindNextAttr(Foo): ", stdout
);
246 if ((attr
= ppdFindNextAttr(ppd
, "cupsTest", "Foo")) != NULL
)
249 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
254 fputs("ppdMarkDefaults: ", stdout
);
255 ppdMarkDefaults(ppd
);
257 if ((conflicts
= ppdConflicts(ppd
)) == 0)
262 printf("FAIL (%d conflicts)\n", conflicts
);
265 fputs("ppdEmitString (defaults): ", stdout
);
266 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
267 !strcmp(s
, default_code
))
272 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
273 (int)strlen(default_code
));
282 fputs("ppdEmitString (custom size and string): ", stdout
);
283 ppdMarkOption(ppd
, "PageSize", "Custom.400x500");
284 ppdMarkOption(ppd
, "StringOption", "{String1=\"value 1\" String2=value(2)}");
286 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
287 !strcmp(s
, custom_code
))
292 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
293 (int)strlen(custom_code
));
303 * Test constraints...
306 fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout
);
307 ppdMarkOption(ppd
, "PageSize", "Letter");
309 num_options
= cupsGetConflicts(ppd
, "InputSlot", "Envelope", &options
);
310 if (num_options
!= 2 ||
311 (val
= cupsGetOption("PageRegion", num_options
, options
)) == NULL
||
312 _cups_strcasecmp(val
, "Letter") ||
313 (val
= cupsGetOption("PageSize", num_options
, options
)) == NULL
||
314 _cups_strcasecmp(val
, "Letter"))
316 printf("FAIL (%d options:", num_options
);
317 for (i
= 0; i
< num_options
; i
++)
318 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
325 fputs("ppdConflicts(): ", stdout
);
326 ppdMarkOption(ppd
, "InputSlot", "Envelope");
328 if ((conflicts
= ppdConflicts(ppd
)) == 2)
332 printf("FAIL (%d)\n", conflicts
);
336 fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout
);
339 if (!cupsResolveConflicts(ppd
, "InputSlot", "Envelope", &num_options
,
342 puts("FAIL (Unable to resolve)");
345 else if (num_options
!= 2 ||
346 !cupsGetOption("PageSize", num_options
, options
))
348 printf("FAIL (%d options:", num_options
);
349 for (i
= 0; i
< num_options
; i
++)
350 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
355 puts("PASS (Resolved by changing PageSize)");
357 cupsFreeOptions(num_options
, options
);
359 fputs("cupsResolveConflicts(No option/choice): ", stdout
);
362 if (cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
) &&
363 num_options
== 1 && !_cups_strcasecmp(options
[0].name
, "InputSlot") &&
364 !_cups_strcasecmp(options
[0].value
, "Tray"))
365 puts("PASS (Resolved by changing InputSlot)");
366 else if (num_options
> 0)
368 printf("FAIL (%d options:", num_options
);
369 for (i
= 0; i
< num_options
; i
++)
370 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
376 puts("FAIL (Unable to resolve)");
379 cupsFreeOptions(num_options
, options
);
381 fputs("ppdInstallableConflict(): ", stdout
);
382 if (ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble") &&
383 !ppdInstallableConflict(ppd
, "Duplex", "None"))
385 else if (!ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble"))
387 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
392 puts("FAIL (Duplex=None conflicted)");
400 fputs("ppdPageSizeLimits: ", stdout
);
401 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
403 if (fabs(minsize
.width
- 36.0) > 0.001 || fabs(minsize
.length
- 36.0) > 0.001 ||
404 fabs(maxsize
.width
- 1080.0) > 0.001 || fabs(maxsize
.length
- 86400.0) > 0.001)
406 printf("FAIL (got min=%.3fx%.3f, max=%.3fx%.3f, "
407 "expected min=36x36, max=1080x86400)\n", minsize
.width
,
408 minsize
.length
, maxsize
.width
, maxsize
.length
);
416 puts("FAIL (returned 0)");
421 * cupsMarkOptions with PWG and IPP size names.
424 fputs("cupsMarkOptions(media=iso-a4): ", stdout
);
425 num_options
= cupsAddOption("media", "iso-a4", 0, &options
);
426 cupsMarkOptions(ppd
, num_options
, options
);
427 cupsFreeOptions(num_options
, options
);
429 size
= ppdPageSize(ppd
, NULL
);
430 if (!size
|| strcmp(size
->name
, "A4"))
432 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
438 fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout
);
439 num_options
= cupsAddOption("media", "na_letter_8.5x11in", 0, &options
);
440 cupsMarkOptions(ppd
, num_options
, options
);
441 cupsFreeOptions(num_options
, options
);
443 size
= ppdPageSize(ppd
, NULL
);
444 if (!size
|| strcmp(size
->name
, "Letter"))
446 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
452 fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout
);
453 num_options
= cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
455 cupsMarkOptions(ppd
, num_options
, options
);
456 cupsFreeOptions(num_options
, options
);
458 size
= ppdPageSize(ppd
, NULL
);
459 if (!size
|| strcmp(size
->name
, "Letter.Fullbleed"))
461 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
467 fputs("cupsMarkOptions(media=A4): ", stdout
);
468 num_options
= cupsAddOption("media", "A4", 0, &options
);
469 cupsMarkOptions(ppd
, num_options
, options
);
470 cupsFreeOptions(num_options
, options
);
472 size
= ppdPageSize(ppd
, NULL
);
473 if (!size
|| strcmp(size
->name
, "A4"))
475 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
485 fputs("cupsMarkOptions(media=Custom.8x10in): ", stdout
);
486 num_options
= cupsAddOption("media", "Custom.8x10in", 0, &options
);
487 cupsMarkOptions(ppd
, num_options
, options
);
488 cupsFreeOptions(num_options
, options
);
490 size
= ppdPageSize(ppd
, NULL
);
491 if (!size
|| strcmp(size
->name
, "Custom") ||
492 fabs(size
->width
- 576.0) > 0.001 ||
493 fabs(size
->length
- 720.0) > 0.001)
495 printf("FAIL (%s - %gx%g)\n", size
? size
->name
: "unknown",
496 size
? size
->width
: 0.0, size
? size
->length
: 0.0);
503 * Test localization...
506 fputs("ppdLocalizeIPPReason(text): ", stdout
);
507 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
508 !strcmp(buffer
, "Foo Reason"))
513 printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer
);
516 fputs("ppdLocalizeIPPReason(http): ", stdout
);
517 if (ppdLocalizeIPPReason(ppd
, "foo", "http", buffer
, sizeof(buffer
)) &&
518 !strcmp(buffer
, "http://foo/bar.html"))
523 printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer
);
526 fputs("ppdLocalizeIPPReason(help): ", stdout
);
527 if (ppdLocalizeIPPReason(ppd
, "foo", "help", buffer
, sizeof(buffer
)) &&
528 !strcmp(buffer
, "help:anchor='foo'%20bookID=Vendor%20Help"))
533 printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer
);
536 fputs("ppdLocalizeIPPReason(file): ", stdout
);
537 if (ppdLocalizeIPPReason(ppd
, "foo", "file", buffer
, sizeof(buffer
)) &&
538 !strcmp(buffer
, "/help/foo/bar.html"))
543 printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer
);
548 putenv("LC_CTYPE=fr");
549 putenv("LC_MESSAGES=fr");
551 fputs("ppdLocalizeIPPReason(fr text): ", stdout
);
552 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
553 !strcmp(buffer
, "La Long Foo Reason"))
558 printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer
);
561 putenv("LANG=zh_TW");
562 putenv("LC_ALL=zh_TW");
563 putenv("LC_CTYPE=zh_TW");
564 putenv("LC_MESSAGES=zh_TW");
566 fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout
);
567 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
568 !strcmp(buffer
, "Number 1 Foo Reason"))
573 printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer
);
577 * cupsMarkerName localization...
582 putenv("LC_CTYPE=en");
583 putenv("LC_MESSAGES=en");
585 fputs("ppdLocalizeMarkerName(bogus): ", stdout
);
587 if ((text
= ppdLocalizeMarkerName(ppd
, "bogus")) != NULL
)
590 printf("FAIL (\"%s\" instead of NULL)\n", text
);
595 fputs("ppdLocalizeMarkerName(cyan): ", stdout
);
597 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
598 !strcmp(text
, "Cyan Toner"))
603 printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
604 text
? text
: "(null)");
609 putenv("LC_CTYPE=fr");
610 putenv("LC_MESSAGES=fr");
612 fputs("ppdLocalizeMarkerName(fr cyan): ", stdout
);
613 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
614 !strcmp(text
, "La Toner Cyan"))
619 printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
620 text
? text
: "(null)");
623 putenv("LANG=zh_TW");
624 putenv("LC_ALL=zh_TW");
625 putenv("LC_CTYPE=zh_TW");
626 putenv("LC_MESSAGES=zh_TW");
628 fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout
);
629 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
630 !strcmp(text
, "Number 1 Cyan Toner"))
635 printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
636 text
? text
: "(null)");
642 * Test new constraints...
645 fputs("ppdOpenFile(test2.ppd): ", stdout
);
647 if ((ppd
= ppdOpenFile("test2.ppd")) != NULL
)
651 ppd_status_t err
; /* Last error in file */
652 int line
; /* Line number in file */
656 err
= ppdLastError(&line
);
658 printf("FAIL (%s on line %d)\n", ppdErrorString(err
), line
);
661 fputs("ppdMarkDefaults: ", stdout
);
662 ppdMarkDefaults(ppd
);
664 if ((conflicts
= ppdConflicts(ppd
)) == 0)
669 printf("FAIL (%d conflicts)\n", conflicts
);
672 fputs("ppdEmitString (defaults): ", stdout
);
673 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
674 !strcmp(s
, default2_code
))
679 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
680 (int)strlen(default2_code
));
689 fputs("ppdConflicts(): ", stdout
);
690 ppdMarkOption(ppd
, "PageSize", "Env10");
691 ppdMarkOption(ppd
, "InputSlot", "Envelope");
692 ppdMarkOption(ppd
, "Quality", "Photo");
694 if ((conflicts
= ppdConflicts(ppd
)) == 1)
698 printf("FAIL (%d)\n", conflicts
);
702 fputs("cupsResolveConflicts(Quality=Photo): ", stdout
);
705 if (cupsResolveConflicts(ppd
, "Quality", "Photo", &num_options
,
708 printf("FAIL (%d options:", num_options
);
709 for (i
= 0; i
< num_options
; i
++)
710 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
715 puts("PASS (Unable to resolve)");
716 cupsFreeOptions(num_options
, options
);
718 fputs("cupsResolveConflicts(No option/choice): ", stdout
);
721 if (cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
) &&
722 num_options
== 1 && !_cups_strcasecmp(options
->name
, "Quality") &&
723 !_cups_strcasecmp(options
->value
, "Normal"))
725 else if (num_options
> 0)
727 printf("FAIL (%d options:", num_options
);
728 for (i
= 0; i
< num_options
; i
++)
729 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
735 puts("FAIL (Unable to resolve!)");
738 cupsFreeOptions(num_options
, options
);
740 fputs("cupsResolveConflicts(loop test): ", stdout
);
741 ppdMarkOption(ppd
, "PageSize", "A4");
742 ppdMarkOption(ppd
, "InputSlot", "Tray");
743 ppdMarkOption(ppd
, "Quality", "Photo");
746 if (!cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
))
748 else if (num_options
> 0)
750 printf("FAIL (%d options:", num_options
);
751 for (i
= 0; i
< num_options
; i
++)
752 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
756 puts("FAIL (No conflicts!)");
758 fputs("ppdInstallableConflict(): ", stdout
);
759 if (ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble") &&
760 !ppdInstallableConflict(ppd
, "Duplex", "None"))
762 else if (!ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble"))
764 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
769 puts("FAIL (Duplex=None conflicted)");
777 ppdMarkDefaults(ppd
);
779 fputs("ppdPageSizeLimits(default): ", stdout
);
780 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
782 if (fabs(minsize
.width
- 36.0) > 0.001 || fabs(minsize
.length
- 36.0) > 0.001 ||
783 fabs(maxsize
.width
- 1080.0) > 0.001 || fabs(maxsize
.length
- 86400.0) > 0.001)
785 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
786 "expected min=36x36, max=1080x86400)\n", minsize
.width
,
787 minsize
.length
, maxsize
.width
, maxsize
.length
);
795 puts("FAIL (returned 0)");
799 ppdMarkOption(ppd
, "InputSlot", "Manual");
801 fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout
);
802 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
804 if (fabs(minsize
.width
- 100.0) > 0.001 || fabs(minsize
.length
- 100.0) > 0.001 ||
805 fabs(maxsize
.width
- 1000.0) > 0.001 || fabs(maxsize
.length
- 1000.0) > 0.001)
807 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
808 "expected min=100x100, max=1000x1000)\n", minsize
.width
,
809 minsize
.length
, maxsize
.width
, maxsize
.length
);
817 puts("FAIL (returned 0)");
821 ppdMarkOption(ppd
, "Quality", "Photo");
823 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout
);
824 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
826 if (fabs(minsize
.width
- 200.0) > 0.001 || fabs(minsize
.length
- 200.0) > 0.001 ||
827 fabs(maxsize
.width
- 1000.0) > 0.001 || fabs(maxsize
.length
- 1000.0) > 0.001)
829 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
830 "expected min=200x200, max=1000x1000)\n", minsize
.width
,
831 minsize
.length
, maxsize
.width
, maxsize
.length
);
839 puts("FAIL (returned 0)");
843 ppdMarkOption(ppd
, "InputSlot", "Tray");
845 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout
);
846 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
848 if (fabs(minsize
.width
- 300.0) > 0.001 || fabs(minsize
.length
- 300.0) > 0.001 ||
849 fabs(maxsize
.width
- 1080.0) > 0.001 || fabs(maxsize
.length
- 86400.0) > 0.001)
851 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
852 "expected min=300x300, max=1080x86400)\n", minsize
.width
,
853 minsize
.length
, maxsize
.width
, maxsize
.length
);
861 puts("FAIL (returned 0)");
865 else if (!strncmp(argv
[1], "ipp://", 6) || !strncmp(argv
[1], "ipps://", 7))
868 * ipp://... or ipps://...
871 http_t
*http
; /* Connection to printer */
872 ipp_t
*request
, /* Get-Printer-Attributes request */
873 *response
; /* Get-Printer-Attributes response */
874 char scheme
[32], /* URI scheme */
875 userpass
[256], /* Username:password */
876 host
[256], /* Hostname */
877 resource
[256]; /* Resource path */
878 int port
; /* Port number */
880 if (httpSeparateURI(HTTP_URI_CODING_ALL
, argv
[1], scheme
, sizeof(scheme
), userpass
, sizeof(userpass
), host
, sizeof(host
), &port
, resource
, sizeof(resource
)) < HTTP_URI_STATUS_OK
)
882 printf("Bad URI \"%s\".\n", argv
[1]);
886 http
= httpConnect2(host
, port
, NULL
, AF_UNSPEC
, !strcmp(scheme
, "ipps") ? HTTP_ENCRYPTION_ALWAYS
: HTTP_ENCRYPTION_IF_REQUESTED
, 1, 30000, NULL
);
889 printf("Unable to connect to \"%s:%d\": %s\n", host
, port
, cupsLastErrorString());
893 request
= ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES
);
894 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri", NULL
, argv
[1]);
895 response
= cupsDoRequest(http
, request
, resource
);
897 if (_ppdCreateFromIPP(buffer
, sizeof(buffer
), response
))
898 printf("Created PPD: %s\n", buffer
);
900 puts("Unable to create PPD.");
908 const char *filename
; /* PPD filename */
909 struct stat fileinfo
; /* File information */
912 if (strchr(argv
[1], ':'))
918 if ((filename
= cupsGetServerPPD(CUPS_HTTP_DEFAULT
, argv
[1])) == NULL
)
920 printf("%s: %s\n", argv
[1], cupsLastErrorString());
924 else if (!strncmp(argv
[1], "-d", 2))
926 const char *printer
; /* Printer name */
929 printer
= argv
[1] + 2;
934 puts("Usage: ./testppd -d printer");
938 filename
= cupsGetPPD(printer
);
942 printf("%s: %s\n", printer
, cupsLastErrorString());
949 if (lstat(filename
, &fileinfo
))
951 printf("%s: %s\n", filename
, strerror(errno
));
955 if (S_ISLNK(fileinfo
.st_mode
))
957 char realfile
[1024]; /* Real file path */
958 ssize_t realsize
; /* Size of real file path */
961 if ((realsize
= readlink(filename
, realfile
, sizeof(realfile
) - 1)) < 0)
962 strlcpy(realfile
, "Unknown", sizeof(realfile
));
964 realfile
[realsize
] = '\0';
966 if (stat(realfile
, &fileinfo
))
967 printf("%s: symlink to \"%s\", %s\n", filename
, realfile
,
970 printf("%s: symlink to \"%s\", %ld bytes\n", filename
, realfile
,
971 (long)fileinfo
.st_size
);
974 printf("%s: regular file, %ld bytes\n", filename
, (long)fileinfo
.st_size
);
976 if ((ppd
= ppdOpenFile(filename
)) == NULL
)
978 ppd_status_t err
; /* Last error in file */
979 int line
; /* Line number in file */
983 err
= ppdLastError(&line
);
985 printf("%s: %s on line %d\n", argv
[1], ppdErrorString(err
), line
);
989 int j
, k
; /* Looping vars */
990 ppd_group_t
*group
; /* Option group */
991 ppd_option_t
*option
; /* Option */
992 ppd_coption_t
*coption
; /* Custom option */
993 ppd_cparam_t
*cparam
; /* Custom parameter */
994 ppd_const_t
*c
; /* UIConstraints */
995 char lang
[255], /* LANG environment variable */
996 lc_all
[255], /* LC_ALL environment variable */
997 lc_ctype
[255], /* LC_CTYPE environment variable */
998 lc_messages
[255];/* LC_MESSAGES environment variable */
1003 snprintf(lang
, sizeof(lang
), "LANG=%s", argv
[2]);
1005 snprintf(lc_all
, sizeof(lc_all
), "LC_ALL=%s", argv
[2]);
1007 snprintf(lc_ctype
, sizeof(lc_ctype
), "LC_CTYPE=%s", argv
[2]);
1009 snprintf(lc_messages
, sizeof(lc_messages
), "LC_MESSAGES=%s", argv
[2]);
1010 putenv(lc_messages
);
1014 ppdMarkDefaults(ppd
);
1018 text
= ppdLocalizeIPPReason(ppd
, argv
[3], NULL
, buffer
, sizeof(buffer
));
1019 printf("ppdLocalizeIPPReason(%s)=%s\n", argv
[3],
1020 text
? text
: "(null)");
1021 return (text
== NULL
);
1024 for (i
= ppd
->num_groups
, group
= ppd
->groups
;
1028 printf("%s (%s):\n", group
->name
, group
->text
);
1030 for (j
= group
->num_options
, option
= group
->options
;
1034 printf(" %s (%s):\n", option
->keyword
, option
->text
);
1036 for (k
= 0; k
< option
->num_choices
; k
++)
1037 printf(" - %s%s (%s)\n",
1038 option
->choices
[k
].marked
? "*" : "",
1039 option
->choices
[k
].choice
, option
->choices
[k
].text
);
1041 if ((coption
= ppdFindCustomOption(ppd
, option
->keyword
)) != NULL
)
1043 for (cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
);
1045 cparam
= (ppd_cparam_t
*)cupsArrayNext(coption
->params
))
1047 switch (cparam
->type
)
1049 case PPD_CUSTOM_CURVE
:
1050 printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
1051 cparam
->name
, cparam
->text
,
1052 cparam
->minimum
.custom_curve
,
1053 cparam
->maximum
.custom_curve
);
1056 case PPD_CUSTOM_INT
:
1057 printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
1058 cparam
->name
, cparam
->text
,
1059 cparam
->minimum
.custom_int
,
1060 cparam
->maximum
.custom_int
);
1063 case PPD_CUSTOM_INVCURVE
:
1064 printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
1065 cparam
->name
, cparam
->text
,
1066 cparam
->minimum
.custom_invcurve
,
1067 cparam
->maximum
.custom_invcurve
);
1070 case PPD_CUSTOM_PASSCODE
:
1071 printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
1072 cparam
->name
, cparam
->text
,
1073 cparam
->minimum
.custom_passcode
,
1074 cparam
->maximum
.custom_passcode
);
1077 case PPD_CUSTOM_PASSWORD
:
1078 printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
1079 cparam
->name
, cparam
->text
,
1080 cparam
->minimum
.custom_password
,
1081 cparam
->maximum
.custom_password
);
1084 case PPD_CUSTOM_POINTS
:
1085 printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
1086 cparam
->name
, cparam
->text
,
1087 cparam
->minimum
.custom_points
,
1088 cparam
->maximum
.custom_points
);
1091 case PPD_CUSTOM_REAL
:
1092 printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
1093 cparam
->name
, cparam
->text
,
1094 cparam
->minimum
.custom_real
,
1095 cparam
->maximum
.custom_real
);
1098 case PPD_CUSTOM_STRING
:
1099 printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
1100 cparam
->name
, cparam
->text
,
1101 cparam
->minimum
.custom_string
,
1102 cparam
->maximum
.custom_string
);
1111 for (i
= ppd
->num_sizes
, size
= ppd
->sizes
; i
> 0; i
--, size
++)
1112 printf(" %s = %gx%g, [%g %g %g %g]\n", size
->name
, size
->width
,
1113 size
->length
, size
->left
, size
->bottom
, size
->right
, size
->top
);
1115 puts("\nConstraints:");
1117 for (i
= ppd
->num_consts
, c
= ppd
->consts
; i
> 0; i
--, c
++)
1118 printf(" *UIConstraints: *%s %s *%s %s\n", c
->option1
, c
->choice1
,
1119 c
->option2
, c
->choice2
);
1120 if (ppd
->num_consts
== 0)
1121 puts(" NO CONSTRAINTS");
1125 for (i
= 0; i
< ppd
->num_filters
; i
++)
1126 printf(" %s\n", ppd
->filters
[i
]);
1128 if (ppd
->num_filters
== 0)
1129 puts(" NO FILTERS");
1131 puts("\nAttributes:");
1133 for (attr
= (ppd_attr_t
*)cupsArrayFirst(ppd
->sorted_attrs
);
1135 attr
= (ppd_attr_t
*)cupsArrayNext(ppd
->sorted_attrs
))
1136 printf(" *%s %s/%s: \"%s\"\n", attr
->name
, attr
->spec
,
1137 attr
->text
, attr
->value
? attr
->value
: "");
1139 puts("\nPPD Cache:");
1140 if ((pc
= _ppdCacheCreateWithPPD(ppd
)) == NULL
)
1141 printf(" Unable to create: %s\n", cupsLastErrorString());
1144 _ppdCacheWriteFile(pc
, "t.cache", NULL
);
1145 puts(" Wrote t.cache.");
1149 if (!strncmp(argv
[1], "-d", 2))
1154 if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
1156 char command
[1024]; /* malloc_history command */
1158 snprintf(command
, sizeof(command
), "malloc_history %d -all_by_size",
1163 #endif /* __APPLE__ */