X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=systemv%2Fcupstestppd.c;h=6faf67f179128752e670244be61dcaabbd883ec3;hb=61515785f7de12d8b2a29090020e684988f89977;hp=b8052b3b588ae4114d2d761819e40ea8b101c185;hpb=005dd1eb9e7844f4bf631111847c26c9a4b56df3;p=thirdparty%2Fcups.git diff --git a/systemv/cupstestppd.c b/systemv/cupstestppd.c index b8052b3b5..6faf67f17 100644 --- a/systemv/cupstestppd.c +++ b/systemv/cupstestppd.c @@ -1,9 +1,9 @@ /* - * "$Id: cupstestppd.c 7637 2008-06-11 17:25:36Z mike $" + * "$Id: cupstestppd.c 10996 2013-05-29 11:51:34Z msweet $" * - * PPD test program for the Common UNIX Printing System (CUPS). + * PPD test program for CUPS. * - * Copyright 2007-2008 by Apple Inc. + * Copyright 2007-2013 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -22,13 +22,18 @@ * check_basics() - Check for CR LF, mixed line endings, and blank * lines. * check_constraints() - Check UIConstraints in the PPD file. + * check_case() - Check that there are no duplicate groups, options, + * or choices that differ only by case. * check_defaults() - Check default option keywords in the PPD file. + * check_duplex() - Check duplex keywords in the PPD file. * check_filters() - Check filters in the PPD file. * check_profiles() - Check ICC color profiles in the PPD file. + * check_sizes() - Check media sizes in the PPD file. * check_translations() - Check translations in the PPD file. * show_conflicts() - Show option conflicts in a PPD file. * test_raster() - Test PostScript commands for raster printers. - * usage() - Show program usage... + * usage() - Show program usage. + * valid_path() - Check whether a path has the correct capitalization. * valid_utf8() - Check whether a string contains valid UTF-8 text. */ @@ -36,14 +41,14 @@ * Include necessary headers... */ -#include -#include +#include +#include #include -#include #include -#include -#include -#include +#include +#ifdef WIN32 +# define X_OK 0 +#endif /* WIN32 */ /* @@ -58,7 +63,10 @@ enum WARN_FILTERS = 4, WARN_PROFILES = 8, WARN_TRANSLATIONS = 16, - WARN_ALL = 31 + WARN_DUPLEX = 32, + WARN_SIZES = 64, + WARN_FILENAME = 128, + WARN_ALL = 255 }; @@ -89,6 +97,17 @@ enum }; +/* + * File permissions... + */ + +#define MODE_WRITE 0022 /* Group/other write */ +#define MODE_MASK 0555 /* Owner/group/other read+exec/search */ +#define MODE_DATAFILE 0444 /* Owner/group/other read */ +#define MODE_DIRECTORY 0555 /* Owner/group/other read+search */ +#define MODE_PROGRAM 0555 /* Owner/group/other read+exec */ + + /* * Local functions... */ @@ -96,17 +115,23 @@ enum static void check_basics(const char *filename); static int check_constraints(ppd_file_t *ppd, int errors, int verbose, int warn); +static int check_case(ppd_file_t *ppd, int errors, int verbose); static int check_defaults(ppd_file_t *ppd, int errors, int verbose, int warn); +static int check_duplex(ppd_file_t *ppd, int errors, int verbose, + int warn); static int check_filters(ppd_file_t *ppd, const char *root, int errors, int verbose, int warn); static int check_profiles(ppd_file_t *ppd, const char *root, int errors, int verbose, int warn); -static int check_translations(ppd_file_t *ppd, int errors, int verbose,\ +static int check_sizes(ppd_file_t *ppd, int errors, int verbose, int warn); +static int check_translations(ppd_file_t *ppd, int errors, int verbose, int warn); -static void show_conflicts(ppd_file_t *ppd); +static void show_conflicts(ppd_file_t *ppd, const char *prefix); static int test_raster(ppd_file_t *ppd, int verbose); -static void usage(void); +static void usage(void) __attribute__((noreturn)); +static int valid_path(const char *keyword, const char *path, int errors, + int verbose, int warn); static int valid_utf8(const char *s); @@ -122,9 +147,11 @@ main(int argc, /* I - Number of command-line args */ int len; /* Length of option name */ char *opt; /* Option character */ const char *ptr; /* Pointer into string */ + cups_file_t *fp; /* PPD file */ int files; /* Number of files */ int verbose; /* Want verbose output? */ int warn; /* Which errors to just warn about */ + int ignore; /* Which errors to ignore */ int status; /* Exit status */ int errors; /* Number of conformance errors */ int ppdversion; /* PPD spec version in PPD file */ @@ -162,6 +189,7 @@ main(int argc, /* I - Number of command-line args */ status = ERROR_NONE; root = ""; warn = WARN_NONE; + ignore = WARN_NONE; for (i = 1; i < argc; i ++) if (argv[i][0] == '-' && argv[i][1]) @@ -169,6 +197,26 @@ main(int argc, /* I - Number of command-line args */ for (opt = argv[i] + 1; *opt; opt ++) switch (*opt) { + case 'I' : /* Ignore errors */ + i ++; + + if (i >= argc) + usage(); + + if (!strcmp(argv[i], "none")) + ignore = WARN_NONE; + else if (!strcmp(argv[i], "filename")) + ignore |= WARN_FILENAME; + else if (!strcmp(argv[i], "filters")) + ignore |= WARN_FILTERS; + else if (!strcmp(argv[i], "profiles")) + ignore |= WARN_PROFILES; + else if (!strcmp(argv[i], "all")) + ignore = WARN_FILTERS | WARN_PROFILES; + else + usage(); + break; + case 'R' : /* Alternate root directory */ i ++; @@ -178,7 +226,7 @@ main(int argc, /* I - Number of command-line args */ root = argv[i]; break; - case 'W' : /* Turn errors into warnings */ + case 'W' : /* Turn errors into warnings */ i ++; if (i >= argc) @@ -190,10 +238,14 @@ main(int argc, /* I - Number of command-line args */ warn |= WARN_CONSTRAINTS; else if (!strcmp(argv[i], "defaults")) warn |= WARN_DEFAULTS; + else if (!strcmp(argv[i], "duplex")) + warn |= WARN_DUPLEX; else if (!strcmp(argv[i], "filters")) warn |= WARN_FILTERS; else if (!strcmp(argv[i], "profiles")) warn |= WARN_PROFILES; + else if (!strcmp(argv[i], "sizes")) + warn |= WARN_SIZES; else if (!strcmp(argv[i], "translations")) warn |= WARN_TRANSLATIONS; else if (!strcmp(argv[i], "all")) @@ -207,7 +259,7 @@ main(int argc, /* I - Number of command-line args */ { _cupsLangPuts(stderr, _("cupstestppd: The -q option is incompatible " - "with the -v option.\n")); + "with the -v option.")); return (1); } @@ -223,7 +275,7 @@ main(int argc, /* I - Number of command-line args */ { _cupsLangPuts(stderr, _("cupstestppd: The -v option is incompatible " - "with the -q option.\n")); + "with the -q option.")); return (1); } @@ -242,7 +294,7 @@ main(int argc, /* I - Number of command-line args */ */ if (files && verbose >= 0) - _cupsLangPuts(stdout, "\n"); + puts(""); files ++; @@ -252,7 +304,7 @@ main(int argc, /* I - Number of command-line args */ * Read from stdin... */ - ppd = ppdOpen(stdin); + ppd = _ppdOpen(cupsFileStdin(), _PPD_LOCALIZATION_ALL); if (verbose >= 0) printf("%s:", (ppd && ppd->pcfilename) ? ppd->pcfilename : "(stdin)"); @@ -266,7 +318,24 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) printf("%s:", argv[i]); - ppd = ppdOpenFile(argv[i]); + if ((fp = cupsFileOpen(argv[i], "r")) != NULL) + { + ppd = _ppdOpen(fp, _PPD_LOCALIZATION_ALL); + cupsFileClose(fp); + } + else + { + status = ERROR_FILE_OPEN; + + if (verbose >= 0) + { + _cupsLangPuts(stdout, _(" FAIL")); + _cupsLangPrintf(stdout, + _(" **FAIL** Unable to open PPD file - %s on " + "line %d."), strerror(errno), 0); + continue; + } + } } if (ppd == NULL) @@ -278,74 +347,88 @@ main(int argc, /* I - Number of command-line args */ status = ERROR_FILE_OPEN; if (verbose >= 0) + { + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" FAIL\n" - " **FAIL** Unable to open PPD file - %s\n"), - strerror(errno)); + _(" **FAIL** Unable to open PPD file - %s on " + "line %d."), strerror(errno), 0); + } } else { status = ERROR_PPD_FORMAT; if (verbose >= 0) - { + { + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" FAIL\n" - " **FAIL** Unable to open PPD file - " - "%s on line %d.\n"), + _(" **FAIL** Unable to open PPD file - " + "%s on line %d."), ppdErrorString(error), line); switch (error) { case PPD_MISSING_PPDADOBE4 : _cupsLangPuts(stdout, - _(" REF: Page 42, section 5.2.\n")); + _(" REF: Page 42, section " + "5.2.")); break; case PPD_MISSING_VALUE : _cupsLangPuts(stdout, - _(" REF: Page 20, section 3.4.\n")); + _(" REF: Page 20, section " + "3.4.")); break; case PPD_BAD_OPEN_GROUP : case PPD_NESTED_OPEN_GROUP : _cupsLangPuts(stdout, - _(" REF: Pages 45-46, section 5.2.\n")); + _(" REF: Pages 45-46, section " + "5.2.")); break; case PPD_BAD_OPEN_UI : case PPD_NESTED_OPEN_UI : _cupsLangPuts(stdout, - _(" REF: Pages 42-45, section 5.2.\n")); + _(" REF: Pages 42-45, section " + "5.2.")); break; case PPD_BAD_ORDER_DEPENDENCY : _cupsLangPuts(stdout, - _(" REF: Pages 48-49, section 5.2.\n")); + _(" REF: Pages 48-49, section " + "5.2.")); break; case PPD_BAD_UI_CONSTRAINTS : _cupsLangPuts(stdout, - _(" REF: Pages 52-54, section 5.2.\n")); + _(" REF: Pages 52-54, section " + "5.2.")); break; case PPD_MISSING_ASTERISK : _cupsLangPuts(stdout, - _(" REF: Page 15, section 3.2.\n")); + _(" REF: Page 15, section " + "3.2.")); break; case PPD_LINE_TOO_LONG : _cupsLangPuts(stdout, - _(" REF: Page 15, section 3.1.\n")); + _(" REF: Page 15, section " + "3.1.")); break; case PPD_ILLEGAL_CHARACTER : _cupsLangPuts(stdout, - _(" REF: Page 15, section 3.1.\n")); + _(" REF: Page 15, section " + "3.1.")); break; case PPD_ILLEGAL_MAIN_KEYWORD : _cupsLangPuts(stdout, - _(" REF: Pages 16-17, section 3.2.\n")); + _(" REF: Pages 16-17, section " + "3.2.")); break; case PPD_ILLEGAL_OPTION_KEYWORD : _cupsLangPuts(stdout, - _(" REF: Page 19, section 3.3.\n")); + _(" REF: Page 19, section " + "3.3.")); break; case PPD_ILLEGAL_TRANSLATION : _cupsLangPuts(stdout, - _(" REF: Page 27, section 3.5.\n")); + _(" REF: Page 27, section " + "3.5.")); break; default : break; @@ -368,19 +451,35 @@ main(int argc, /* I - Number of command-line args */ if (verbose > 0) _cupsLangPuts(stdout, - _("\n DETAILED CONFORMANCE TEST RESULTS\n")); + _("\n DETAILED CONFORMANCE TEST RESULTS")); if ((attr = ppdFindAttr(ppd, "FormatVersion", NULL)) != NULL && attr->value) ppdversion = (int)(10 * _cupsStrScand(attr->value, NULL, loc) + 0.5); - for (j = 0; j < ppd->num_filters; j ++) - if (strstr(ppd->filters[j], "application/vnd.cups-raster")) - { - if (!test_raster(ppd, verbose)) - errors ++; - break; + if ((attr = ppdFindAttr(ppd, "cupsFilter2", NULL)) != NULL) + { + do + { + if (strstr(attr->value, "application/vnd.cups-raster")) + { + if (!test_raster(ppd, verbose)) + errors ++; + break; + } } + while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL); + } + else + { + for (j = 0; j < ppd->num_filters; j ++) + if (strstr(ppd->filters[j], "application/vnd.cups-raster")) + { + if (!test_raster(ppd, verbose)) + errors ++; + break; + } + } /* * Look for default keywords with no matching option... @@ -394,11 +493,11 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED DefaultImageableArea\n" - " REF: Page 102, section 5.15.\n")); + " REF: Page 102, section 5.15.")); } errors ++; @@ -409,11 +508,11 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" **FAIL** BAD DefaultImageableArea %s!\n" - " REF: Page 102, section 5.15.\n"), + _(" **FAIL** Bad DefaultImageableArea %s\n" + " REF: Page 102, section 5.15."), attr->value); } @@ -422,7 +521,7 @@ main(int argc, /* I - Number of command-line args */ else { if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS DefaultImageableArea\n")); + _cupsLangPuts(stdout, _(" PASS DefaultImageableArea")); } if ((attr = ppdFindAttr(ppd, "DefaultPaperDimension", NULL)) == NULL) @@ -430,11 +529,11 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED DefaultPaperDimension\n" - " REF: Page 103, section 5.15.\n")); + " REF: Page 103, section 5.15.")); } errors ++; @@ -445,21 +544,23 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" **FAIL** BAD DefaultPaperDimension %s!\n" - " REF: Page 103, section 5.15.\n"), + _(" **FAIL** Bad DefaultPaperDimension %s\n" + " REF: Page 103, section 5.15."), attr->value); } errors ++; } else if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS DefaultPaperDimension\n")); + _cupsLangPuts(stdout, _(" PASS DefaultPaperDimension")); for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) - for (k = 0, option = group->options; k < group->num_options; k ++, option ++) + for (k = 0, option = group->options; + k < group->num_options; + k ++, option ++) { /* * Verify that we have a default choice... @@ -473,11 +574,11 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" **FAIL** BAD Default%s %s\n" - " REF: Page 40, section 4.5.\n"), + _(" **FAIL** Bad Default%s %s\n" + " REF: Page 40, section 4.5."), option->keyword, option->defchoice); } @@ -485,7 +586,7 @@ main(int argc, /* I - Number of command-line args */ } else if (verbose > 0) _cupsLangPrintf(stdout, - _(" PASS Default%s\n"), + _(" PASS Default%s"), option->keyword); } else @@ -493,11 +594,11 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" **FAIL** REQUIRED Default%s\n" - " REF: Page 40, section 4.5.\n"), + " REF: Page 40, section 4.5."), option->keyword); } @@ -505,41 +606,84 @@ main(int argc, /* I - Number of command-line args */ } } - if (ppdFindAttr(ppd, "FileVersion", NULL) != NULL) + if ((attr = ppdFindAttr(ppd, "FileVersion", NULL)) != NULL) { - if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS FileVersion\n")); + for (ptr = attr->value; *ptr; ptr ++) + if (!isdigit(*ptr & 255) && *ptr != '.') + break; + + if (*ptr) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad FileVersion \"%s\"\n" + " REF: Page 56, section 5.3."), + attr->value); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS FileVersion")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED FileVersion\n" - " REF: Page 56, section 5.3.\n")); + " REF: Page 56, section 5.3.")); } errors ++; } - if (ppdFindAttr(ppd, "FormatVersion", NULL) != NULL) + if ((attr = ppdFindAttr(ppd, "FormatVersion", NULL)) != NULL) { - if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS FormatVersion\n")); + ptr = attr->value; + if (*ptr == '4' && ptr[1] == '.') + { + + for (ptr += 2; *ptr; ptr ++) + if (!isdigit(*ptr & 255)) + break; + } + + if (*ptr) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad FormatVersion \"%s\"\n" + " REF: Page 56, section 5.3."), + attr->value); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS FormatVersion")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED FormatVersion\n" - " REF: Page 56, section 5.3.\n")); + " REF: Page 56, section 5.3.")); } errors ++; @@ -548,18 +692,18 @@ main(int argc, /* I - Number of command-line args */ if (ppd->lang_encoding != NULL) { if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS LanguageEncoding\n")); + _cupsLangPuts(stdout, _(" PASS LanguageEncoding")); } else if (ppdversion > 40) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED LanguageEncoding\n" - " REF: Pages 56-57, section 5.3.\n")); + " REF: Pages 56-57, section 5.3.")); } errors ++; @@ -568,18 +712,18 @@ main(int argc, /* I - Number of command-line args */ if (ppd->lang_version != NULL) { if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS LanguageVersion\n")); + _cupsLangPuts(stdout, _(" PASS LanguageVersion")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED LanguageVersion\n" - " REF: Pages 57-58, section 5.3.\n")); + " REF: Pages 57-58, section 5.3.")); } errors ++; @@ -587,51 +731,53 @@ main(int argc, /* I - Number of command-line args */ if (ppd->manufacturer != NULL) { - if (!strncasecmp(ppd->manufacturer, "Hewlett-Packard", 15) || - !strncasecmp(ppd->manufacturer, "Hewlett Packard", 15)) + if (!_cups_strncasecmp(ppd->manufacturer, "Hewlett-Packard", 15) || + !_cups_strncasecmp(ppd->manufacturer, "Hewlett Packard", 15)) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); - _cupsLangPuts(stdout, - _(" **FAIL** BAD Manufacturer (should be " - "\"HP\")\n" - " REF: Page 211, table D.1.\n")); + _cupsLangPrintf(stdout, + _(" **FAIL** Bad Manufacturer (should be " + "\"%s\")\n" + " REF: Page 211, table D.1."), + "HP"); } errors ++; } - else if (!strncasecmp(ppd->manufacturer, "OkiData", 7) || - !strncasecmp(ppd->manufacturer, "Oki Data", 8)) + else if (!_cups_strncasecmp(ppd->manufacturer, "OkiData", 7) || + !_cups_strncasecmp(ppd->manufacturer, "Oki Data", 8)) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); - _cupsLangPuts(stdout, - _(" **FAIL** BAD Manufacturer (should be " - "\"Oki\")\n" - " REF: Page 211, table D.1.\n")); + _cupsLangPrintf(stdout, + _(" **FAIL** Bad Manufacturer (should be " + "\"%s\")\n" + " REF: Page 211, table D.1."), + "Oki"); } errors ++; } else if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS Manufacturer\n")); + _cupsLangPuts(stdout, _(" PASS Manufacturer")); } else if (ppdversion >= 43) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED Manufacturer\n" - " REF: Pages 58-59, section 5.3.\n")); + " REF: Pages 58-59, section 5.3.")); } errors ++; @@ -648,30 +794,30 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" **FAIL** BAD ModelName - \"%c\" not " + _(" **FAIL** Bad ModelName - \"%c\" not " "allowed in string.\n" - " REF: Pages 59-60, section 5.3.\n"), + " REF: Pages 59-60, section 5.3."), *ptr); } errors ++; } else if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS ModelName\n")); + _cupsLangPuts(stdout, _(" PASS ModelName")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED ModelName\n" - " REF: Pages 59-60, section 5.3.\n")); + " REF: Pages 59-60, section 5.3.")); } errors ++; @@ -680,18 +826,18 @@ main(int argc, /* I - Number of command-line args */ if (ppd->nickname != NULL) { if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS NickName\n")); + _cupsLangPuts(stdout, _(" PASS NickName")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED NickName\n" - " REF: Page 60, section 5.3.\n")); + " REF: Page 60, section 5.3.")); } errors ++; @@ -700,18 +846,18 @@ main(int argc, /* I - Number of command-line args */ if (ppdFindOption(ppd, "PageSize") != NULL) { if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS PageSize\n")); + _cupsLangPuts(stdout, _(" PASS PageSize")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED PageSize\n" - " REF: Pages 99-100, section 5.14.\n")); + " REF: Pages 99-100, section 5.14.")); } errors ++; @@ -720,18 +866,18 @@ main(int argc, /* I - Number of command-line args */ if (ppdFindOption(ppd, "PageRegion") != NULL) { if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS PageRegion\n")); + _cupsLangPuts(stdout, _(" PASS PageRegion")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED PageRegion\n" - " REF: Page 100, section 5.14.\n")); + " REF: Page 100, section 5.14.")); } errors ++; @@ -740,18 +886,18 @@ main(int argc, /* I - Number of command-line args */ if (ppd->pcfilename != NULL) { if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS PCFileName\n")); + _cupsLangPuts(stdout, _(" PASS PCFileName")); } - else + else if (!(ignore & WARN_FILENAME)) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED PCFileName\n" - " REF: Pages 61-62, section 5.3.\n")); + " REF: Pages 61-62, section 5.3.")); } errors ++; @@ -765,28 +911,28 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, - _(" **FAIL** BAD Product - not \"(string)\".\n" - " REF: Page 62, section 5.3.\n")); + _(" **FAIL** Bad Product - not \"(string)\".\n" + " REF: Page 62, section 5.3.")); } errors ++; } else if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS Product\n")); + _cupsLangPuts(stdout, _(" PASS Product")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED Product\n" - " REF: Page 62, section 5.3.\n")); + " REF: Page 62, section 5.3.")); } errors ++; @@ -804,29 +950,29 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, - _(" **FAIL** BAD PSVersion - not \"(string) " + _(" **FAIL** Bad PSVersion - not \"(string) " "int\".\n" - " REF: Pages 62-64, section 5.3.\n")); + " REF: Pages 62-64, section 5.3.")); } errors ++; } else if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS PSVersion\n")); + _cupsLangPuts(stdout, _(" PASS PSVersion")); } else { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED PSVersion\n" - " REF: Pages 62-64, section 5.3.\n")); + " REF: Pages 62-64, section 5.3.")); } errors ++; @@ -839,29 +985,29 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, - _(" **FAIL** BAD ShortNickName - longer " + _(" **FAIL** Bad ShortNickName - longer " "than 31 chars.\n" - " REF: Pages 64-65, section 5.3.\n")); + " REF: Pages 64-65, section 5.3.")); } errors ++; } else if (verbose > 0) - _cupsLangPuts(stdout, _(" PASS ShortNickName\n")); + _cupsLangPuts(stdout, _(" PASS ShortNickName")); } else if (ppdversion >= 43) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED ShortNickName\n" - " REF: Page 64-65, section 5.3.\n")); + " REF: Page 64-65, section 5.3.")); } errors ++; @@ -873,11 +1019,11 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, - _(" **FAIL** BAD JobPatchFile attribute in file\n" - " REF: Page 24, section 3.4.\n")); + _(" **FAIL** Bad JobPatchFile attribute in file\n" + " REF: Page 24, section 3.4.")); } errors ++; @@ -893,12 +1039,12 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPuts(stdout, _(" **FAIL** REQUIRED PageSize\n" " REF: Page 41, section 5.\n" - " REF: Page 99, section 5.14.\n")); + " REF: Page 99, section 5.14.")); } errors ++; @@ -924,13 +1070,13 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" **FAIL** REQUIRED ImageableArea for " "PageSize %s\n" " REF: Page 41, section 5.\n" - " REF: Page 102, section 5.15.\n"), + " REF: Page 102, section 5.15."), size->name); } @@ -941,18 +1087,18 @@ main(int argc, /* I - Number of command-line args */ * Check for PaperDimension... */ - if (size->width == 0.0 && size->length == 0.0) + if (size->width <= 0.0 && size->length <= 0.0) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" **FAIL** REQUIRED PaperDimension " "for PageSize %s\n" " REF: Page 41, section 5.\n" - " REF: Page 103, section 5.15.\n"), + " REF: Page 103, section 5.15."), size->name); } @@ -971,7 +1117,9 @@ main(int argc, /* I - Number of command-line args */ if (option != NULL) { - for (j = option->num_choices, choice = option->choices; j > 0; j --, choice ++) + for (j = option->num_choices, choice = option->choices; + j > 0; + j --, choice ++) { /* * Verify that all resolution options are of the form NNNdpi @@ -995,11 +1143,11 @@ main(int argc, /* I - Number of command-line args */ if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" **FAIL** Bad %s choice %s!\n" - " REF: Page 84, section 5.9\n"), + _(" **FAIL** Bad option %s choice %s\n" + " REF: Page 84, section 5.9"), option->keyword, choice->choice); } @@ -1008,84 +1156,43 @@ main(int argc, /* I - Number of command-line args */ } } - /* - * Check for a duplex option, and for standard values... - */ - - if ((option = ppdFindOption(ppd, "Duplex")) == NULL) - if ((option = ppdFindOption(ppd, "JCLDuplex")) == NULL) - if ((option = ppdFindOption(ppd, "EFDuplex")) == NULL) - option = ppdFindOption(ppd, "KD03Duplex"); - - if (option != NULL) - { - if (ppdFindChoice(option, "None") == NULL) - { - if (verbose >= 0) - { - if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); - - _cupsLangPrintf(stdout, - _(" **FAIL** REQUIRED %s does not define " - "choice None!\n" - " REF: Page 122, section 5.17\n"), - option->keyword); - } - - errors ++; - } - - for (j = option->num_choices, choice = option->choices; j > 0; j --, choice ++) - if (strcmp(choice->choice, "None") && - strcmp(choice->choice, "DuplexNoTumble") && - strcmp(choice->choice, "DuplexTumble") && - strcmp(choice->choice, "SimplexTumble")) - { - if (verbose >= 0) - { - if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); - - _cupsLangPrintf(stdout, - _(" **FAIL** Bad %s choice %s!\n" - " REF: Page 122, section 5.17\n"), - option->keyword, choice->choice); - } - - errors ++; - } - } - if ((attr = ppdFindAttr(ppd, "1284DeviceID", NULL)) && strcmp(attr->name, "1284DeviceID")) { if (verbose >= 0) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" **FAIL** %s must be 1284DeviceID!\n" - " REF: Page 72, section 5.5\n"), + _(" **FAIL** %s must be 1284DeviceID\n" + " REF: Page 72, section 5.5"), attr->name); } errors ++; } + errors = check_case(ppd, errors, verbose); + if (!(warn & WARN_CONSTRAINTS)) errors = check_constraints(ppd, errors, verbose, 0); - if (!(warn & WARN_FILTERS)) + if (!(warn & WARN_FILTERS) && !(ignore & WARN_FILTERS)) errors = check_filters(ppd, root, errors, verbose, 0); - if (!(warn & WARN_PROFILES)) + if (!(warn & WARN_PROFILES) && !(ignore & WARN_PROFILES)) errors = check_profiles(ppd, root, errors, verbose, 0); + if (!(warn & WARN_SIZES)) + errors = check_sizes(ppd, errors, verbose, 0); + if (!(warn & WARN_TRANSLATIONS)) errors = check_translations(ppd, errors, verbose, 0); + if (!(warn & WARN_DUPLEX)) + errors = check_duplex(ppd, errors, verbose, 0); + if ((attr = ppdFindAttr(ppd, "cupsLanguages", NULL)) != NULL && attr->value) { @@ -1099,12 +1206,12 @@ main(int argc, /* I - Number of command-line args */ if (!attr->value || strcmp(attr->value, "ISOLatin1")) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" **FAIL** Bad LanguageEncoding %s - " - "must be ISOLatin1!\n"), + "must be ISOLatin1."), attr->value ? attr->value : "(null)"); errors ++; @@ -1113,17 +1220,17 @@ main(int argc, /* I - Number of command-line args */ if (!ppd->lang_version || strcmp(ppd->lang_version, "English")) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" **FAIL** Bad LanguageVersion %s - " - "must be English!\n"), + "must be English."), ppd->lang_version ? ppd->lang_version : "(null)"); errors ++; } - + /* * Loop through all options and choices... */ @@ -1145,13 +1252,13 @@ main(int argc, /* I - Number of command-line args */ if (*ptr) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" **FAIL** Default translation " "string for option %s contains 8-bit " - "characters!\n"), + "characters."), option->keyword); errors ++; @@ -1172,13 +1279,13 @@ main(int argc, /* I - Number of command-line args */ if (*ptr) { if (!errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" **FAIL** Default translation " "string for option %s choice %s contains " - "8-bit characters!\n"), + "8-bit characters."), option->keyword, option->choices[j].choice); @@ -1196,27 +1303,50 @@ main(int argc, /* I - Number of command-line args */ if (errors) status = ERROR_CONFORMANCE; else if (!verbose) - _cupsLangPuts(stdout, _(" PASS\n")); + _cupsLangPuts(stdout, _(" PASS")); if (verbose >= 0) { check_basics(argv[i]); + if (warn & WARN_DEFAULTS) + errors = check_defaults(ppd, errors, verbose, 1); + if (warn & WARN_CONSTRAINTS) errors = check_constraints(ppd, errors, verbose, 1); - if (warn & WARN_DEFAULTS) - errors = check_defaults(ppd, errors, verbose, 1); + if ((warn & WARN_FILTERS) && !(ignore & WARN_FILTERS)) + errors = check_filters(ppd, root, errors, verbose, 1); - if (warn & WARN_PROFILES) + if ((warn & WARN_PROFILES) && !(ignore & WARN_PROFILES)) errors = check_profiles(ppd, root, errors, verbose, 1); - if (warn & WARN_FILTERS) - errors = check_filters(ppd, root, errors, verbose, 1); + if (warn & WARN_SIZES) + errors = check_sizes(ppd, errors, verbose, 1); + else + errors = check_sizes(ppd, errors, verbose, 2); if (warn & WARN_TRANSLATIONS) errors = check_translations(ppd, errors, verbose, 1); + if (warn & WARN_DUPLEX) + errors = check_duplex(ppd, errors, verbose, 1); + + /* + * Look for legacy duplex keywords... + */ + + if ((option = ppdFindOption(ppd, "JCLDuplex")) == NULL) + if ((option = ppdFindOption(ppd, "EFDuplex")) == NULL) + option = ppdFindOption(ppd, "KD03Duplex"); + + if (option) + _cupsLangPrintf(stdout, + _(" WARN Duplex option keyword %s may not " + "work as expected and should be named Duplex.\n" + " REF: Page 122, section 5.17"), + option->keyword); + /* * Look for default keywords with no corresponding option... */ @@ -1238,44 +1368,19 @@ main(int argc, /* I - Number of command-line args */ !strcmp(attr->name, "DefaultTransfer")) continue; - if (!strncmp(attr->name, "Default", 7) && + if (!strncmp(attr->name, "Default", 7) && !ppdFindOption(ppd, attr->name + 7)) _cupsLangPrintf(stdout, _(" WARN %s has no corresponding " - "options!\n"), + "options."), attr->name); } - /* - * Check for old Duplex option names... - */ - - if ((option = ppdFindOption(ppd, "EFDuplex")) == NULL) - option = ppdFindOption(ppd, "KD03Duplex"); - - if (option) - { - _cupsLangPrintf(stdout, - _(" WARN Duplex option keyword %s " - "should be named Duplex or JCLDuplex!\n" - " REF: Page 122, section 5.17\n"), - option->keyword); - } - - ppdMarkDefaults(ppd); - if (ppdConflicts(ppd)) - { - _cupsLangPuts(stdout, - _(" WARN Default choices conflicting!\n")); - - show_conflicts(ppd); - } - if (ppdversion < 43) { _cupsLangPrintf(stdout, - _(" WARN Obsolete PPD version %.1f!\n" - " REF: Page 42, section 5.2.\n"), + _(" WARN Obsolete PPD version %.1f.\n" + " REF: Page 42, section 5.2."), 0.1f * ppdversion); } @@ -1284,7 +1389,7 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPuts(stdout, _(" WARN LanguageEncoding required by PPD " "4.3 spec.\n" - " REF: Pages 56-57, section 5.3.\n")); + " REF: Pages 56-57, section 5.3.")); } if (!ppd->manufacturer && ppdversion < 43) @@ -1292,7 +1397,7 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPuts(stdout, _(" WARN Manufacturer required by PPD " "4.3 spec.\n" - " REF: Pages 58-59, section 5.3.\n")); + " REF: Pages 58-59, section 5.3.")); } /* @@ -1300,12 +1405,23 @@ main(int argc, /* I - Number of command-line args */ * a warning and not a hard error... */ - if (ppd->pcfilename && strlen(ppd->pcfilename) > 12) - { - _cupsLangPuts(stdout, - _(" WARN PCFileName longer than 8.3 in " - "violation of PPD spec.\n" - " REF: Pages 61-62, section 5.3.\n")); + if (!(ignore & WARN_FILENAME) && ppd->pcfilename) + { + if (strlen(ppd->pcfilename) > 12) + { + _cupsLangPuts(stdout, + _(" WARN PCFileName longer than 8.3 in " + "violation of PPD spec.\n" + " REF: Pages 61-62, section " + "5.3.")); + } + + if (!_cups_strcasecmp(ppd->pcfilename, "unused.ppd")) + _cupsLangPuts(stdout, + _(" WARN PCFileName should contain a " + "unique filename.\n" + " REF: Pages 61-62, section " + "5.3.")); } if (!ppd->shortnickname && ppdversion < 43) @@ -1313,7 +1429,7 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPuts(stdout, _(" WARN ShortNickName required by PPD " "4.3 spec.\n" - " REF: Pages 64-65, section 5.3.\n")); + " REF: Pages 64-65, section 5.3.")); } /* @@ -1330,7 +1446,7 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPuts(stdout, _(" WARN Protocols contains both PJL " "and BCP; expected TBCP.\n" - " REF: Pages 78-79, section 5.7.\n")); + " REF: Pages 78-79, section 5.7.")); } if (strstr(ppd->protocols, "PJL") && @@ -1339,7 +1455,7 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPuts(stdout, _(" WARN Protocols contains PJL but JCL " "attributes are not set.\n" - " REF: Pages 78-79, section 5.7.\n")); + " REF: Pages 78-79, section 5.7.")); } } @@ -1350,9 +1466,11 @@ main(int argc, /* I - Number of command-line args */ */ for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) - for (k = 0, option = group->options; k < group->num_options; k ++, option ++) + for (k = 0, option = group->options; + k < group->num_options; + k ++, option ++) { - len = strlen(option->keyword); + len = (int)strlen(option->keyword); for (m = 0, group2 = ppd->groups; m < ppd->num_groups; @@ -1361,60 +1479,30 @@ main(int argc, /* I - Number of command-line args */ n < group2->num_options; n ++, option2 ++) if (option != option2 && - len < strlen(option2->keyword) && + len < (int)strlen(option2->keyword) && !strncmp(option->keyword, option2->keyword, len)) { _cupsLangPrintf(stdout, _(" WARN %s shares a common " "prefix with %s\n" " REF: Page 15, section " - "3.2.\n"), + "3.2."), option->keyword, option2->keyword); } } } -#ifdef __APPLE__ - /* - * APDialogExtension - */ - - for (attr = ppdFindAttr(ppd, "APDialogExtension", NULL); - attr != NULL; - attr = ppdFindNextAttr(ppd, "APDialogExtension", NULL)) - { - if ((!attr->value || access(attr->value, 0)) && verbose >= 0) - _cupsLangPrintf(stdout, _(" WARN Missing " - "APDialogExtension file \"%s\"\n"), - attr->value ? attr->value : ""); - } - - /* - * APPrinterIconPath - */ - - for (attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL); - attr != NULL; - attr = ppdFindNextAttr(ppd, "APPrinterIconPath", NULL)) - { - if ((!attr->value || access(attr->value, 0)) && verbose >= 0) - _cupsLangPrintf(stdout, _(" WARN Missing " - "APPrinterIconPath file \"%s\"\n"), - attr->value ? attr->value : ""); - } -#endif /* __APPLE__ */ - if (verbose > 0) { if (errors) - _cupsLangPrintf(stdout, _(" %d ERRORS FOUND\n"), errors); + _cupsLangPrintf(stdout, _(" %d ERRORS FOUND"), errors); else - _cupsLangPuts(stdout, _(" NO ERRORS FOUND\n")); + _cupsLangPuts(stdout, _(" NO ERRORS FOUND")); } /* * Then list the options, if "-v" was provided... - */ + */ if (verbose > 1) { @@ -1423,7 +1511,7 @@ main(int argc, /* I - Number of command-line args */ " language_level = %d\n" " color_device = %s\n" " variable_sizes = %s\n" - " landscape = %d\n", + " landscape = %d", ppd->language_level, ppd->color_device ? "TRUE" : "FALSE", ppd->variable_sizes ? "TRUE" : "FALSE", @@ -1432,55 +1520,55 @@ main(int argc, /* I - Number of command-line args */ switch (ppd->colorspace) { case PPD_CS_CMYK : - _cupsLangPuts(stdout, " colorspace = PPD_CS_CMYK\n"); + _cupsLangPuts(stdout, " colorspace = PPD_CS_CMYK"); break; case PPD_CS_CMY : - _cupsLangPuts(stdout, " colorspace = PPD_CS_CMY\n"); + _cupsLangPuts(stdout, " colorspace = PPD_CS_CMY"); break; case PPD_CS_GRAY : - _cupsLangPuts(stdout, " colorspace = PPD_CS_GRAY\n"); + _cupsLangPuts(stdout, " colorspace = PPD_CS_GRAY"); break; case PPD_CS_RGB : - _cupsLangPuts(stdout, " colorspace = PPD_CS_RGB\n"); + _cupsLangPuts(stdout, " colorspace = PPD_CS_RGB"); break; default : - _cupsLangPuts(stdout, " colorspace = \n"); + _cupsLangPuts(stdout, " colorspace = "); break; } - _cupsLangPrintf(stdout, " num_emulations = %d\n", + _cupsLangPrintf(stdout, " num_emulations = %d", ppd->num_emulations); for (j = 0; j < ppd->num_emulations; j ++) - _cupsLangPrintf(stdout, " emulations[%d] = %s\n", + _cupsLangPrintf(stdout, " emulations[%d] = %s", j, ppd->emulations[j].name); - _cupsLangPrintf(stdout, " lang_encoding = %s\n", + _cupsLangPrintf(stdout, " lang_encoding = %s", ppd->lang_encoding); - _cupsLangPrintf(stdout, " lang_version = %s\n", + _cupsLangPrintf(stdout, " lang_version = %s", ppd->lang_version); - _cupsLangPrintf(stdout, " modelname = %s\n", ppd->modelname); - _cupsLangPrintf(stdout, " ttrasterizer = %s\n", + _cupsLangPrintf(stdout, " modelname = %s", ppd->modelname); + _cupsLangPrintf(stdout, " ttrasterizer = %s", ppd->ttrasterizer == NULL ? "None" : ppd->ttrasterizer); - _cupsLangPrintf(stdout, " manufacturer = %s\n", + _cupsLangPrintf(stdout, " manufacturer = %s", ppd->manufacturer); - _cupsLangPrintf(stdout, " product = %s\n", ppd->product); - _cupsLangPrintf(stdout, " nickname = %s\n", ppd->nickname); - _cupsLangPrintf(stdout, " shortnickname = %s\n", + _cupsLangPrintf(stdout, " product = %s", ppd->product); + _cupsLangPrintf(stdout, " nickname = %s", ppd->nickname); + _cupsLangPrintf(stdout, " shortnickname = %s", ppd->shortnickname); - _cupsLangPrintf(stdout, " patches = %d bytes\n", + _cupsLangPrintf(stdout, " patches = %d bytes", ppd->patches == NULL ? 0 : (int)strlen(ppd->patches)); - _cupsLangPrintf(stdout, " num_groups = %d\n", ppd->num_groups); + _cupsLangPrintf(stdout, " num_groups = %d", ppd->num_groups); for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) { - _cupsLangPrintf(stdout, " group[%d] = %s\n", + _cupsLangPrintf(stdout, " group[%d] = %s", j, group->text); for (k = 0, option = group->options; k < group->num_options; k ++, option ++) { _cupsLangPrintf(stdout, " options[%d] = %s (%s) %s %s %.0f " - "(%d choices)\n", + "(%d choices)", k, option->keyword, option->text, uis[option->ui], sections[option->section], option->order, option->num_choices); @@ -1496,21 +1584,20 @@ main(int argc, /* I - Number of command-line args */ if (size == NULL) _cupsLangPrintf(stdout, - " %s (%s) = ERROR", - choice->choice, choice->text); + " %s (%s) = ERROR%s", + choice->choice, choice->text, + !strcmp(option->defchoice, choice->choice) + ? " *" : ""); else _cupsLangPrintf(stdout, " %s (%s) = %.2fx%.2fin " - "(%.1f,%.1f,%.1f,%.1f)", + "(%.1f,%.1f,%.1f,%.1f)%s", choice->choice, choice->text, size->width / 72.0, size->length / 72.0, size->left / 72.0, size->bottom / 72.0, - size->right / 72.0, size->top / 72.0); - - if (!strcmp(option->defchoice, choice->choice)) - _cupsLangPuts(stdout, " *\n"); - else - _cupsLangPuts(stdout, "\n"); + size->right / 72.0, size->top / 72.0, + !strcmp(option->defchoice, choice->choice) + ? " *" : ""); } } else @@ -1519,32 +1606,29 @@ main(int argc, /* I - Number of command-line args */ m > 0; m --, choice ++) { - _cupsLangPrintf(stdout, " %s (%s)", - choice->choice, choice->text); - - if (!strcmp(option->defchoice, choice->choice)) - _cupsLangPuts(stdout, " *\n"); - else - _cupsLangPuts(stdout, "\n"); + _cupsLangPrintf(stdout, " %s (%s)%s", + choice->choice, choice->text, + !strcmp(option->defchoice, choice->choice) + ? " *" : ""); } } } } - _cupsLangPrintf(stdout, " num_consts = %d\n", + _cupsLangPrintf(stdout, " num_consts = %d", ppd->num_consts); for (j = 0; j < ppd->num_consts; j ++) _cupsLangPrintf(stdout, - " consts[%d] = *%s %s *%s %s\n", + " consts[%d] = *%s %s *%s %s", j, ppd->consts[j].option1, ppd->consts[j].choice1, ppd->consts[j].option2, ppd->consts[j].choice2); - _cupsLangPrintf(stdout, " num_profiles = %d\n", + _cupsLangPrintf(stdout, " num_profiles = %d", ppd->num_profiles); for (j = 0; j < ppd->num_profiles; j ++) _cupsLangPrintf(stdout, " profiles[%d] = %s/%s %.3f %.3f " - "[ %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f ]\n", + "[ %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f ]", j, ppd->profiles[j].resolution, ppd->profiles[j].media_type, ppd->profiles[j].gamma, ppd->profiles[j].density, @@ -1558,15 +1642,15 @@ main(int argc, /* I - Number of command-line args */ ppd->profiles[j].matrix[2][1], ppd->profiles[j].matrix[2][2]); - _cupsLangPrintf(stdout, " num_fonts = %d\n", ppd->num_fonts); + _cupsLangPrintf(stdout, " num_fonts = %d", ppd->num_fonts); for (j = 0; j < ppd->num_fonts; j ++) - _cupsLangPrintf(stdout, " fonts[%d] = %s\n", + _cupsLangPrintf(stdout, " fonts[%d] = %s", j, ppd->fonts[j]); - _cupsLangPrintf(stdout, " num_attrs = %d\n", ppd->num_attrs); + _cupsLangPrintf(stdout, " num_attrs = %d", ppd->num_attrs); for (j = 0; j < ppd->num_attrs; j ++) _cupsLangPrintf(stdout, - " attrs[%d] = %s %s%s%s: \"%s\"\n", j, + " attrs[%d] = %s %s%s%s: \"%s\"", j, ppd->attrs[j]->name, ppd->attrs[j]->spec, ppd->attrs[j]->text[0] ? "/" : "", ppd->attrs[j]->text, @@ -1636,10 +1720,10 @@ check_basics(const char *filename) /* I - PPD file to check */ else if (eol != EOL_CR) mixed = 1; } - + if (col > 0 && whitespace) _cupsLangPrintf(stdout, - _(" WARN Line %d only contains whitespace!\n"), + _(" WARN Line %d only contains whitespace."), linenum); linenum ++; @@ -1658,12 +1742,12 @@ check_basics(const char *filename) /* I - PPD file to check */ if (mixed) _cupsLangPuts(stdout, _(" WARN File contains a mix of CR, LF, and " - "CR LF line endings!\n")); + "CR LF line endings.")); if (eol == EOL_CRLF) _cupsLangPuts(stdout, _(" WARN Non-Windows PPD files should use lines " - "ending with only LF, not CR LF!\n")); + "ending with only LF, not CR LF.")); cupsFileClose(fp); } @@ -1713,10 +1797,10 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ if (!constattr->value) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" %s Empty cupsUIConstraints %s!\n"), + _(" %s Empty cupsUIConstraints %s"), prefix, constattr->spec); if (!warn) @@ -1732,10 +1816,10 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ if (i == 0) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" %s Bad cupsUIConstraints %s: \"%s\"!\n"), + _(" %s Bad cupsUIConstraints %s: \"%s\""), prefix, constattr->spec, constattr->value); if (!warn) @@ -1750,10 +1834,10 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ !ppdFindAttr(ppd, "cupsUIResolver", constattr->spec)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" %s Missing cupsUIResolver %s!\n"), + _(" %s Missing cupsUIResolver %s"), prefix, constattr->spec); if (!warn) @@ -1793,22 +1877,22 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ *ptr = '\0'; } - if (!strncasecmp(option, "Custom", 6) && !strcasecmp(choice, "True")) + if (!_cups_strncasecmp(option, "Custom", 6) && !_cups_strcasecmp(choice, "True")) { _cups_strcpy(option, option + 6); - strcpy(choice, "Custom"); + strlcpy(choice, "Custom", sizeof(choice)); } if ((o = ppdFindOption(ppd, option)) == NULL) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" %s Missing option %s in " - "cupsUIConstraints %s: \"%s\"!\n"), + "cupsUIConstraints %s: \"%s\""), prefix, option, constattr->spec, constattr->value); - + if (!warn) errors ++; @@ -1818,11 +1902,11 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ if (choice[0] && !ppdFindChoice(o, choice)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" %s Missing choice *%s %s in " - "cupsUIConstraints %s: \"%s\"!\n"), + "cupsUIConstraints %s: \"%s\""), prefix, option, choice, constattr->spec, constattr->value); @@ -1837,9 +1921,9 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ else { for (i = 0; i < o->num_choices; i ++) - if (strcasecmp(o->choices[i].choice, "None") && - strcasecmp(o->choices[i].choice, "Off") && - strcasecmp(o->choices[i].choice, "False")) + if (_cups_strcasecmp(o->choices[i].choice, "None") && + _cups_strcasecmp(o->choices[i].choice, "Off") && + _cups_strcasecmp(o->choices[i].choice, "False")) { num_options = cupsAddOption(option, o->choices[i].choice, num_options, &options); @@ -1848,6 +1932,24 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ } } + /* + * Resolvers must list at least two options... + */ + + if (num_options < 2) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + _cupsLangPrintf(stdout, + _(" %s cupsUIResolver %s does not list at least " + "two different options."), + prefix, constattr->spec); + + if (!warn) + errors ++; + } + /* * Test the resolver... */ @@ -1855,10 +1957,10 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, - _(" %s cupsUIResolver %s causes a loop!\n"), + _(" %s cupsUIResolver %s causes a loop."), prefix, constattr->spec); if (!warn) @@ -1876,26 +1978,26 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++) { - if (!strncasecmp(c->option1, "Custom", 6) && - !strcasecmp(c->choice1, "True")) + if (!_cups_strncasecmp(c->option1, "Custom", 6) && + !_cups_strcasecmp(c->choice1, "True")) { - strcpy(option, c->option1 + 6); - strcpy(choice, "Custom"); + strlcpy(option, c->option1 + 6, sizeof(option)); + strlcpy(choice, "Custom", sizeof(choice)); } else { - strcpy(option, c->option1); - strcpy(choice, c->choice1); + strlcpy(option, c->option1, sizeof(option)); + strlcpy(choice, c->choice1, sizeof(choice)); } if ((o = ppdFindOption(ppd, option)) == NULL) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" %s Missing option %s in " - "UIConstraints \"*%s %s *%s %s\"!\n"), + "UIConstraints \"*%s %s *%s %s\"."), prefix, c->option1, c->option1, c->choice1, c->option2, c->choice2); @@ -1905,11 +2007,11 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ else if (choice[0] && !ppdFindChoice(o, choice)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" %s Missing choice *%s %s in " - "UIConstraints \"*%s %s *%s %s\"!\n"), + "UIConstraints \"*%s %s *%s %s\"."), prefix, c->option1, c->choice1, c->option1, c->choice1, c->option2, c->choice2); @@ -1917,26 +2019,26 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ errors ++; } - if (!strncasecmp(c->option2, "Custom", 6) && - !strcasecmp(c->choice2, "True")) + if (!_cups_strncasecmp(c->option2, "Custom", 6) && + !_cups_strcasecmp(c->choice2, "True")) { - strcpy(option, c->option2 + 6); - strcpy(choice, "Custom"); + strlcpy(option, c->option2 + 6, sizeof(option)); + strlcpy(choice, "Custom", sizeof(choice)); } else { - strcpy(option, c->option2); - strcpy(choice, c->choice2); + strlcpy(option, c->option2, sizeof(option)); + strlcpy(choice, c->choice2, sizeof(choice)); } if ((o = ppdFindOption(ppd, option)) == NULL) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" %s Missing option %s in " - "UIConstraints \"*%s %s *%s %s\"!\n"), + "UIConstraints \"*%s %s *%s %s\"."), prefix, c->option2, c->option1, c->choice1, c->option2, c->choice2); @@ -1946,11 +2048,11 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ else if (choice[0] && !ppdFindChoice(o, choice)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); _cupsLangPrintf(stdout, _(" %s Missing choice *%s %s in " - "UIConstraints \"*%s %s *%s %s\"!\n"), + "UIConstraints \"*%s %s *%s %s\"."), prefix, c->option2, c->choice2, c->option1, c->choice1, c->option2, c->choice2); @@ -1964,6 +2066,116 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */ } +/* + * 'check_case()' - Check that there are no duplicate groups, options, + * or choices that differ only by case. + */ + +static int /* O - Errors found */ +check_case(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Errors found */ + int verbose) /* I - Verbosity level */ +{ + int i, j; /* Looping vars */ + ppd_group_t *groupa, /* First group */ + *groupb; /* Second group */ + ppd_option_t *optiona, /* First option */ + *optionb; /* Second option */ + ppd_choice_t *choicea, /* First choice */ + *choiceb; /* Second choice */ + + + /* + * Check that the groups do not have any duplicate names... + */ + + for (i = ppd->num_groups, groupa = ppd->groups; i > 1; i --, groupa ++) + for (j = i - 1, groupb = groupa + 1; j > 0; j --, groupb ++) + if (!_cups_strcasecmp(groupa->name, groupb->name)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Group names %s and %s differ only " + "by case."), + groupa->name, groupb->name); + + errors ++; + } + + /* + * Check that the options do not have any duplicate names... + */ + + for (optiona = ppdFirstOption(ppd); optiona; optiona = ppdNextOption(ppd)) + { + cupsArraySave(ppd->options); + for (optionb = ppdNextOption(ppd); optionb; optionb = ppdNextOption(ppd)) + if (!_cups_strcasecmp(optiona->keyword, optionb->keyword)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Option names %s and %s differ only " + "by case."), + optiona->keyword, optionb->keyword); + + errors ++; + } + cupsArrayRestore(ppd->options); + + /* + * Then the choices... + */ + + for (i = optiona->num_choices, choicea = optiona->choices; + i > 1; + i --, choicea ++) + for (j = i - 1, choiceb = choicea + 1; j > 0; j --, choiceb ++) + if (!strcmp(choicea->choice, choiceb->choice)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Multiple occurrences of " + "option %s choice name %s."), + optiona->keyword, choicea->choice); + + errors ++; + + choicea ++; + i --; + break; + } + else if (!_cups_strcasecmp(choicea->choice, choiceb->choice)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Option %s choice names %s and " + "%s differ only by case."), + optiona->keyword, choicea->choice, choiceb->choice); + + errors ++; + } + } + + /* + * Return the number of errors found... + */ + + return (errors); +} + + /* * 'check_defaults()' - Check default option keywords in the PPD file. */ @@ -1982,13 +2194,29 @@ check_defaults(ppd_file_t *ppd, /* I - PPD file */ prefix = warn ? " WARN " : "**FAIL**"; - for (j = 0; j < ppd->num_attrs; j ++) + ppdMarkDefaults(ppd); + if (ppdConflicts(ppd)) { - attr = ppd->attrs[j]; + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); - if (!strcmp(attr->name, "DefaultColorSpace") || - !strcmp(attr->name, "DefaultFont") || - !strcmp(attr->name, "DefaultHalftoneType") || + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Default choices conflicting."), prefix); + + show_conflicts(ppd, prefix); + + if (!warn) + errors ++; + } + + for (j = 0; j < ppd->num_attrs; j ++) + { + attr = ppd->attrs[j]; + + if (!strcmp(attr->name, "DefaultColorSpace") || + !strcmp(attr->name, "DefaultFont") || + !strcmp(attr->name, "DefaultHalftoneType") || !strcmp(attr->name, "DefaultImageableArea") || !strcmp(attr->name, "DefaultLeadingEdge") || !strcmp(attr->name, "DefaultOutputOrder") || @@ -2013,11 +2241,11 @@ check_defaults(ppd_file_t *ppd, /* I - PPD file */ if (k >= option->num_choices) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, - _(" %s %s %s does not exist!\n"), + _(" %s %s %s does not exist."), prefix, attr->name, attr->value); if (!warn) @@ -2031,6 +2259,76 @@ check_defaults(ppd_file_t *ppd, /* I - PPD file */ } +/* + * 'check_duplex()' - Check duplex keywords in the PPD file. + */ + +static int /* O - Errors found */ +check_duplex(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Error found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int i; /* Looping var */ + ppd_option_t *option; /* PPD option */ + ppd_choice_t *choice; /* Current choice */ + const char *prefix; /* Message prefix */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + /* + * Check for a duplex option, and for standard values... + */ + + if ((option = ppdFindOption(ppd, "Duplex")) != NULL) + { + if (!ppdFindChoice(option, "None")) + { + if (verbose >= 0) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + _cupsLangPrintf(stdout, + _(" %s REQUIRED %s does not define " + "choice None.\n" + " REF: Page 122, section 5.17"), + prefix, option->keyword); + } + + if (!warn) + errors ++; + } + + for (i = option->num_choices, choice = option->choices; + i > 0; + i --, choice ++) + if (strcmp(choice->choice, "None") && + strcmp(choice->choice, "DuplexNoTumble") && + strcmp(choice->choice, "DuplexTumble") && + strcmp(choice->choice, "SimplexTumble")) + { + if (verbose >= 0) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + _cupsLangPrintf(stdout, + _(" %s Bad %s choice %s.\n" + " REF: Page 122, section 5.17"), + prefix, option->keyword, choice->choice); + } + + if (!warn) + errors ++; + } + } + + return (errors); +} + + /* * 'check_filters()' - Check filters in the PPD file. */ @@ -2042,36 +2340,59 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */ int verbose, /* I - Verbosity level */ int warn) /* I - Warnings only? */ { - int i; /* Looping var */ ppd_attr_t *attr; /* PPD attribute */ const char *ptr; /* Pointer into string */ char super[16], /* Super-type for filter */ type[256], /* Type for filter */ + dstsuper[16], /* Destination super-type for filter */ + dsttype[256], /* Destination type for filter */ program[1024], /* Program/filter name */ pathprog[1024]; /* Complete path to program/filter */ int cost; /* Cost of filter */ const char *prefix; /* WARN/FAIL prefix */ + struct stat fileinfo; /* File information */ prefix = warn ? " WARN " : "**FAIL**"; - for (i = 0; i < ppd->num_filters; i ++) + /* + * cupsFilter + */ + + for (attr = ppdFindAttr(ppd, "cupsFilter", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsFilter", NULL)) { - if (sscanf(ppd->filters[i], "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, + if (strcmp(attr->name, "cupsFilter")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "cupsFilter"); + + if (!warn) + errors ++; + } + + if (!attr->value || + sscanf(attr->value, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, &cost, program) != 4) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, - _(" %s Bad cupsFilter value \"%s\"!\n"), - prefix, ppd->filters[i]); + _(" %s Bad cupsFilter value \"%s\"."), + prefix, attr->value); if (!warn) errors ++; } - else + else if (strcmp(program, "-")) { if (program[0] == '/') snprintf(pathprog, sizeof(pathprog), "%s%s", root, program); @@ -2088,71 +2409,510 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */ program); } - if (access(pathprog, X_OK)) + if (stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "cupsFilter", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) - _cupsLangPrintf(stdout, _(" %s Missing cupsFilter " - "file \"%s\"\n"), prefix, program); + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "cupsFilter", pathprog); if (!warn) errors ++; } + else + errors = valid_path("cupsFilter", pathprog, errors, verbose, warn); } } + /* + * cupsFilter2 + */ + + for (attr = ppdFindAttr(ppd, "cupsFilter2", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) + { + if (strcmp(attr->name, "cupsFilter2")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "cupsFilter2"); + + if (!warn) + errors ++; + } + + if (!attr->value || + sscanf(attr->value, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]", + super, type, dstsuper, dsttype, &cost, program) != 6) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad cupsFilter2 value \"%s\"."), + prefix, attr->value); + + if (!warn) + errors ++; + } + else if (strcmp(program, "-")) + { + if (strncmp(program, "maxsize(", 8) && + (ptr = strchr(program + 8, ')')) != NULL) + { + ptr ++; + while (_cups_isspace(*ptr)) + ptr ++; + + _cups_strcpy(program, ptr); + } + + if (program[0] == '/') + snprintf(pathprog, sizeof(pathprog), "%s%s", root, program); + else + { + if ((ptr = getenv("CUPS_SERVERBIN")) == NULL) + ptr = CUPS_SERVERBIN; + + if (*ptr == '/' || !*root) + snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr, + program); + else + snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr, + program); + } + + if (stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "cupsFilter2", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "cupsFilter2", pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("cupsFilter2", pathprog, errors, verbose, warn); + } + } + + /* + * cupsPreFilter + */ + for (attr = ppdFindAttr(ppd, "cupsPreFilter", NULL); attr; attr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL)) { - if (!attr->value || - sscanf(attr->value, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, - &cost, program) != 4) + if (strcmp(attr->name, "cupsPreFilter")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "cupsPreFilter"); + + if (!warn) + errors ++; + } + + if (!attr->value || + sscanf(attr->value, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, + &cost, program) != 4) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad cupsPreFilter value \"%s\"."), + prefix, attr->value ? attr->value : ""); + + if (!warn) + errors ++; + } + else if (strcmp(program, "-")) + { + if (program[0] == '/') + snprintf(pathprog, sizeof(pathprog), "%s%s", root, program); + else + { + if ((ptr = getenv("CUPS_SERVERBIN")) == NULL) + ptr = CUPS_SERVERBIN; + + if (*ptr == '/' || !*root) + snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr, + program); + else + snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr, + program); + } + + if (stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "cupsPreFilter", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "cupsPreFilter", pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("cupsPreFilter", pathprog, errors, verbose, warn); + } + } + +#ifdef __APPLE__ + /* + * APDialogExtension + */ + + for (attr = ppdFindAttr(ppd, "APDialogExtension", NULL); + attr != NULL; + attr = ppdFindNextAttr(ppd, "APDialogExtension", NULL)) + { + if (strcmp(attr->name, "APDialogExtension")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "APDialogExtension"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "APDialogExtension", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "APDialogExtension", pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APDialogExtension", pathprog, errors, verbose, + warn); + } + + /* + * APPrinterIconPath + */ + + if ((attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL) + { + if (strcmp(attr->name, "APPrinterIconPath")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "APPrinterIconPath"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "APPrinterIconPath", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DATAFILE) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "APPrinterIconPath", pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APPrinterIconPath", pathprog, errors, verbose, + warn); + } + + /* + * APPrinterLowInkTool + */ + + if ((attr = ppdFindAttr(ppd, "APPrinterLowInkTool", NULL)) != NULL) + { + if (strcmp(attr->name, "APPrinterLowInkTool")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "APPrinterLowInkTool"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "APPrinterLowInkTool", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "APPrinterLowInkTool", pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APPrinterLowInkTool", pathprog, errors, verbose, + warn); + } + + /* + * APPrinterUtilityPath + */ + + if ((attr = ppdFindAttr(ppd, "APPrinterUtilityPath", NULL)) != NULL) + { + if (strcmp(attr->name, "APPrinterUtilityPath")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "APPrinterUtilityPath"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "APPrinterUtilityPath", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "APPrinterUtilityPath", pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APPrinterUtilityPath", pathprog, errors, verbose, + warn); + } + + /* + * APScanAppBundleID and APScanAppPath + */ + + if ((attr = ppdFindAttr(ppd, "APScanAppPath", NULL)) != NULL) + { + if (strcmp(attr->name, "APScanAppPath")) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, - _(" %s Bad cupsPreFilter value \"%s\"!\n"), - prefix, attr->value ? attr->value : ""); + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "APScanAppPath"); if (!warn) errors ++; } - else + + if (!attr->value || stat(attr->value, &fileinfo)) { - if (program[0] == '/') - snprintf(pathprog, sizeof(pathprog), "%s%s", root, program); - else - { - if ((ptr = getenv("CUPS_SERVERBIN")) == NULL) - ptr = CUPS_SERVERBIN; + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); - if (*ptr == '/' || !*root) - snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr, - program); - else - snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr, - program); - } + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "APScanAppPath", + attr->value ? attr->value : ""); - if (access(pathprog, X_OK)) - { - if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); - if (verbose >= 0) - _cupsLangPrintf(stdout, _(" %s Missing cupsPreFilter " - "file \"%s\"\n"), prefix, program); + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "APScanAppPath", attr->value); - if (!warn) - errors ++; - } + if (!warn) + errors ++; + } + else + errors = valid_path("APScanAppPath", attr->value, errors, verbose, + warn); + + if (ppdFindAttr(ppd, "APScanAppBundleID", NULL)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Cannot provide both " + "APScanAppPath and APScanAppBundleID."), + prefix); + + if (!warn) + errors ++; } } +#endif /* __APPLE__ */ return (errors); } @@ -2174,6 +2934,7 @@ check_profiles(ppd_file_t *ppd, /* I - PPD file */ const char *ptr; /* Pointer into string */ const char *prefix; /* WARN/FAIL prefix */ char filename[1024]; /* Profile filename */ + struct stat fileinfo; /* File information */ int num_profiles = 0; /* Number of profiles */ unsigned hash, /* Current hash value */ hashes[1000]; /* Hash values of profile names */ @@ -2196,11 +2957,11 @@ check_profiles(ppd_file_t *ppd, /* I - PPD file */ if (!attr->value || i < 2) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, - _(" %s Bad cupsICCProfile %s!\n"), + _(" %s Bad cupsICCProfile %s."), prefix, attr->spec); if (!warn) @@ -2228,18 +2989,35 @@ check_profiles(ppd_file_t *ppd, /* I - PPD file */ attr->value); } - if (access(filename, 0)) + if (stat(filename, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "cupsICCProfile", filename); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DATAFILE) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) - _cupsLangPrintf(stdout, _(" %s Missing cupsICCProfile " - "file \"%s\"!\n"), prefix, attr->value); + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "cupsICCProfile", filename); if (!warn) errors ++; } + else + errors = valid_path("cupsICCProfile", filename, errors, verbose, warn); /* * Check for hash collisions... @@ -2256,12 +3034,12 @@ check_profiles(ppd_file_t *ppd, /* I - PPD file */ if (i < num_profiles) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s cupsICCProfile %s hash value " - "collides with %s!\n"), prefix, attr->spec, + "collides with %s."), prefix, attr->spec, specs[i]); if (!warn) @@ -2285,6 +3063,303 @@ check_profiles(ppd_file_t *ppd, /* I - PPD file */ } +/* + * 'check_sizes()' - Check media sizes in the PPD file. + */ + +static int /* O - Errors found */ +check_sizes(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int i; /* Looping var */ + ppd_size_t *size; /* Current size */ + int width, /* Custom width */ + length; /* Custom length */ + const char *prefix; /* WARN/FAIL prefix */ + ppd_option_t *page_size, /* PageSize option */ + *page_region; /* PageRegion option */ + _pwg_media_t *pwg_media; /* PWG media */ + char buf[PPD_MAX_NAME]; /* PapeSize name that is supposed to be */ + const char *ptr; /* Pointer into string */ + int width_2540ths, /* PageSize width in 2540ths */ + length_2540ths; /* PageSize length in 2540ths */ + int is_ok; /* Flag for PageSize name verification */ + double width_tmp, /* Width after rounded up */ + length_tmp, /* Length after rounded up */ + width_inch, /* Width in inches */ + length_inch, /* Length in inches */ + width_mm, /* Width in millimeters */ + length_mm; /* Length in millimeters */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + if ((page_size = ppdFindOption(ppd, "PageSize")) == NULL && warn != 2) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Missing REQUIRED PageSize option.\n" + " REF: Page 99, section 5.14."), + prefix); + + if (!warn) + errors ++; + } + + if ((page_region = ppdFindOption(ppd, "PageRegion")) == NULL && warn != 2) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Missing REQUIRED PageRegion option.\n" + " REF: Page 100, section 5.14."), + prefix); + + if (!warn) + errors ++; + } + + for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) + { + /* + * Check that the size name is standard... + */ + + if (!strcmp(size->name, "Custom")) + { + /* + * Skip custom page size... + */ + + continue; + } + + if (warn != 2 && size->name[0] == 'w' && + sscanf(size->name, "w%dh%d", &width, &length) == 2) + { + /* + * Validate device-specific size wNNNhNNN should have proper width and + * length... + */ + + if (fabs(width - size->width) >= 1.0 || + fabs(length - size->length) >= 1.0) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" has unexpected dimensions " + "(%gx%g)."), + prefix, size->name, size->width, size->length); + + if (!warn) + errors ++; + } + } + + /* + * Verify that the size is defined for both PageSize and PageRegion... + */ + + if (warn != 2 && !ppdFindChoice(page_size, size->name)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" defined for %s but not for " + "%s."), + prefix, size->name, "PageRegion", "PageSize"); + + if (!warn) + errors ++; + } + else if (warn != 2 && !ppdFindChoice(page_region, size->name)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" defined for %s but not for " + "%s."), + prefix, size->name, "PageSize", "PageRegion"); + + if (!warn) + errors ++; + } + + /* + * Verify that the size name is Adobe standard name if it's a standard size + * and the dimentional name if it's not a standard size. Suffix should be + * .Fullbleed, etc., or numeric, e.g., Letter, Letter.Fullbleed, + * Letter.Transverse, Letter1, Letter2, 4x8, 55x91mm, 55x91mm.Fullbleed, etc. + */ + + if (warn != 0) + { + is_ok = 1; + width_2540ths = (size->length > size->width) ? + PWG_FROM_POINTS(size->width) : + PWG_FROM_POINTS(size->length); + length_2540ths = (size->length > size->width) ? + PWG_FROM_POINTS(size->length) : + PWG_FROM_POINTS(size->width); + pwg_media = pwgMediaForSize(width_2540ths, length_2540ths); + + if (pwg_media && + (fabs(pwg_media->width - width_2540ths) > 34 || + fabs(pwg_media->length - length_2540ths) > 34)) + pwg_media = NULL; /* Only flag matches within a point */ + + if (pwg_media && pwg_media->ppd && + (pwg_media->ppd[0] < 'a' || pwg_media->ppd[0] > 'z')) + { + size_t ppdlen = strlen(pwg_media->ppd); + /* Length of standard PPD name */ + + strlcpy(buf, pwg_media->ppd, sizeof(buf)); + + if (strcmp(size->name, buf) && size->width > size->length) + { + if (!strcmp(pwg_media->ppd, "DoublePostcardRotated")) + strlcpy(buf, "DoublePostcard", sizeof(buf)); + else if (strstr(size->name, ".Transverse")) + snprintf(buf, sizeof(buf), "%s.Transverse", pwg_media->ppd); + else + snprintf(buf, sizeof(buf), "%sRotated", pwg_media->ppd); + + ppdlen = strlen(buf); + } + + if (size->left == 0 && size->bottom == 0 && + size->right == size->width && size->top == size->length) + { + strlcat(buf, ".Fullbleed", sizeof(buf) - strlen(buf)); + if (_cups_strcasecmp(size->name, buf)) + { + /* + * Allow an additional qualifier such as ".WithTab"... + */ + + size_t buflen = strlen(buf);/* Length of full bleed name */ + + if (_cups_strncasecmp(size->name, buf, buflen) || + size->name[buflen] != '.') + is_ok = 0; + } + } + else if (!strncmp(size->name, pwg_media->ppd, ppdlen)) + { + /* + * Check for a proper qualifier (number, "Small", or .something)... + */ + + ptr = size->name + ppdlen; + + if (isdigit(*ptr & 255)) + { + for (ptr ++; *ptr; ptr ++) + { + if (!isdigit(*ptr & 255)) + { + is_ok = 0; + break; + } + } + } + else if (*ptr != '.' && *ptr && strcmp(ptr, "Small")) + is_ok = 0; + } + else + { + /* + * Check for EnvSizeName as well... + */ + + if (strncmp(pwg_media->ppd, "Env", 3) && + !strncmp(size->name, "Env", 3)) + snprintf(buf, sizeof(buf), "Env%s", pwg_media->ppd); + + if (strcmp(size->name, buf)) + is_ok = 0; + } + + if (!is_ok) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" should be the Adobe " + "standard name \"%s\"."), + prefix, size->name, buf); + } + else + { + width_tmp = (fabs(size->width - ceil(size->width)) < 0.1) ? + ceil(size->width) : size->width; + length_tmp = (fabs(size->length - ceil(size->length)) < 0.1) ? + ceil(size->length) : size->length; + + if (fmod(width_tmp, 9.0) == 0.0 && fmod(length_tmp, 9.0) == 0.0) + { + width_inch = width_tmp / 72.0; + length_inch = length_tmp / 72.0; + + snprintf(buf, sizeof(buf), "%gx%g", width_inch, length_inch); + } + else + { + width_mm = size->width / 72.0 * 25.4; + length_mm = size->length / 72.0 * 25.4; + + snprintf(buf, sizeof(buf), "%.0fx%.0fmm", width_mm, length_mm); + } + + if (size->left == 0 && size->bottom == 0 && + size->right == size->width && size->top == size->length) + strlcat(buf, ".Fullbleed", sizeof(buf)); + else if (size->width > size->length) + strlcat(buf, ".Transverse", sizeof(buf)); + + if (_cups_strcasecmp(size->name, buf)) + { + size_t buflen = strlen(buf); + /* Length of proposed name */ + + if (_cups_strncasecmp(size->name, buf, buflen) || + (strcmp(size->name + buflen, "in") && + size->name[buflen] != '.')) + { + char altbuf[PPD_MAX_NAME]; + /* Alternate "wNNNhNNN" name */ + size_t altlen; /* Length of alternate name */ + + snprintf(altbuf, sizeof(altbuf), "w%.0fh%.0f", size->width, + size->length); + altlen = strlen(altbuf); + if (_cups_strncasecmp(size->name, altbuf, altlen) || + (size->name[altlen] && size->name[altlen] != '.')) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" should be \"%s\"."), + prefix, size->name, buf); + } + } + } + } + } + + return (errors); +} + + /* * 'check_translations()' - Check translations in the PPD file. */ @@ -2310,6 +3385,7 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ ppd_cparam_t *cparam; /* Custom parameter */ char ll[3]; /* Base language */ const char *prefix; /* WARN/FAIL prefix */ + const char *text; /* Pointer into UI text */ prefix = warn ? " WARN " : "**FAIL**"; @@ -2324,15 +3400,15 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ language; language = (char *)cupsArrayNext(languages)) { - langlen = strlen(language); + langlen = (int)strlen(language); if (langlen != 2 && langlen != 5) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, - _(" %s Bad language \"%s\"!\n"), + _(" %s Bad language \"%s\"."), prefix, language); if (!warn) @@ -2364,12 +3440,12 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ (attr = ppdFindAttr(ppd, llkeyword, option->keyword)) == NULL) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s Missing \"%s\" translation " - "string for option %s!\n"), + "string for option %s."), prefix, language, option->keyword); if (!warn) @@ -2378,12 +3454,12 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ else if (!valid_utf8(attr->text)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s Bad UTF-8 \"%s\" translation " - "string for option %s!\n"), + "string for option %s."), prefix, language, option->keyword); if (!warn) @@ -2397,7 +3473,23 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ for (j = 0; j < option->num_choices; j ++) { - if (!strcasecmp(option->choices[j].choice, "Custom") && + /* + * First see if this choice is a number; if so, don't require + * translation... + */ + + for (text = option->choices[j].text; *text; text ++) + if (!strchr("0123456789-+.", *text)) + break; + + if (!*text) + continue; + + /* + * Check custom choices differently... + */ + + if (!_cups_strcasecmp(option->choices[j].choice, "Custom") && (coption = ppdFindCustomOption(ppd, option->keyword)) != NULL) { @@ -2408,13 +3500,13 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ !valid_utf8(attr->text)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s Bad UTF-8 \"%s\" " "translation string for option %s, " - "choice %s!\n"), + "choice %s."), prefix, language, ckeyword + 1 + strlen(language), "True"); @@ -2423,7 +3515,7 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ errors ++; } - if (strcasecmp(option->keyword, "PageSize")) + if (_cups_strcasecmp(option->keyword, "PageSize")) { for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); cparam; @@ -2440,13 +3532,13 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ cparam->name)) == NULL) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s Missing \"%s\" " "translation string for option %s, " - "choice %s!\n"), + "choice %s."), prefix, language, ckeyword + 1 + strlen(language), cparam->name); @@ -2457,13 +3549,13 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ else if (!valid_utf8(attr->text)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s Bad UTF-8 \"%s\" " "translation string for option %s, " - "choice %s!\n"), + "choice %s."), prefix, language, ckeyword + 1 + strlen(language), cparam->name); @@ -2480,13 +3572,13 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ option->choices[j].choice)) == NULL) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s Missing \"%s\" " "translation string for option %s, " - "choice %s!\n"), + "choice %s."), prefix, language, option->keyword, option->choices[j].choice); @@ -2496,13 +3588,13 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ else if (!valid_utf8(attr->text)) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s Bad UTF-8 \"%s\" " "translation string for option %s, " - "choice %s!\n"), + "choice %s."), prefix, language, option->keyword, option->choices[j].choice); @@ -2534,12 +3626,12 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ strcmp(ll, "zh") && strcmp(ll, "en")) { if (!warn && !errors && !verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" %s No base translation \"%s\" " - "is included in file!\n"), prefix, ll); + "is included in file."), prefix, ll); if (!warn) errors ++; @@ -2564,7 +3656,8 @@ check_translations(ppd_file_t *ppd, /* I - PPD file */ */ static void -show_conflicts(ppd_file_t *ppd) /* I - PPD to check */ +show_conflicts(ppd_file_t *ppd, /* I - PPD to check */ + const char *prefix) /* I - Prefix string */ { int i, j; /* Looping variables */ ppd_const_t *c; /* Current constraint */ @@ -2606,9 +3699,9 @@ show_conflicts(ppd_file_t *ppd) /* I - PPD to check */ break; if (j == 0 || - !strcasecmp(c1->choice, "None") || - !strcasecmp(c1->choice, "Off") || - !strcasecmp(c1->choice, "False")) + !_cups_strcasecmp(c1->choice, "None") || + !_cups_strcasecmp(c1->choice, "Off") || + !_cups_strcasecmp(c1->choice, "False")) c1 = NULL; } @@ -2639,9 +3732,9 @@ show_conflicts(ppd_file_t *ppd) /* I - PPD to check */ break; if (j == 0 || - !strcasecmp(c2->choice, "None") || - !strcasecmp(c2->choice, "Off") || - !strcasecmp(c2->choice, "False")) + !_cups_strcasecmp(c2->choice, "None") || + !_cups_strcasecmp(c2->choice, "Off") || + !_cups_strcasecmp(c2->choice, "False")) c2 = NULL; } @@ -2651,9 +3744,9 @@ show_conflicts(ppd_file_t *ppd) /* I - PPD to check */ if (c1 != NULL && c1->marked && c2 != NULL && c2->marked) _cupsLangPrintf(stdout, - _(" WARN \"%s %s\" conflicts with \"%s %s\"\n" - " (constraint=\"%s %s %s %s\")\n"), - o1->keyword, c1->choice, o2->keyword, c2->choice, + _(" %s \"%s %s\" conflicts with \"%s %s\"\n" + " (constraint=\"%s %s %s %s\")."), + prefix, o1->keyword, c1->choice, o2->keyword, c2->choice, c->option1, c->choice1, c->option2, c->choice2); } } @@ -2674,12 +3767,12 @@ test_raster(ppd_file_t *ppd, /* I - PPD file */ if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, 0)) { if (!verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" **FAIL** Default option code cannot be " - "interpreted: %s\n"), cupsRasterErrorString()); + "interpreted: %s"), cupsRasterErrorString()); return (0); } @@ -2696,12 +3789,12 @@ test_raster(ppd_file_t *ppd, /* I - PPD file */ if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, 0)) { if (!verbose) - _cupsLangPuts(stdout, _(" FAIL\n")); + _cupsLangPuts(stdout, _(" FAIL")); if (verbose >= 0) _cupsLangPrintf(stdout, _(" **FAIL** Default option code cannot be " - "interpreted: %s\n"), cupsRasterErrorString()); + "interpreted: %s"), cupsRasterErrorString()); return (0); } @@ -2711,31 +3804,117 @@ test_raster(ppd_file_t *ppd, /* I - PPD file */ /* - * 'usage()' - Show program usage... + * 'usage()' - Show program usage. */ static void usage(void) { - _cupsLangPuts(stdout, - _("Usage: cupstestppd [options] filename1.ppd[.gz] " - "[... filenameN.ppd[.gz]]\n" - " program | cupstestppd [options] -\n" - "\n" - "Options:\n" - "\n" - " -R root-directory Set alternate root\n" - " -W {all,none,constraints,defaults,filters,translations}\n" - " Issue warnings instead of errors\n" - " -q Run silently\n" - " -r Use 'relaxed' open mode\n" - " -v Be slightly verbose\n" - " -vv Be very verbose\n")); + _cupsLangPuts(stdout, _("Usage: cupstestppd [options] filename1.ppd[.gz] " + "[... filenameN.ppd[.gz]]")); + _cupsLangPuts(stdout, _(" program | cupstestppd [options] -")); + _cupsLangPuts(stdout, ""); + _cupsLangPuts(stdout, _("Options:")); + _cupsLangPuts(stdout, ""); + _cupsLangPuts(stdout, _(" -I {filename,filters,none,profiles}")); + _cupsLangPuts(stdout, _(" Ignore specific warnings.")); + _cupsLangPuts(stdout, _(" -R root-directory Set alternate root.")); + _cupsLangPuts(stdout, _(" -W {all,none,constraints,defaults,duplex," + "filters,profiles,sizes,translations}")); + _cupsLangPuts(stdout, _(" Issue warnings instead of " + "errors.")); + _cupsLangPuts(stdout, _(" -q Run silently.")); + _cupsLangPuts(stdout, _(" -r Use 'relaxed' open mode.")); + _cupsLangPuts(stdout, _(" -v Be verbose.")); + _cupsLangPuts(stdout, _(" -vv Be very verbose.")); exit(ERROR_USAGE); } +/* + * 'valid_path()' - Check whether a path has the correct capitalization. + */ + +static int /* O - Errors found */ +valid_path(const char *keyword, /* I - Keyword using path */ + const char *path, /* I - Path to check */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + cups_dir_t *dir; /* Current directory */ + cups_dentry_t *dentry; /* Current directory entry */ + char temp[1024], /* Temporary path */ + *ptr; /* Pointer into temporary path */ + const char *prefix; /* WARN/FAIL prefix */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + /* + * Loop over the components of the path, checking that the entry exists with + * the same capitalization... + */ + + strlcpy(temp, path, sizeof(temp)); + + while ((ptr = strrchr(temp, '/')) != NULL) + { + /* + * Chop off the trailing component so temp == dirname and ptr == basename. + */ + + *ptr++ = '\0'; + + /* + * Try opening the directory containing the base name... + */ + + if (temp[0]) + dir = cupsDirOpen(temp); + else + dir = cupsDirOpen("/"); + + if (!dir) + dentry = NULL; + else + { + while ((dentry = cupsDirRead(dir)) != NULL) + { + if (!strcmp(dentry->filename, ptr)) + break; + } + + cupsDirClose(dir); + } + + /* + * Display an error if the filename doesn't exist with the same + * capitalization... + */ + + if (!dentry) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s %s file \"%s\" has the wrong " + "capitalization."), prefix, keyword, path); + + if (!warn) + errors ++; + + break; + } + } + + return (errors); +} + + /* * 'valid_utf8()' - Check whether a string contains valid UTF-8 text. */ @@ -2813,5 +3992,5 @@ valid_utf8(const char *s) /* I - String to check */ /* - * End of "$Id: cupstestppd.c 7637 2008-06-11 17:25:36Z mike $". + * End of "$Id: cupstestppd.c 10996 2013-05-29 11:51:34Z msweet $". */