/*
- * "$Id: cupstestppd.c 7807 2008-07-28 21:54:24Z mike $"
+ * PPD test program for CUPS.
*
- * PPD test program for CUPS.
+ * THIS PROGRAM IS DEPRECATED AND WILL BE REMOVED IN A FUTURE VERSION OF CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more
+ * information.
*
- * PostScript is a trademark of Adobe Systems, Inc.
- *
- * This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- * main() - Main entry for test program.
- * 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.
- * valid_path() - Check whether a path has the correct capitalization.
- * valid_utf8() - Check whether a string contains valid UTF-8 text.
+ * PostScript is a trademark of Adobe Systems, Inc.
*/
/*
#include <cups/ppd-private.h>
#include <cups/raster.h>
#include <math.h>
-#ifdef WIN32
+#ifdef _WIN32
# define X_OK 0
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
int warn);
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) __attribute__((noreturn));
+static void usage(void) _CUPS_NORETURN;
static int valid_path(const char *keyword, const char *path, int errors,
int verbose, int warn);
static int valid_utf8(const char *s);
char *argv[]) /* I - Command-line arguments */
{
int i, j, k, m, n; /* Looping vars */
- int len; /* Length of option name */
+ size_t 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 */
ignore = WARN_NONE;
for (i = 1; i < argc; i ++)
- if (argv[i][0] == '-' && argv[i][1])
+ if (!strcmp(argv[i], "--help"))
+ usage();
+ else if (argv[i][0] == '-' && argv[i][1])
{
for (opt = argv[i] + 1; *opt; opt ++)
switch (*opt)
* Read from stdin...
*/
- ppd = ppdOpen(stdin);
+ ppd = _ppdOpen(cupsFileStdin(), _PPD_LOCALIZATION_ALL);
if (verbose >= 0)
printf("%s:", (ppd && ppd->pcfilename) ? ppd->pcfilename : "(stdin)");
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)
{
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPrintf(stdout,
- _(" **FAIL** Unable to open PPD file - %s"),
- strerror(errno));
+ _(" **FAIL** Unable to open PPD file - %s on "
+ "line %d."), strerror(errno), 0);
}
}
else
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPrintf(stdout,
- _(" **FAIL** BAD DefaultImageableArea %s\n"
+ _(" **FAIL** Bad DefaultImageableArea %s\n"
" REF: Page 102, section 5.15."),
attr->value);
}
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPrintf(stdout,
- _(" **FAIL** BAD DefaultPaperDimension %s\n"
+ _(" **FAIL** Bad DefaultPaperDimension %s\n"
" REF: Page 103, section 5.15."),
attr->value);
}
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPrintf(stdout,
- _(" **FAIL** BAD Default%s %s\n"
+ _(" **FAIL** Bad Default%s %s\n"
" REF: Page 40, section 4.5."),
option->keyword, option->defchoice);
}
if (!errors && !verbose)
_cupsLangPuts(stdout, _(" FAIL"));
- _cupsLangPuts(stdout,
- _(" **FAIL** BAD Manufacturer (should be "
- "\"HP\")\n"
- " REF: Page 211, table D.1."));
+ _cupsLangPrintf(stdout,
+ _(" **FAIL** Bad Manufacturer (should be "
+ "\"%s\")\n"
+ " REF: Page 211, table D.1."),
+ "HP");
}
errors ++;
if (!errors && !verbose)
_cupsLangPuts(stdout, _(" FAIL"));
- _cupsLangPuts(stdout,
- _(" **FAIL** BAD Manufacturer (should be "
- "\"Oki\")\n"
- " REF: Page 211, table D.1."));
+ _cupsLangPrintf(stdout,
+ _(" **FAIL** Bad Manufacturer (should be "
+ "\"%s\")\n"
+ " REF: Page 211, table D.1."),
+ "Oki");
}
errors ++;
_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."),
*ptr);
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPuts(stdout,
- _(" **FAIL** BAD Product - not \"(string)\".\n"
+ _(" **FAIL** Bad Product - not \"(string)\".\n"
" REF: Page 62, section 5.3."));
}
int junkint; /* Temp integer */
- if (sscanf(attr->value, "(%[^)])%d", junkstr, &junkint) != 2)
+ if (sscanf(attr->value, "(%254[^)\n])%d", junkstr, &junkint) != 2)
{
if (verbose >= 0)
{
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPuts(stdout,
- _(" **FAIL** BAD PSVersion - not \"(string) "
+ _(" **FAIL** Bad PSVersion - not \"(string) "
"int\".\n"
" REF: Pages 62-64, section 5.3."));
}
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPuts(stdout,
- _(" **FAIL** BAD ShortNickName - longer "
+ _(" **FAIL** Bad ShortNickName - longer "
"than 31 chars.\n"
" REF: Pages 64-65, section 5.3."));
}
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPuts(stdout,
- _(" **FAIL** BAD JobPatchFile attribute in file\n"
+ _(" **FAIL** Bad JobPatchFile attribute in file\n"
" REF: Page 24, section 3.4."));
}
* Check for PaperDimension...
*/
- if (size->width == 0.0 && size->length == 0.0)
+ if (size->width <= 0.0 && size->length <= 0.0)
{
if (verbose >= 0)
{
_cupsLangPuts(stdout, _(" FAIL"));
_cupsLangPrintf(stdout,
- _(" **FAIL** Bad %s choice %s\n"
+ _(" **FAIL** Bad option %s choice %s\n"
" REF: Page 84, section 5.9"),
option->keyword, choice->choice);
}
k < group->num_options;
k ++, option ++)
{
- len = (int)strlen(option->keyword);
+ len = strlen(option->keyword);
for (m = 0, group2 = ppd->groups;
m < ppd->num_groups;
n < group2->num_options;
n ++, option2 ++)
if (option != option2 &&
- len < (int)strlen(option2->keyword) &&
+ len < strlen(option2->keyword) &&
!strncmp(option->keyword, option2->keyword, len))
{
_cupsLangPrintf(stdout,
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 (!_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 (!_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 (verbose >= 0)
_cupsLangPrintf(stdout,
- _(" **FAIL** Multiple occurrences of %s "
- "choice name %s."),
+ _(" **FAIL** Multiple occurrences of "
+ "option %s choice name %s."),
optiona->keyword, choicea->choice);
errors ++;
if (verbose >= 0)
_cupsLangPrintf(stdout,
- _(" **FAIL** %s choice names %s and %s "
- "differ only by case."),
+ _(" **FAIL** Option %s choice names %s and "
+ "%s differ only by case."),
optiona->keyword, choicea->choice, choiceb->choice);
errors ++;
if (!warn)
errors ++;
+
+ continue;
}
- else if (strcmp(program, "-"))
+
+ if (!strncmp(program, "maxsize(", 8))
+ {
+ char *mptr; /* Pointer into maxsize(nnnn) program */
+
+ strtoll(program + 8, &mptr, 10);
+
+ if (*mptr != ')')
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s Bad cupsFilter value \"%s\"."),
+ prefix, attr->value);
+
+ if (!warn)
+ errors ++;
+
+ continue;
+ }
+
+ mptr ++;
+ while (_cups_isspace(*mptr))
+ mptr ++;
+
+ _cups_strcpy(program, mptr);
+ }
+
+ if (strcmp(program, "-"))
{
if (program[0] == '/')
snprintf(pathprog, sizeof(pathprog), "%s%s", root, program);
if (!warn)
errors ++;
+
+ continue;
}
- else if (strcmp(program, "-"))
+
+ if (!strncmp(program, "maxsize(", 8))
+ {
+ char *mptr; /* Pointer into maxsize(nnnn) program */
+
+ strtoll(program + 8, &mptr, 10);
+
+ if (*mptr != ')')
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s Bad cupsFilter2 value \"%s\"."),
+ prefix, attr->value);
+
+ if (!warn)
+ errors ++;
+
+ continue;
+ }
+
+ mptr ++;
+ while (_cups_isspace(*mptr))
+ mptr ++;
+
+ _cups_strcpy(program, mptr);
+ }
+
+ if (strcmp(program, "-"))
{
if (strncmp(program, "maxsize(", 8) &&
(ptr = strchr(program + 8, ')')) != NULL)
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[1024]; /* PapeSize name that is supposed to be */
+ 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 */
continue;
}
- else if (warn != 2 && size->name[0] == 'w' &&
- sscanf(size->name, "w%dh%d", &width, &length) == 2)
+
+ 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
/*
* Verify that the size name is Adobe standard name if it's a standard size
- * and the dementional name if it's not a standard size. Suffix should be
+ * 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.
*/
{
is_ok = 1;
width_2540ths = (size->length > size->width) ?
- _PWG_FROMPTS(size->width) :
- _PWG_FROMPTS(size->length);
+ PWG_FROM_POINTS(size->width) :
+ PWG_FROM_POINTS(size->length);
length_2540ths = (size->length > size->width) ?
- _PWG_FROMPTS(size->length) :
- _PWG_FROMPTS(size->width);
- pwg_media = _pwgMediaForSize(width_2540ths, length_2540ths);
+ PWG_FROM_POINTS(size->length) :
+ PWG_FROM_POINTS(size->width);
+ pwg_media = pwgMediaForSize(width_2540ths, length_2540ths);
- if (pwg_media && pwg_media->ppd)
+ if (pwg_media &&
+ (abs(pwg_media->width - width_2540ths) > 34 ||
+ abs(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 (size->left == 0 && size->bottom == 0 &&
- size->right == size->width && size->top == size->length)
+ if (strcmp(size->name, buf) && size->width > size->length)
{
- snprintf(buf, sizeof(buf), "%s.Fullbleed", pwg_media->ppd);
- if (strcmp(size->name, buf))
- is_ok = 0;
+ 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);
}
- else if (size->width > size->length)
+
+ if (size->left == 0 && size->bottom == 0 &&
+ size->right == size->width && size->top == size->length)
{
- if ((ptr = pwg_media->ppd + strlen(pwg_media->ppd) - 7)
- >= pwg_media->ppd && !strcmp(ptr, "Rotated"))
+ strlcat(buf, ".Fullbleed", sizeof(buf) - strlen(buf));
+ if (_cups_strcasecmp(size->name, buf))
{
- if (strcmp(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
- {
- snprintf(buf, sizeof(buf), "%sRotated", pwg_media->ppd);
- if (strcmp(size->name, buf))
- {
- snprintf(buf, sizeof(buf), "%s.Transverse", pwg_media->ppd);
- if (strcmp(size->name, buf))
- is_ok = 0;
- }
- }
}
- else
- {
- if ((!strncmp(size->name, pwg_media->ppd, strlen(pwg_media->ppd))))
+ 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 = size->name + strlen(pwg_media->ppd); *ptr; ptr ++)
+ for (ptr ++; *ptr; ptr ++)
{
if (!isdigit(*ptr & 255))
{
}
}
}
- else
- is_ok = 0;
+ 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,
length_tmp = (fabs(size->length - ceil(size->length)) < 0.1) ?
ceil(size->length) : size->length;
- if (fmod(width_tmp, 18.0) == 0.0 && fmod(length_tmp, 18.0) == 0.0)
+ 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;
else if (size->width > size->length)
strlcat(buf, ".Transverse", sizeof(buf));
- if (strcmp(size->name, buf))
- _cupsLangPrintf(stdout,
- _(" %s Size \"%s\" should be \"%s\"."),
- prefix, size->name, 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);
+ }
+ }
}
}
}
static void
usage(void)
{
- _cupsLangPuts(stdout, _("Usage: cupstestppd [options] filename1.ppd[.gz] "
- "[... filenameN.ppd[.gz]]"));
- _cupsLangPuts(stdout, _(" program | cupstestppd [options] -"));
- _cupsLangPuts(stdout, "");
+ _cupsLangPuts(stdout, _("Warning: This program will be removed in a future version of CUPS."));
+ _cupsLangPuts(stdout, _("Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n"
+ " program | cupstestppd [options] -"));
_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 slightly verbose."));
- _cupsLangPuts(stdout, _(" -vv Be very verbose."));
+ _cupsLangPuts(stdout, _("-I {filename,filters,none,profiles}\n"
+ " Ignore specific warnings"));
+ _cupsLangPuts(stdout, _("-R root-directory Set alternate root"));
+ _cupsLangPuts(stdout, _("-W {all,none,constraints,defaults,duplex,filters,profiles,sizes,translations}\n"
+ " 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);
}
return (1);
}
-
-
-/*
- * End of "$Id: cupstestppd.c 7807 2008-07-28 21:54:24Z mike $".
- */