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