]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testppd.c
Import CUPS v1.7.1
[thirdparty/cups.git] / cups / testppd.c
CommitLineData
fa73b229 1/*
61515785 2 * "$Id: testppd.c 11060 2013-06-25 15:02:18Z msweet $"
fa73b229 3 *
71e16022 4 * PPD test program for CUPS.
fa73b229 5 *
5489ad43 6 * Copyright 2007-2013 by Apple Inc.
fa73b229 7 * Copyright 1997-2006 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
fa73b229 14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
19 * main() - Main entry.
20 */
21
22/*
23 * Include necessary headers...
24 */
25
5489ad43 26#undef _CUPS_NO_DEPRECATED
71e16022 27#include "cups-private.h"
c9fc04c6 28#include <sys/stat.h>
fa73b229 29#ifdef WIN32
30# include <io.h>
31#else
32# include <unistd.h>
33# include <fcntl.h>
34#endif /* WIN32 */
35
36
e1d6a774 37/*
38 * Test data...
39 */
40
41static const char *default_code =
66ab9486
MS
42 "[{\n"
43 "%%BeginFeature: *InstalledDuplexer False\n"
44 "%%EndFeature\n"
45 "} stopped cleartomark\n"
e1d6a774 46 "[{\n"
47 "%%BeginFeature: *PageRegion Letter\n"
48 "PageRegion=Letter\n"
49 "%%EndFeature\n"
50 "} stopped cleartomark\n"
51 "[{\n"
52 "%%BeginFeature: *InputSlot Tray\n"
53 "InputSlot=Tray\n"
54 "%%EndFeature\n"
8ca02f3c 55 "} stopped cleartomark\n"
56 "[{\n"
54afec33
MS
57 "%%BeginFeature: *MediaType Plain\n"
58 "MediaType=Plain\n"
59 "%%EndFeature\n"
60 "} stopped cleartomark\n"
61 "[{\n"
8ca02f3c 62 "%%BeginFeature: *IntOption None\n"
63 "%%EndFeature\n"
64 "} stopped cleartomark\n"
65 "[{\n"
66 "%%BeginFeature: *StringOption None\n"
67 "%%EndFeature\n"
68 "} stopped cleartomark\n";
69
70static const char *custom_code =
66ab9486
MS
71 "[{\n"
72 "%%BeginFeature: *InstalledDuplexer False\n"
73 "%%EndFeature\n"
74 "} stopped cleartomark\n"
8ca02f3c 75 "[{\n"
76 "%%BeginFeature: *InputSlot Tray\n"
77 "InputSlot=Tray\n"
78 "%%EndFeature\n"
79 "} stopped cleartomark\n"
80 "[{\n"
54afec33
MS
81 "%%BeginFeature: *MediaType Plain\n"
82 "MediaType=Plain\n"
83 "%%EndFeature\n"
84 "} stopped cleartomark\n"
85 "[{\n"
8ca02f3c 86 "%%BeginFeature: *IntOption None\n"
87 "%%EndFeature\n"
88 "} stopped cleartomark\n"
89 "[{\n"
ee571f26
MS
90 "%%BeginFeature: *CustomStringOption True\n"
91 "(value\\0502\\051)\n"
92 "(value 1)\n"
93 "StringOption=Custom\n"
8ca02f3c 94 "%%EndFeature\n"
0a682745
MS
95 "} stopped cleartomark\n"
96 "[{\n"
97 "%%BeginFeature: *CustomPageSize True\n"
98 "400\n"
99 "500\n"
100 "0\n"
101 "0\n"
102 "0\n"
103 "PageSize=Custom\n"
104 "%%EndFeature\n"
e1d6a774 105 "} stopped cleartomark\n";
106
f11a948a
MS
107static const char *default2_code =
108 "[{\n"
109 "%%BeginFeature: *InstalledDuplexer False\n"
110 "%%EndFeature\n"
111 "} stopped cleartomark\n"
112 "[{\n"
113 "%%BeginFeature: *InputSlot Tray\n"
114 "InputSlot=Tray\n"
115 "%%EndFeature\n"
116 "} stopped cleartomark\n"
117 "[{\n"
118 "%%BeginFeature: *Quality Normal\n"
119 "Quality=Normal\n"
120 "%%EndFeature\n"
121 "} stopped cleartomark\n"
122 "[{\n"
123 "%%BeginFeature: *IntOption None\n"
124 "%%EndFeature\n"
125 "} stopped cleartomark\n"
126 "[{\n"
127 "%%BeginFeature: *StringOption None\n"
128 "%%EndFeature\n"
129 "} stopped cleartomark\n";
130
e1d6a774 131
fa73b229 132/*
133 * 'main()' - Main entry.
134 */
135
136int /* O - Exit status */
137main(int argc, /* I - Number of command-line arguments */
138 char *argv[]) /* I - Command-line arguments */
139{
66ab9486 140 int i; /* Looping var */
fa73b229 141 ppd_file_t *ppd; /* PPD file loaded from disk */
142 int status; /* Status of tests (0 = success, 1 = fail) */
e1d6a774 143 int conflicts; /* Number of conflicts */
144 char *s; /* String */
bc44d920 145 char buffer[8192]; /* String buffer */
d2354e63
MS
146 const char *text, /* Localized text */
147 *val; /* Option value */
66ab9486
MS
148 int num_options; /* Number of options */
149 cups_option_t *options; /* Options */
005dd1eb 150 ppd_size_t minsize, /* Minimum size */
c168a833
MS
151 maxsize, /* Maximum size */
152 *size; /* Current size */
6e8b116d 153 ppd_attr_t *attr; /* Current attribute */
5a9febac 154 _ppd_cache_t *pc; /* PPD cache */
fa73b229 155
156
157 status = 0;
158
a74454a7 159 if (argc == 1)
fa73b229 160 {
c9fc04c6
MS
161 /*
162 * Setup directories for locale stuff...
163 */
164
165 if (access("locale", 0))
166 {
167 mkdir("locale", 0777);
168 mkdir("locale/fr", 0777);
169 symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
170 mkdir("locale/zh_TW", 0777);
171 symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
172 }
173
174 putenv("LOCALEDIR=locale");
b0f6947b 175 putenv("SOFTWARE=CUPS");
c9fc04c6
MS
176
177 /*
178 * Do tests with test.ppd...
179 */
180
66ab9486 181 fputs("ppdOpenFile(test.ppd): ", stdout);
a74454a7 182
9c80ffa2 183 if ((ppd = _ppdOpenFile("test.ppd", _PPD_LOCALIZATION_ALL)) != NULL)
a74454a7 184 puts("PASS");
185 else
186 {
187 ppd_status_t err; /* Last error in file */
188 int line; /* Line number in file */
189
190
191 status ++;
192 err = ppdLastError(&line);
193
194 printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
195 }
196
6e8b116d
MS
197 fputs("ppdFindAttr(wildcard): ", stdout);
198 if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL)
199 {
200 status ++;
201 puts("FAIL (not found)");
202 }
203 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
204 {
205 status ++;
206 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
207 }
208 else
209 puts("PASS");
210
211 fputs("ppdFindNextAttr(wildcard): ", stdout);
212 if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL)
213 {
214 status ++;
215 puts("FAIL (not found)");
216 }
217 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar"))
218 {
219 status ++;
220 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
221 }
222 else
223 puts("PASS");
224
225 fputs("ppdFindAttr(Foo): ", stdout);
226 if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL)
227 {
228 status ++;
229 puts("FAIL (not found)");
230 }
231 else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
232 {
233 status ++;
234 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
235 }
236 else
237 puts("PASS");
238
239 fputs("ppdFindNextAttr(Foo): ", stdout);
240 if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL)
241 {
242 status ++;
243 printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
244 }
245 else
246 puts("PASS");
247
a74454a7 248 fputs("ppdMarkDefaults: ", stdout);
249 ppdMarkDefaults(ppd);
250
251 if ((conflicts = ppdConflicts(ppd)) == 0)
252 puts("PASS");
253 else
254 {
255 status ++;
256 printf("FAIL (%d conflicts)\n", conflicts);
257 }
258
8ca02f3c 259 fputs("ppdEmitString (defaults): ", stdout);
a74454a7 260 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
261 !strcmp(s, default_code))
262 puts("PASS");
263 else
264 {
bc44d920 265 status ++;
a74454a7 266 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
267 (int)strlen(default_code));
268
269 if (s)
270 puts(s);
ed486911 271 }
272
8ca02f3c 273 if (s)
274 free(s);
275
ee571f26 276 fputs("ppdEmitString (custom size and string): ", stdout);
8ca02f3c 277 ppdMarkOption(ppd, "PageSize", "Custom.400x500");
ee571f26 278 ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}");
8ca02f3c 279
280 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
281 !strcmp(s, custom_code))
282 puts("PASS");
283 else
284 {
bc44d920 285 status ++;
8ca02f3c 286 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
287 (int)strlen(custom_code));
288
289 if (s)
290 puts(s);
291 }
292
a74454a7 293 if (s)
294 free(s);
e1d6a774 295
66ab9486
MS
296 /*
297 * Test constraints...
298 */
299
d2354e63 300 fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout);
66ab9486 301 ppdMarkOption(ppd, "PageSize", "Letter");
d2354e63
MS
302
303 num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options);
304 if (num_options != 2 ||
305 (val = cupsGetOption("PageRegion", num_options, options)) == NULL ||
88f9aafc 306 _cups_strcasecmp(val, "Letter") ||
d2354e63 307 (val = cupsGetOption("PageSize", num_options, options)) == NULL ||
88f9aafc 308 _cups_strcasecmp(val, "Letter"))
d2354e63
MS
309 {
310 printf("FAIL (%d options:", num_options);
311 for (i = 0; i < num_options; i ++)
312 printf(" %s=%s", options[i].name, options[i].value);
313 puts(")");
314 status ++;
315 }
316 else
317 puts("PASS");
318
319 fputs("ppdConflicts(): ", stdout);
66ab9486
MS
320 ppdMarkOption(ppd, "InputSlot", "Envelope");
321
322 if ((conflicts = ppdConflicts(ppd)) == 2)
323 puts("PASS (2)");
324 else
325 {
326 printf("FAIL (%d)\n", conflicts);
327 status ++;
328 }
329
06d4e77b 330 fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout);
66ab9486
MS
331 num_options = 0;
332 options = NULL;
c168a833 333 if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options,
06d4e77b
MS
334 &options))
335 {
c168a833
MS
336 puts("FAIL (Unable to resolve)");
337 status ++;
338 }
339 else if (num_options != 2 ||
340 !cupsGetOption("PageSize", num_options, options))
341 {
342 printf("FAIL (%d options:", num_options);
343 for (i = 0; i < num_options; i ++)
344 printf(" %s=%s", options[i].name, options[i].value);
345 puts(")");
06d4e77b
MS
346 status ++;
347 }
348 else
c168a833
MS
349 puts("PASS (Resolved by changing PageSize)");
350
06d4e77b
MS
351 cupsFreeOptions(num_options, options);
352
353 fputs("cupsResolveConflicts(No option/choice): ", stdout);
354 num_options = 0;
355 options = NULL;
356 if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
88f9aafc
MS
357 num_options == 1 && !_cups_strcasecmp(options[0].name, "InputSlot") &&
358 !_cups_strcasecmp(options[0].value, "Tray"))
c168a833 359 puts("PASS (Resolved by changing InputSlot)");
66ab9486
MS
360 else if (num_options > 0)
361 {
362 printf("FAIL (%d options:", num_options);
363 for (i = 0; i < num_options; i ++)
364 printf(" %s=%s", options[i].name, options[i].value);
365 puts(")");
366 status ++;
367 }
368 else
369 {
06d4e77b 370 puts("FAIL (Unable to resolve)");
66ab9486
MS
371 status ++;
372 }
373 cupsFreeOptions(num_options, options);
374
375 fputs("ppdInstallableConflict(): ", stdout);
376 if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
377 !ppdInstallableConflict(ppd, "Duplex", "None"))
378 puts("PASS");
379 else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
380 {
381 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
382 status ++;
383 }
384 else
385 {
386 puts("FAIL (Duplex=None conflicted)");
387 status ++;
388 }
389
005dd1eb
MS
390 /*
391 * ppdPageSizeLimits
392 */
393
394 fputs("ppdPageSizeLimits: ", stdout);
395 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
396 {
397 if (minsize.width != 36 || minsize.length != 36 ||
398 maxsize.width != 1080 || maxsize.length != 86400)
399 {
400 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
401 "expected min=36x36, max=1080x86400)\n", minsize.width,
402 minsize.length, maxsize.width, maxsize.length);
403 status ++;
404 }
405 else
406 puts("PASS");
407 }
408 else
409 {
410 puts("FAIL (returned 0)");
411 status ++;
412 }
413
c168a833
MS
414 /*
415 * cupsMarkOptions with PWG and IPP size names.
416 */
417
418 fputs("cupsMarkOptions(media=iso-a4): ", stdout);
419 num_options = cupsAddOption("media", "iso-a4", 0, &options);
420 cupsMarkOptions(ppd, num_options, options);
421 cupsFreeOptions(num_options, options);
422
423 size = ppdPageSize(ppd, NULL);
424 if (!size || strcmp(size->name, "A4"))
425 {
426 printf("FAIL (%s)\n", size ? size->name : "unknown");
427 status ++;
428 }
429 else
430 puts("PASS");
431
432 fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout);
433 num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options);
434 cupsMarkOptions(ppd, num_options, options);
435 cupsFreeOptions(num_options, options);
436
437 size = ppdPageSize(ppd, NULL);
438 if (!size || strcmp(size->name, "Letter"))
439 {
440 printf("FAIL (%s)\n", size ? size->name : "unknown");
441 status ++;
442 }
443 else
444 puts("PASS");
445
f14324a7
MS
446 fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout);
447 num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
448 &options);
449 cupsMarkOptions(ppd, num_options, options);
450 cupsFreeOptions(num_options, options);
451
452 size = ppdPageSize(ppd, NULL);
453 if (!size || strcmp(size->name, "Letter.Fullbleed"))
454 {
455 printf("FAIL (%s)\n", size ? size->name : "unknown");
456 status ++;
457 }
458 else
459 puts("PASS");
460
cc754834
MS
461 fputs("cupsMarkOptions(media=A4): ", stdout);
462 num_options = cupsAddOption("media", "A4", 0, &options);
463 cupsMarkOptions(ppd, num_options, options);
464 cupsFreeOptions(num_options, options);
465
466 size = ppdPageSize(ppd, NULL);
467 if (!size || strcmp(size->name, "A4"))
468 {
469 printf("FAIL (%s)\n", size ? size->name : "unknown");
470 status ++;
471 }
472 else
473 puts("PASS");
474
dcb445bc
MS
475 /*
476 * Custom sizes...
477 */
478
479 fputs("cupsMarkOptions(media=Custom.8x10in): ", stdout);
480 num_options = cupsAddOption("media", "Custom.8x10in", 0, &options);
481 cupsMarkOptions(ppd, num_options, options);
482 cupsFreeOptions(num_options, options);
483
484 size = ppdPageSize(ppd, NULL);
485 if (!size || strcmp(size->name, "Custom") ||
486 size->width != 576 || size->length != 720)
487 {
488 printf("FAIL (%s - %gx%g)\n", size ? size->name : "unknown",
489 size ? size->width : 0.0, size ? size->length : 0.0);
490 status ++;
491 }
492 else
493 puts("PASS");
494
bc44d920 495 /*
496 * Test localization...
497 */
498
499 fputs("ppdLocalizeIPPReason(text): ", stdout);
500 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
501 !strcmp(buffer, "Foo Reason"))
502 puts("PASS");
503 else
504 {
505 status ++;
506 printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer);
507 }
508
509 fputs("ppdLocalizeIPPReason(http): ", stdout);
510 if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) &&
511 !strcmp(buffer, "http://foo/bar.html"))
512 puts("PASS");
513 else
514 {
515 status ++;
516 printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer);
517 }
518
519 fputs("ppdLocalizeIPPReason(help): ", stdout);
520 if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) &&
521 !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help"))
522 puts("PASS");
523 else
524 {
525 status ++;
526 printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer);
527 }
528
529 fputs("ppdLocalizeIPPReason(file): ", stdout);
530 if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) &&
531 !strcmp(buffer, "/help/foo/bar.html"))
532 puts("PASS");
533 else
534 {
535 status ++;
536 printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer);
537 }
538
539 putenv("LANG=fr");
c5571a1d
MS
540 putenv("LC_ALL=fr");
541 putenv("LC_CTYPE=fr");
542 putenv("LC_MESSAGES=fr");
bc44d920 543
544 fputs("ppdLocalizeIPPReason(fr text): ", stdout);
545 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
546 !strcmp(buffer, "La Long Foo Reason"))
547 puts("PASS");
548 else
549 {
550 status ++;
551 printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer);
552 }
553
db1f069b 554 putenv("LANG=zh_TW");
c5571a1d
MS
555 putenv("LC_ALL=zh_TW");
556 putenv("LC_CTYPE=zh_TW");
557 putenv("LC_MESSAGES=zh_TW");
db1f069b
MS
558
559 fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout);
560 if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
561 !strcmp(buffer, "Number 1 Foo Reason"))
562 puts("PASS");
563 else
564 {
565 status ++;
566 printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
567 }
5a738aea
MS
568
569 /*
570 * cupsMarkerName localization...
571 */
572
573 putenv("LANG=en");
c5571a1d
MS
574 putenv("LC_ALL=en");
575 putenv("LC_CTYPE=en");
576 putenv("LC_MESSAGES=en");
5a738aea
MS
577
578 fputs("ppdLocalizeMarkerName(bogus): ", stdout);
579
580 if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
581 {
582 status ++;
583 printf("FAIL (\"%s\" instead of NULL)\n", text);
584 }
585 else
586 puts("PASS");
587
588 fputs("ppdLocalizeMarkerName(cyan): ", stdout);
589
590 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
591 !strcmp(text, "Cyan Toner"))
592 puts("PASS");
593 else
594 {
595 status ++;
596 printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
597 text ? text : "(null)");
598 }
599
600 putenv("LANG=fr");
c5571a1d
MS
601 putenv("LC_ALL=fr");
602 putenv("LC_CTYPE=fr");
603 putenv("LC_MESSAGES=fr");
5a738aea
MS
604
605 fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
606 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
607 !strcmp(text, "La Toner Cyan"))
608 puts("PASS");
609 else
610 {
611 status ++;
612 printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
613 text ? text : "(null)");
614 }
615
616 putenv("LANG=zh_TW");
c5571a1d
MS
617 putenv("LC_ALL=zh_TW");
618 putenv("LC_CTYPE=zh_TW");
619 putenv("LC_MESSAGES=zh_TW");
5a738aea
MS
620
621 fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
622 if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
623 !strcmp(text, "Number 1 Cyan Toner"))
624 puts("PASS");
625 else
626 {
627 status ++;
628 printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
629 text ? text : "(null)");
630 }
66ab9486
MS
631
632 ppdClose(ppd);
633
634 /*
635 * Test new constraints...
636 */
637
638 fputs("ppdOpenFile(test2.ppd): ", stdout);
639
640 if ((ppd = ppdOpenFile("test2.ppd")) != NULL)
641 puts("PASS");
642 else
643 {
644 ppd_status_t err; /* Last error in file */
645 int line; /* Line number in file */
646
647
648 status ++;
649 err = ppdLastError(&line);
650
651 printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
652 }
653
654 fputs("ppdMarkDefaults: ", stdout);
655 ppdMarkDefaults(ppd);
656
657 if ((conflicts = ppdConflicts(ppd)) == 0)
658 puts("PASS");
659 else
660 {
661 status ++;
662 printf("FAIL (%d conflicts)\n", conflicts);
663 }
664
f11a948a
MS
665 fputs("ppdEmitString (defaults): ", stdout);
666 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
667 !strcmp(s, default2_code))
668 puts("PASS");
669 else
670 {
671 status ++;
672 printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
673 (int)strlen(default2_code));
674
675 if (s)
676 puts(s);
677 }
678
679 if (s)
680 free(s);
681
66ab9486
MS
682 fputs("ppdConflicts(): ", stdout);
683 ppdMarkOption(ppd, "PageSize", "Env10");
684 ppdMarkOption(ppd, "InputSlot", "Envelope");
685 ppdMarkOption(ppd, "Quality", "Photo");
686
1340db2d
MS
687 if ((conflicts = ppdConflicts(ppd)) == 1)
688 puts("PASS (1)");
66ab9486
MS
689 else
690 {
691 printf("FAIL (%d)\n", conflicts);
692 status ++;
693 }
694
06d4e77b 695 fputs("cupsResolveConflicts(Quality=Photo): ", stdout);
66ab9486
MS
696 num_options = 0;
697 options = NULL;
698 if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
06d4e77b
MS
699 &options))
700 {
701 printf("FAIL (%d options:", num_options);
702 for (i = 0; i < num_options; i ++)
703 printf(" %s=%s", options[i].name, options[i].value);
704 puts(")");
705 status ++;
706 }
707 else
708 puts("PASS (Unable to resolve)");
709 cupsFreeOptions(num_options, options);
710
711 fputs("cupsResolveConflicts(No option/choice): ", stdout);
712 num_options = 0;
713 options = NULL;
714 if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
88f9aafc
MS
715 num_options == 1 && !_cups_strcasecmp(options->name, "Quality") &&
716 !_cups_strcasecmp(options->value, "Normal"))
66ab9486
MS
717 puts("PASS");
718 else if (num_options > 0)
719 {
720 printf("FAIL (%d options:", num_options);
721 for (i = 0; i < num_options; i ++)
722 printf(" %s=%s", options[i].name, options[i].value);
723 puts(")");
724 status ++;
725 }
726 else
727 {
728 puts("FAIL (Unable to resolve!)");
729 status ++;
730 }
731 cupsFreeOptions(num_options, options);
732
733 fputs("cupsResolveConflicts(loop test): ", stdout);
734 ppdMarkOption(ppd, "PageSize", "A4");
1340db2d 735 ppdMarkOption(ppd, "InputSlot", "Tray");
66ab9486
MS
736 ppdMarkOption(ppd, "Quality", "Photo");
737 num_options = 0;
738 options = NULL;
06d4e77b 739 if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
66ab9486
MS
740 puts("PASS");
741 else if (num_options > 0)
742 {
743 printf("FAIL (%d options:", num_options);
744 for (i = 0; i < num_options; i ++)
745 printf(" %s=%s", options[i].name, options[i].value);
746 puts(")");
747 }
748 else
749 puts("FAIL (No conflicts!)");
6d2f911b 750
66ab9486
MS
751 fputs("ppdInstallableConflict(): ", stdout);
752 if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
753 !ppdInstallableConflict(ppd, "Duplex", "None"))
754 puts("PASS");
755 else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
756 {
757 puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
758 status ++;
759 }
760 else
761 {
762 puts("FAIL (Duplex=None conflicted)");
763 status ++;
764 }
005dd1eb
MS
765
766 /*
767 * ppdPageSizeLimits
768 */
769
770 ppdMarkDefaults(ppd);
771
772 fputs("ppdPageSizeLimits(default): ", stdout);
773 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
774 {
775 if (minsize.width != 36 || minsize.length != 36 ||
776 maxsize.width != 1080 || maxsize.length != 86400)
777 {
778 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
779 "expected min=36x36, max=1080x86400)\n", minsize.width,
780 minsize.length, maxsize.width, maxsize.length);
781 status ++;
782 }
783 else
784 puts("PASS");
785 }
786 else
787 {
788 puts("FAIL (returned 0)");
789 status ++;
790 }
791
792 ppdMarkOption(ppd, "InputSlot", "Manual");
793
794 fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout);
795 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
796 {
797 if (minsize.width != 100 || minsize.length != 100 ||
798 maxsize.width != 1000 || maxsize.length != 1000)
799 {
800 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
801 "expected min=100x100, max=1000x1000)\n", minsize.width,
802 minsize.length, maxsize.width, maxsize.length);
803 status ++;
804 }
805 else
806 puts("PASS");
807 }
808 else
809 {
810 puts("FAIL (returned 0)");
811 status ++;
812 }
813
814 ppdMarkOption(ppd, "Quality", "Photo");
815
816 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
817 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
818 {
819 if (minsize.width != 200 || minsize.length != 200 ||
820 maxsize.width != 1000 || maxsize.length != 1000)
821 {
822 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
823 "expected min=200x200, max=1000x1000)\n", minsize.width,
824 minsize.length, maxsize.width, maxsize.length);
825 status ++;
826 }
827 else
828 puts("PASS");
829 }
830 else
831 {
832 puts("FAIL (returned 0)");
833 status ++;
834 }
835
836 ppdMarkOption(ppd, "InputSlot", "Tray");
837
838 fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
839 if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
840 {
841 if (minsize.width != 300 || minsize.length != 300 ||
842 maxsize.width != 1080 || maxsize.length != 86400)
843 {
844 printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
845 "expected min=300x300, max=1080x86400)\n", minsize.width,
846 minsize.length, maxsize.width, maxsize.length);
847 status ++;
848 }
849 else
850 puts("PASS");
851 }
852 else
853 {
854 puts("FAIL (returned 0)");
855 status ++;
856 }
e1d6a774 857 }
e1d6a774 858 else
859 {
dd1abb6b 860 const char *filename; /* PPD filename */
d1c13e16 861 struct stat fileinfo; /* File information */
dd1abb6b
MS
862
863
864 if (!strncmp(argv[1], "-d", 2))
749b1e90 865 {
c8fef167
MS
866 const char *printer; /* Printer name */
867
868 if (argv[1][2])
869 printer = argv[1] + 2;
870 else if (argv[2])
871 printer = argv[2];
872 else
873 {
874 puts("Usage: ./testppd -d printer");
875 return (1);
876 }
877
878 filename = cupsGetPPD(printer);
879
749b1e90
MS
880 if (!filename)
881 {
c8fef167 882 printf("%s: %s\n", printer, cupsLastErrorString());
749b1e90
MS
883 return (1);
884 }
885 }
dd1abb6b
MS
886 else
887 filename = argv[1];
888
d1c13e16
MS
889 if (lstat(filename, &fileinfo))
890 {
891 printf("%s: %s\n", filename, strerror(errno));
892 return (1);
893 }
894
895 if (S_ISLNK(fileinfo.st_mode))
896 {
897 char realfile[1024]; /* Real file path */
898 ssize_t realsize; /* Size of real file path */
899
900
901 if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0)
5a9febac 902 strlcpy(realfile, "Unknown", sizeof(realfile));
d1c13e16
MS
903 else
904 realfile[realsize] = '\0';
905
906 if (stat(realfile, &fileinfo))
907 printf("%s: symlink to \"%s\", %s\n", filename, realfile,
908 strerror(errno));
909 else
910 printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile,
911 (long)fileinfo.st_size);
912 }
913 else
914 printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size);
915
dd1abb6b 916 if ((ppd = ppdOpenFile(filename)) == NULL)
a74454a7 917 {
918 ppd_status_t err; /* Last error in file */
919 int line; /* Line number in file */
920
921
922 status ++;
923 err = ppdLastError(&line);
924
925 printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
926 }
927 else
928 {
66ab9486 929 int j, k; /* Looping vars */
a74454a7 930 ppd_group_t *group; /* Option group */
931 ppd_option_t *option; /* Option */
b86bc4cf 932 ppd_coption_t *coption; /* Custom option */
933 ppd_cparam_t *cparam; /* Custom parameter */
66ab9486 934 ppd_const_t *c; /* UIConstraints */
c5571a1d
MS
935 char lang[255], /* LANG environment variable */
936 lc_all[255], /* LC_ALL environment variable */
937 lc_ctype[255], /* LC_CTYPE environment variable */
938 lc_messages[255];/* LC_MESSAGES environment variable */
a74454a7 939
940
d09495fa 941 if (argc > 2)
942 {
943 snprintf(lang, sizeof(lang), "LANG=%s", argv[2]);
944 putenv(lang);
c5571a1d
MS
945 snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]);
946 putenv(lc_all);
947 snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]);
948 putenv(lc_ctype);
949 snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]);
950 putenv(lc_messages);
d09495fa 951 }
952
a74454a7 953 ppdLocalize(ppd);
f0ab5bff 954 ppdMarkDefaults(ppd);
a74454a7 955
e4572d57
MS
956 if (argc > 3)
957 {
958 text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer));
959 printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3],
960 text ? text : "(null)");
961 return (text == NULL);
962 }
963
a74454a7 964 for (i = ppd->num_groups, group = ppd->groups;
965 i > 0;
966 i --, group ++)
967 {
968 printf("%s (%s):\n", group->name, group->text);
d09495fa 969
a74454a7 970 for (j = group->num_options, option = group->options;
971 j > 0;
972 j --, option ++)
973 {
974 printf(" %s (%s):\n", option->keyword, option->text);
975
976 for (k = 0; k < option->num_choices; k ++)
f0ab5bff
MS
977 printf(" - %s%s (%s)\n",
978 option->choices[k].marked ? "*" : "",
979 option->choices[k].choice, option->choices[k].text);
b86bc4cf 980
981 if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
982 {
983 for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
984 cparam;
985 cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
986 {
987 switch (cparam->type)
988 {
989 case PPD_CUSTOM_CURVE :
990 printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
991 cparam->name, cparam->text,
992 cparam->minimum.custom_curve,
993 cparam->maximum.custom_curve);
994 break;
995
996 case PPD_CUSTOM_INT :
997 printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
998 cparam->name, cparam->text,
999 cparam->minimum.custom_int,
1000 cparam->maximum.custom_int);
1001 break;
1002
1003 case PPD_CUSTOM_INVCURVE :
1004 printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
1005 cparam->name, cparam->text,
1006 cparam->minimum.custom_invcurve,
1007 cparam->maximum.custom_invcurve);
1008 break;
1009
1010 case PPD_CUSTOM_PASSCODE :
1011 printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
1012 cparam->name, cparam->text,
1013 cparam->minimum.custom_passcode,
1014 cparam->maximum.custom_passcode);
1015 break;
1016
1017 case PPD_CUSTOM_PASSWORD :
1018 printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
1019 cparam->name, cparam->text,
1020 cparam->minimum.custom_password,
1021 cparam->maximum.custom_password);
1022 break;
1023
1024 case PPD_CUSTOM_POINTS :
1025 printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
1026 cparam->name, cparam->text,
1027 cparam->minimum.custom_points,
1028 cparam->maximum.custom_points);
1029 break;
1030
1031 case PPD_CUSTOM_REAL :
1032 printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
1033 cparam->name, cparam->text,
1034 cparam->minimum.custom_real,
1035 cparam->maximum.custom_real);
1036 break;
1037
1038 case PPD_CUSTOM_STRING :
1039 printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
1040 cparam->name, cparam->text,
1041 cparam->minimum.custom_string,
1042 cparam->maximum.custom_string);
1043 break;
1044 }
1045 }
1046 }
a74454a7 1047 }
1048 }
d09495fa 1049
030ae6a1
MS
1050 puts("\nSizes:");
1051 for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
1052 printf(" %s = %gx%g, [%g %g %g %g]\n", size->name, size->width,
1053 size->length, size->left, size->bottom, size->right, size->top);
1054
1340db2d 1055 puts("\nConstraints:");
66ab9486
MS
1056
1057 for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
1058 printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
1059 c->option2, c->choice2);
1340db2d
MS
1060 if (ppd->num_consts == 0)
1061 puts(" NO CONSTRAINTS");
1062
1063 puts("\nFilters:");
1064
1065 for (i = 0; i < ppd->num_filters; i ++)
1066 printf(" %s\n", ppd->filters[i]);
1067
1068 if (ppd->num_filters == 0)
1069 puts(" NO FILTERS");
66ab9486 1070
1340db2d 1071 puts("\nAttributes:");
d09495fa 1072
1073 for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
1074 attr;
1075 attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
1076 printf(" *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
1077 attr->text, attr->value ? attr->value : "");
5a9febac
MS
1078
1079 puts("\nPPD Cache:");
1080 if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
1081 printf(" Unable to create: %s\n", cupsLastErrorString());
1082 else
1083 {
1084 _ppdCacheWriteFile(pc, "t.cache", NULL);
1085 puts(" Wrote t.cache.");
1086 }
a74454a7 1087 }
dd1abb6b
MS
1088
1089 if (!strncmp(argv[1], "-d", 2))
1090 unlink(filename);
e1d6a774 1091 }
1092
2e4ff8af
MS
1093#ifdef __APPLE__
1094 if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
1095 {
1096 char command[1024]; /* malloc_history command */
1097
1098 snprintf(command, sizeof(command), "malloc_history %d -all_by_size",
1099 getpid());
1100 fflush(stdout);
1101 system(command);
1102 }
1103#endif /* __APPLE__ */
1104
1105 ppdClose(ppd);
1106
fa73b229 1107 return (status);
1108}
1109
1110
1111/*
61515785 1112 * End of "$Id: testppd.c 11060 2013-06-25 15:02:18Z msweet $".
fa73b229 1113 */