1/* 2 * "$Id: testppd.c 11645 2014-02-27 16:35:53Z msweet $" 3 * 4 * PPD test program for CUPS. 5 * 6 * Copyright 2007-2014 by Apple Inc. 7 * Copyright 1997-2006 by Easy Software Products. 8 * 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/". 14 * 15 * This file is subject to the Apple OS-Developed Software exception. 16 */ 17 18/* 19 * Include necessary headers... 20 */ 21 22#undef _CUPS_NO_DEPRECATED 23#include "cups-private.h" 24#include <sys/stat.h> 25#ifdef WIN32 26# include <io.h> 27#else 28# include <unistd.h> 29# include <fcntl.h> 30#endif /* WIN32 */ 31#include <math.h> 32 33 34/* 35 * Test data... 36 */ 37 38static const char *default_code = 39 "[{\n" 40 "%%BeginFeature: *InstalledDuplexer False\n" 41 "%%EndFeature\n" 42 "} stopped cleartomark\n" 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" 52 "} stopped cleartomark\n" 53 "[{\n" 54 "%%BeginFeature: *MediaType Plain\n" 55 "MediaType=Plain\n" 56 "%%EndFeature\n" 57 "} stopped cleartomark\n" 58 "[{\n" 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 = 68 "[{\n" 69 "%%BeginFeature: *InstalledDuplexer False\n" 70 "%%EndFeature\n" 71 "} stopped cleartomark\n" 72 "[{\n" 73 "%%BeginFeature: *InputSlot Tray\n" 74 "InputSlot=Tray\n" 75 "%%EndFeature\n" 76 "} stopped cleartomark\n" 77 "[{\n" 78 "%%BeginFeature: *MediaType Plain\n" 79 "MediaType=Plain\n" 80 "%%EndFeature\n" 81 "} stopped cleartomark\n" 82 "[{\n" 83 "%%BeginFeature: *IntOption None\n" 84 "%%EndFeature\n" 85 "} stopped cleartomark\n" 86 "[{\n" 87 "%%BeginFeature: *CustomStringOption True\n" 88 "(value\\0502\\051)\n" 89 "(value 1)\n" 90 "StringOption=Custom\n" 91 "%%EndFeature\n" 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" 102 "} stopped cleartomark\n"; 103 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 128 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{ 137 int i; /* Looping var */ 138 ppd_file_t *ppd; /* PPD file loaded from disk */ 139 int status; /* Status of tests (0 = success, 1 = fail) */ 140 int conflicts; /* Number of conflicts */ 141 char *s; /* String */ 142 char buffer[8192]; /* String buffer */ 143 const char *text, /* Localized text */ 144 *val; /* Option value */ 145 int num_options; /* Number of options */ 146 cups_option_t *options; /* Options */ 147 ppd_size_t minsize, /* Minimum size */ 148 maxsize, /* Maximum size */ 149 *size; /* Current size */ 150 ppd_attr_t *attr; /* Current attribute */ 151 _ppd_cache_t *pc; /* PPD cache */ 152 153 154 status = 0; 155 156 if (argc == 1) 157 { 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"); 172 putenv("SOFTWARE=CUPS"); 173 174 /* 175 * Do tests with test.ppd... 176 */ 177 178 fputs("ppdOpenFile(test.ppd): ", stdout); 179 180 if ((ppd = _ppdOpenFile("test.ppd", _PPD_LOCALIZATION_ALL)) != NULL) 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 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 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 256 fputs("ppdEmitString (defaults): ", stdout); 257 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && 258 !strcmp(s, default_code)) 259 puts("PASS"); 260 else 261 { 262 status ++; 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); 268 } 269 270 if (s) 271 free(s); 272 273 fputs("ppdEmitString (custom size and string): ", stdout); 274 ppdMarkOption(ppd, "PageSize", "Custom.400x500"); 275 ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}"); 276 277 if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && 278 !strcmp(s, custom_code)) 279 puts("PASS"); 280 else 281 { 282 status ++; 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 290 if (s) 291 free(s); 292 293 /* 294 * Test constraints... 295 */ 296 297 fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout); 298 ppdMarkOption(ppd, "PageSize", "Letter"); 299 300 num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options); 301 if (num_options != 2 || 302 (val = cupsGetOption("PageRegion", num_options, options)) == NULL || 303 _cups_strcasecmp(val, "Letter") || 304 (val = cupsGetOption("PageSize", num_options, options)) == NULL || 305 _cups_strcasecmp(val, "Letter")) 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); 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 327 fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout); 328 num_options = 0; 329 options = NULL; 330 if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options, 331 &options)) 332 { 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(")"); 343 status ++; 344 } 345 else 346 puts("PASS (Resolved by changing PageSize)"); 347 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) && 354 num_options == 1 && !_cups_strcasecmp(options[0].name, "InputSlot") && 355 !_cups_strcasecmp(options[0].value, "Tray")) 356 puts("PASS (Resolved by changing InputSlot)"); 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 { 367 puts("FAIL (Unable to resolve)"); 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 387 /* 388 * ppdPageSizeLimits 389 */ 390 391 fputs("ppdPageSizeLimits: ", stdout); 392 if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) 393 { 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) 396 { 397 printf("FAIL (got min=%.3fx%.3f, max=%.3fx%.3f, " 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 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 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 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 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") || 483 fabs(size->width - 576.0) > 0.001 || 484 fabs(size->length - 720.0) > 0.001) 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 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"); 538 putenv("LC_ALL=fr"); 539 putenv("LC_CTYPE=fr"); 540 putenv("LC_MESSAGES=fr"); 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 552 putenv("LANG=zh_TW"); 553 putenv("LC_ALL=zh_TW"); 554 putenv("LC_CTYPE=zh_TW"); 555 putenv("LC_MESSAGES=zh_TW"); 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 } 566 567 /* 568 * cupsMarkerName localization... 569 */ 570 571 putenv("LANG=en"); 572 putenv("LC_ALL=en"); 573 putenv("LC_CTYPE=en"); 574 putenv("LC_MESSAGES=en"); 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"); 599 putenv("LC_ALL=fr"); 600 putenv("LC_CTYPE=fr"); 601 putenv("LC_MESSAGES=fr"); 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"); 615 putenv("LC_ALL=zh_TW"); 616 putenv("LC_CTYPE=zh_TW"); 617 putenv("LC_MESSAGES=zh_TW"); 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 } 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 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 680 fputs("ppdConflicts(): ", stdout); 681 ppdMarkOption(ppd, "PageSize", "Env10"); 682 ppdMarkOption(ppd, "InputSlot", "Envelope"); 683 ppdMarkOption(ppd, "Quality", "Photo"); 684 685 if ((conflicts = ppdConflicts(ppd)) == 1) 686 puts("PASS (1)"); 687 else 688 { 689 printf("FAIL (%d)\n", conflicts); 690 status ++; 691 } 692 693 fputs("cupsResolveConflicts(Quality=Photo): ", stdout); 694 num_options = 0; 695 options = NULL; 696 if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options, 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) && 713 num_options == 1 && !_cups_strcasecmp(options->name, "Quality") && 714 !_cups_strcasecmp(options->value, "Normal")) 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"); 733 ppdMarkOption(ppd, "InputSlot", "Tray"); 734 ppdMarkOption(ppd, "Quality", "Photo"); 735 num_options = 0; 736 options = NULL; 737 if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options)) 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!)"); 748 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 } 763 764 /* 765 * ppdPageSizeLimits 766 */ 767 768 ppdMarkDefaults(ppd); 769 770 fputs("ppdPageSizeLimits(default): ", stdout); 771 if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) 772 { 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) 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 { 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) 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 { 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) 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 { 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) 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 } 855 } 856 else 857 { 858 const char *filename; /* PPD filename */ 859 struct stat fileinfo; /* File information */ 860 861 862 if (!strncmp(argv[1], "-d", 2)) 863 { 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 878 if (!filename) 879 { 880 printf("%s: %s\n", printer, cupsLastErrorString()); 881 return (1); 882 } 883 } 884 else 885 filename = argv[1]; 886 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) 900 strlcpy(realfile, "Unknown", sizeof(realfile)); 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 914 if ((ppd = ppdOpenFile(filename)) == NULL) 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 { 927 int j, k; /* Looping vars */ 928 ppd_group_t *group; /* Option group */ 929 ppd_option_t *option; /* Option */ 930 ppd_coption_t *coption; /* Custom option */ 931 ppd_cparam_t *cparam; /* Custom parameter */ 932 ppd_const_t *c; /* UIConstraints */ 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 */ 937 938 939 if (argc > 2) 940 { 941 snprintf(lang, sizeof(lang), "LANG=%s", argv[2]); 942 putenv(lang); 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); 949 } 950 951 ppdLocalize(ppd); 952 ppdMarkDefaults(ppd); 953 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 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); 967 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 ++) 975 printf(" - %s%s (%s)\n", 976 option->choices[k].marked ? "*" : "", 977 option->choices[k].choice, option->choices[k].text); 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 } 1045 } 1046 } 1047 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 1053 puts("\nConstraints:"); 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); 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"); 1068 1069 puts("\nAttributes:"); 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 : ""); 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 } 1085 } 1086 1087 if (!strncmp(argv[1], "-d", 2)) 1088 unlink(filename); 1089 } 1090 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 1105 return (status); 1106} 1107 1108 1109/* 1110 * End of "$Id: testppd.c 11645 2014-02-27 16:35:53Z msweet $". 1111 */ 1112