+#define DEBUG
/*
* "$Id$"
*
* PPD file routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products 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 missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * 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/".
*
* PostScript is a trademark of Adobe Systems, Inc.
*
*
* ppdClose() - Free all memory used by the PPD file.
* ppdErrorString() - Returns the text assocated with a status.
+ * _ppdGetEncoding() - Get the CUPS encoding value for the given
+ * LanguageEncoding.
* ppdLastError() - Return the status from the last ppdOpen*().
* ppdOpen() - Read a PPD file into memory.
* ppdOpen2() - Read a PPD file into memory.
* ppd_add_choice() - Add a choice to an option.
* ppd_add_size() - Add a page size.
* ppd_compare_attrs() - Compare two attributes.
+ * ppd_compare_choices() - Compare two choices...
+ * ppd_compare_consts() - Compare two constraints.
* ppd_compare_coptions() - Compare two custom options.
* ppd_compare_cparams() - Compare two custom parameters.
* ppd_compare_options() - Compare two options.
* ppd_free_option() - Free a single option.
* ppd_get_coption() - Get a custom option record.
* ppd_get_cparam() - Get a custom parameter record.
- * ppd_get_encoding() - Get the CUPS encoding value for the given
- * LanguageEncoding.
* ppd_get_group() - Find or create the named group as needed.
* ppd_get_option() - Find or create the named option as needed.
+ * ppd_hash_option() - Generate a hash of the option name...
* ppd_read() - Read a line from a PPD file, skipping comment
* lines as necessary.
*/
#define PPD_TEXT 4 /* Line contained human-readable text */
#define PPD_STRING 8 /* Line contained a string or code */
+#define PPD_HASHSIZE 512 /* Size of hash */
+
/*
* Local functions...
static ppd_choice_t *ppd_add_choice(ppd_option_t *option, const char *name);
static ppd_size_t *ppd_add_size(ppd_file_t *ppd, const char *name);
static int ppd_compare_attrs(ppd_attr_t *a, ppd_attr_t *b);
+static int ppd_compare_choices(ppd_choice_t *a, ppd_choice_t *b);
+static int ppd_compare_consts(ppd_const_t *a, ppd_const_t *b);
static int ppd_compare_coptions(ppd_coption_t *a,
ppd_coption_t *b);
static int ppd_compare_cparams(ppd_cparam_t *a, ppd_cparam_t *b);
static ppd_cparam_t *ppd_get_cparam(ppd_coption_t *opt,
const char *param,
const char *text);
-static cups_encoding_t ppd_get_encoding(const char *name);
static ppd_group_t *ppd_get_group(ppd_file_t *ppd, const char *name,
const char *text, _cups_globals_t *cg,
cups_encoding_t encoding);
static ppd_option_t *ppd_get_option(ppd_group_t *group, const char *name);
+static int ppd_hash_option(ppd_option_t *option);
static int ppd_read(cups_file_t *fp, char *keyword, char *option,
char *text, char **string, int ignoreblank,
_cups_globals_t *cg);
* Free all strings at the top level...
*/
- if (!ppd->lang_encoding || strcasecmp(ppd->lang_encoding, "UTF-8"))
- ppd_free(ppd->nickname);
-
ppd_free(ppd->lang_encoding);
+ ppd_free(ppd->nickname);
ppd_free(ppd->patches);
ppd_free(ppd->jcl_begin);
ppd_free(ppd->jcl_end);
}
cupsArrayDelete(ppd->options);
+ cupsArrayDelete(ppd->marked);
/*
* Free any page sizes...
}
+/*
+ * '_ppdGetEncoding()' - Get the CUPS encoding value for the given
+ * LanguageEncoding.
+ */
+
+cups_encoding_t /* O - CUPS encoding value */
+_ppdGetEncoding(const char *name) /* I - LanguageEncoding string */
+{
+ if (!strcasecmp(name, "ISOLatin1"))
+ return (CUPS_ISO8859_1);
+ else if (!strcasecmp(name, "ISOLatin2"))
+ return (CUPS_ISO8859_2);
+ else if (!strcasecmp(name, "ISOLatin5"))
+ return (CUPS_ISO8859_5);
+ else if (!strcasecmp(name, "JIS83-RKSJ"))
+ return (CUPS_WINDOWS_932);
+ else if (!strcasecmp(name, "MacStandard"))
+ return (CUPS_MAC_ROMAN);
+ else if (!strcasecmp(name, "WindowsANSI"))
+ return (CUPS_WINDOWS_1252);
+ else
+ return (CUPS_UTF8);
+}
+
+
/*
* 'ppdLastError()' - Return the status from the last ppdOpen*().
*
*/
ppd->lang_encoding = strdup("UTF-8");
- encoding = ppd_get_encoding(string);
+ encoding = _ppdGetEncoding(string);
}
else if (!strcmp(keyword, "LanguageVersion"))
ppd->lang_version = string;
ppd->nickname = strdup((char *)utf8);
}
else
- ppd->nickname = string;
+ ppd->nickname = strdup(string);
}
else if (!strcmp(keyword, "Product"))
ppd->product = string;
strlcpy(profile->resolution, name, sizeof(profile->resolution));
strlcpy(profile->media_type, text, sizeof(profile->media_type));
- profile->density = _cupsStrScand(string, &sptr, loc);
- profile->gamma = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[0][0] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[0][1] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[0][2] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[1][0] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[1][1] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[1][2] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[2][0] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[2][1] = _cupsStrScand(sptr, &sptr, loc);
- profile->matrix[2][2] = _cupsStrScand(sptr, &sptr, loc);
+ profile->density = (float)_cupsStrScand(string, &sptr, loc);
+ profile->gamma = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[0][0] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[0][1] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[0][2] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[1][0] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[1][1] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[1][2] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[2][0] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[2][1] = (float)_cupsStrScand(sptr, &sptr, loc);
+ profile->matrix[2][2] = (float)_cupsStrScand(sptr, &sptr, loc);
}
else if (!strcmp(keyword, "cupsFilter"))
{
if (!strcmp(ctype, "curve"))
{
cparam->type = PPD_CUSTOM_CURVE;
- cparam->minimum.custom_curve = _cupsStrScand(cminimum, NULL, loc);
- cparam->maximum.custom_curve = _cupsStrScand(cmaximum, NULL, loc);
+ cparam->minimum.custom_curve = (float)_cupsStrScand(cminimum, NULL, loc);
+ cparam->maximum.custom_curve = (float)_cupsStrScand(cmaximum, NULL, loc);
}
else if (!strcmp(ctype, "int"))
{
else if (!strcmp(ctype, "invcurve"))
{
cparam->type = PPD_CUSTOM_INVCURVE;
- cparam->minimum.custom_invcurve = _cupsStrScand(cminimum, NULL, loc);
- cparam->maximum.custom_invcurve = _cupsStrScand(cmaximum, NULL, loc);
+ cparam->minimum.custom_invcurve = (float)_cupsStrScand(cminimum, NULL, loc);
+ cparam->maximum.custom_invcurve = (float)_cupsStrScand(cmaximum, NULL, loc);
}
else if (!strcmp(ctype, "passcode"))
{
else if (!strcmp(ctype, "points"))
{
cparam->type = PPD_CUSTOM_POINTS;
- cparam->minimum.custom_points = _cupsStrScand(cminimum, NULL, loc);
- cparam->maximum.custom_points = _cupsStrScand(cmaximum, NULL, loc);
+ cparam->minimum.custom_points = (float)_cupsStrScand(cminimum, NULL, loc);
+ cparam->maximum.custom_points = (float)_cupsStrScand(cmaximum, NULL, loc);
}
else if (!strcmp(ctype, "real"))
{
cparam->type = PPD_CUSTOM_REAL;
- cparam->minimum.custom_real = _cupsStrScand(cminimum, NULL, loc);
- cparam->maximum.custom_real = _cupsStrScand(cmaximum, NULL, loc);
+ cparam->minimum.custom_real = (float)_cupsStrScand(cminimum, NULL, loc);
+ cparam->maximum.custom_real = (float)_cupsStrScand(cmaximum, NULL, loc);
}
else if (!strcmp(ctype, "string"))
{
else if (!strcmp(keyword, "HWMargins"))
{
for (i = 0, sptr = string; i < 4; i ++)
- ppd->custom_margins[i] = _cupsStrScand(sptr, &sptr, loc);
+ ppd->custom_margins[i] = (float)_cupsStrScand(sptr, &sptr, loc);
}
- else if (!strncmp(keyword, "Custom", 6) && !strcmp(name, "True"))
+ else if (!strncmp(keyword, "Custom", 6) && !strcmp(name, "True") && !option)
{
DEBUG_puts("Processing Custom option...");
if ((option = ppdFindOption(ppd, keyword + 6)) == NULL)
{
+ int groupidx = -1; /* Index for current group */
ppd_group_t *gtemp; /* Temporary group */
DEBUG_printf(("%s option not found for %s...\n", keyword + 6, keyword));
+ if (group)
+ groupidx = group - ppd->groups; /* Save index for current group */
+
if ((gtemp = ppd_get_group(ppd, "General", _("General"), cg,
encoding)) == NULL)
{
goto error;
}
+ if (group)
+ group = ppd->groups + groupidx; /* Restore group pointer */
+
if ((option = ppd_get_option(gtemp, keyword + 6)) == NULL)
{
DEBUG_printf(("Unable to get %s option!\n", keyword + 6));
*/
ppd_add_size(ppd, "Custom");
+
+ if ((option = ppdFindOption(ppd, "PageRegion")) == NULL)
+ {
+ int groupidx = -1; /* Index to current group */
+ ppd_group_t *gtemp; /* Temporary group */
+
+ if (group)
+ groupidx = group - ppd->groups; /* Save index for current group */
+
+ if ((gtemp = ppd_get_group(ppd, "General", _("General"), cg,
+ encoding)) == NULL)
+ {
+ DEBUG_puts("Unable to get general group!");
+
+ goto error;
+ }
+
+ if (group)
+ group = ppd->groups + groupidx; /* Restore group pointer */
+
+ option = ppd_get_option(gtemp, "PageRegion");
+ }
+
+ if ((choice = ppd_add_choice(option, "Custom")) == NULL)
+ {
+ DEBUG_puts("Unable to add Custom choice!");
+
+ cg->ppd_status = PPD_ALLOC_ERROR;
+
+ goto error;
+ }
+
+ strlcpy(choice->text, text[0] ? text : _("Custom"),
+ sizeof(choice->text));
+ option = NULL;
}
}
else if (!strcmp(keyword, "LandscapeOrientation"))
* Add an option record to the current sub-group, group, or file...
*/
+ printf("name=\"%s\" (%d)\n", name, strlen(name));
+
if (name[0] == '*')
_cups_strcpy(name, name + 1); /* Eliminate leading asterisk */
else if (!strcmp(keyword, "OrderDependency") ||
!strcmp(keyword, "NonUIOrderDependency"))
{
- order = _cupsStrScand(string, &sptr, loc);
+ order = (float)_cupsStrScand(string, &sptr, loc);
if (!sptr || sscanf(sptr, "%40s%40s", name, keyword) != 2)
{
!strcmp(keyword, "NonUIConstraints"))
{
if (ppd->num_consts == 0)
- constraint = calloc(1, sizeof(ppd_const_t));
+ constraint = calloc(2, sizeof(ppd_const_t));
else
constraint = realloc(ppd->consts,
- (ppd->num_consts + 1) * sizeof(ppd_const_t));
+ (ppd->num_consts + 2) * sizeof(ppd_const_t));
if (constraint == NULL)
{
goto error;
case 2 : /* Two options... */
+ /*
+ * Check for broken constraints like "* Option"...
+ */
+
+ if (cg->ppd_conform == PPD_CONFORM_STRICT &&
+ (!strcmp(constraint->option1, "*") ||
+ !strcmp(constraint->choice1, "*")))
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
+
/*
* The following strcpy's are safe, as optionN and
* choiceN are all the same size (size defined by PPD spec...)
if (constraint->option1[0] == '*')
_cups_strcpy(constraint->option1, constraint->option1 + 1);
+ else if (cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
if (constraint->choice1[0] == '*')
_cups_strcpy(constraint->option2, constraint->choice1 + 1);
- else
- _cups_strcpy(constraint->option2, constraint->choice1);
+ else if (cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
constraint->choice1[0] = '\0';
constraint->choice2[0] = '\0';
break;
case 3 : /* Two options, one choice... */
+ /*
+ * Check for broken constraints like "* Option"...
+ */
+
+ if (cg->ppd_conform == PPD_CONFORM_STRICT &&
+ (!strcmp(constraint->option1, "*") ||
+ !strcmp(constraint->choice1, "*") ||
+ !strcmp(constraint->option2, "*")))
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
+
/*
* The following _cups_strcpy's are safe, as optionN and
* choiceN are all the same size (size defined by PPD spec...)
if (constraint->option1[0] == '*')
_cups_strcpy(constraint->option1, constraint->option1 + 1);
+ else if (cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
if (constraint->choice1[0] == '*')
{
+ if (cg->ppd_conform == PPD_CONFORM_STRICT &&
+ constraint->option2[0] == '*')
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
+
_cups_strcpy(constraint->choice2, constraint->option2);
_cups_strcpy(constraint->option2, constraint->choice1 + 1);
constraint->choice1[0] = '\0';
{
if (constraint->option2[0] == '*')
_cups_strcpy(constraint->option2, constraint->option2 + 1);
+ else if (cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
constraint->choice2[0] = '\0';
}
break;
case 4 : /* Two options, two choices... */
+ /*
+ * Check for broken constraints like "* Option"...
+ */
+
+ if (cg->ppd_conform == PPD_CONFORM_STRICT &&
+ (!strcmp(constraint->option1, "*") ||
+ !strcmp(constraint->choice1, "*") ||
+ !strcmp(constraint->option2, "*") ||
+ !strcmp(constraint->choice2, "*")))
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
+
if (constraint->option1[0] == '*')
_cups_strcpy(constraint->option1, constraint->option1 + 1);
+ else if (cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
+
+ if (cg->ppd_conform == PPD_CONFORM_STRICT &&
+ constraint->choice1[0] == '*')
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
if (constraint->option2[0] == '*')
_cups_strcpy(constraint->option2, constraint->option2 + 1);
+ else if (cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
+
+ if (cg->ppd_conform == PPD_CONFORM_STRICT &&
+ constraint->choice2[0] == '*')
+ {
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ goto error;
+ }
break;
}
+ /*
+ * For CustomPageSize and InputSlot/ManualFeed, create a duplicate
+ * constraint for PageRegion...
+ */
+
+ if (!strcasecmp(constraint->option1, "CustomPageSize") &&
+ (!strcasecmp(constraint->option2, "InputSlot") ||
+ !strcasecmp(constraint->option2, "ManualFeed")))
+ {
+ ppd->num_consts ++;
+
+ strcpy(constraint[1].option1, "PageRegion");
+ strcpy(constraint[1].choice1, "Custom");
+ strcpy(constraint[1].option2, constraint->option2);
+ strcpy(constraint[1].choice2, constraint->choice2);
+ }
+ else if (!strcasecmp(constraint->option2, "CustomPageSize") &&
+ (!strcasecmp(constraint->option1, "InputSlot") ||
+ !strcasecmp(constraint->option1, "ManualFeed")))
+ {
+ ppd->num_consts ++;
+
+ strcpy(constraint[1].option1, constraint->option1);
+ strcpy(constraint[1].choice1, constraint->choice1);
+ strcpy(constraint[1].option2, "PageRegion");
+ strcpy(constraint[1].choice2, "Custom");
+ }
+
+ /*
+ * Handle CustomFoo option constraints...
+ */
+
+ if (!strncasecmp(constraint->option1, "Custom", 6) &&
+ !strcasecmp(constraint->choice1, "True"))
+ {
+ _cups_strcpy(constraint->option1, constraint->option1 + 6);
+ strcpy(constraint->choice1, "Custom");
+ }
+
+ if (!strncasecmp(constraint->option2, "Custom", 6) &&
+ !strcasecmp(constraint->choice2, "True"))
+ {
+ _cups_strcpy(constraint->option2, constraint->option2 + 6);
+ strcpy(constraint->choice2, "Custom");
+ }
+
+ /*
+ * Don't add this one as an attribute...
+ */
+
ppd_free(string);
string = NULL;
}
goto error;
}
- size->width = _cupsStrScand(string, &sptr, loc);
- size->length = _cupsStrScand(sptr, NULL, loc);
+ size->width = (float)_cupsStrScand(string, &sptr, loc);
+ size->length = (float)_cupsStrScand(sptr, NULL, loc);
ppd_free(string);
string = NULL;
goto error;
}
- size->left = _cupsStrScand(string, &sptr, loc);
- size->bottom = _cupsStrScand(sptr, &sptr, loc);
- size->right = _cupsStrScand(sptr, &sptr, loc);
- size->top = _cupsStrScand(sptr, NULL, loc);
+ size->left = (float)_cupsStrScand(string, &sptr, loc);
+ size->bottom = (float)_cupsStrScand(sptr, &sptr, loc);
+ size->right = (float)_cupsStrScand(sptr, &sptr, loc);
+ size->top = (float)_cupsStrScand(sptr, NULL, loc);
ppd_free(string);
string = NULL;
cupsLangFree(language);
#ifdef DEBUG
- if (!feof(fp))
- printf("Premature EOF at %lu...\n", (unsigned long)ftell(fp));
+ if (!cupsFileEOF(fp))
+ printf("Premature EOF at %lu...\n", (unsigned long)cupsFileTell(fp));
#endif /* DEBUG */
if (cg->ppd_status != PPD_OK)
* each choice and custom option...
*/
- ppd->options = cupsArrayNew((cups_array_func_t)ppd_compare_options, NULL);
+ ppd->options = cupsArrayNew2((cups_array_func_t)ppd_compare_options, NULL,
+ (cups_ahash_func_t)ppd_hash_option,
+ PPD_HASHSIZE);
for (i = ppd->num_groups, group = ppd->groups;
i > 0;
}
}
+ /*
+ * Sort the constraints...
+ */
+
+ if (ppd->num_consts > 1)
+ qsort(ppd->consts, ppd->num_consts, sizeof(ppd_const_t),
+ (int (*)(const void *, const void *))ppd_compare_consts);
+
+ /*
+ * Create an array to track the marked choices...
+ */
+
+ ppd->marked = cupsArrayNew((cups_array_func_t)ppd_compare_choices, NULL);
+
/*
* Return the PPD file structure...
*/
if ((ret = strcasecmp(a->name, b->name)) != 0)
return (ret);
- else if (a->spec[0] && b->spec[0])
+ else
return (strcasecmp(a->spec, b->spec));
+}
+
+
+/*
+ * 'ppd_compare_choices()' - Compare two choices...
+ */
+
+static int /* O - Result of comparison */
+ppd_compare_choices(ppd_choice_t *a, /* I - First choice */
+ ppd_choice_t *b) /* I - Second choice */
+{
+ return (a->option - b->option);
+}
+
+
+/*
+ * 'ppd_compare_consts()' - Compare two constraints.
+ */
+
+static int /* O - Result of comparison */
+ppd_compare_consts(ppd_const_t *a, /* I - First constraint */
+ ppd_const_t *b) /* I - Second constraint */
+{
+ int ret; /* Result of comparison */
+
+
+ if ((ret = strcmp(a->option1, b->option1)) != 0)
+ return (ret);
+ else if ((ret = strcmp(a->choice1, b->choice1)) != 0)
+ return (ret);
+ else if ((ret = strcmp(a->option2, b->option2)) != 0)
+ return (ret);
else
- return (0);
+ return (strcmp(a->choice2, b->choice2));
}
return (NULL);
strlcpy(cparam->name, param, sizeof(cparam->name));
- strlcpy(cparam->text, text, sizeof(cparam->text));
+ strlcpy(cparam->text, text[0] ? text : param, sizeof(cparam->text));
/*
* Add this record to the array...
}
-/*
- * 'ppd_get_encoding()' - Get the CUPS encoding value for the given
- * LanguageEncoding.
- */
-
-static cups_encoding_t /* O - CUPS encoding value */
-ppd_get_encoding(const char *name) /* I - LanguageEncoding string */
-{
- if (!strcasecmp(name, "ISOLatin1"))
- return (CUPS_ISO8859_1);
- else if (!strcasecmp(name, "ISOLatin2"))
- return (CUPS_ISO8859_2);
- else if (!strcasecmp(name, "ISOLatin5"))
- return (CUPS_ISO8859_5);
- else if (!strcasecmp(name, "JIS83-RKSJ"))
- return (CUPS_WINDOWS_932);
- else if (!strcasecmp(name, "MacStandard"))
- return (CUPS_MAC_ROMAN);
- else if (!strcasecmp(name, "WindowsANSI"))
- return (CUPS_WINDOWS_1252);
- else
- return (CUPS_UTF8);
-}
-
-
/*
* 'ppd_get_group()' - Find or create the named group as needed.
*/
}
+/*
+ * 'ppd_hash_option()' - Generate a hash of the option name...
+ */
+
+static int /* O - Hash index */
+ppd_hash_option(ppd_option_t *option) /* I - Option */
+{
+ int hash = 0; /* Hash index */
+ const char *k; /* Pointer into keyword */
+
+
+ for (hash = option->keyword[0], k = option->keyword + 1; *k;)
+ hash = 33 * hash + *k++;
+
+ return (hash & 511);
+}
+
+
/*
* 'ppd_read()' - Read a line from a PPD file, skipping comment lines as
* necessary.
*lineptr = '\0';
- DEBUG_printf(("LINE = \"%s\"\n", line));
+/* DEBUG_printf(("LINE = \"%s\"\n", line));*/
/*
* The dynamically created PPDs for older style Mac OS X