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