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