2 * PPD test program for CUPS.
4 * Copyright 2007-2017 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 * Include necessary headers...
14 #undef _CUPS_NO_DEPRECATED
15 #include "cups-private.h"
16 #include "ppd-private.h"
31 static const char *default_code
=
33 "%%BeginFeature: *InstalledDuplexer False\n"
35 "} stopped cleartomark\n"
37 "%%BeginFeature: *PageRegion Letter\n"
40 "} stopped cleartomark\n"
42 "%%BeginFeature: *InputSlot Tray\n"
45 "} stopped cleartomark\n"
47 "%%BeginFeature: *OutputBin Tray1\n"
50 "} stopped cleartomark\n"
52 "%%BeginFeature: *MediaType Plain\n"
55 "} stopped cleartomark\n"
57 "%%BeginFeature: *IntOption None\n"
59 "} stopped cleartomark\n"
61 "%%BeginFeature: *StringOption None\n"
63 "} stopped cleartomark\n";
65 static const char *custom_code
=
67 "%%BeginFeature: *InstalledDuplexer False\n"
69 "} stopped cleartomark\n"
71 "%%BeginFeature: *InputSlot Tray\n"
74 "} stopped cleartomark\n"
76 "%%BeginFeature: *MediaType Plain\n"
79 "} stopped cleartomark\n"
81 "%%BeginFeature: *OutputBin Tray1\n"
84 "} stopped cleartomark\n"
86 "%%BeginFeature: *IntOption None\n"
88 "} stopped cleartomark\n"
90 "%%BeginFeature: *CustomStringOption True\n"
91 "(value\\0502\\051)\n"
93 "StringOption=Custom\n"
95 "} stopped cleartomark\n"
97 "%%BeginFeature: *CustomPageSize True\n"
105 "} stopped cleartomark\n";
107 static const char *default2_code
=
109 "%%BeginFeature: *InstalledDuplexer False\n"
111 "} stopped cleartomark\n"
113 "%%BeginFeature: *InputSlot Tray\n"
116 "} stopped cleartomark\n"
118 "%%BeginFeature: *Quality Normal\n"
121 "} stopped cleartomark\n"
123 "%%BeginFeature: *IntOption None\n"
125 "} stopped cleartomark\n"
127 "%%BeginFeature: *StringOption None\n"
129 "} stopped cleartomark\n";
133 * 'main()' - Main entry.
136 int /* O - Exit status */
137 main(int argc
, /* I - Number of command-line arguments */
138 char *argv
[]) /* I - Command-line arguments */
140 int i
; /* Looping var */
141 ppd_file_t
*ppd
; /* PPD file loaded from disk */
142 int status
; /* Status of tests (0 = success, 1 = fail) */
143 int conflicts
; /* Number of conflicts */
144 char *s
; /* String */
145 char buffer
[8192]; /* String buffer */
146 const char *text
, /* Localized text */
147 *val
; /* Option value */
148 int num_options
; /* Number of options */
149 cups_option_t
*options
; /* Options */
150 ppd_size_t minsize
, /* Minimum size */
151 maxsize
, /* Maximum size */
152 *size
; /* Current size */
153 ppd_attr_t
*attr
; /* Current attribute */
154 _ppd_cache_t
*pc
; /* PPD cache */
162 * Setup directories for locale stuff...
165 if (access("locale", 0))
167 mkdir("locale", 0777);
168 mkdir("locale/fr", 0777);
169 symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
170 mkdir("locale/zh_TW", 0777);
171 symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
174 putenv("LOCALEDIR=locale");
175 putenv("SOFTWARE=CUPS");
178 * Do tests with test.ppd...
181 fputs("ppdOpenFile(test.ppd): ", stdout
);
183 if ((ppd
= _ppdOpenFile("test.ppd", _PPD_LOCALIZATION_ALL
)) != NULL
)
187 ppd_status_t err
; /* Last error in file */
188 int line
; /* Line number in file */
192 err
= ppdLastError(&line
);
194 printf("FAIL (%s on line %d)\n", ppdErrorString(err
), line
);
197 fputs("ppdFindAttr(wildcard): ", stdout
);
198 if ((attr
= ppdFindAttr(ppd
, "cupsTest", NULL
)) == NULL
)
201 puts("FAIL (not found)");
203 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Foo"))
206 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
211 fputs("ppdFindNextAttr(wildcard): ", stdout
);
212 if ((attr
= ppdFindNextAttr(ppd
, "cupsTest", NULL
)) == NULL
)
215 puts("FAIL (not found)");
217 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Bar"))
220 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
225 fputs("ppdFindAttr(Foo): ", stdout
);
226 if ((attr
= ppdFindAttr(ppd
, "cupsTest", "Foo")) == NULL
)
229 puts("FAIL (not found)");
231 else if (strcmp(attr
->name
, "cupsTest") || strcmp(attr
->spec
, "Foo"))
234 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
239 fputs("ppdFindNextAttr(Foo): ", stdout
);
240 if ((attr
= ppdFindNextAttr(ppd
, "cupsTest", "Foo")) != NULL
)
243 printf("FAIL (got \"%s %s\")\n", attr
->name
, attr
->spec
);
248 fputs("ppdMarkDefaults: ", stdout
);
249 ppdMarkDefaults(ppd
);
251 if ((conflicts
= ppdConflicts(ppd
)) == 0)
256 printf("FAIL (%d conflicts)\n", conflicts
);
259 fputs("ppdEmitString (defaults): ", stdout
);
260 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
261 !strcmp(s
, default_code
))
266 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
267 (int)strlen(default_code
));
276 fputs("ppdEmitString (custom size and string): ", stdout
);
277 ppdMarkOption(ppd
, "PageSize", "Custom.400x500");
278 ppdMarkOption(ppd
, "StringOption", "{String1=\"value 1\" String2=value(2)}");
280 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
281 !strcmp(s
, custom_code
))
286 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
287 (int)strlen(custom_code
));
297 * Test constraints...
300 fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout
);
301 ppdMarkOption(ppd
, "PageSize", "Letter");
303 num_options
= cupsGetConflicts(ppd
, "InputSlot", "Envelope", &options
);
304 if (num_options
!= 2 ||
305 (val
= cupsGetOption("PageRegion", num_options
, options
)) == NULL
||
306 _cups_strcasecmp(val
, "Letter") ||
307 (val
= cupsGetOption("PageSize", num_options
, options
)) == NULL
||
308 _cups_strcasecmp(val
, "Letter"))
310 printf("FAIL (%d options:", num_options
);
311 for (i
= 0; i
< num_options
; i
++)
312 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
319 fputs("ppdConflicts(): ", stdout
);
320 ppdMarkOption(ppd
, "InputSlot", "Envelope");
322 if ((conflicts
= ppdConflicts(ppd
)) == 2)
326 printf("FAIL (%d)\n", conflicts
);
330 fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout
);
333 if (!cupsResolveConflicts(ppd
, "InputSlot", "Envelope", &num_options
,
336 puts("FAIL (Unable to resolve)");
339 else if (num_options
!= 2 ||
340 !cupsGetOption("PageSize", num_options
, options
))
342 printf("FAIL (%d options:", num_options
);
343 for (i
= 0; i
< num_options
; i
++)
344 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
349 puts("PASS (Resolved by changing PageSize)");
351 cupsFreeOptions(num_options
, options
);
353 fputs("cupsResolveConflicts(No option/choice): ", stdout
);
356 if (cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
) &&
357 num_options
== 1 && !_cups_strcasecmp(options
[0].name
, "InputSlot") &&
358 !_cups_strcasecmp(options
[0].value
, "Tray"))
359 puts("PASS (Resolved by changing InputSlot)");
360 else if (num_options
> 0)
362 printf("FAIL (%d options:", num_options
);
363 for (i
= 0; i
< num_options
; i
++)
364 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
370 puts("FAIL (Unable to resolve)");
373 cupsFreeOptions(num_options
, options
);
375 fputs("ppdInstallableConflict(): ", stdout
);
376 if (ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble") &&
377 !ppdInstallableConflict(ppd
, "Duplex", "None"))
379 else if (!ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble"))
381 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
386 puts("FAIL (Duplex=None conflicted)");
394 fputs("ppdPageSizeLimits: ", stdout
);
395 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
397 if (fabs(minsize
.width
- 36.0) > 0.001 || fabs(minsize
.length
- 36.0) > 0.001 ||
398 fabs(maxsize
.width
- 1080.0) > 0.001 || fabs(maxsize
.length
- 86400.0) > 0.001)
400 printf("FAIL (got min=%.3fx%.3f, max=%.3fx%.3f, "
401 "expected min=36x36, max=1080x86400)\n", minsize
.width
,
402 minsize
.length
, maxsize
.width
, maxsize
.length
);
410 puts("FAIL (returned 0)");
415 * cupsMarkOptions with PWG and IPP size names.
418 fputs("cupsMarkOptions(media=iso-a4): ", stdout
);
419 num_options
= cupsAddOption("media", "iso-a4", 0, &options
);
420 cupsMarkOptions(ppd
, num_options
, options
);
421 cupsFreeOptions(num_options
, options
);
423 size
= ppdPageSize(ppd
, NULL
);
424 if (!size
|| strcmp(size
->name
, "A4"))
426 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
432 fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout
);
433 num_options
= cupsAddOption("media", "na_letter_8.5x11in", 0, &options
);
434 cupsMarkOptions(ppd
, num_options
, options
);
435 cupsFreeOptions(num_options
, options
);
437 size
= ppdPageSize(ppd
, NULL
);
438 if (!size
|| strcmp(size
->name
, "Letter"))
440 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
446 fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout
);
447 num_options
= cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
449 cupsMarkOptions(ppd
, num_options
, options
);
450 cupsFreeOptions(num_options
, options
);
452 size
= ppdPageSize(ppd
, NULL
);
453 if (!size
|| strcmp(size
->name
, "Letter.Fullbleed"))
455 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
461 fputs("cupsMarkOptions(media=A4): ", stdout
);
462 num_options
= cupsAddOption("media", "A4", 0, &options
);
463 cupsMarkOptions(ppd
, num_options
, options
);
464 cupsFreeOptions(num_options
, options
);
466 size
= ppdPageSize(ppd
, NULL
);
467 if (!size
|| strcmp(size
->name
, "A4"))
469 printf("FAIL (%s)\n", size
? size
->name
: "unknown");
479 fputs("cupsMarkOptions(media=Custom.8x10in): ", stdout
);
480 num_options
= cupsAddOption("media", "Custom.8x10in", 0, &options
);
481 cupsMarkOptions(ppd
, num_options
, options
);
482 cupsFreeOptions(num_options
, options
);
484 size
= ppdPageSize(ppd
, NULL
);
485 if (!size
|| strcmp(size
->name
, "Custom") ||
486 fabs(size
->width
- 576.0) > 0.001 ||
487 fabs(size
->length
- 720.0) > 0.001)
489 printf("FAIL (%s - %gx%g)\n", size
? size
->name
: "unknown",
490 size
? size
->width
: 0.0, size
? size
->length
: 0.0);
497 * Test localization...
500 fputs("ppdLocalizeIPPReason(text): ", stdout
);
501 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
502 !strcmp(buffer
, "Foo Reason"))
507 printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer
);
510 fputs("ppdLocalizeIPPReason(http): ", stdout
);
511 if (ppdLocalizeIPPReason(ppd
, "foo", "http", buffer
, sizeof(buffer
)) &&
512 !strcmp(buffer
, "http://foo/bar.html"))
517 printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer
);
520 fputs("ppdLocalizeIPPReason(help): ", stdout
);
521 if (ppdLocalizeIPPReason(ppd
, "foo", "help", buffer
, sizeof(buffer
)) &&
522 !strcmp(buffer
, "help:anchor='foo'%20bookID=Vendor%20Help"))
527 printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer
);
530 fputs("ppdLocalizeIPPReason(file): ", stdout
);
531 if (ppdLocalizeIPPReason(ppd
, "foo", "file", buffer
, sizeof(buffer
)) &&
532 !strcmp(buffer
, "/help/foo/bar.html"))
537 printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer
);
542 putenv("LC_CTYPE=fr");
543 putenv("LC_MESSAGES=fr");
545 fputs("ppdLocalizeIPPReason(fr text): ", stdout
);
546 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
547 !strcmp(buffer
, "La Long Foo Reason"))
552 printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer
);
555 putenv("LANG=zh_TW");
556 putenv("LC_ALL=zh_TW");
557 putenv("LC_CTYPE=zh_TW");
558 putenv("LC_MESSAGES=zh_TW");
560 fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout
);
561 if (ppdLocalizeIPPReason(ppd
, "foo", NULL
, buffer
, sizeof(buffer
)) &&
562 !strcmp(buffer
, "Number 1 Foo Reason"))
567 printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer
);
571 * cupsMarkerName localization...
576 putenv("LC_CTYPE=en");
577 putenv("LC_MESSAGES=en");
579 fputs("ppdLocalizeMarkerName(bogus): ", stdout
);
581 if ((text
= ppdLocalizeMarkerName(ppd
, "bogus")) != NULL
)
584 printf("FAIL (\"%s\" instead of NULL)\n", text
);
589 fputs("ppdLocalizeMarkerName(cyan): ", stdout
);
591 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
592 !strcmp(text
, "Cyan Toner"))
597 printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
598 text
? text
: "(null)");
603 putenv("LC_CTYPE=fr");
604 putenv("LC_MESSAGES=fr");
606 fputs("ppdLocalizeMarkerName(fr cyan): ", stdout
);
607 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
608 !strcmp(text
, "La Toner Cyan"))
613 printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
614 text
? text
: "(null)");
617 putenv("LANG=zh_TW");
618 putenv("LC_ALL=zh_TW");
619 putenv("LC_CTYPE=zh_TW");
620 putenv("LC_MESSAGES=zh_TW");
622 fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout
);
623 if ((text
= ppdLocalizeMarkerName(ppd
, "cyan")) != NULL
&&
624 !strcmp(text
, "Number 1 Cyan Toner"))
629 printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
630 text
? text
: "(null)");
636 * Test new constraints...
639 fputs("ppdOpenFile(test2.ppd): ", stdout
);
641 if ((ppd
= ppdOpenFile("test2.ppd")) != NULL
)
645 ppd_status_t err
; /* Last error in file */
646 int line
; /* Line number in file */
650 err
= ppdLastError(&line
);
652 printf("FAIL (%s on line %d)\n", ppdErrorString(err
), line
);
655 fputs("ppdMarkDefaults: ", stdout
);
656 ppdMarkDefaults(ppd
);
658 if ((conflicts
= ppdConflicts(ppd
)) == 0)
663 printf("FAIL (%d conflicts)\n", conflicts
);
666 fputs("ppdEmitString (defaults): ", stdout
);
667 if ((s
= ppdEmitString(ppd
, PPD_ORDER_ANY
, 0.0)) != NULL
&&
668 !strcmp(s
, default2_code
))
673 printf("FAIL (%d bytes instead of %d)\n", s
? (int)strlen(s
) : 0,
674 (int)strlen(default2_code
));
683 fputs("ppdConflicts(): ", stdout
);
684 ppdMarkOption(ppd
, "PageSize", "Env10");
685 ppdMarkOption(ppd
, "InputSlot", "Envelope");
686 ppdMarkOption(ppd
, "Quality", "Photo");
688 if ((conflicts
= ppdConflicts(ppd
)) == 1)
692 printf("FAIL (%d)\n", conflicts
);
696 fputs("cupsResolveConflicts(Quality=Photo): ", stdout
);
699 if (cupsResolveConflicts(ppd
, "Quality", "Photo", &num_options
,
702 printf("FAIL (%d options:", num_options
);
703 for (i
= 0; i
< num_options
; i
++)
704 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
709 puts("PASS (Unable to resolve)");
710 cupsFreeOptions(num_options
, options
);
712 fputs("cupsResolveConflicts(No option/choice): ", stdout
);
715 if (cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
) &&
716 num_options
== 1 && !_cups_strcasecmp(options
->name
, "Quality") &&
717 !_cups_strcasecmp(options
->value
, "Normal"))
719 else if (num_options
> 0)
721 printf("FAIL (%d options:", num_options
);
722 for (i
= 0; i
< num_options
; i
++)
723 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
729 puts("FAIL (Unable to resolve!)");
732 cupsFreeOptions(num_options
, options
);
734 fputs("cupsResolveConflicts(loop test): ", stdout
);
735 ppdMarkOption(ppd
, "PageSize", "A4");
736 ppdMarkOption(ppd
, "InputSlot", "Tray");
737 ppdMarkOption(ppd
, "Quality", "Photo");
740 if (!cupsResolveConflicts(ppd
, NULL
, NULL
, &num_options
, &options
))
742 else if (num_options
> 0)
744 printf("FAIL (%d options:", num_options
);
745 for (i
= 0; i
< num_options
; i
++)
746 printf(" %s=%s", options
[i
].name
, options
[i
].value
);
750 puts("FAIL (No conflicts!)");
752 fputs("ppdInstallableConflict(): ", stdout
);
753 if (ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble") &&
754 !ppdInstallableConflict(ppd
, "Duplex", "None"))
756 else if (!ppdInstallableConflict(ppd
, "Duplex", "DuplexNoTumble"))
758 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
763 puts("FAIL (Duplex=None conflicted)");
771 ppdMarkDefaults(ppd
);
773 fputs("ppdPageSizeLimits(default): ", stdout
);
774 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
776 if (fabs(minsize
.width
- 36.0) > 0.001 || fabs(minsize
.length
- 36.0) > 0.001 ||
777 fabs(maxsize
.width
- 1080.0) > 0.001 || fabs(maxsize
.length
- 86400.0) > 0.001)
779 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
780 "expected min=36x36, max=1080x86400)\n", minsize
.width
,
781 minsize
.length
, maxsize
.width
, maxsize
.length
);
789 puts("FAIL (returned 0)");
793 ppdMarkOption(ppd
, "InputSlot", "Manual");
795 fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout
);
796 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
798 if (fabs(minsize
.width
- 100.0) > 0.001 || fabs(minsize
.length
- 100.0) > 0.001 ||
799 fabs(maxsize
.width
- 1000.0) > 0.001 || fabs(maxsize
.length
- 1000.0) > 0.001)
801 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
802 "expected min=100x100, max=1000x1000)\n", minsize
.width
,
803 minsize
.length
, maxsize
.width
, maxsize
.length
);
811 puts("FAIL (returned 0)");
815 ppdMarkOption(ppd
, "Quality", "Photo");
817 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout
);
818 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
820 if (fabs(minsize
.width
- 200.0) > 0.001 || fabs(minsize
.length
- 200.0) > 0.001 ||
821 fabs(maxsize
.width
- 1000.0) > 0.001 || fabs(maxsize
.length
- 1000.0) > 0.001)
823 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
824 "expected min=200x200, max=1000x1000)\n", minsize
.width
,
825 minsize
.length
, maxsize
.width
, maxsize
.length
);
833 puts("FAIL (returned 0)");
837 ppdMarkOption(ppd
, "InputSlot", "Tray");
839 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout
);
840 if (ppdPageSizeLimits(ppd
, &minsize
, &maxsize
))
842 if (fabs(minsize
.width
- 300.0) > 0.001 || fabs(minsize
.length
- 300.0) > 0.001 ||
843 fabs(maxsize
.width
- 1080.0) > 0.001 || fabs(maxsize
.length
- 86400.0) > 0.001)
845 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
846 "expected min=300x300, max=1080x86400)\n", minsize
.width
,
847 minsize
.length
, maxsize
.width
, maxsize
.length
);
855 puts("FAIL (returned 0)");
859 else if (!strncmp(argv
[1], "ipp://", 6) || !strncmp(argv
[1], "ipps://", 7))
862 * ipp://... or ipps://...
865 http_t
*http
; /* Connection to printer */
866 ipp_t
*request
, /* Get-Printer-Attributes request */
867 *response
; /* Get-Printer-Attributes response */
868 char scheme
[32], /* URI scheme */
869 userpass
[256], /* Username:password */
870 host
[256], /* Hostname */
871 resource
[256]; /* Resource path */
872 int port
; /* Port number */
873 static const char * const pattrs
[] =/* Requested printer attributes */
877 "printer-description",
881 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
)
883 printf("Bad URI \"%s\".\n", argv
[1]);
887 http
= httpConnect2(host
, port
, NULL
, AF_UNSPEC
, !strcmp(scheme
, "ipps") ? HTTP_ENCRYPTION_ALWAYS
: HTTP_ENCRYPTION_IF_REQUESTED
, 1, 30000, NULL
);
890 printf("Unable to connect to \"%s:%d\": %s\n", host
, port
, cupsLastErrorString());
894 request
= ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES
);
895 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri", NULL
, argv
[1]);
896 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
, "requested-attributes", sizeof(pattrs
) / sizeof(pattrs
[0]), NULL
, pattrs
);
897 response
= cupsDoRequest(http
, request
, resource
);
899 if (_ppdCreateFromIPP(buffer
, sizeof(buffer
), response
))
900 printf("Created PPD: %s\n", buffer
);
902 puts("Unable to create PPD.");
910 const char *filename
; /* PPD filename */
911 struct stat fileinfo
; /* File information */
914 if (strchr(argv
[1], ':'))
920 if ((filename
= cupsGetServerPPD(CUPS_HTTP_DEFAULT
, argv
[1])) == NULL
)
922 printf("%s: %s\n", argv
[1], cupsLastErrorString());
926 else if (!strncmp(argv
[1], "-d", 2))
928 const char *printer
; /* Printer name */
931 printer
= argv
[1] + 2;
936 puts("Usage: ./testppd -d printer");
940 filename
= cupsGetPPD(printer
);
944 printf("%s: %s\n", printer
, cupsLastErrorString());
951 if (lstat(filename
, &fileinfo
))
953 printf("%s: %s\n", filename
, strerror(errno
));
957 if (S_ISLNK(fileinfo
.st_mode
))
959 char realfile
[1024]; /* Real file path */
960 ssize_t realsize
; /* Size of real file path */
963 if ((realsize
= readlink(filename
, realfile
, sizeof(realfile
) - 1)) < 0)
964 strlcpy(realfile
, "Unknown", sizeof(realfile
));
966 realfile
[realsize
] = '\0';
968 if (stat(realfile
, &fileinfo
))
969 printf("%s: symlink to \"%s\", %s\n", filename
, realfile
,
972 printf("%s: symlink to \"%s\", %ld bytes\n", filename
, realfile
,
973 (long)fileinfo
.st_size
);
976 printf("%s: regular file, %ld bytes\n", filename
, (long)fileinfo
.st_size
);
978 if ((ppd
= ppdOpenFile(filename
)) == NULL
)
980 ppd_status_t err
; /* Last error in file */
981 int line
; /* Line number in file */
985 err
= ppdLastError(&line
);
987 printf("%s: %s on line %d\n", argv
[1], ppdErrorString(err
), line
);
991 int j
, k
; /* Looping vars */
992 ppd_group_t
*group
; /* Option group */
993 ppd_option_t
*option
; /* Option */
994 ppd_coption_t
*coption
; /* Custom option */
995 ppd_cparam_t
*cparam
; /* Custom parameter */
996 ppd_const_t
*c
; /* UIConstraints */
997 char lang
[255], /* LANG environment variable */
998 lc_all
[255], /* LC_ALL environment variable */
999 lc_ctype
[255], /* LC_CTYPE environment variable */
1000 lc_messages
[255];/* LC_MESSAGES environment variable */
1005 snprintf(lang
, sizeof(lang
), "LANG=%s", argv
[2]);
1007 snprintf(lc_all
, sizeof(lc_all
), "LC_ALL=%s", argv
[2]);
1009 snprintf(lc_ctype
, sizeof(lc_ctype
), "LC_CTYPE=%s", argv
[2]);
1011 snprintf(lc_messages
, sizeof(lc_messages
), "LC_MESSAGES=%s", argv
[2]);
1012 putenv(lc_messages
);
1016 ppdMarkDefaults(ppd
);
1020 text
= ppdLocalizeIPPReason(ppd
, argv
[3], NULL
, buffer
, sizeof(buffer
));
1021 printf("ppdLocalizeIPPReason(%s)=%s\n", argv
[3],
1022 text
? text
: "(null)");
1023 return (text
== NULL
);
1026 for (i
= ppd
->num_groups
, group
= ppd
->groups
;
1030 printf("%s (%s):\n", group
->name
, group
->text
);
1032 for (j
= group
->num_options
, option
= group
->options
;
1036 printf(" %s (%s):\n", option
->keyword
, option
->text
);
1038 for (k
= 0; k
< option
->num_choices
; k
++)
1039 printf(" - %s%s (%s)\n",
1040 option
->choices
[k
].marked
? "*" : "",
1041 option
->choices
[k
].choice
, option
->choices
[k
].text
);
1043 if ((coption
= ppdFindCustomOption(ppd
, option
->keyword
)) != NULL
)
1045 for (cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
);
1047 cparam
= (ppd_cparam_t
*)cupsArrayNext(coption
->params
))
1049 switch (cparam
->type
)
1051 case PPD_CUSTOM_CURVE
:
1052 printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
1053 cparam
->name
, cparam
->text
,
1054 cparam
->minimum
.custom_curve
,
1055 cparam
->maximum
.custom_curve
);
1058 case PPD_CUSTOM_INT
:
1059 printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
1060 cparam
->name
, cparam
->text
,
1061 cparam
->minimum
.custom_int
,
1062 cparam
->maximum
.custom_int
);
1065 case PPD_CUSTOM_INVCURVE
:
1066 printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
1067 cparam
->name
, cparam
->text
,
1068 cparam
->minimum
.custom_invcurve
,
1069 cparam
->maximum
.custom_invcurve
);
1072 case PPD_CUSTOM_PASSCODE
:
1073 printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
1074 cparam
->name
, cparam
->text
,
1075 cparam
->minimum
.custom_passcode
,
1076 cparam
->maximum
.custom_passcode
);
1079 case PPD_CUSTOM_PASSWORD
:
1080 printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
1081 cparam
->name
, cparam
->text
,
1082 cparam
->minimum
.custom_password
,
1083 cparam
->maximum
.custom_password
);
1086 case PPD_CUSTOM_POINTS
:
1087 printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
1088 cparam
->name
, cparam
->text
,
1089 cparam
->minimum
.custom_points
,
1090 cparam
->maximum
.custom_points
);
1093 case PPD_CUSTOM_REAL
:
1094 printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
1095 cparam
->name
, cparam
->text
,
1096 cparam
->minimum
.custom_real
,
1097 cparam
->maximum
.custom_real
);
1100 case PPD_CUSTOM_STRING
:
1101 printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
1102 cparam
->name
, cparam
->text
,
1103 cparam
->minimum
.custom_string
,
1104 cparam
->maximum
.custom_string
);
1113 for (i
= ppd
->num_sizes
, size
= ppd
->sizes
; i
> 0; i
--, size
++)
1114 printf(" %s = %gx%g, [%g %g %g %g]\n", size
->name
, size
->width
,
1115 size
->length
, size
->left
, size
->bottom
, size
->right
, size
->top
);
1117 puts("\nConstraints:");
1119 for (i
= ppd
->num_consts
, c
= ppd
->consts
; i
> 0; i
--, c
++)
1120 printf(" *UIConstraints: *%s %s *%s %s\n", c
->option1
, c
->choice1
,
1121 c
->option2
, c
->choice2
);
1122 if (ppd
->num_consts
== 0)
1123 puts(" NO CONSTRAINTS");
1127 for (i
= 0; i
< ppd
->num_filters
; i
++)
1128 printf(" %s\n", ppd
->filters
[i
]);
1130 if (ppd
->num_filters
== 0)
1131 puts(" NO FILTERS");
1133 puts("\nAttributes:");
1135 for (attr
= (ppd_attr_t
*)cupsArrayFirst(ppd
->sorted_attrs
);
1137 attr
= (ppd_attr_t
*)cupsArrayNext(ppd
->sorted_attrs
))
1138 printf(" *%s %s/%s: \"%s\"\n", attr
->name
, attr
->spec
,
1139 attr
->text
, attr
->value
? attr
->value
: "");
1141 puts("\nPPD Cache:");
1142 if ((pc
= _ppdCacheCreateWithPPD(ppd
)) == NULL
)
1143 printf(" Unable to create: %s\n", cupsLastErrorString());
1146 _ppdCacheWriteFile(pc
, "t.cache", NULL
);
1147 puts(" Wrote t.cache.");
1151 if (!strncmp(argv
[1], "-d", 2))
1156 if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
1158 char command
[1024]; /* malloc_history command */
1160 snprintf(command
, sizeof(command
), "malloc_history %d -all_by_size",
1165 #endif /* __APPLE__ */