1 /*
2 * PPD test program for CUPS.
3 *
4 * Copyright © 2020-2024 by OpenPrinting.
5 * Copyright © 2007-2018 by Apple Inc.
6 * Copyright © 1997-2006 by Easy Software Products.
7 *
8 * Licensed under Apache License v2.0. See the file "LICENSE" for more
9 * information.
10 */
11
12 /*
13 * Include necessary headers...
14 */
15
16 #undef _CUPS_NO_DEPRECATED
17 #include "cups-private.h"
18 #include "ppd-private.h"
19 #include "raster-private.h"
20 #include <sys/stat.h>
21 #ifdef _WIN32
22 # include <io.h>
23 #else
24 # include <unistd.h>
25 # include <fcntl.h>
26 #endif /* _WIN32 */
27 #include <math.h>
28
29
30 /*
31 * Local functions...
32 */
33
34 static int do_ppd_tests(const char *filename, int num_options, cups_option_t *options);
35 static int do_ps_tests(void);
36 static void print_changes(cups_page_header2_t *header, cups_page_header2_t *expected);
37
38
39 /*
40 * Test data...
41 */
42
43 static const char *dsc_code =
44 "[{\n"
45 "%%BeginFeature: *PageSize Tabloid\n"
46 "<</PageSize[792 1224]>>setpagedevice\n"
47 "%%EndFeature\n"
48 "} stopped cleartomark\n";
49 static const char *setpagedevice_code =
50 "<<"
51 "/MediaClass(Media Class)"
52 "/MediaColor((Media Color))"
53 "/MediaType(Media\\\\Type)"
54 "/OutputType<416263>"
55 "/AdvanceDistance 1000"
56 "/AdvanceMedia 1"
57 "/Collate false"
58 "/CutMedia 2"
59 "/Duplex true"
60 "/HWResolution[100 200]"
61 "/InsertSheet true"
62 "/Jog 3"
63 "/LeadingEdge 1"
64 "/ManualFeed true"
65 "/MediaPosition 8#777"
66 "/MediaWeight 16#fe01"
67 "/MirrorPrint true"
68 "/NegativePrint true"
69 "/NumCopies 1"
70 "/Orientation 1"
71 "/OutputFaceUp true"
72 "/PageSize[612 792.1]"
73 "/Separations true"
74 "/TraySwitch true"
75 "/Tumble true"
76 "/cupsMediaType 2"
77 "/cupsColorOrder 1"
78 "/cupsColorSpace 1"
79 "/cupsCompression 1"
80 "/cupsRowCount 1"
81 "/cupsRowFeed 1"
82 "/cupsRowStep 1"
83 "/cupsBorderlessScalingFactor 1.001"
84 "/cupsInteger0 1"
85 "/cupsInteger1 2"
86 "/cupsInteger2 3"
87 "/cupsInteger3 4"
88 "/cupsInteger4 5"
89 "/cupsInteger5 6"
90 "/cupsInteger6 7"
91 "/cupsInteger7 8"
92 "/cupsInteger8 9"
93 "/cupsInteger9 10"
94 "/cupsInteger10 11"
95 "/cupsInteger11 12"
96 "/cupsInteger12 13"
97 "/cupsInteger13 14"
98 "/cupsInteger14 15"
99 "/cupsInteger15 16"
100 "/cupsReal0 1.1"
101 "/cupsReal1 2.1"
102 "/cupsReal2 3.1"
103 "/cupsReal3 4.1"
104 "/cupsReal4 5.1"
105 "/cupsReal5 6.1"
106 "/cupsReal6 7.1"
107 "/cupsReal7 8.1"
108 "/cupsReal8 9.1"
109 "/cupsReal9 10.1"
110 "/cupsReal10 11.1"
111 "/cupsReal11 12.1"
112 "/cupsReal12 13.1"
113 "/cupsReal13 14.1"
114 "/cupsReal14 15.1"
115 "/cupsReal15 16.1"
116 "/cupsString0(1)"
117 "/cupsString1(2)"
118 "/cupsString2(3)"
119 "/cupsString3(4)"
120 "/cupsString4(5)"
121 "/cupsString5(6)"
122 "/cupsString6(7)"
123 "/cupsString7(8)"
124 "/cupsString8(9)"
125 "/cupsString9(10)"
126 "/cupsString10(11)"
127 "/cupsString11(12)"
128 "/cupsString12(13)"
129 "/cupsString13(14)"
130 "/cupsString14(15)"
131 "/cupsString15(16)"
132 "/cupsMarkerType(Marker Type)"
133 "/cupsRenderingIntent(Rendering Intent)"
134 "/cupsPageSizeName(Letter)"
135 "/cupsPreferredBitsPerColor 17"
136 ">> setpagedevice";
137
138 static cups_page_header2_t setpagedevice_header =
139 {
140 "Media Class", /* MediaClass */
141 "(Media Color)", /* MediaColor */
142 "Media\\Type", /* MediaType */
143 "Abc", /* OutputType */
144 1000, /* AdvanceDistance */
145 CUPS_ADVANCE_FILE, /* AdvanceMedia */
146 CUPS_FALSE, /* Collate */
147 CUPS_CUT_JOB, /* CutMedia */
148 CUPS_TRUE, /* Duplex */
149 { 100, 200 }, /* HWResolution */
150 { 0, 0, 0, 0 }, /* ImagingBoundingBox */
151 CUPS_TRUE, /* InsertSheet */
152 CUPS_JOG_SET, /* Jog */
153 CUPS_EDGE_RIGHT, /* LeadingEdge */
154 { 0, 0 }, /* Margins */
155 CUPS_TRUE, /* ManualFeed */
156 0777, /* MediaPosition */
157 0xfe01, /* MediaWeight */
158 CUPS_TRUE, /* MirrorPrint */
159 CUPS_TRUE, /* NegativePrint */
160 1, /* NumCopies */
161 CUPS_ORIENT_90, /* Orientation */
162 CUPS_TRUE, /* OutputFaceUp */
163 { 612, 792 }, /* PageSize */
164 CUPS_TRUE, /* Separations */
165 CUPS_TRUE, /* TraySwitch */
166 CUPS_TRUE, /* Tumble */
167 0, /* cupsWidth */
168 0, /* cupsHeight */
169 2, /* cupsMediaType */
170 0, /* cupsBitsPerColor */
171 0, /* cupsBitsPerPixel */
172 0, /* cupsBytesPerLine */
173 CUPS_ORDER_BANDED, /* cupsColorOrder */
174 CUPS_CSPACE_RGB, /* cupsColorSpace */
175 1, /* cupsCompression */
176 1, /* cupsRowCount */
177 1, /* cupsRowFeed */
178 1, /* cupsRowStep */
179 0, /* cupsNumColors */
180 1.001f, /* cupsBorderlessScalingFactor */
181 { 612.0f, 792.1f }, /* cupsPageSize */
182 { 0.0f, 0.0f, 0.0f, 0.0f }, /* cupsImagingBBox */
183 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
184 /* cupsInteger[16] */
185 { 1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1f, 8.1f, 9.1f, 10.1f, 11.1f, 12.1f, 13.1f, 14.1f, 15.1f, 16.1f }, /* cupsReal[16] */
186 { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
187 "14", "15", "16" }, /* cupsString[16] */
188 "Marker Type", /* cupsMarkerType */
189 "Rendering Intent", /* cupsRenderingIntent */
190 "Letter" /* cupsPageSizeName */
191 };
192
193 static const char *default_code =
194 "[{\n"
195 "%%BeginFeature: *InstalledDuplexer False\n"
196 "%%EndFeature\n"
197 "} stopped cleartomark\n"
198 "[{\n"
199 "%%BeginFeature: *PageRegion Letter\n"
200 "PageRegion=Letter\n"
201 "%%EndFeature\n"
202 "} stopped cleartomark\n"
203 "[{\n"
204 "%%BeginFeature: *InputSlot Tray\n"
205 "InputSlot=Tray\n"
206 "%%EndFeature\n"
207 "} stopped cleartomark\n"
208 "[{\n"
209 "%%BeginFeature: *OutputBin Tray1\n"
210 "OutputBin=Tray1\n"
211 "%%EndFeature\n"
212 "} stopped cleartomark\n"
213 "[{\n"
214 "%%BeginFeature: *MediaType Plain\n"
215 "MediaType=Plain\n"
216 "%%EndFeature\n"
217 "} stopped cleartomark\n"
218 "[{\n"
219 "%%BeginFeature: *IntOption None\n"
220 "%%EndFeature\n"
221 "} stopped cleartomark\n"
222 "[{\n"
223 "%%BeginFeature: *StringOption None\n"
224 "%%EndFeature\n"
225 "} stopped cleartomark\n";
226
227 static const char *custom_code =
228 "[{\n"
229 "%%BeginFeature: *InstalledDuplexer False\n"
230 "%%EndFeature\n"
231 "} stopped cleartomark\n"
232 "[{\n"
233 "%%BeginFeature: *InputSlot Tray\n"
234 "InputSlot=Tray\n"
235 "%%EndFeature\n"
236 "} stopped cleartomark\n"
237 "[{\n"
238 "%%BeginFeature: *MediaType Plain\n"
239 "MediaType=Plain\n"
240 "%%EndFeature\n"
241 "} stopped cleartomark\n"
242 "[{\n"
243 "%%BeginFeature: *OutputBin Tray1\n"
244 "OutputBin=Tray1\n"
245 "%%EndFeature\n"
246 "} stopped cleartomark\n"
247 "[{\n"
248 "%%BeginFeature: *IntOption None\n"
249 "%%EndFeature\n"
250 "} stopped cleartomark\n"
251 "[{\n"
252 "%%BeginFeature: *CustomStringOption True\n"
253 "(value\\0502\\051)\n"
254 "(value 1)\n"
255 "StringOption=Custom\n"
256 "%%EndFeature\n"
257 "} stopped cleartomark\n"
258 "[{\n"
259 "%%BeginFeature: *CustomPageSize True\n"
260 "400\n"
261 "500\n"
262 "0\n"
263 "0\n"
264 "0\n"
265 "PageSize=Custom\n"
266 "%%EndFeature\n"
267 "} stopped cleartomark\n";
268
269 static const char *default2_code =
270 "[{\n"
271 "%%BeginFeature: *InstalledDuplexer False\n"
272 "%%EndFeature\n"
273 "} stopped cleartomark\n"
274 "[{\n"
275 "%%BeginFeature: *InputSlot Tray\n"
276 "InputSlot=Tray\n"
277 "%%EndFeature\n"
278 "} stopped cleartomark\n"
279 "[{\n"
280 "%%BeginFeature: *Quality Normal\n"
281 "Quality=Normal\n"
282 "%%EndFeature\n"
283 "} stopped cleartomark\n"
284 "[{\n"
285 "%%BeginFeature: *IntOption None\n"
286 "%%EndFeature\n"
287 "} stopped cleartomark\n"
288 "[{\n"
289 "%%BeginFeature: *StringOption None\n"
290 "%%EndFeature\n"
291 "} stopped cleartomark\n";
292
293
294 /*
295 * 'main()' - Main entry.
296 */
297
298 int /* O - Exit status */
main(int argc,char * argv[])299 main(int argc, /* I - Number of command-line arguments */
300 char *argv[]) /* I - Command-line arguments */
301 {
302 int i; /* Looping var */
303 ppd_file_t *ppd = NULL; /* PPD file loaded from disk */
304 int status; /* Status of tests (0 = success, 1 = fail) */
305 int conflicts; /* Number of conflicts */
306 char *s; /* String */
307 char buffer[8192]; /* String buffer */
308 const char *text, /* Localized text */
309 *val; /* Option value */
310 int num_options; /* Number of options */
311 cups_option_t *options; /* Options */
312 ppd_size_t minsize, /* Minimum size */
313 maxsize, /* Maximum size */
314 *size; /* Current size */
315 ppd_attr_t *attr; /* Current attribute */
316 _ppd_cache_t *pc; /* PPD cache */
317
318
319 status = 0;
320
321 if (argc == 1)
322 {
323 /*
324 * Setup directories for locale stuff...
325 */
326
327 if (access("locale", 0))
328 {
329 mkdir("locale", 0777);
330 mkdir("locale/fr", 0777);
331 symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
332 mkdir("locale/zh_TW", 0777);
333 symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
334 }
335
336 putenv("LOCALEDIR=locale");
337 putenv("SOFTWARE=CUPS");
338
339 /*
340 * Do tests with test.ppd...
341 */
342
343 fputs("ppdOpenFile(test.ppd): ", stdout);
344
345 if ((ppd = _ppdOpenFile("test.ppd", _PPD_LOCALIZATION_ALL)) != NULL)
346 puts("PASS");
347 else
348 {
349 ppd_status_t err; /* Last error in file */
350 int line; /* Line number in file */
351
352
353 status ++;
354 err = ppdLastError(&line);
355
356 printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
357 }
358
359 fputs("ppdFindAttr(wildcard): ", stdout);
360 if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL)
361 {
362 status ++;
363 puts("FAIL (not found)");
364 }
365 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
366 {
367 status ++;
368 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
369 }
370 else
371 puts("PASS");
372
373 fputs("ppdFindNextAttr(wildcard): ", stdout);
374 if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL)
375 {
376 status ++;
377 puts("FAIL (not found)");
378 }
379 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar"))
380 {
381 status ++;
382 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
383 }
384 else
385 puts("PASS");
386
387 fputs("ppdFindAttr(Foo): ", stdout);
388 if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL)
389 {
390 status ++;
391 puts("FAIL (not found)");
392 }
393 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
394 {
395 status ++;
396 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
397 }
398 else
399 puts("PASS");
400
401 fputs("ppdFindNextAttr(Foo): ", stdout);
402 if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL)
403 {
404 status ++;
405 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
406 }
407 else
408 puts("PASS");
409
410 fputs("ppdMarkDefaults: ", stdout);
411 ppdMarkDefaults(ppd);
412
413 if ((conflicts = ppdConflicts(ppd)) == 0)
414 puts("PASS");
415 else
416 {
417 status ++;
418 printf("FAIL (%d conflicts)\n", conflicts);
419 }
420
421 fputs("ppdEmitString (defaults): ", stdout);
422 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
423 !strcmp(s, default_code))
424 puts("PASS");
425 else
426 {
427 status ++;
428 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
429 (int)strlen(default_code));
430
431 if (s)
432 puts(s);
433 }
434
435 if (s)
436 free(s);
437
438 fputs("ppdEmitString (custom size and string): ", stdout);
439 ppdMarkOption(ppd, "PageSize", "Custom.400x500");
440 ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}");
441
442 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
443 !strcmp(s, custom_code))
444 puts("PASS");
445 else
446 {
447 status ++;
448 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
449 (int)strlen(custom_code));
450
451 if (s)
452 puts(s);
453 }
454
455 if (s)
456 free(s);
457
458 /*
459 * Test constraints...
460 */
461
462 fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout);
463 ppdMarkOption(ppd, "PageSize", "Letter");
464
465 num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options);
466 if (num_options != 2 ||
467 (val = cupsGetOption("PageRegion", num_options, options)) == NULL ||
468 _cups_strcasecmp(val, "Letter") ||
469 (val = cupsGetOption("PageSize", num_options, options)) == NULL ||
470 _cups_strcasecmp(val, "Letter"))
471 {
472 printf("FAIL (%d options:", num_options);
473 for (i = 0; i < num_options; i ++)
474 printf(" %s=%s", options[i].name, options[i].value);
475 puts(")");
476 status ++;
477 }
478 else
479 puts("PASS");
480
481 fputs("ppdConflicts(): ", stdout);
482 ppdMarkOption(ppd, "InputSlot", "Envelope");
483
484 if ((conflicts = ppdConflicts(ppd)) == 2)
485 puts("PASS (2)");
486 else
487 {
488 printf("FAIL (%d)\n", conflicts);
489 status ++;
490 }
491
492 fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout);
493 num_options = 0;
494 options = NULL;
495 if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options,
496 &options))
497 {
498 puts("FAIL (Unable to resolve)");
499 status ++;
500 }
501 else if (num_options != 2 ||
502 !cupsGetOption("PageSize", num_options, options))
503 {
504 printf("FAIL (%d options:", num_options);
505 for (i = 0; i < num_options; i ++)
506 printf(" %s=%s", options[i].name, options[i].value);
507 puts(")");
508 status ++;
509 }
510 else
511 puts("PASS (Resolved by changing PageSize)");
512
513 cupsFreeOptions(num_options, options);
514
515 fputs("cupsResolveConflicts(No option/choice): ", stdout);
516 num_options = 0;
517 options = NULL;
518 if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
519 num_options == 1 && !_cups_strcasecmp(options[0].name, "InputSlot") &&
520 !_cups_strcasecmp(options[0].value, "Tray"))
521 puts("PASS (Resolved by changing InputSlot)");
522 else if (num_options > 0)
523 {
524 printf("FAIL (%d options:", num_options);
525 for (i = 0; i < num_options; i ++)
526 printf(" %s=%s", options[i].name, options[i].value);
527 puts(")");
528 status ++;
529 }
530 else
531 {
532 puts("FAIL (Unable to resolve)");
533 status ++;
534 }
535 cupsFreeOptions(num_options, options);
536
537 fputs("ppdInstallableConflict(): ", stdout);
538 if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
539 !ppdInstallableConflict(ppd, "Duplex", "None"))
540 puts("PASS");
541 else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
542 {
543 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
544 status ++;
545 }
546 else
547 {
548 puts("FAIL (Duplex=None conflicted)");
549 status ++;
550 }
551
552 /*
553 * ppdPageSizeLimits
554 */
555
556 fputs("ppdPageSizeLimits: ", stdout);
557 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
558 {
559 if (fabs(minsize.width - 36.0) > 0.001 || fabs(minsize.length - 36.0) > 0.001 ||
560 fabs(maxsize.width - 1080.0) > 0.001 || fabs(maxsize.length - 86400.0) > 0.001)
561 {
562 printf("FAIL (got min=%.3fx%.3f, max=%.3fx%.3f, "
563 "expected min=36x36, max=1080x86400)\n", minsize.width,
564 minsize.length, maxsize.width, maxsize.length);
565 status ++;
566 }
567 else
568 puts("PASS");
569 }
570 else
571 {
572 puts("FAIL (returned 0)");
573 status ++;
574 }
575
576 /*
577 * cupsMarkOptions with PWG and IPP size names.
578 */
579
580 fputs("cupsMarkOptions(media=iso-a4): ", stdout);
581 num_options = cupsAddOption("media", "iso-a4", 0, &options);
582 cupsMarkOptions(ppd, num_options, options);
583 cupsFreeOptions(num_options, options);
584
585 size = ppdPageSize(ppd, NULL);
586 if (!size || strcmp(size->name, "A4"))
587 {
588 printf("FAIL (%s)\n", size ? size->name : "unknown");
589 status ++;
590 }
591 else
592 puts("PASS");
593
594 fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout);
595 num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options);
596 cupsMarkOptions(ppd, num_options, options);
597 cupsFreeOptions(num_options, options);
598
599 size = ppdPageSize(ppd, NULL);
600 if (!size || strcmp(size->name, "Letter"))
601 {
602 printf("FAIL (%s)\n", size ? size->name : "unknown");
603 status ++;
604 }
605 else
606 puts("PASS");
607
608 fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout);
609 num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
610 &options);
611 cupsMarkOptions(ppd, num_options, options);
612 cupsFreeOptions(num_options, options);
613
614 size = ppdPageSize(ppd, NULL);
615 if (!size || strcmp(size->name, "Letter.Fullbleed"))
616 {
617 printf("FAIL (%s)\n", size ? size->name : "unknown");
618 status ++;
619 }
620 else
621 puts("PASS");
622
623 fputs("cupsMarkOptions(media=A4): ", stdout);
624 num_options = cupsAddOption("media", "A4", 0, &options);
625 cupsMarkOptions(ppd, num_options, options);
626 cupsFreeOptions(num_options, options);
627
628 size = ppdPageSize(ppd, NULL);
629 if (!size || strcmp(size->name, "A4"))
630 {
631 printf("FAIL (%s)\n", size ? size->name : "unknown");
632 status ++;
633 }
634 else
635 puts("PASS");
636
637 /*
638 * Custom sizes...
639 */
640
641 fputs("cupsMarkOptions(media=Custom.8x10in): ", stdout);
642 num_options = cupsAddOption("media", "Custom.8x10in", 0, &options);
643 cupsMarkOptions(ppd, num_options, options);
644 cupsFreeOptions(num_options, options);
645
646 size = ppdPageSize(ppd, NULL);
647 if (!size || strcmp(size->name, "Custom") ||
648 fabs(size->width - 576.0) > 0.001 ||
649 fabs(size->length - 720.0) > 0.001)
650 {
651 printf("FAIL (%s - %gx%g)\n", size ? size->name : "unknown",
652 size ? size->width : 0.0, size ? size->length : 0.0);
653 status ++;
654 }
655 else
656 puts("PASS");
657
658 /*
659 * Test localization...
660 */
661
662 /* Force US English base locale */
663 putenv("LANG=en");
664 putenv("LC_ALL=en");
665 putenv("LC_CTYPE=en");
666 putenv("LC_MESSAGES=en");
667
668 fputs("ppdLocalizeIPPReason(text): ", stdout);
669 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
670 !strcmp(buffer, "Foo Reason"))
671 puts("PASS");
672 else
673 {
674 status ++;
675 printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer);
676 }
677
678 fputs("ppdLocalizeIPPReason(http): ", stdout);
679 if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) &&
680 !strcmp(buffer, "http://foo/bar.html"))
681 puts("PASS");
682 else
683 {
684 status ++;
685 printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer);
686 }
687
688 fputs("ppdLocalizeIPPReason(help): ", stdout);
689 if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) &&
690 !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help"))
691 puts("PASS");
692 else
693 {
694 status ++;
695 printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer);
696 }
697
698 fputs("ppdLocalizeIPPReason(file): ", stdout);
699 if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) &&
700 !strcmp(buffer, "/help/foo/bar.html"))
701 puts("PASS");
702 else
703 {
704 status ++;
705 printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer);
706 }
707
708 /* Force French */
709 putenv("LANG=fr");
710 putenv("LC_ALL=fr");
711 putenv("LC_CTYPE=fr");
712 putenv("LC_MESSAGES=fr");
713
714 fputs("ppdLocalizeIPPReason(fr text): ", stdout);
715 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
716 !strcmp(buffer, "La Long Foo Reason"))
717 puts("PASS");
718 else
719 {
720 status ++;
721 printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer);
722 }
723
724 /* Force Simplified Chinese */
725 putenv("LANG=zh_TW");
726 putenv("LC_ALL=zh_TW");
727 putenv("LC_CTYPE=zh_TW");
728 putenv("LC_MESSAGES=zh_TW");
729
730 fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout);
731 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
732 !strcmp(buffer, "Number 1 Foo Reason"))
733 puts("PASS");
734 else
735 {
736 status ++;
737 printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
738 }
739
740 /*
741 * cupsMarkerName localization...
742 */
743
744 /* Force US English base locale */
745 putenv("LANG=en");
746 putenv("LC_ALL=en");
747 putenv("LC_CTYPE=en");
748 putenv("LC_MESSAGES=en");
749
750 fputs("ppdLocalizeMarkerName(bogus): ", stdout);
751
752 if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
753 {
754 status ++;
755 printf("FAIL (\"%s\" instead of NULL)\n", text);
756 }
757 else
758 puts("PASS");
759
760 fputs("ppdLocalizeMarkerName(cyan): ", stdout);
761
762 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
763 !strcmp(text, "Cyan Toner"))
764 puts("PASS");
765 else
766 {
767 status ++;
768 printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
769 text ? text : "(null)");
770 }
771
772 /* Force French locale */
773 putenv("LANG=fr");
774 putenv("LC_ALL=fr");
775 putenv("LC_CTYPE=fr");
776 putenv("LC_MESSAGES=fr");
777
778 fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
779 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
780 !strcmp(text, "La Toner Cyan"))
781 puts("PASS");
782 else
783 {
784 status ++;
785 printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
786 text ? text : "(null)");
787 }
788
789 /* Force Simplified Chinese locale */
790 putenv("LANG=zh_TW");
791 putenv("LC_ALL=zh_TW");
792 putenv("LC_CTYPE=zh_TW");
793 putenv("LC_MESSAGES=zh_TW");
794
795 fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
796 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
797 !strcmp(text, "Number 1 Cyan Toner"))
798 puts("PASS");
799 else
800 {
801 status ++;
802 printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
803 text ? text : "(null)");
804 }
805
806 ppdClose(ppd);
807
808 /* Force US English base locale */
809 putenv("LANG=en");
810 putenv("LC_ALL=en");
811 putenv("LC_CTYPE=en");
812 putenv("LC_MESSAGES=en");
813
814 /*
815 * Test new constraints...
816 */
817
818 fputs("ppdOpenFile(test2.ppd): ", stdout);
819
820 if ((ppd = ppdOpenFile("test2.ppd")) != NULL)
821 puts("PASS");
822 else
823 {
824 ppd_status_t err; /* Last error in file */
825 int line; /* Line number in file */
826
827
828 status ++;
829 err = ppdLastError(&line);
830
831 printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
832 }
833
834 fputs("ppdMarkDefaults: ", stdout);
835 ppdMarkDefaults(ppd);
836
837 if ((conflicts = ppdConflicts(ppd)) == 0)
838 puts("PASS");
839 else
840 {
841 status ++;
842 printf("FAIL (%d conflicts)\n", conflicts);
843 }
844
845 fputs("ppdEmitString (defaults): ", stdout);
846 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
847 !strcmp(s, default2_code))
848 puts("PASS");
849 else
850 {
851 status ++;
852 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
853 (int)strlen(default2_code));
854
855 if (s)
856 puts(s);
857 }
858
859 if (s)
860 free(s);
861
862 fputs("ppdConflicts(): ", stdout);
863 ppdMarkOption(ppd, "PageSize", "Env10");
864 ppdMarkOption(ppd, "InputSlot", "Envelope");
865 ppdMarkOption(ppd, "Quality", "Photo");
866
867 if ((conflicts = ppdConflicts(ppd)) == 1)
868 puts("PASS (1)");
869 else
870 {
871 printf("FAIL (%d)\n", conflicts);
872 status ++;
873 }
874
875 fputs("cupsResolveConflicts(Quality=Photo): ", stdout);
876 num_options = 0;
877 options = NULL;
878 if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
879 &options))
880 {
881 printf("FAIL (%d options:", num_options);
882 for (i = 0; i < num_options; i ++)
883 printf(" %s=%s", options[i].name, options[i].value);
884 puts(")");
885 status ++;
886 }
887 else
888 puts("PASS (Unable to resolve)");
889 cupsFreeOptions(num_options, options);
890
891 fputs("cupsResolveConflicts(No option/choice): ", stdout);
892 num_options = 0;
893 options = NULL;
894 if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
895 num_options == 1 && !_cups_strcasecmp(options->name, "Quality") &&
896 !_cups_strcasecmp(options->value, "Normal"))
897 puts("PASS");
898 else if (num_options > 0)
899 {
900 printf("FAIL (%d options:", num_options);
901 for (i = 0; i < num_options; i ++)
902 printf(" %s=%s", options[i].name, options[i].value);
903 puts(")");
904 status ++;
905 }
906 else
907 {
908 puts("FAIL (Unable to resolve!)");
909 status ++;
910 }
911 cupsFreeOptions(num_options, options);
912
913 fputs("cupsResolveConflicts(loop test): ", stdout);
914 ppdMarkOption(ppd, "PageSize", "A4");
915 ppdMarkOption(ppd, "InputSlot", "Tray");
916 ppdMarkOption(ppd, "Quality", "Photo");
917 num_options = 0;
918 options = NULL;
919 if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
920 puts("PASS");
921 else if (num_options > 0)
922 {
923 printf("FAIL (%d options:", num_options);
924 for (i = 0; i < num_options; i ++)
925 printf(" %s=%s", options[i].name, options[i].value);
926 puts(")");
927 }
928 else
929 puts("FAIL (No conflicts!)");
930
931 fputs("ppdInstallableConflict(): ", stdout);
932 if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
933 !ppdInstallableConflict(ppd, "Duplex", "None"))
934 puts("PASS");
935 else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
936 {
937 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
938 status ++;
939 }
940 else
941 {
942 puts("FAIL (Duplex=None conflicted)");
943 status ++;
944 }
945
946 /*
947 * ppdPageSizeLimits
948 */
949
950 ppdMarkDefaults(ppd);
951
952 fputs("ppdPageSizeLimits(default): ", stdout);
953 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
954 {
955 if (fabs(minsize.width - 36.0) > 0.001 || fabs(minsize.length - 36.0) > 0.001 ||
956 fabs(maxsize.width - 1080.0) > 0.001 || fabs(maxsize.length - 86400.0) > 0.001)
957 {
958 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
959 "expected min=36x36, max=1080x86400)\n", minsize.width,
960 minsize.length, maxsize.width, maxsize.length);
961 status ++;
962 }
963 else
964 puts("PASS");
965 }
966 else
967 {
968 puts("FAIL (returned 0)");
969 status ++;
970 }
971
972 ppdMarkOption(ppd, "InputSlot", "Manual");
973
974 fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout);
975 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
976 {
977 if (fabs(minsize.width - 100.0) > 0.001 || fabs(minsize.length - 100.0) > 0.001 ||
978 fabs(maxsize.width - 1000.0) > 0.001 || fabs(maxsize.length - 1000.0) > 0.001)
979 {
980 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
981 "expected min=100x100, max=1000x1000)\n", minsize.width,
982 minsize.length, maxsize.width, maxsize.length);
983 status ++;
984 }
985 else
986 puts("PASS");
987 }
988 else
989 {
990 puts("FAIL (returned 0)");
991 status ++;
992 }
993
994 ppdMarkOption(ppd, "Quality", "Photo");
995
996 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
997 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
998 {
999 if (fabs(minsize.width - 200.0) > 0.001 || fabs(minsize.length - 200.0) > 0.001 ||
1000 fabs(maxsize.width - 1000.0) > 0.001 || fabs(maxsize.length - 1000.0) > 0.001)
1001 {
1002 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
1003 "expected min=200x200, max=1000x1000)\n", minsize.width,
1004 minsize.length, maxsize.width, maxsize.length);
1005 status ++;
1006 }
1007 else
1008 puts("PASS");
1009 }
1010 else
1011 {
1012 puts("FAIL (returned 0)");
1013 status ++;
1014 }
1015
1016 ppdMarkOption(ppd, "InputSlot", "Tray");
1017
1018 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
1019 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
1020 {
1021 if (fabs(minsize.width - 300.0) > 0.001 || fabs(minsize.length - 300.0) > 0.001 ||
1022 fabs(maxsize.width - 1080.0) > 0.001 || fabs(maxsize.length - 86400.0) > 0.001)
1023 {
1024 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
1025 "expected min=300x300, max=1080x86400)\n", minsize.width,
1026 minsize.length, maxsize.width, maxsize.length);
1027 status ++;
1028 }
1029 else
1030 puts("PASS");
1031 }
1032 else
1033 {
1034 puts("FAIL (returned 0)");
1035 status ++;
1036 }
1037
1038 status += do_ps_tests();
1039 }
1040 else if (!strcmp(argv[1], "--raster"))
1041 {
1042 for (status = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++)
1043 {
1044 if (argv[i][0] == '-')
1045 {
1046 if (argv[i][1] == 'o')
1047 {
1048 if (argv[i][2])
1049 num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
1050 else
1051 {
1052 i ++;
1053 if (i < argc)
1054 num_options = cupsParseOptions(argv[i], num_options, &options);
1055 else
1056 {
1057 puts("Usage: testppd --raster [-o name=value ...] [filename.ppd ...]");
1058 return (1);
1059 }
1060 }
1061 }
1062 else
1063 {
1064 puts("Usage: testppd --raster [-o name=value ...] [filename.ppd ...]");
1065 return (1);
1066 }
1067 }
1068 else
1069 status += do_ppd_tests(argv[i], num_options, options);
1070 }
1071
1072 cupsFreeOptions(num_options, options);
1073 }
1074 else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7))
1075 {
1076 /*
1077 * ipp://... or ipps://...
1078 */
1079
1080 http_t *http; /* Connection to printer */
1081 ipp_t *request, /* Get-Printer-Attributes request */
1082 *response; /* Get-Printer-Attributes response */
1083 char scheme[32], /* URI scheme */
1084 userpass[256], /* Username:password */
1085 host[256], /* Hostname */
1086 resource[256]; /* Resource path */
1087 int port; /* Port number */
1088 static const char * const pattrs[] =/* Requested printer attributes */
1089 {
1090 "job-template",
1091 "printer-defaults",
1092 "printer-description",
1093 "media-col-database"
1094 };
1095
1096 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)
1097 {
1098 printf("Bad URI \"%s\".\n", argv[1]);
1099 return (1);
1100 }
1101
1102 http = httpConnect2(host, port, NULL, AF_UNSPEC, !strcmp(scheme, "ipps") ? HTTP_ENCRYPTION_ALWAYS : HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
1103 if (!http)
1104 {
1105 printf("Unable to connect to \"%s:%d\": %s\n", host, port, cupsLastErrorString());
1106 return (1);
1107 }
1108
1109 request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
1110 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, argv[1]);
1111 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs);
1112 response = cupsDoRequest(http, request, resource);
1113
1114 if (_ppdCreateFromIPP(buffer, sizeof(buffer), response))
1115 printf("Created PPD: %s\n", buffer);
1116 else
1117 puts("Unable to create PPD.");
1118
1119 ippDelete(response);
1120 httpClose(http);
1121 return (0);
1122 }
1123 else
1124 {
1125 const char *filename; /* PPD filename */
1126 struct stat fileinfo; /* File information */
1127
1128
1129 if (strchr(argv[1], ':'))
1130 {
1131 /*
1132 * Server PPD...
1133 */
1134
1135 if ((filename = cupsGetServerPPD(CUPS_HTTP_DEFAULT, argv[1])) == NULL)
1136 {
1137 printf("%s: %s\n", argv[1], cupsLastErrorString());
1138 return (1);
1139 }
1140 }
1141 else if (!strncmp(argv[1], "-d", 2))
1142 {
1143 const char *printer; /* Printer name */
1144
1145 if (argv[1][2])
1146 printer = argv[1] + 2;
1147 else if (argv[2])
1148 printer = argv[2];
1149 else
1150 {
1151 puts("Usage: ./testppd -d printer");
1152 return (1);
1153 }
1154
1155 filename = cupsGetPPD(printer);
1156
1157 if (!filename)
1158 {
1159 printf("%s: %s\n", printer, cupsLastErrorString());
1160 return (1);
1161 }
1162 }
1163 else
1164 filename = argv[1];
1165
1166 if (lstat(filename, &fileinfo))
1167 {
1168 printf("%s: %s\n", filename, strerror(errno));
1169 return (1);
1170 }
1171
1172 if (S_ISLNK(fileinfo.st_mode))
1173 {
1174 char realfile[1024]; /* Real file path */
1175 ssize_t realsize; /* Size of real file path */
1176
1177
1178 if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0)
1179 strlcpy(realfile, "Unknown", sizeof(realfile));
1180 else
1181 realfile[realsize] = '\0';
1182
1183 if (stat(realfile, &fileinfo))
1184 printf("%s: symlink to \"%s\", %s\n", filename, realfile,
1185 strerror(errno));
1186 else
1187 printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile,
1188 (long)fileinfo.st_size);
1189 }
1190 else
1191 printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size);
1192
1193 if ((ppd = ppdOpenFile(filename)) == NULL)
1194 {
1195 ppd_status_t err; /* Last error in file */
1196 int line; /* Line number in file */
1197
1198
1199 status ++;
1200 err = ppdLastError(&line);
1201
1202 printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
1203 }
1204 else
1205 {
1206 int j, k; /* Looping vars */
1207 ppd_group_t *group; /* Option group */
1208 ppd_option_t *option; /* Option */
1209 ppd_coption_t *coption; /* Custom option */
1210 ppd_cparam_t *cparam; /* Custom parameter */
1211 ppd_const_t *c; /* UIConstraints */
1212 char lang[255], /* LANG environment variable */
1213 lc_all[255], /* LC_ALL environment variable */
1214 lc_ctype[255], /* LC_CTYPE environment variable */
1215 lc_messages[255];/* LC_MESSAGES environment variable */
1216
1217
1218 if (argc > 2)
1219 {
1220 snprintf(lang, sizeof(lang), "LANG=%s", argv[2]);
1221 putenv(lang);
1222 snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]);
1223 putenv(lc_all);
1224 snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]);
1225 putenv(lc_ctype);
1226 snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]);
1227 putenv(lc_messages);
1228 }
1229
1230 ppdLocalize(ppd);
1231 ppdMarkDefaults(ppd);
1232
1233 if (argc > 3)
1234 {
1235 text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer));
1236 printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3],
1237 text ? text : "(null)");
1238 return (text == NULL);
1239 }
1240
1241 for (i = ppd->num_groups, group = ppd->groups;
1242 i > 0;
1243 i --, group ++)
1244 {
1245 printf("%s (%s):\n", group->name, group->text);
1246
1247 for (j = group->num_options, option = group->options;
1248 j > 0;
1249 j --, option ++)
1250 {
1251 printf(" %s (%s):\n", option->keyword, option->text);
1252
1253 for (k = 0; k < option->num_choices; k ++)
1254 printf(" - %s%s (%s)\n",
1255 option->choices[k].marked ? "*" : "",
1256 option->choices[k].choice, option->choices[k].text);
1257
1258 if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
1259 {
1260 for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
1261 cparam;
1262 cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
1263 {
1264 switch (cparam->type)
1265 {
1266 case PPD_CUSTOM_UNKNOWN :
1267 printf(" %s(%s): PPD_CUSTOM_UNKNOWN (error)\n", cparam->name, cparam->text);
1268 break;
1269
1270 case PPD_CUSTOM_CURVE :
1271 printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
1272 cparam->name, cparam->text,
1273 cparam->minimum.custom_curve,
1274 cparam->maximum.custom_curve);
1275 break;
1276
1277 case PPD_CUSTOM_INT :
1278 printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
1279 cparam->name, cparam->text,
1280 cparam->minimum.custom_int,
1281 cparam->maximum.custom_int);
1282 break;
1283
1284 case PPD_CUSTOM_INVCURVE :
1285 printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
1286 cparam->name, cparam->text,
1287 cparam->minimum.custom_invcurve,
1288 cparam->maximum.custom_invcurve);
1289 break;
1290
1291 case PPD_CUSTOM_PASSCODE :
1292 printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
1293 cparam->name, cparam->text,
1294 cparam->minimum.custom_passcode,
1295 cparam->maximum.custom_passcode);
1296 break;
1297
1298 case PPD_CUSTOM_PASSWORD :
1299 printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
1300 cparam->name, cparam->text,
1301 cparam->minimum.custom_password,
1302 cparam->maximum.custom_password);
1303 break;
1304
1305 case PPD_CUSTOM_POINTS :
1306 printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
1307 cparam->name, cparam->text,
1308 cparam->minimum.custom_points,
1309 cparam->maximum.custom_points);
1310 break;
1311
1312 case PPD_CUSTOM_REAL :
1313 printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
1314 cparam->name, cparam->text,
1315 cparam->minimum.custom_real,
1316 cparam->maximum.custom_real);
1317 break;
1318
1319 case PPD_CUSTOM_STRING :
1320 printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
1321 cparam->name, cparam->text,
1322 cparam->minimum.custom_string,
1323 cparam->maximum.custom_string);
1324 break;
1325 }
1326 }
1327 }
1328 }
1329 }
1330
1331 puts("\nSizes:");
1332 for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
1333 printf(" %s = %gx%g, [%g %g %g %g]\n", size->name, size->width,
1334 size->length, size->left, size->bottom, size->right, size->top);
1335
1336 puts("\nConstraints:");
1337
1338 for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
1339 printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
1340 c->option2, c->choice2);
1341 if (ppd->num_consts == 0)
1342 puts(" NO CONSTRAINTS");
1343
1344 puts("\nFilters:");
1345
1346 for (i = 0; i < ppd->num_filters; i ++)
1347 printf(" %s\n", ppd->filters[i]);
1348
1349 if (ppd->num_filters == 0)
1350 puts(" NO FILTERS");
1351
1352 puts("\nAttributes:");
1353
1354 for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
1355 attr;
1356 attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
1357 printf(" *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
1358 attr->text, attr->value ? attr->value : "");
1359
1360 puts("\nPPD Cache:");
1361 if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
1362 printf(" Unable to create: %s\n", cupsLastErrorString());
1363 else
1364 {
1365 _ppdCacheWriteFile(pc, "t.cache", NULL);
1366 puts(" Wrote t.cache.");
1367 }
1368 }
1369
1370 if (!strncmp(argv[1], "-d", 2))
1371 unlink(filename);
1372 }
1373
1374 #ifdef __APPLE__
1375 if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
1376 {
1377 char command[1024]; /* malloc_history command */
1378
1379 snprintf(command, sizeof(command), "malloc_history %d -all_by_size",
1380 getpid());
1381 fflush(stdout);
1382 system(command);
1383 }
1384 #endif /* __APPLE__ */
1385
1386 ppdClose(ppd);
1387
1388 return (status);
1389 }
1390
1391
1392 /*
1393 * 'do_ppd_tests()' - Test the default option commands in a PPD file.
1394 */
1395
1396 static int /* O - Number of errors */
do_ppd_tests(const char * filename,int num_options,cups_option_t * options)1397 do_ppd_tests(const char *filename, /* I - PPD file */
1398 int num_options, /* I - Number of options */
1399 cups_option_t *options) /* I - Options */
1400 {
1401 ppd_file_t *ppd; /* PPD file data */
1402 cups_page_header2_t header; /* Page header */
1403
1404
1405 printf("\"%s\": ", filename);
1406 fflush(stdout);
1407
1408 if ((ppd = ppdOpenFile(filename)) == NULL)
1409 {
1410 ppd_status_t status; /* Status from PPD loader */
1411 int line; /* Line number containing error */
1412
1413
1414 status = ppdLastError(&line);
1415
1416 puts("FAIL (bad PPD file)");
1417 printf(" %s on line %d\n", ppdErrorString(status), line);
1418
1419 return (1);
1420 }
1421
1422 ppdMarkDefaults(ppd);
1423 cupsMarkOptions(ppd, num_options, options);
1424
1425 if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, NULL))
1426 {
1427 puts("FAIL (error from function)");
1428 puts(cupsRasterErrorString());
1429
1430 return (1);
1431 }
1432 else
1433 {
1434 puts("PASS");
1435
1436 return (0);
1437 }
1438 }
1439
1440
1441 /*
1442 * 'do_ps_tests()' - Test standard PostScript commands.
1443 */
1444
1445 static int
do_ps_tests(void)1446 do_ps_tests(void)
1447 {
1448 cups_page_header2_t header; /* Page header */
1449 int preferred_bits; /* Preferred bits */
1450 int errors = 0; /* Number of errors */
1451
1452
1453 /*
1454 * Test PS exec code...
1455 */
1456
1457 fputs("_cupsRasterExecPS(\"setpagedevice\"): ", stdout);
1458 fflush(stdout);
1459
1460 memset(&header, 0, sizeof(header));
1461 header.Collate = CUPS_TRUE;
1462 preferred_bits = 0;
1463
1464 if (_cupsRasterExecPS(&header, &preferred_bits, setpagedevice_code))
1465 {
1466 puts("FAIL (error from function)");
1467 puts(cupsRasterErrorString());
1468 errors ++;
1469 }
1470 else if (preferred_bits != 17 ||
1471 memcmp(&header, &setpagedevice_header, sizeof(header)))
1472 {
1473 puts("FAIL (bad header)");
1474
1475 if (preferred_bits != 17)
1476 printf(" cupsPreferredBitsPerColor %d, expected 17\n",
1477 preferred_bits);
1478
1479 print_changes(&setpagedevice_header, &header);
1480 errors ++;
1481 }
1482 else
1483 puts("PASS");
1484
1485 fputs("_cupsRasterExecPS(\"roll\"): ", stdout);
1486 fflush(stdout);
1487
1488 if (_cupsRasterExecPS(&header, &preferred_bits,
1489 "792 612 0 0 0\n"
1490 "pop pop pop\n"
1491 "<</PageSize[5 -2 roll]/ImagingBBox null>>"
1492 "setpagedevice\n"))
1493 {
1494 puts("FAIL (error from function)");
1495 puts(cupsRasterErrorString());
1496 errors ++;
1497 }
1498 else if (header.PageSize[0] != 792 || header.PageSize[1] != 612)
1499 {
1500 printf("FAIL (PageSize [%d %d], expected [792 612])\n", header.PageSize[0],
1501 header.PageSize[1]);
1502 errors ++;
1503 }
1504 else
1505 puts("PASS");
1506
1507 fputs("_cupsRasterExecPS(\"dup index\"): ", stdout);
1508 fflush(stdout);
1509
1510 if (_cupsRasterExecPS(&header, &preferred_bits,
1511 "true false dup\n"
1512 "<</Collate 4 index"
1513 "/Duplex 5 index"
1514 "/Tumble 6 index>>setpagedevice\n"
1515 "pop pop pop"))
1516 {
1517 puts("FAIL (error from function)");
1518 puts(cupsRasterErrorString());
1519 errors ++;
1520 }
1521 else
1522 {
1523 if (!header.Collate)
1524 {
1525 printf("FAIL (Collate false, expected true)\n");
1526 errors ++;
1527 }
1528
1529 if (header.Duplex)
1530 {
1531 printf("FAIL (Duplex true, expected false)\n");
1532 errors ++;
1533 }
1534
1535 if (header.Tumble)
1536 {
1537 printf("FAIL (Tumble true, expected false)\n");
1538 errors ++;
1539 }
1540
1541 if(header.Collate && !header.Duplex && !header.Tumble)
1542 puts("PASS");
1543 }
1544
1545 fputs("_cupsRasterExecPS(\"%%Begin/EndFeature code\"): ", stdout);
1546 fflush(stdout);
1547
1548 if (_cupsRasterExecPS(&header, &preferred_bits, dsc_code))
1549 {
1550 puts("FAIL (error from function)");
1551 puts(cupsRasterErrorString());
1552 errors ++;
1553 }
1554 else if (header.PageSize[0] != 792 || header.PageSize[1] != 1224)
1555 {
1556 printf("FAIL (bad PageSize [%d %d], expected [792 1224])\n",
1557 header.PageSize[0], header.PageSize[1]);
1558 errors ++;
1559 }
1560 else
1561 puts("PASS");
1562
1563 return (errors);
1564 }
1565
1566
1567
1568
1569 /*
1570 * 'print_changes()' - Print differences in the page header.
1571 */
1572
1573 static void
print_changes(cups_page_header2_t * header,cups_page_header2_t * expected)1574 print_changes(
1575 cups_page_header2_t *header, /* I - Actual page header */
1576 cups_page_header2_t *expected) /* I - Expected page header */
1577 {
1578 int i; /* Looping var */
1579
1580
1581 if (strcmp(header->MediaClass, expected->MediaClass))
1582 printf(" MediaClass (%s), expected (%s)\n", header->MediaClass,
1583 expected->MediaClass);
1584
1585 if (strcmp(header->MediaColor, expected->MediaColor))
1586 printf(" MediaColor (%s), expected (%s)\n", header->MediaColor,
1587 expected->MediaColor);
1588
1589 if (strcmp(header->MediaType, expected->MediaType))
1590 printf(" MediaType (%s), expected (%s)\n", header->MediaType,
1591 expected->MediaType);
1592
1593 if (strcmp(header->OutputType, expected->OutputType))
1594 printf(" OutputType (%s), expected (%s)\n", header->OutputType,
1595 expected->OutputType);
1596
1597 if (header->AdvanceDistance != expected->AdvanceDistance)
1598 printf(" AdvanceDistance %d, expected %d\n", header->AdvanceDistance,
1599 expected->AdvanceDistance);
1600
1601 if (header->AdvanceMedia != expected->AdvanceMedia)
1602 printf(" AdvanceMedia %d, expected %d\n", header->AdvanceMedia,
1603 expected->AdvanceMedia);
1604
1605 if (header->Collate != expected->Collate)
1606 printf(" Collate %d, expected %d\n", header->Collate,
1607 expected->Collate);
1608
1609 if (header->CutMedia != expected->CutMedia)
1610 printf(" CutMedia %d, expected %d\n", header->CutMedia,
1611 expected->CutMedia);
1612
1613 if (header->Duplex != expected->Duplex)
1614 printf(" Duplex %d, expected %d\n", header->Duplex,
1615 expected->Duplex);
1616
1617 if (header->HWResolution[0] != expected->HWResolution[0] ||
1618 header->HWResolution[1] != expected->HWResolution[1])
1619 printf(" HWResolution [%d %d], expected [%d %d]\n",
1620 header->HWResolution[0], header->HWResolution[1],
1621 expected->HWResolution[0], expected->HWResolution[1]);
1622
1623 if (memcmp(header->ImagingBoundingBox, expected->ImagingBoundingBox,
1624 sizeof(header->ImagingBoundingBox)))
1625 printf(" ImagingBoundingBox [%d %d %d %d], expected [%d %d %d %d]\n",
1626 header->ImagingBoundingBox[0],
1627 header->ImagingBoundingBox[1],
1628 header->ImagingBoundingBox[2],
1629 header->ImagingBoundingBox[3],
1630 expected->ImagingBoundingBox[0],
1631 expected->ImagingBoundingBox[1],
1632 expected->ImagingBoundingBox[2],
1633 expected->ImagingBoundingBox[3]);
1634
1635 if (header->InsertSheet != expected->InsertSheet)
1636 printf(" InsertSheet %d, expected %d\n", header->InsertSheet,
1637 expected->InsertSheet);
1638
1639 if (header->Jog != expected->Jog)
1640 printf(" Jog %d, expected %d\n", header->Jog,
1641 expected->Jog);
1642
1643 if (header->LeadingEdge != expected->LeadingEdge)
1644 printf(" LeadingEdge %d, expected %d\n", header->LeadingEdge,
1645 expected->LeadingEdge);
1646
1647 if (header->Margins[0] != expected->Margins[0] ||
1648 header->Margins[1] != expected->Margins[1])
1649 printf(" Margins [%d %d], expected [%d %d]\n",
1650 header->Margins[0], header->Margins[1],
1651 expected->Margins[0], expected->Margins[1]);
1652
1653 if (header->ManualFeed != expected->ManualFeed)
1654 printf(" ManualFeed %d, expected %d\n", header->ManualFeed,
1655 expected->ManualFeed);
1656
1657 if (header->MediaPosition != expected->MediaPosition)
1658 printf(" MediaPosition %d, expected %d\n", header->MediaPosition,
1659 expected->MediaPosition);
1660
1661 if (header->MediaWeight != expected->MediaWeight)
1662 printf(" MediaWeight %d, expected %d\n", header->MediaWeight,
1663 expected->MediaWeight);
1664
1665 if (header->MirrorPrint != expected->MirrorPrint)
1666 printf(" MirrorPrint %d, expected %d\n", header->MirrorPrint,
1667 expected->MirrorPrint);
1668
1669 if (header->NegativePrint != expected->NegativePrint)
1670 printf(" NegativePrint %d, expected %d\n", header->NegativePrint,
1671 expected->NegativePrint);
1672
1673 if (header->NumCopies != expected->NumCopies)
1674 printf(" NumCopies %d, expected %d\n", header->NumCopies,
1675 expected->NumCopies);
1676
1677 if (header->Orientation != expected->Orientation)
1678 printf(" Orientation %d, expected %d\n", header->Orientation,
1679 expected->Orientation);
1680
1681 if (header->OutputFaceUp != expected->OutputFaceUp)
1682 printf(" OutputFaceUp %d, expected %d\n", header->OutputFaceUp,
1683 expected->OutputFaceUp);
1684
1685 if (header->PageSize[0] != expected->PageSize[0] ||
1686 header->PageSize[1] != expected->PageSize[1])
1687 printf(" PageSize [%d %d], expected [%d %d]\n",
1688 header->PageSize[0], header->PageSize[1],
1689 expected->PageSize[0], expected->PageSize[1]);
1690
1691 if (header->Separations != expected->Separations)
1692 printf(" Separations %d, expected %d\n", header->Separations,
1693 expected->Separations);
1694
1695 if (header->TraySwitch != expected->TraySwitch)
1696 printf(" TraySwitch %d, expected %d\n", header->TraySwitch,
1697 expected->TraySwitch);
1698
1699 if (header->Tumble != expected->Tumble)
1700 printf(" Tumble %d, expected %d\n", header->Tumble,
1701 expected->Tumble);
1702
1703 if (header->cupsWidth != expected->cupsWidth)
1704 printf(" cupsWidth %d, expected %d\n", header->cupsWidth,
1705 expected->cupsWidth);
1706
1707 if (header->cupsHeight != expected->cupsHeight)
1708 printf(" cupsHeight %d, expected %d\n", header->cupsHeight,
1709 expected->cupsHeight);
1710
1711 if (header->cupsMediaType != expected->cupsMediaType)
1712 printf(" cupsMediaType %d, expected %d\n", header->cupsMediaType,
1713 expected->cupsMediaType);
1714
1715 if (header->cupsBitsPerColor != expected->cupsBitsPerColor)
1716 printf(" cupsBitsPerColor %d, expected %d\n", header->cupsBitsPerColor,
1717 expected->cupsBitsPerColor);
1718
1719 if (header->cupsBitsPerPixel != expected->cupsBitsPerPixel)
1720 printf(" cupsBitsPerPixel %d, expected %d\n", header->cupsBitsPerPixel,
1721 expected->cupsBitsPerPixel);
1722
1723 if (header->cupsBytesPerLine != expected->cupsBytesPerLine)
1724 printf(" cupsBytesPerLine %d, expected %d\n", header->cupsBytesPerLine,
1725 expected->cupsBytesPerLine);
1726
1727 if (header->cupsColorOrder != expected->cupsColorOrder)
1728 printf(" cupsColorOrder %d, expected %d\n", header->cupsColorOrder,
1729 expected->cupsColorOrder);
1730
1731 if (header->cupsColorSpace != expected->cupsColorSpace)
1732 printf(" cupsColorSpace %s, expected %s\n", _cupsRasterColorSpaceString(header->cupsColorSpace),
1733 _cupsRasterColorSpaceString(expected->cupsColorSpace));
1734
1735 if (header->cupsCompression != expected->cupsCompression)
1736 printf(" cupsCompression %d, expected %d\n", header->cupsCompression,
1737 expected->cupsCompression);
1738
1739 if (header->cupsRowCount != expected->cupsRowCount)
1740 printf(" cupsRowCount %d, expected %d\n", header->cupsRowCount,
1741 expected->cupsRowCount);
1742
1743 if (header->cupsRowFeed != expected->cupsRowFeed)
1744 printf(" cupsRowFeed %d, expected %d\n", header->cupsRowFeed,
1745 expected->cupsRowFeed);
1746
1747 if (header->cupsRowStep != expected->cupsRowStep)
1748 printf(" cupsRowStep %d, expected %d\n", header->cupsRowStep,
1749 expected->cupsRowStep);
1750
1751 if (header->cupsNumColors != expected->cupsNumColors)
1752 printf(" cupsNumColors %d, expected %d\n", header->cupsNumColors,
1753 expected->cupsNumColors);
1754
1755 if (fabs(header->cupsBorderlessScalingFactor - expected->cupsBorderlessScalingFactor) > 0.001)
1756 printf(" cupsBorderlessScalingFactor %g, expected %g\n",
1757 header->cupsBorderlessScalingFactor,
1758 expected->cupsBorderlessScalingFactor);
1759
1760 if (fabs(header->cupsPageSize[0] - expected->cupsPageSize[0]) > 0.001 ||
1761 fabs(header->cupsPageSize[1] - expected->cupsPageSize[1]) > 0.001)
1762 printf(" cupsPageSize [%g %g], expected [%g %g]\n",
1763 header->cupsPageSize[0], header->cupsPageSize[1],
1764 expected->cupsPageSize[0], expected->cupsPageSize[1]);
1765
1766 if (fabs(header->cupsImagingBBox[0] - expected->cupsImagingBBox[0]) > 0.001 ||
1767 fabs(header->cupsImagingBBox[1] - expected->cupsImagingBBox[1]) > 0.001 ||
1768 fabs(header->cupsImagingBBox[2] - expected->cupsImagingBBox[2]) > 0.001 ||
1769 fabs(header->cupsImagingBBox[3] - expected->cupsImagingBBox[3]) > 0.001)
1770 printf(" cupsImagingBBox [%g %g %g %g], expected [%g %g %g %g]\n",
1771 header->cupsImagingBBox[0], header->cupsImagingBBox[1],
1772 header->cupsImagingBBox[2], header->cupsImagingBBox[3],
1773 expected->cupsImagingBBox[0], expected->cupsImagingBBox[1],
1774 expected->cupsImagingBBox[2], expected->cupsImagingBBox[3]);
1775
1776 for (i = 0; i < 16; i ++)
1777 if (header->cupsInteger[i] != expected->cupsInteger[i])
1778 printf(" cupsInteger%d %d, expected %d\n", i, header->cupsInteger[i],
1779 expected->cupsInteger[i]);
1780
1781 for (i = 0; i < 16; i ++)
1782 if (fabs(header->cupsReal[i] - expected->cupsReal[i]) > 0.001)
1783 printf(" cupsReal%d %g, expected %g\n", i, header->cupsReal[i],
1784 expected->cupsReal[i]);
1785
1786 for (i = 0; i < 16; i ++)
1787 if (strcmp(header->cupsString[i], expected->cupsString[i]))
1788 printf(" cupsString%d (%s), expected (%s)\n", i,
1789 header->cupsString[i], expected->cupsString[i]);
1790
1791 if (strcmp(header->cupsMarkerType, expected->cupsMarkerType))
1792 printf(" cupsMarkerType (%s), expected (%s)\n", header->cupsMarkerType,
1793 expected->cupsMarkerType);
1794
1795 if (strcmp(header->cupsRenderingIntent, expected->cupsRenderingIntent))
1796 printf(" cupsRenderingIntent (%s), expected (%s)\n",
1797 header->cupsRenderingIntent,
1798 expected->cupsRenderingIntent);
1799
1800 if (strcmp(header->cupsPageSizeName, expected->cupsPageSizeName))
1801 printf(" cupsPageSizeName (%s), expected (%s)\n",
1802 header->cupsPageSizeName,
1803 expected->cupsPageSizeName);
1804 }
1805