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