+#define DEBUG
/*
- * "$Id: ppd.c,v 1.51.2.60 2003/08/20 15:54:39 mike Exp $"
+ * "$Id$"
*
* PPD file routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2003 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-3111 USA
- *
- * Voice: (301) 373-9603
- * 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.
*
*
* Contents:
*
- * _ppd_attr_compare() - Compare two attributes.
- * ppdClose() - Free all memory used by the PPD file.
- * ppdErrorString() - Returns the text assocated with a status.
- * ppdLastError() - Return the status from the last ppdOpen*().
- * ppdOpen() - Read a PPD file into memory.
- * ppdOpenFd() - Read a PPD file into memory.
- * ppdOpenFile() - Read a PPD file into memory.
- * ppdSetConformance() - Set the conformance level for PPD files.
- * ppd_add_attr() - Add an attribute to the PPD data.
- * ppd_add_choice() - Add a choice to an option.
- * ppd_add_size() - Add a page size.
- * ppd_compare_groups() - Compare two groups.
- * ppd_compare_options() - Compare two options.
- * ppd_decode() - Decode a string value...
- * ppd_fix() - Fix WinANSI characters in the range 0x80 to
- * 0x9f to be valid ISO-8859-1 characters...
- * ppd_free_group() - Free a single UI group.
- * ppd_free_option() - Free a single option.
- * ppd_get_extoption() - Get an extended option record.
- * ppd_get_extparam() - Get an extended parameter record.
- * ppd_get_group() - Find or create the named group as needed.
- * ppd_get_option() - Find or create the named option as needed.
- * ppd_read() - Read a line from a PPD file, skipping comment
- * lines as necessary.
+ * 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.
+ * ppdOpenFd() - Read a PPD file into memory.
+ * ppdOpenFile() - Read a PPD file into memory.
+ * ppdSetConformance() - Set the conformance level for PPD files.
+ * ppd_add_attr() - Add an attribute to the PPD data.
+ * 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_decode() - Decode a string value...
+ * ppd_free_group() - Free a single UI group.
+ * 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_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.
*/
/*
* Include necessary headers.
*/
-#include "ppd.h"
-#include <stdlib.h>
-#include <ctype.h>
-#include "string.h"
-#include "language.h"
+#include "globals.h"
#include "debug.h"
+#include <stdlib.h>
/*
#define PPD_TEXT 4 /* Line contained human-readable text */
#define PPD_STRING 8 /* Line contained a string or code */
-
-/*
- * Local globals...
- */
-
-static ppd_status_t ppd_status = PPD_OK;
- /* Status of last ppdOpen*() */
-static int ppd_line = 0; /* Current line number */
-static ppd_conform_t ppd_conform = PPD_CONFORM_RELAXED;
- /* Level of conformance required */
+#define PPD_HASHSIZE 512 /* Size of hash */
/*
const char *value);
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);
-#ifndef __APPLE__
-static int ppd_compare_groups(ppd_group_t *g0, ppd_group_t *g1);
-static int ppd_compare_options(ppd_option_t *o0, ppd_option_t *o1);
-#endif /* !__APPLE__ */
-static void ppd_decode(char *string);
-#ifndef __APPLE__
-static void ppd_fix(char *string);
-#else
-# define ppd_fix(s)
-#endif /* !__APPLE__ */
+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 int ppd_compare_options(ppd_option_t *a, ppd_option_t *b);
+static int ppd_decode(char *string);
static void ppd_free_group(ppd_group_t *group);
static void ppd_free_option(ppd_option_t *option);
-static ppd_ext_option_t *ppd_get_extoption(ppd_file_t *ppd, const char *name);
-static ppd_ext_param_t *ppd_get_extparam(ppd_ext_option_t *opt,
- const char *param,
- const char *text);
+static ppd_coption_t *ppd_get_coption(ppd_file_t *ppd, const char *name);
+static ppd_cparam_t *ppd_get_cparam(ppd_coption_t *opt,
+ const char *param,
+ const char *text);
static ppd_group_t *ppd_get_group(ppd_file_t *ppd, const char *name,
- const char *text);
+ 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_read(FILE *fp, char *keyword, char *option,
- char *text, char **string, int ignoreblank);
-
-
-/*
- * '_ppd_attr_compare()' - Compare two attributes.
- */
-
-int /* O - Result of comparison */
-_ppd_attr_compare(ppd_attr_t **a, /* I - First attribute */
- ppd_attr_t **b) /* I - Second attribute */
-{
- int ret; /* Result of comparison */
-
-
- if ((ret = strcasecmp((*a)->name, (*b)->name)) != 0)
- return (ret);
- else if ((*a)->spec[0] && (*b)->spec[0])
- return (strcasecmp((*a)->spec, (*b)->spec));
- else
- return (0);
-}
+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);
/*
void
ppdClose(ppd_file_t *ppd) /* I - PPD file record */
{
- int i, j; /* Looping var */
+ int i; /* Looping var */
ppd_emul_t *emul; /* Current emulation */
ppd_group_t *group; /* Current group */
char **font; /* Current font */
char **filter; /* Current filter */
ppd_attr_t **attr; /* Current attribute */
- ppd_ext_option_t **opt; /* Current extended option */
- ppd_ext_param_t **param; /* Current extended parameter */
+ ppd_coption_t *coption; /* Current custom option */
+ ppd_cparam_t *cparam; /* Current custom parameter */
/*
- * Range check the PPD file record...
+ * Range check arguments...
*/
- if (ppd == NULL)
+ if (!ppd)
return;
/*
* Free all strings at the top level...
*/
+ ppd_free(ppd->lang_encoding);
+ ppd_free(ppd->nickname);
ppd_free(ppd->patches);
ppd_free(ppd->jcl_begin);
ppd_free(ppd->jcl_end);
ppd_free(ppd->groups);
}
+ cupsArrayDelete(ppd->options);
+ cupsArrayDelete(ppd->marked);
+
/*
* Free any page sizes...
*/
if (ppd->num_sizes > 0)
- {
ppd_free(ppd->sizes);
- }
/*
* Free any constraints...
*/
if (ppd->num_consts > 0)
- {
ppd_free(ppd->consts);
- }
/*
* Free any filters...
*/
if (ppd->num_profiles > 0)
- {
ppd_free(ppd->profiles);
- }
/*
* Free any attributes...
ppd_free(ppd->attrs);
}
- if (ppd->num_extended)
+ cupsArrayDelete(ppd->sorted_attrs);
+
+ /*
+ * Free custom options...
+ */
+
+ for (coption = (ppd_coption_t *)cupsArrayFirst(ppd->coptions);
+ coption;
+ coption = (ppd_coption_t *)cupsArrayNext(ppd->coptions))
{
- for (i = ppd->num_extended, opt = ppd->extended; i > 0; i --, opt ++)
+ for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
+ cparam;
+ cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
{
- ppd_free((*opt)->code);
+ switch (cparam->type)
+ {
+ case PPD_CUSTOM_PASSCODE :
+ case PPD_CUSTOM_PASSWORD :
+ case PPD_CUSTOM_STRING :
+ ppd_free(cparam->current.custom_string);
+ break;
- for (j = (*opt)->num_params, param = (*opt)->params; j > 0; j --, param ++)
- ppd_free((*param)->value);
+ default :
+ break;
+ }
- ppd_free((*opt)->params);
+ free(cparam);
}
- ppd_free(ppd->extended);
+ cupsArrayDelete(coption->params);
+
+ free(coption);
}
+ cupsArrayDelete(ppd->coptions);
+
/*
* Free the whole record...
*/
/*
* 'ppdErrorString()' - Returns the text assocated with a status.
+ *
+ * @since CUPS 1.1.19@
*/
const char * /* O - Status string */
{
static const char * const messages[] =/* Status messages */
{
- "OK",
- "Unable to open PPD file",
- "NULL PPD file pointer",
- "Memory allocation error",
- "Missing PPD-Adobe-4.x header",
- "Missing value string",
- "Internal error",
- "Bad OpenGroup",
- "OpenGroup without a CloseGroup first",
- "Bad OpenUI/JCLOpenUI",
- "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first",
- "Bad OrderDependency",
- "Bad UIConstraints",
- "Missing asterisk in column 1",
- "Line longer than the maximum allowed (255 characters)",
- "Illegal control character",
- "Illegal main keyword string",
- "Illegal option keyword string",
- "Illegal translation string",
- "Illegal whitespace character"
+ _("OK"),
+ _("Unable to open PPD file"),
+ _("NULL PPD file pointer"),
+ _("Memory allocation error"),
+ _("Missing PPD-Adobe-4.x header"),
+ _("Missing value string"),
+ _("Internal error"),
+ _("Bad OpenGroup"),
+ _("OpenGroup without a CloseGroup first"),
+ _("Bad OpenUI/JCLOpenUI"),
+ _("OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first"),
+ _("Bad OrderDependency"),
+ _("Bad UIConstraints"),
+ _("Missing asterisk in column 1"),
+ _("Line longer than the maximum allowed (255 characters)"),
+ _("Illegal control character"),
+ _("Illegal main keyword string"),
+ _("Illegal option keyword string"),
+ _("Illegal translation string"),
+ _("Illegal whitespace character"),
+ _("Bad custom parameter")
};
if (status < PPD_OK || status > PPD_ILLEGAL_WHITESPACE)
- return ("Unknown");
+ return (_cupsLangString(cupsLangDefault(), _("Unknown")));
+ else
+ return (_cupsLangString(cupsLangDefault(), messages[status]));
+}
+
+
+/*
+ * '_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 (messages[status]);
+ return (CUPS_UTF8);
}
/*
* 'ppdLastError()' - Return the status from the last ppdOpen*().
+ *
+ * @since CUPS 1.1.19@
*/
ppd_status_t /* O - Status code */
ppdLastError(int *line) /* O - Line number */
{
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Global data */
+
+
if (line)
- *line = ppd_line;
+ *line = cg->ppd_line;
- return (ppd_status);
+ return (cg->ppd_status);
}
ppd_file_t * /* O - PPD file record */
ppdOpen(FILE *fp) /* I - File to read from */
{
- char *oldlocale; /* Old locale settings */
- int i, j, k, m; /* Looping vars */
+ ppd_file_t *ppd; /* PPD file record */
+ cups_file_t *cf; /* CUPS file */
+
+
+ /*
+ * Reopen the stdio file as a CUPS file...
+ */
+
+ if ((cf = cupsFileOpenFd(fileno(fp), "r")) == NULL)
+ return (NULL);
+
+ /*
+ * Load the PPD file using the newer API...
+ */
+
+ ppd = ppdOpen2(cf);
+
+ /*
+ * Close the CUPS file and return the PPD...
+ */
+
+ cupsFileClose(cf);
+
+ return (ppd);
+}
+
+
+/*
+ * 'ppdOpen2()' - Read a PPD file into memory.
+ *
+ * @since CUPS 1.2@
+ */
+
+ppd_file_t * /* O - PPD file record */
+ppdOpen2(cups_file_t *fp) /* I - File to read from */
+{
+ int i, j, k; /* Looping vars */
int count; /* Temporary count */
ppd_file_t *ppd; /* PPD file record */
ppd_group_t *group, /* Current group */
*subgroup; /* Current sub-group */
ppd_option_t *option; /* Current option */
- ppd_ext_option_t *extopt; /* Current extended option */
ppd_choice_t *choice; /* Current choice */
ppd_const_t *constraint; /* Current constraint */
ppd_size_t *size; /* Current page size */
ppd_profile_t *profile; /* Pointer to color profile */
char **filter; /* Pointer to filter */
cups_lang_t *language; /* Default language */
+ struct lconv *loc; /* Locale data */
int ui_keyword; /* Is this line a UI keyword? */
+ cups_encoding_t encoding; /* Encoding of PPD file */
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Global data */
static const char * const ui_keywords[] =
{
+#ifdef CUPS_USE_FULL_UI_KEYWORDS_LIST
+ /*
+ * Adobe defines some 41 keywords as "UI", meaning that they are
+ * user interface elements and that they should be treated as such
+ * even if the PPD creator doesn't use Open/CloseUI around them.
+ *
+ * Since this can cause previously invisible options to appear and
+ * confuse users, the default is to only treat the PageSize and
+ * PageRegion keywords this way.
+ */
/* Boolean keywords */
"BlackSubstitution",
"Booklet",
"StapleWhen",
"StapleX",
"StapleY"
+#else /* !CUPS_USE_FULL_UI_KEYWORDS_LIST */
+ "PageRegion",
+ "PageSize"
+#endif /* CUPS_USE_FULL_UI_KEYWORDS_LIST */
};
* Default to "OK" status...
*/
- ppd_status = PPD_OK;
- ppd_line = 0;
+ cg->ppd_status = PPD_OK;
+ cg->ppd_line = 0;
/*
* Range check input...
if (fp == NULL)
{
- ppd_status = PPD_NULL_FILE;
+ cg->ppd_status = PPD_NULL_FILE;
return (NULL);
}
* Grab the first line and make sure it reads '*PPD-Adobe: "major.minor"'...
*/
- mask = ppd_read(fp, keyword, name, text, &string, 0);
+ mask = ppd_read(fp, keyword, name, text, &string, 0, cg);
DEBUG_printf(("mask=%x, keyword=\"%s\"...\n", mask, keyword));
if (mask == 0 ||
- strcmp(keyword, "PPD-Adobe") != 0 ||
+ strcmp(keyword, "PPD-Adobe") ||
string == NULL || string[0] != '4')
{
/*
* Either this is not a PPD file, or it is not a 4.x PPD file.
*/
- if (ppd_status == PPD_OK)
- ppd_status = PPD_MISSING_PPDADOBE4;
+ if (cg->ppd_status == PPD_OK)
+ cg->ppd_status = PPD_MISSING_PPDADOBE4;
ppd_free(string);
if ((ppd = calloc(1, sizeof(ppd_file_t))) == NULL)
{
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
return (NULL);
}
ppd->color_device = 0;
ppd->colorspace = PPD_CS_GRAY;
ppd->landscape = -90;
+ ppd->coptions = cupsArrayNew((cups_array_func_t)ppd_compare_coptions,
+ NULL);
/*
* Get the default language for the user...
*/
language = cupsLangDefault();
-
-#ifdef LC_NUMERIC
- oldlocale = _cupsSaveLocale(LC_NUMERIC, "C");
-#else
- oldlocale = _cupsSaveLocale(LC_ALL, "C");
-#endif /* LC_NUMERIC */
+ loc = localeconv();
/*
* Read lines from the PPD file and add them to the file record...
option = NULL;
choice = NULL;
ui_keyword = 0;
+ encoding = CUPS_ISO8859_1;
- while ((mask = ppd_read(fp, keyword, name, text, &string, 1)) != 0)
+ while ((mask = ppd_read(fp, keyword, name, text, &string, 1, cg)) != 0)
{
#ifdef DEBUG
printf("mask = %x, keyword = \"%s\"", mask, keyword);
* Need a string value!
*/
- ppd_status = PPD_MISSING_VALUE;
+ cg->ppd_status = PPD_MISSING_VALUE;
goto error;
}
if (!group)
{
- if (strcmp(keyword, "Collate") && strcmp(keyword, "Duplex") &&
- strcmp(keyword, "InputSlot") && strcmp(keyword, "ManualFeed") &&
- strcmp(keyword, "MediaType") && strcmp(keyword, "MediaColor") &&
- strcmp(keyword, "MediaWeight") && strcmp(keyword, "OutputBin") &&
- strcmp(keyword, "OutputMode") && strcmp(keyword, "OutputOrder") &&
- strcmp(keyword, "PageSize") && strcmp(keyword, "PageRegion"))
- group = ppd_get_group(ppd, "Extra",
- cupsLangString(language, CUPS_MSG_EXTRA));
- else
- group = ppd_get_group(ppd, "General",
- cupsLangString(language, CUPS_MSG_GENERAL));
-
- if (group == NULL)
- {
- ppd_status = PPD_ALLOC_ERROR;
-
+ if ((group = ppd_get_group(ppd, "General", _("General"), cg,
+ encoding)) == NULL)
goto error;
- }
DEBUG_printf(("Adding to group %s...\n", group->text));
option = ppd_get_option(group, keyword);
if (option == NULL)
{
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
break;
}
- if (strcmp(keyword, "PageSize") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SIZE),
- sizeof(option->text));
- else if (strcmp(keyword, "MediaType") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_TYPE),
- sizeof(option->text));
- else if (strcmp(keyword, "InputSlot") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SOURCE),
- sizeof(option->text));
- else if (strcmp(keyword, "ColorModel") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_OUTPUT_MODE),
- sizeof(option->text));
- else if (strcmp(keyword, "Resolution") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_RESOLUTION),
- sizeof(option->text));
+ if (!strcmp(keyword, "PageSize"))
+ strlcpy(option->text, _("Media Size"), sizeof(option->text));
+ else if (!strcmp(keyword, "MediaType"))
+ strlcpy(option->text, _("Media Type"), sizeof(option->text));
+ else if (!strcmp(keyword, "InputSlot"))
+ strlcpy(option->text, _("Media Source"), sizeof(option->text));
+ else if (!strcmp(keyword, "ColorModel"))
+ strlcpy(option->text, _("Output Mode"), sizeof(option->text));
+ else if (!strcmp(keyword, "Resolution"))
+ strlcpy(option->text, _("Resolution"), sizeof(option->text));
else
strlcpy(option->text, keyword, sizeof(option->text));
}
}
- if (strcmp(keyword, "LanguageLevel") == 0)
+ if (!strcmp(keyword, "LanguageLevel"))
ppd->language_level = atoi(string);
- else if (strcmp(keyword, "LanguageEncoding") == 0)
- ppd->lang_encoding = string;
- else if (strcmp(keyword, "LanguageVersion") == 0)
+ else if (!strcmp(keyword, "LanguageEncoding"))
+ {
+ /*
+ * Say all PPD files are UTF-8, since we convert to UTF-8...
+ */
+
+ ppd->lang_encoding = strdup("UTF-8");
+ encoding = _ppdGetEncoding(string);
+ }
+ else if (!strcmp(keyword, "LanguageVersion"))
ppd->lang_version = string;
- else if (strcmp(keyword, "Manufacturer") == 0)
+ else if (!strcmp(keyword, "Manufacturer"))
ppd->manufacturer = string;
- else if (strcmp(keyword, "ModelName") == 0)
+ else if (!strcmp(keyword, "ModelName"))
ppd->modelname = string;
- else if (strcmp(keyword, "Protocols") == 0)
+ else if (!strcmp(keyword, "Protocols"))
ppd->protocols = string;
- else if (strcmp(keyword, "PCFileName") == 0)
+ else if (!strcmp(keyword, "PCFileName"))
ppd->pcfilename = string;
- else if (strcmp(keyword, "NickName") == 0)
- ppd->nickname = string;
- else if (strcmp(keyword, "Product") == 0)
+ else if (!strcmp(keyword, "NickName"))
+ {
+ if (encoding != CUPS_UTF8)
+ {
+ cups_utf8_t utf8[256]; /* UTF-8 version of NickName */
+
+
+ cupsCharsetToUTF8(utf8, string, sizeof(utf8), encoding);
+ ppd->nickname = strdup((char *)utf8);
+ }
+ else
+ ppd->nickname = strdup(string);
+ }
+ else if (!strcmp(keyword, "Product"))
ppd->product = string;
- else if (strcmp(keyword, "ShortNickName") == 0)
+ else if (!strcmp(keyword, "ShortNickName"))
ppd->shortnickname = string;
- else if (strcmp(keyword, "TTRasterizer") == 0)
+ else if (!strcmp(keyword, "TTRasterizer"))
ppd->ttrasterizer = string;
- else if (strcmp(keyword, "JCLBegin") == 0)
+ else if (!strcmp(keyword, "JCLBegin"))
{
ppd->jcl_begin = strdup(string);
ppd_decode(ppd->jcl_begin); /* Decode quoted string */
}
- else if (strcmp(keyword, "JCLEnd") == 0)
+ else if (!strcmp(keyword, "JCLEnd"))
{
ppd->jcl_end = strdup(string);
ppd_decode(ppd->jcl_end); /* Decode quoted string */
}
- else if (strcmp(keyword, "JCLToPSInterpreter") == 0)
+ else if (!strcmp(keyword, "JCLToPSInterpreter"))
{
ppd->jcl_ps = strdup(string);
ppd_decode(ppd->jcl_ps); /* Decode quoted string */
}
- else if (strcmp(keyword, "AccurateScreensSupport") == 0)
- ppd->accurate_screens = strcmp(string, "True") == 0;
- else if (strcmp(keyword, "ColorDevice") == 0)
- ppd->color_device = strcmp(string, "True") == 0;
- else if (strcmp(keyword, "ContoneOnly") == 0)
- ppd->contone_only = strcmp(string, "True") == 0;
- else if (strcmp(keyword, "cupsFlipDuplex") == 0)
- ppd->flip_duplex = strcmp(string, "True") == 0;
- else if (strcmp(keyword, "cupsManualCopies") == 0)
- ppd->manual_copies = strcmp(string, "True") == 0;
- else if (strcmp(keyword, "cupsModelNumber") == 0)
+ else if (!strcmp(keyword, "AccurateScreensSupport"))
+ ppd->accurate_screens = !strcmp(string, "True");
+ else if (!strcmp(keyword, "ColorDevice"))
+ ppd->color_device = !strcmp(string, "True");
+ else if (!strcmp(keyword, "ContoneOnly"))
+ ppd->contone_only = !strcmp(string, "True");
+ else if (!strcmp(keyword, "cupsFlipDuplex"))
+ ppd->flip_duplex = !strcmp(string, "True");
+ else if (!strcmp(keyword, "cupsManualCopies"))
+ ppd->manual_copies = !strcmp(string, "True");
+ else if (!strcmp(keyword, "cupsModelNumber"))
ppd->model_number = atoi(string);
- else if (strcmp(keyword, "cupsColorProfile") == 0)
+ else if (!strcmp(keyword, "cupsColorProfile"))
{
if (ppd->num_profiles == 0)
profile = malloc(sizeof(ppd_profile_t));
memset(profile, 0, sizeof(ppd_profile_t));
strlcpy(profile->resolution, name, sizeof(profile->resolution));
strlcpy(profile->media_type, text, sizeof(profile->media_type));
- sscanf(string, "%f%f%f%f%f%f%f%f%f%f%f", &(profile->density),
- &(profile->gamma),
- profile->matrix[0] + 0, profile->matrix[0] + 1,
- profile->matrix[0] + 2, profile->matrix[1] + 0,
- profile->matrix[1] + 1, profile->matrix[1] + 2,
- profile->matrix[2] + 0, profile->matrix[2] + 1,
- profile->matrix[2] + 2);
+
+ 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") == 0)
+ else if (!strcmp(keyword, "cupsFilter"))
{
if (ppd->num_filters == 0)
filter = malloc(sizeof(char *));
{
ppd_free(filter);
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
*filter = string;
string = NULL;
}
- else if (strcmp(keyword, "Throughput") == 0)
+ else if (!strcmp(keyword, "Throughput"))
ppd->throughput = atoi(string);
- else if (strcmp(keyword, "Font") == 0)
+ else if (!strcmp(keyword, "Font"))
{
/*
* Add this font to the list of available fonts...
if (tempfonts == NULL)
{
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
ppd->fonts[ppd->num_fonts] = strdup(name);
ppd->num_fonts ++;
}
- else if (strcmp(keyword, "ParamCustomPageSize") == 0)
- {
- if (strcmp(name, "Width") == 0)
- sscanf(string, "%*s%*s%f%f", ppd->custom_min + 0,
- ppd->custom_max + 0);
- else if (strcmp(name, "Height") == 0)
- sscanf(string, "%*s%*s%f%f", ppd->custom_min + 1,
- ppd->custom_max + 1);
- }
- else if (strcmp(keyword, "HWMargins") == 0)
- sscanf(string, "%f%f%f%f", ppd->custom_margins + 0,
- ppd->custom_margins + 1, ppd->custom_margins + 2,
- ppd->custom_margins + 3);
- else if (strcmp(keyword, "CustomPageSize") == 0 &&
- strcmp(name, "True") == 0)
+ else if (!strncmp(keyword, "ParamCustom", 11))
{
- DEBUG_puts("Processing CustomPageSize...");
+ ppd_coption_t *coption; /* Custom option */
+ ppd_cparam_t *cparam; /* Custom parameter */
+ int corder; /* Order number */
+ char ctype[33], /* Data type */
+ cminimum[65], /* Minimum value */
+ cmaximum[65]; /* Maximum value */
+
+
+ /*
+ * Get the custom option and parameter...
+ */
- if (!ppd->variable_sizes)
+ if ((coption = ppd_get_coption(ppd, keyword + 11)) == NULL)
{
- ppd->variable_sizes = 1;
+ cg->ppd_status = PPD_ALLOC_ERROR;
- /*
- * Add a "Custom" page size entry...
- */
+ goto error;
+ }
- ppd_add_size(ppd, "Custom");
+ if ((cparam = ppd_get_cparam(coption, name, text)) == NULL)
+ {
+ cg->ppd_status = PPD_ALLOC_ERROR;
- /*
- * Add a "Custom" page size option...
- */
+ goto error;
+ }
+
+ /*
+ * Get the parameter data...
+ */
+
+ if (sscanf(string, "%d%32s%64s%64s", &corder, ctype, cminimum,
+ cmaximum) != 4)
+ {
+ cg->ppd_status = PPD_BAD_CUSTOM_PARAM;
+
+ goto error;
+ }
+
+ cparam->order = corder;
+
+ if (!strcmp(ctype, "curve"))
+ {
+ cparam->type = PPD_CUSTOM_CURVE;
+ cparam->minimum.custom_curve = (float)_cupsStrScand(cminimum, NULL, loc);
+ cparam->maximum.custom_curve = (float)_cupsStrScand(cmaximum, NULL, loc);
+ }
+ else if (!strcmp(ctype, "int"))
+ {
+ cparam->type = PPD_CUSTOM_INT;
+ cparam->minimum.custom_int = atoi(cminimum);
+ cparam->maximum.custom_int = atoi(cmaximum);
+ }
+ else if (!strcmp(ctype, "invcurve"))
+ {
+ cparam->type = PPD_CUSTOM_INVCURVE;
+ cparam->minimum.custom_invcurve = (float)_cupsStrScand(cminimum, NULL, loc);
+ cparam->maximum.custom_invcurve = (float)_cupsStrScand(cmaximum, NULL, loc);
+ }
+ else if (!strcmp(ctype, "passcode"))
+ {
+ cparam->type = PPD_CUSTOM_PASSCODE;
+ cparam->minimum.custom_passcode = atoi(cminimum);
+ cparam->maximum.custom_passcode = atoi(cmaximum);
+ }
+ else if (!strcmp(ctype, "password"))
+ {
+ cparam->type = PPD_CUSTOM_PASSWORD;
+ cparam->minimum.custom_password = atoi(cminimum);
+ cparam->maximum.custom_password = atoi(cmaximum);
+ }
+ else if (!strcmp(ctype, "points"))
+ {
+ cparam->type = PPD_CUSTOM_POINTS;
+ 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 = (float)_cupsStrScand(cminimum, NULL, loc);
+ cparam->maximum.custom_real = (float)_cupsStrScand(cmaximum, NULL, loc);
+ }
+ else if (!strcmp(ctype, "string"))
+ {
+ cparam->type = PPD_CUSTOM_STRING;
+ cparam->minimum.custom_string = atoi(cminimum);
+ cparam->maximum.custom_string = atoi(cmaximum);
+ }
+ else
+ {
+ cg->ppd_status = PPD_BAD_CUSTOM_PARAM;
+
+ goto error;
+ }
- if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
+ /*
+ * Now special-case for CustomPageSize...
+ */
+
+ if (!strcmp(coption->keyword, "PageSize"))
+ {
+ if (!strcmp(name, "Width"))
{
- ppd_group_t *temp;
+ ppd->custom_min[0] = cparam->minimum.custom_points;
+ ppd->custom_max[0] = cparam->maximum.custom_points;
+ }
+ else if (!strcmp(name, "Height"))
+ {
+ ppd->custom_min[1] = cparam->minimum.custom_points;
+ ppd->custom_max[1] = cparam->maximum.custom_points;
+ }
+ }
+ }
+ else if (!strcmp(keyword, "HWMargins"))
+ {
+ for (i = 0, sptr = string; i < 4; i ++)
+ ppd->custom_margins[i] = (float)_cupsStrScand(sptr, &sptr, loc);
+ }
+ else if (!strncmp(keyword, "Custom", 6) && !strcmp(name, "True") && !option)
+ {
+ DEBUG_puts("Processing Custom option...");
+ /*
+ * Get the option and custom option...
+ */
- DEBUG_puts("PageSize option not found for CustomPageSize...");
+ if ((option = ppdFindOption(ppd, keyword + 6)) == NULL)
+ {
+ int groupidx = -1; /* Index for current group */
+ ppd_group_t *gtemp; /* Temporary group */
- if ((temp = ppd_get_group(ppd, "General",
- cupsLangString(language,
- CUPS_MSG_GENERAL))) == NULL)
- {
- DEBUG_puts("Unable to get general group!");
- ppd_status = PPD_ALLOC_ERROR;
+ DEBUG_printf(("%s option not found for %s...\n", keyword + 6, keyword));
- goto error;
- }
+ if (group)
+ groupidx = group - ppd->groups; /* Save index for current group */
- if ((option = ppd_get_option(temp, "PageSize")) == NULL)
- {
- DEBUG_puts("Unable to get PageSize option!");
+ if ((gtemp = ppd_get_group(ppd, "General", _("General"), cg,
+ encoding)) == NULL)
+ {
+ DEBUG_puts("Unable to get general group!");
- ppd_status = PPD_ALLOC_ERROR;
+ goto error;
+ }
- goto error;
- }
- }
+ if (group)
+ group = ppd->groups + groupidx; /* Restore group pointer */
- if ((choice = ppd_add_choice(option, "Custom")) == NULL)
+ if ((option = ppd_get_option(gtemp, keyword + 6)) == NULL)
{
- DEBUG_puts("Unable to add Custom choice!");
+ DEBUG_printf(("Unable to get %s option!\n", keyword + 6));
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
-
- strlcpy(choice->text, cupsLangString(language, CUPS_MSG_VARIABLE),
- sizeof(choice->text));
- option = NULL;
}
- if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
+ if (!ppd_get_coption(ppd, keyword + 6))
{
- DEBUG_puts("Unable to find PageSize option!");
-
- ppd_status = PPD_INTERNAL_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
- if ((choice = ppdFindChoice(option, "Custom")) == NULL)
+ /*
+ * Add the "custom" option...
+ */
+
+ if ((choice = ppd_add_choice(option, "Custom")) == NULL)
{
- DEBUG_puts("Unable to find Custom choice!");
+ DEBUG_puts("Unable to add Custom choice!");
- ppd_status = PPD_INTERNAL_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
+ strlcpy(choice->text, text[0] ? text : _("Custom"),
+ sizeof(choice->text));
+
choice->code = string;
- option = NULL;
string = NULL; /* Don't add as an attribute below */
+ option = NULL;
+
+ /*
+ * Now process custom page sizes specially...
+ */
+
+ if (!strcmp(keyword, "CustomPageSize"))
+ {
+ ppd->variable_sizes = 1;
+
+ /*
+ * Add a "Custom" page size entry...
+ */
+
+ 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") == 0)
+ else if (!strcmp(keyword, "LandscapeOrientation"))
{
- if (strcmp(string, "Minus90") == 0)
+ if (!strcmp(string, "Minus90"))
ppd->landscape = -90;
- else if (strcmp(string, "Plus90") == 0)
+ else if (!strcmp(string, "Plus90"))
ppd->landscape = 90;
}
- else if (strcmp(keyword, "Emulators") == 0)
+ else if (!strcmp(keyword, "Emulators"))
{
for (count = 1, sptr = string; sptr != NULL;)
if ((sptr = strchr(sptr, ' ')) != NULL)
sptr ++;
}
}
- else if (strncmp(keyword, "StartEmulator_", 14) == 0)
+ else if (!strncmp(keyword, "StartEmulator_", 14))
{
ppd_decode(string);
for (i = 0; i < ppd->num_emulations; i ++)
- if (strcmp(keyword + 14, ppd->emulations[i].name) == 0)
+ if (!strcmp(keyword + 14, ppd->emulations[i].name))
{
ppd->emulations[i].start = string;
string = NULL;
}
}
- else if (strncmp(keyword, "StopEmulator_", 13) == 0)
+ else if (!strncmp(keyword, "StopEmulator_", 13))
{
ppd_decode(string);
for (i = 0; i < ppd->num_emulations; i ++)
- if (strcmp(keyword + 13, ppd->emulations[i].name) == 0)
+ if (!strcmp(keyword + 13, ppd->emulations[i].name))
{
ppd->emulations[i].stop = string;
string = NULL;
}
}
- else if (strcmp(keyword, "JobPatchFile") == 0)
+ else if (!strcmp(keyword, "JobPatchFile"))
{
if (ppd->patches == NULL)
ppd->patches = strdup(string);
strlen(string) + 1);
if (temp == NULL)
{
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
strcpy(ppd->patches + strlen(ppd->patches), string);
}
}
- else if (strcmp(keyword, "OpenUI") == 0)
+ else if (!strcmp(keyword, "OpenUI"))
{
/*
* Don't allow nesting of options...
*/
- if (option && ppd_conform == PPD_CONFORM_STRICT)
+ if (option && cg->ppd_conform == PPD_CONFORM_STRICT)
{
- ppd_status = PPD_NESTED_OPEN_UI;
+ cg->ppd_status = PPD_NESTED_OPEN_UI;
goto error;
}
* 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 */
+ _cups_strcpy(name, name + 1); /* Eliminate leading asterisk */
- for (i = strlen(name) - 1; i > 0 && isspace(name[i]); i --)
+ for (i = (int)strlen(name) - 1; i > 0 && isspace(name[i] & 255); i --)
name[i] = '\0'; /* Eliminate trailing spaces */
DEBUG_printf(("OpenUI of %s in group %s...\n", name,
option = ppd_get_option(subgroup, name);
else if (group == NULL)
{
- if (strcmp(name, "Collate") && strcmp(name, "Duplex") &&
- strcmp(name, "InputSlot") && strcmp(name, "ManualFeed") &&
- strcmp(name, "MediaType") && strcmp(name, "MediaColor") &&
- strcmp(name, "MediaWeight") && strcmp(name, "OutputBin") &&
- strcmp(name, "OutputMode") && strcmp(name, "OutputOrder") &&
- strcmp(name, "PageSize") && strcmp(name, "PageRegion"))
- group = ppd_get_group(ppd, "Extra",
- cupsLangString(language, CUPS_MSG_EXTRA));
- else
- group = ppd_get_group(ppd, "General",
- cupsLangString(language, CUPS_MSG_GENERAL));
-
- if (group == NULL)
- {
- ppd_status = PPD_ALLOC_ERROR;
-
+ if ((group = ppd_get_group(ppd, "General", _("General"), cg,
+ encoding)) == NULL)
goto error;
- }
DEBUG_printf(("Adding to group %s...\n", group->text));
option = ppd_get_option(group, name);
if (option == NULL)
{
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
* Now fill in the initial information for the option...
*/
- if (string && strcmp(string, "PickMany") == 0)
+ if (string && !strcmp(string, "PickMany"))
option->ui = PPD_UI_PICKMANY;
- else if (string && strcmp(string, "Boolean") == 0)
+ else if (string && !strcmp(string, "Boolean"))
option->ui = PPD_UI_BOOLEAN;
- else if (string && strcmp(string, "PickOne") == 0)
+ else if (string && !strcmp(string, "PickOne"))
option->ui = PPD_UI_PICKONE;
- else if (ppd_conform == PPD_CONFORM_STRICT)
+ else if (cg->ppd_conform == PPD_CONFORM_STRICT)
{
- ppd_status = PPD_BAD_OPEN_UI;
+ cg->ppd_status = PPD_BAD_OPEN_UI;
goto error;
}
}
if (text[0])
- {
- strlcpy(option->text, text, sizeof(option->text));
- ppd_fix(option->text);
- }
+ cupsCharsetToUTF8((cups_utf8_t *)option->text, text,
+ sizeof(option->text), encoding);
else
{
- if (strcmp(name, "PageSize") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SIZE),
- sizeof(option->text));
- else if (strcmp(name, "MediaType") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_TYPE),
- sizeof(option->text));
- else if (strcmp(name, "InputSlot") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SOURCE),
- sizeof(option->text));
- else if (strcmp(name, "ColorModel") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_OUTPUT_MODE),
- sizeof(option->text));
- else if (strcmp(name, "Resolution") == 0)
- strlcpy(option->text, cupsLangString(language, CUPS_MSG_RESOLUTION),
- sizeof(option->text));
+ if (!strcmp(name, "PageSize"))
+ strlcpy(option->text, _("Media Size"), sizeof(option->text));
+ else if (!strcmp(name, "MediaType"))
+ strlcpy(option->text, _("Media Type"), sizeof(option->text));
+ else if (!strcmp(name, "InputSlot"))
+ strlcpy(option->text, _("Media Source"), sizeof(option->text));
+ else if (!strcmp(name, "ColorModel"))
+ strlcpy(option->text, _("Output Mode"), sizeof(option->text));
+ else if (!strcmp(name, "Resolution"))
+ strlcpy(option->text, _("Resolution"), sizeof(option->text));
else
strlcpy(option->text, name, sizeof(option->text));
}
ppd_free(string);
string = NULL;
}
- else if (strcmp(keyword, "JCLOpenUI") == 0)
+ else if (!strcmp(keyword, "JCLOpenUI"))
{
/*
* Don't allow nesting of options...
*/
- if (option && ppd_conform == PPD_CONFORM_STRICT)
+ if (option && cg->ppd_conform == PPD_CONFORM_STRICT)
{
- ppd_status = PPD_NESTED_OPEN_UI;
+ cg->ppd_status = PPD_NESTED_OPEN_UI;
goto error;
}
* Find the JCL group, and add if needed...
*/
- group = ppd_get_group(ppd, "JCL", "JCL");
+ group = ppd_get_group(ppd, "JCL", _("JCL"), cg, encoding);
if (group == NULL)
- {
- ppd_status = PPD_ALLOC_ERROR;
-
goto error;
- }
/*
* Add an option record to the current JCLs...
*/
if (name[0] == '*')
- cups_strcpy(name, name + 1);
+ _cups_strcpy(name, name + 1);
option = ppd_get_option(group, name);
if (option == NULL)
{
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
* Now fill in the initial information for the option...
*/
- if (string && strcmp(string, "PickMany") == 0)
+ if (string && !strcmp(string, "PickMany"))
option->ui = PPD_UI_PICKMANY;
- else if (string && strcmp(string, "Boolean") == 0)
+ else if (string && !strcmp(string, "Boolean"))
option->ui = PPD_UI_BOOLEAN;
- else if (string && strcmp(string, "PickOne") == 0)
+ else if (string && !strcmp(string, "PickOne"))
option->ui = PPD_UI_PICKONE;
else
{
- ppd_status = PPD_BAD_OPEN_UI;
+ cg->ppd_status = PPD_BAD_OPEN_UI;
goto error;
}
break;
}
- strlcpy(option->text, text, sizeof(option->text));
+ if (text[0])
+ cupsCharsetToUTF8((cups_utf8_t *)option->text, text,
+ sizeof(option->text), encoding);
+ else
+ strlcpy(option->text, name, sizeof(option->text));
option->section = PPD_ORDER_JCL;
group = NULL;
ppd_free(string);
string = NULL;
}
- else if (strcmp(keyword, "CloseUI") == 0 ||
- strcmp(keyword, "JCLCloseUI") == 0)
+ else if (!strcmp(keyword, "CloseUI") || !strcmp(keyword, "JCLCloseUI"))
{
option = NULL;
ppd_free(string);
string = NULL;
}
- else if (strcmp(keyword, "OpenGroup") == 0)
+ else if (!strcmp(keyword, "OpenGroup"))
{
/*
* Open a new group...
if (group != NULL)
{
- ppd_status = PPD_NESTED_OPEN_GROUP;
+ cg->ppd_status = PPD_NESTED_OPEN_GROUP;
goto error;
}
if (!string)
{
- ppd_status = PPD_BAD_OPEN_GROUP;
+ cg->ppd_status = PPD_BAD_OPEN_GROUP;
goto error;
}
*/
ppd_decode(sptr);
- ppd_fix(sptr);
/*
* Find/add the group...
*/
- group = ppd_get_group(ppd, string, sptr);
+ group = ppd_get_group(ppd, string, sptr, cg, encoding);
+
+ if (group == NULL)
+ goto error;
ppd_free(string);
string = NULL;
}
- else if (strcmp(keyword, "CloseGroup") == 0)
+ else if (!strcmp(keyword, "CloseGroup"))
{
group = NULL;
ppd_free(string);
string = NULL;
}
- else if (strcmp(keyword, "OrderDependency") == 0 ||
- strcmp(keyword, "NonUIOrderDependency") == 0)
+ else if (!strcmp(keyword, "OrderDependency") ||
+ !strcmp(keyword, "NonUIOrderDependency"))
{
- if (sscanf(string, "%f%40s%40s", &order, name, keyword) != 3)
+ order = (float)_cupsStrScand(string, &sptr, loc);
+
+ if (!sptr || sscanf(sptr, "%40s%40s", name, keyword) != 2)
{
- ppd_status = PPD_BAD_ORDER_DEPENDENCY;
+ cg->ppd_status = PPD_BAD_ORDER_DEPENDENCY;
goto error;
}
if (keyword[0] == '*')
- cups_strcpy(keyword, keyword + 1);
+ _cups_strcpy(keyword, keyword + 1);
- if (strcmp(name, "ExitServer") == 0)
+ if (!strcmp(name, "ExitServer"))
section = PPD_ORDER_EXIT;
- else if (strcmp(name, "Prolog") == 0)
+ else if (!strcmp(name, "Prolog"))
section = PPD_ORDER_PROLOG;
- else if (strcmp(name, "DocumentSetup") == 0)
+ else if (!strcmp(name, "DocumentSetup"))
section = PPD_ORDER_DOCUMENT;
- else if (strcmp(name, "PageSetup") == 0)
+ else if (!strcmp(name, "PageSetup"))
section = PPD_ORDER_PAGE;
- else if (strcmp(name, "JCLSetup") == 0)
+ else if (!strcmp(name, "JCLSetup"))
section = PPD_ORDER_JCL;
else
section = PPD_ORDER_ANY;
if (option == NULL)
{
- ppd_group_t *temp;
+ ppd_group_t *gtemp;
/*
* Only valid for Non-UI options...
*/
- for (i = ppd->num_groups, temp = ppd->groups; i > 0; i --, temp ++)
- if (temp->text[0] == '\0')
+ for (i = ppd->num_groups, gtemp = ppd->groups; i > 0; i --, gtemp ++)
+ if (gtemp->text[0] == '\0')
break;
if (i > 0)
- for (i = 0; i < temp->num_options; i ++)
- if (strcmp(keyword, temp->options[i].keyword) == 0)
+ for (i = 0; i < gtemp->num_options; i ++)
+ if (!strcmp(keyword, gtemp->options[i].keyword))
{
- temp->options[i].section = section;
- temp->options[i].order = order;
+ gtemp->options[i].section = section;
+ gtemp->options[i].order = order;
break;
}
}
ppd_free(string);
string = NULL;
}
- else if (strncmp(keyword, "Default", 7) == 0)
+ else if (!strncmp(keyword, "Default", 7))
{
if (string == NULL)
continue;
* Assign the default value as appropriate...
*/
- if (strcmp(keyword, "DefaultColorSpace") == 0)
+ if (!strcmp(keyword, "DefaultColorSpace"))
{
/*
* Set default colorspace...
*/
- if (strcmp(string, "CMY") == 0)
+ if (!strcmp(string, "CMY"))
ppd->colorspace = PPD_CS_CMY;
- else if (strcmp(string, "CMYK") == 0)
+ else if (!strcmp(string, "CMYK"))
ppd->colorspace = PPD_CS_CMYK;
- else if (strcmp(string, "RGB") == 0)
+ else if (!strcmp(string, "RGB"))
ppd->colorspace = PPD_CS_RGB;
- else if (strcmp(string, "RGBK") == 0)
+ else if (!strcmp(string, "RGBK"))
ppd->colorspace = PPD_CS_RGBK;
- else if (strcmp(string, "N") == 0)
+ else if (!strcmp(string, "N"))
ppd->colorspace = PPD_CS_N;
else
ppd->colorspace = PPD_CS_GRAY;
}
- else if (option && strcmp(keyword + 7, option->keyword) == 0)
+ else if (option && !strcmp(keyword + 7, option->keyword))
{
/*
* Set the default as part of the current option...
}
}
}
- else if (strcmp(keyword, "UIConstraints") == 0 ||
- strcmp(keyword, "NonUIConstraints") == 0)
+ else if (!strcmp(keyword, "UIConstraints") ||
+ !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)
{
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
{
case 0 : /* Error */
case 1 : /* Error */
- ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ cg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
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);
+ _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);
+ _cups_strcpy(constraint->option2, constraint->choice1 + 1);
+ 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';
case 3 : /* Two options, one choice... */
/*
- * The following cups_strcpy's are safe, as optionN and
+ * 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);
+ _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->choice2, constraint->option2);
- cups_strcpy(constraint->option2, constraint->choice1 + 1);
+ 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';
}
else
{
if (constraint->option2[0] == '*')
- cups_strcpy(constraint->option2, constraint->option2 + 1);
+ _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... */
- if (constraint->option1[0] == '*')
- cups_strcpy(constraint->option1, constraint->option1 + 1);
+ /*
+ * 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);
+ _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;
}
- else if (strcmp(keyword, "PaperDimension") == 0)
+ else if (!strcmp(keyword, "PaperDimension"))
{
if ((size = ppdPageSize(ppd, name)) == NULL)
size = ppd_add_size(ppd, name);
* Unable to add or find size!
*/
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
- sscanf(string, "%f%f", &(size->width), &(size->length));
+ size->width = (float)_cupsStrScand(string, &sptr, loc);
+ size->length = (float)_cupsStrScand(sptr, NULL, loc);
ppd_free(string);
string = NULL;
}
- else if (strcmp(keyword, "ImageableArea") == 0)
+ else if (!strcmp(keyword, "ImageableArea"))
{
if ((size = ppdPageSize(ppd, name)) == NULL)
size = ppd_add_size(ppd, name);
* Unable to add or find size!
*/
- ppd_status = PPD_ALLOC_ERROR;
+ cg->ppd_status = PPD_ALLOC_ERROR;
goto error;
}
- sscanf(string, "%f%f%f%f", &(size->left), &(size->bottom),
- &(size->right), &(size->top));
+ 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;
else if (option != NULL &&
(mask & (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) ==
(PPD_KEYWORD | PPD_OPTION | PPD_STRING) &&
- strcmp(keyword, option->keyword) == 0)
+ !strcmp(keyword, option->keyword))
{
DEBUG_printf(("group = %p, subgroup = %p\n", group, subgroup));
- if (strcmp(keyword, "PageSize") == 0)
+ if (!strcmp(keyword, "PageSize"))
{
/*
* Add a page size...
choice = ppd_add_choice(option, name);
- if (mask & PPD_TEXT)
- {
- strlcpy(choice->text, text, sizeof(choice->text));
- ppd_fix(choice->text);
- }
- else if (strcmp(name, "True") == 0)
- strcpy(choice->text, "Yes");
- else if (strcmp(name, "False") == 0)
- strcpy(choice->text, "No");
+ if (text[0])
+ cupsCharsetToUTF8((cups_utf8_t *)choice->text, text,
+ sizeof(choice->text), encoding);
+ else if (!strcmp(name, "True"))
+ strcpy(choice->text, _("Yes"));
+ else if (!strcmp(name, "False"))
+ strcpy(choice->text, _("No"));
else
strlcpy(choice->text, name, sizeof(choice->text));
choice->code = string;
string = NULL; /* Don't add as an attribute below */
}
-#if 0
- else if (strcmp(keyword, "cupsUIType") == 0 &&
- (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING) &&
- option != NULL)
- {
- /*
- * Define an extended option value type...
- */
-
- extopt = ppd_get_extoption(ppd, name);
-
- if (strcmp(string, "Text") == 0)
- option->ui = PPD_UI_CUPS_TEXT;
- else if (strcmp(string, "Integer") == 0)
- {
- option->ui = PPD_UI_CUPS_INTEGER;
- extopt->defval.integer = 0;
- extopt->minval.integer = 0;
- extopt->maxval.integer = 100;
- }
- else if (strcmp(string, "Real") == 0)
- {
- option->ui = PPD_UI_CUPS_REAL;
- extopt->defval.real = 0.0;
- extopt->minval.real = 0.0;
- extopt->maxval.real = 1.0;
- }
- else if (strcmp(string, "Gamma") == 0)
- {
- option->ui = PPD_UI_CUPS_GAMMA;
- extopt->defval.gamma = 1.0;
- extopt->minval.gamma = 1.0;
- extopt->maxval.gamma = 10.0;
- }
- else if (strcmp(string, "Curve") == 0)
- {
- option->ui = PPD_UI_CUPS_CURVE;
- extopt->defval.curve.start = 0.0;
- extopt->defval.curve.end = 0.0;
- extopt->defval.curve.gamma = 1.0;
- extopt->minval.curve.start = 0.0;
- extopt->minval.curve.end = 0.0;
- extopt->minval.curve.gamma = 1.0;
- extopt->maxval.curve.start = 1.0;
- extopt->maxval.curve.end = 1.0;
- extopt->maxval.curve.gamma = 10.0;
- }
- else if (strcmp(string, "IntegerArray") == 0)
- {
- option->ui = PPD_UI_CUPS_INTEGER_ARRAY;
- extopt->defval.integer_array.num_elements = 2;
- extopt->minval.integer_array.num_elements = 2;
- extopt->maxval.integer_array.num_elements = 16;
- }
- else if (strcmp(string, "RealArray") == 0)
- {
- option->ui = PPD_UI_CUPS_REAL_ARRAY;
- extopt->defval.real_array.num_elements = 2;
- extopt->minval.real_array.num_elements = 2;
- extopt->maxval.real_array.num_elements = 16;
- }
- }
- else if (strcmp(keyword, "cupsUIDefault") == 0 &&
- (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING) &&
- option != NULL)
- {
- /*
- * Define an extended option minimum value...
- */
-
- extopt = ppd_get_extoption(ppd, name);
-
- switch (option->ui)
- {
- case PPD_UI_CUPS_INTEGER :
- sscanf(string, "%d", &(extopt->defval.integer));
- break;
-
- case PPD_UI_CUPS_REAL :
- sscanf(string, "%f", &(extopt->defval.real));
- break;
-
- case PPD_UI_CUPS_GAMMA :
- sscanf(string, "%f", &(extopt->defval.gamma));
- break;
-
- case PPD_UI_CUPS_CURVE :
- sscanf(string, "%f%f%f", &(extopt->defval.curve.start),
- &(extopt->defval.curve.end),
- &(extopt->defval.curve.gamma));
- break;
-
- case PPD_UI_CUPS_INTEGER_ARRAY :
- extopt->defval.integer_array.elements = calloc(1, sizeof(int));
- sscanf(string, "%d%d", &(extopt->defval.integer_array.num_elements),
- extopt->defval.integer_array.elements);
- break;
-
- case PPD_UI_CUPS_REAL_ARRAY :
- extopt->defval.real_array.elements = calloc(1, sizeof(float));
- sscanf(string, "%d%f", &(extopt->defval.real_array.num_elements),
- extopt->defval.real_array.elements);
- break;
-
- default :
- break;
- }
- }
- else if (strcmp(keyword, "cupsUIMinimum") == 0 &&
- (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING) &&
- option != NULL)
- {
- /*
- * Define an extended option minimum value...
- */
-
- extopt = ppd_get_extoption(ppd, name);
-
- switch (option->ui)
- {
- case PPD_UI_CUPS_INTEGER :
- sscanf(string, "%d", &(extopt->minval.integer));
- break;
-
- case PPD_UI_CUPS_REAL :
- sscanf(string, "%f", &(extopt->minval.real));
- break;
-
- case PPD_UI_CUPS_GAMMA :
- sscanf(string, "%f", &(extopt->minval.gamma));
- break;
-
- case PPD_UI_CUPS_CURVE :
- sscanf(string, "%f%f%f", &(extopt->minval.curve.start),
- &(extopt->minval.curve.end),
- &(extopt->minval.curve.gamma));
- break;
-
- case PPD_UI_CUPS_INTEGER_ARRAY :
- extopt->minval.integer_array.elements = calloc(1, sizeof(int));
- sscanf(string, "%d%d", &(extopt->minval.integer_array.num_elements),
- extopt->minval.integer_array.elements);
- break;
-
- case PPD_UI_CUPS_REAL_ARRAY :
- extopt->minval.real_array.elements = calloc(1, sizeof(float));
- sscanf(string, "%d%f", &(extopt->minval.real_array.num_elements),
- extopt->minval.real_array.elements);
- break;
-
- default :
- break;
- }
- }
- else if (strcmp(keyword, "cupsUIMaximum") == 0 &&
- (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING) &&
- option != NULL)
- {
- /*
- * Define an extended option maximum value...
- */
-
- extopt = ppd_get_extoption(ppd, name);
-
- switch (option->ui)
- {
- case PPD_UI_CUPS_INTEGER :
- sscanf(string, "%d", &(extopt->maxval.integer));
- break;
-
- case PPD_UI_CUPS_REAL :
- sscanf(string, "%f", &(extopt->maxval.real));
- break;
-
- case PPD_UI_CUPS_GAMMA :
- sscanf(string, "%f", &(extopt->maxval.gamma));
- break;
-
- case PPD_UI_CUPS_CURVE :
- sscanf(string, "%f%f%f", &(extopt->maxval.curve.start),
- &(extopt->maxval.curve.end),
- &(extopt->maxval.curve.gamma));
- break;
-
- case PPD_UI_CUPS_INTEGER_ARRAY :
- extopt->maxval.integer_array.elements = calloc(1, sizeof(int));
- sscanf(string, "%d%d", &(extopt->maxval.integer_array.num_elements),
- extopt->maxval.integer_array.elements);
- break;
-
- case PPD_UI_CUPS_REAL_ARRAY :
- extopt->maxval.real_array.elements = calloc(1, sizeof(float));
- sscanf(string, "%d%f", &(extopt->maxval.real_array.num_elements),
- extopt->maxval.real_array.elements);
- break;
-
- default :
- break;
- }
- }
- else if (strcmp(keyword, "cupsUICommand") == 0 &&
- (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING) &&
- option != NULL)
- {
- /*
- * Define an extended option command...
- */
-
- extopt = ppd_get_extoption(ppd, name);
-
- extopt->command = string;
- string = NULL;
- }
-#endif /* 0 */
/*
* Add remaining lines with keywords and string values as attributes...
(mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING))
ppd_add_attr(ppd, keyword, name, text, string);
else
- {
ppd_free(string);
- }
}
/*
cupsLangFree(language);
-#ifdef LC_NUMERIC
- _cupsRestoreLocale(LC_NUMERIC, oldlocale);
-#else
- _cupsRestoreLocale(LC_ALL, oldlocale);
-#endif /* LC_NUMERIC */
-
#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 (ppd_status != PPD_OK)
+ if (cg->ppd_status != PPD_OK)
{
/*
* Had an error reading the PPD file, cannot continue!
return (NULL);
}
-#ifndef __APPLE__
/*
- * Make sure that all PPD files with an InputSlot option have an
- * "auto" choice that maps to no specific tray or media type.
+ * Create the sorted options array and set the option back-pointer for
+ * each choice and custom option...
*/
- if ((option = ppdFindOption(ppd, "InputSlot")) != NULL)
- {
- for (i = 0; i < option->num_choices; i ++)
- if (option->choices[i].code == NULL || !option->choices[i].code[0] ||
- !strncasecmp(option->choices[i].choice, "Auto", 4))
- break;
-
- if (i >= option->num_choices)
- {
- /*
- * No "auto" input slot, add one...
- */
-
- choice = ppd_add_choice(option, "Auto");
-
- strlcpy(choice->text, cupsLangString(language, CUPS_MSG_AUTO),
- sizeof(choice->text));
- choice->code = NULL;
- }
- }
-#endif /* !__APPLE__ */
-
- /*
- * Set the option back-pointer for each choice...
- */
-
-#ifndef __APPLE__
- qsort(ppd->groups, ppd->num_groups, sizeof(ppd_group_t),
- (int (*)(const void *, const void *))ppd_compare_groups);
-#endif /* !__APPLE__ */
+ 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;
i --, group ++)
{
-#ifndef __APPLE__
- qsort(group->options, group->num_options, sizeof(ppd_option_t),
- (int (*)(const void *, const void *))ppd_compare_options);
-#endif /* !__APPLE__ */
-
for (j = group->num_options, option = group->options;
j > 0;
j --, option ++)
{
- for (k = 0; k < option->num_choices; k ++)
- option->choices[k].option = (void *)option;
- }
+ ppd_coption_t *coption; /* Custom option */
-#ifndef __APPLE__
- qsort(group->subgroups, group->num_subgroups, sizeof(ppd_group_t),
- (int (*)(const void *, const void *))ppd_compare_groups);
-#endif /* !__APPLE__ */
- for (j = group->num_subgroups, subgroup = group->subgroups;
- j > 0;
- j --, subgroup ++)
- {
-#ifndef __APPLE__
- qsort(subgroup->options, subgroup->num_options, sizeof(ppd_option_t),
- (int (*)(const void *, const void *))ppd_compare_options);
-#endif /* !__APPLE__ */
-
- for (k = group->num_options, option = group->options;
- k > 0;
- k --, option ++)
- {
- for (m = 0; m < option->num_choices; m ++)
- option->choices[m].option = (void *)option;
- }
+ cupsArrayAdd(ppd->options, option);
+
+ for (k = 0; k < option->num_choices; k ++)
+ option->choices[k].option = option;
+
+ if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
+ coption->option = option;
}
}
/*
- * Set the option pointers for all extended options...
+ * Sort the constraints...
*/
- for (i = 0; i < ppd->num_extended; i ++)
- ppd->extended[i]->option = ppdFindOption(ppd, ppd->extended[i]->keyword);
+ if (ppd->num_consts > 1)
+ qsort(ppd->consts, ppd->num_consts, sizeof(ppd_const_t),
+ (int (*)(const void *, const void *))ppd_compare_consts);
/*
- * Sort the attributes...
+ * Create an array to track the marked choices...
*/
- if (ppd->num_attrs > 1)
- qsort(ppd->attrs, ppd->num_attrs, sizeof(ppd_attr_t *),
- (int (*)(const void *, const void *))_ppd_attr_compare);
+ ppd->marked = cupsArrayNew((cups_array_func_t)ppd_compare_choices, NULL);
/*
* Return the PPD file structure...
cupsLangFree(language);
-#ifdef LC_NUMERIC
- _cupsRestoreLocale(LC_NUMERIC, oldlocale);
-#else
- _cupsRestoreLocale(LC_ALL, oldlocale);
-#endif /* LC_NUMERIC */
-
return (NULL);
}
ppd_file_t * /* O - PPD file record */
ppdOpenFd(int fd) /* I - File to read from */
{
- FILE *fp; /* File pointer */
- ppd_file_t *ppd; /* PPD file record */
+ cups_file_t *fp; /* CUPS file pointer */
+ ppd_file_t *ppd; /* PPD file record */
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Global data */
/*
* Set the line number to 0...
*/
- ppd_line = 0;
+ cg->ppd_line = 0;
/*
* Range check input...
if (fd < 0)
{
- ppd_status = PPD_NULL_FILE;
+ cg->ppd_status = PPD_NULL_FILE;
return (NULL);
}
* Try to open the file and parse it...
*/
- if ((fp = fdopen(fd, "r")) != NULL)
+ if ((fp = cupsFileOpenFd(fd, "r")) != NULL)
{
- setbuf(fp, NULL);
-
- ppd = ppdOpen(fp);
+ ppd = ppdOpen2(fp);
- fclose(fp);
+ cupsFileClose(fp);
}
else
{
- ppd_status = PPD_FILE_OPEN_ERROR;
- ppd = NULL;
+ cg->ppd_status = PPD_FILE_OPEN_ERROR;
+ ppd = NULL;
}
return (ppd);
ppd_file_t * /* O - PPD file record */
ppdOpenFile(const char *filename) /* I - File to read from */
{
- FILE *fp; /* File pointer */
- ppd_file_t *ppd; /* PPD file record */
+ cups_file_t *fp; /* File pointer */
+ ppd_file_t *ppd; /* PPD file record */
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Global data */
/*
* Set the line number to 0...
*/
- ppd_line = 0;
+ cg->ppd_line = 0;
/*
* Range check input...
if (filename == NULL)
{
- ppd_status = PPD_NULL_FILE;
+ cg->ppd_status = PPD_NULL_FILE;
return (NULL);
}
* Try to open the file and parse it...
*/
- if ((fp = fopen(filename, "r")) != NULL)
+ if ((fp = cupsFileOpen(filename, "r")) != NULL)
{
- ppd = ppdOpen(fp);
+ ppd = ppdOpen2(fp);
- fclose(fp);
+ cupsFileClose(fp);
}
else
{
- ppd_status = PPD_FILE_OPEN_ERROR;
- ppd = NULL;
+ cg->ppd_status = PPD_FILE_OPEN_ERROR;
+ ppd = NULL;
}
return (ppd);
/*
* 'ppdSetConformance()' - Set the conformance level for PPD files.
+ *
+ * @since CUPS 1.1.20@
*/
void
ppdSetConformance(ppd_conform_t c) /* I - Conformance level */
{
- ppd_conform = c;
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Global data */
+
+
+ cg->ppd_conform = c;
}
if (ppd == NULL || name == NULL || spec == NULL)
return (NULL);
+ /*
+ * Create the array as needed...
+ */
+
+ if (!ppd->sorted_attrs)
+ ppd->sorted_attrs = cupsArrayNew((cups_array_func_t)ppd_compare_attrs,
+ NULL);
+
/*
* Allocate memory for the new attribute...
*/
strlcpy(temp->text, text, sizeof(temp->text));
temp->value = (char *)value;
+ /*
+ * Add the attribute to the sorted array...
+ */
+
+ cupsArrayAdd(ppd->sorted_attrs, temp);
+
/*
* Return the attribute...
*/
}
-#ifndef __APPLE__
/*
- * 'ppd_compare_groups()' - Compare two groups.
+ * 'ppd_compare_attrs()' - Compare two attributes.
+ */
+
+static int /* O - Result of comparison */
+ppd_compare_attrs(ppd_attr_t *a, /* I - First attribute */
+ ppd_attr_t *b) /* I - Second attribute */
+{
+ int ret; /* Result of comparison */
+
+
+ if ((ret = strcasecmp(a->name, b->name)) != 0)
+ return (ret);
+ 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 (strcmp(a->choice2, b->choice2));
+}
+
+
+/*
+ * 'ppd_compare_coptions()' - Compare two custom options.
*/
static int /* O - Result of comparison */
-ppd_compare_groups(ppd_group_t *g0, /* I - First group */
- ppd_group_t *g1) /* I - Second group */
+ppd_compare_coptions(ppd_coption_t *a, /* I - First option */
+ ppd_coption_t *b) /* I - Second option */
{
- return (strcasecmp(g0->text, g1->text));
+ return (strcasecmp(a->keyword, b->keyword));
+}
+
+
+/*
+ * 'ppd_compare_cparams()' - Compare two custom parameters.
+ */
+
+static int /* O - Result of comparison */
+ppd_compare_cparams(ppd_cparam_t *a, /* I - First parameter */
+ ppd_cparam_t *b) /* I - Second parameter */
+{
+ return (strcasecmp(a->name, b->name));
}
*/
static int /* O - Result of comparison */
-ppd_compare_options(ppd_option_t *o0, /* I - First option */
- ppd_option_t *o1) /* I - Second option */
+ppd_compare_options(ppd_option_t *a, /* I - First option */
+ ppd_option_t *b) /* I - Second option */
{
- return (strcasecmp(o0->text, o1->text));
+ return (strcasecmp(a->keyword, b->keyword));
}
-#endif /* !__APPLE__ */
/*
* 'ppd_decode()' - Decode a string value...
*/
-static void
+static int /* O - Length of decoded string */
ppd_decode(char *string) /* I - String to decode */
{
char *inptr, /* Input pointer */
outptr = string;
while (*inptr != '\0')
- if (*inptr == '<' && isxdigit(inptr[1]))
+ if (*inptr == '<' && isxdigit(inptr[1] & 255))
{
/*
* Convert hex to 8-bit values...
*/
inptr ++;
- while (isxdigit(*inptr))
+ while (isxdigit(*inptr & 255))
{
if (isalpha(*inptr))
*outptr = (tolower(*inptr) - 'a' + 10) << 4;
inptr ++;
+ if (!isxdigit(*inptr & 255))
+ break;
+
if (isalpha(*inptr))
*outptr |= tolower(*inptr) - 'a' + 10;
else
*outptr++ = *inptr++;
*outptr = '\0';
-}
-
-#ifndef __APPLE__
-/*
- * 'ppd_fix()' - Fix WinANSI characters in the range 0x80 to 0x9f to be
- * valid ISO-8859-1 characters...
- */
-
-static void
-ppd_fix(char *string) /* IO - String to fix */
-{
- unsigned char *p; /* Pointer into string */
- static const unsigned char lut[32] = /* Lookup table for characters */
- {
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 'l',
- '`',
- '\'',
- '^',
- '~',
- 0x20, /* bar */
- 0x20, /* circumflex */
- 0x20, /* dot */
- 0x20, /* double dot */
- 0x20,
- 0x20, /* circle */
- 0x20, /* ??? */
- 0x20,
- '\"', /* should be right quotes */
- 0x20, /* ??? */
- 0x20 /* accent */
- };
-
-
- for (p = (unsigned char *)string; *p; p ++)
- if (*p >= 0x80 && *p < 0xa0)
- *p = lut[*p - 0x80];
+ return ((int)(outptr - string));
}
-#endif /* !__APPLE__ */
/*
/*
- * 'ppd_get_extoption()' - Get an extended option record.
+ * 'ppd_get_coption()' - Get a custom option record.
*/
-static ppd_ext_option_t * /* O - Extended option... */
-ppd_get_extoption(ppd_file_t *ppd, /* I - PPD file */
- const char *name) /* I - Name of option */
+static ppd_coption_t * /* O - Custom option... */
+ppd_get_coption(ppd_file_t *ppd, /* I - PPD file */
+ const char *name) /* I - Name of option */
{
- ppd_ext_option_t **temp, /* New array pointer */
- *extopt; /* New extended option */
+ ppd_coption_t *copt; /* New custom option */
/*
* See if the option already exists...
*/
- if ((extopt = ppdFindExtOption(ppd, name)) != NULL)
- return (extopt);
+ if ((copt = ppdFindCustomOption(ppd, name)) != NULL)
+ return (copt);
/*
- * Not found, so create the extended option record...
+ * Not found, so create the custom option record...
*/
- if ((extopt = calloc(1, sizeof(ppd_ext_option_t))) == NULL)
+ if ((copt = calloc(1, sizeof(ppd_coption_t))) == NULL)
return (NULL);
- strlcpy(extopt->keyword, name, sizeof(extopt->keyword));
-
- /*
- * Add this record to the end of the array...
- */
-
- if (ppd->num_extended == 0)
- temp = malloc(sizeof(ppd_ext_option_t *));
- else
- temp = realloc(ppd->extended, sizeof(ppd_ext_option_t *) *
- (ppd->num_extended + 1));
-
- if (temp == NULL)
- {
- free(extopt);
- return (NULL);
- }
+ strlcpy(copt->keyword, name, sizeof(copt->keyword));
- ppd->extended = temp;
- temp[ppd->num_extended] = extopt;
+ copt->params = cupsArrayNew((cups_array_func_t)ppd_compare_cparams, NULL);
- ppd->num_extended ++;
+ cupsArrayAdd(ppd->coptions, copt);
/*
* Return the new record...
*/
- return (extopt);
+ return (copt);
}
/*
- * 'ppd_get_extparam()' - Get an extended parameter record.
+ * 'ppd_get_cparam()' - Get a custom parameter record.
*/
-static ppd_ext_param_t * /* O - Extended option... */
-ppd_get_extparam(ppd_ext_option_t *opt, /* I - PPD file */
- const char *param,/* I - Name of parameter */
- const char *text) /* I - Human-readable text */
+static ppd_cparam_t * /* O - Extended option... */
+ppd_get_cparam(ppd_coption_t *opt, /* I - PPD file */
+ const char *param, /* I - Name of parameter */
+ const char *text) /* I - Human-readable text */
{
- ppd_ext_param_t **temp, /* New array pointer */
- *extparam; /* New extended parameter */
+ ppd_cparam_t *cparam; /* New custom parameter */
/*
* See if the parameter already exists...
*/
- if ((extparam = ppdFindExtParam(opt, param)) != NULL)
- return (extparam);
+ if ((cparam = ppdFindCustomParam(opt, param)) != NULL)
+ return (cparam);
/*
- * Not found, so create the extended parameter record...
+ * Not found, so create the custom parameter record...
*/
- if ((extparam = calloc(1, sizeof(ppd_ext_param_t))) == NULL)
+ if ((cparam = calloc(1, sizeof(ppd_cparam_t))) == NULL)
return (NULL);
- if ((extparam->value = calloc(4, sizeof(ppd_ext_value_t))) == NULL)
- {
- ppd_free(extparam);
- return (NULL);
- }
-
- extparam->defval = extparam->value + 1;
- extparam->minval = extparam->value + 2;
- extparam->maxval = extparam->value + 3;
-
- strlcpy(extparam->keyword, param, sizeof(extparam->keyword));
- strlcpy(extparam->text, text, sizeof(extparam->text));
+ strlcpy(cparam->name, param, sizeof(cparam->name));
+ strlcpy(cparam->text, text[0] ? text : param, sizeof(cparam->text));
/*
- * Add this record to the end of the array...
+ * Add this record to the array...
*/
- if (opt->num_params == 0)
- temp = malloc(sizeof(ppd_ext_param_t *));
- else
- temp = realloc(opt->params, sizeof(ppd_ext_param_t *) *
- (opt->num_params + 1));
-
- if (temp == NULL)
- {
- free(extparam);
- return (NULL);
- }
-
- opt->params = temp;
- temp[opt->num_params] = extparam;
-
- opt->num_params ++;
+ cupsArrayAdd(opt->params, cparam);
/*
* Return the new record...
*/
- return (extparam);
+ return (cparam);
}
*/
static ppd_group_t * /* O - Named group */
-ppd_get_group(ppd_file_t *ppd, /* I - PPD file */
- const char *name, /* I - Name of group */
- const char *text) /* I - Text for group */
+ppd_get_group(ppd_file_t *ppd, /* I - PPD file */
+ const char *name, /* I - Name of group */
+ const char *text, /* I - Text for group */
+ _cups_globals_t *cg, /* I - Global data */
+ cups_encoding_t encoding) /* I - Encoding of text */
{
int i; /* Looping var */
ppd_group_t *group; /* Group */
- DEBUG_printf(("ppd_get_group(%p, \"%s\")\n", ppd, name));
+ DEBUG_printf(("ppd_get_group(ppd=%p, name=\"%s\", text=\"%s\", cg=%p)\n",
+ ppd, name, text, cg));
for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
- if (strcmp(group->name, name) == 0)
+ if (!strcmp(group->name, name))
break;
if (i == 0)
{
DEBUG_printf(("Adding group %s...\n", name));
+ if (cg->ppd_conform == PPD_CONFORM_STRICT && strlen(text) >= sizeof(group->text))
+ {
+ cg->ppd_status = PPD_ILLEGAL_TRANSLATION;
+
+ return (NULL);
+ }
+
if (ppd->num_groups == 0)
group = malloc(sizeof(ppd_group_t));
else
(ppd->num_groups + 1) * sizeof(ppd_group_t));
if (group == NULL)
+ {
+ cg->ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
+ }
ppd->groups = group;
group += ppd->num_groups;
memset(group, 0, sizeof(ppd_group_t));
strlcpy(group->name, name, sizeof(group->name));
- strlcpy(group->text, text, sizeof(group->text));
+
+ cupsCharsetToUTF8((cups_utf8_t *)group->text, text,
+ sizeof(group->text), encoding);
}
return (group);
group, group->name, name));
for (i = group->num_options, option = group->options; i > 0; i --, option ++)
- if (strcmp(option->keyword, name) == 0)
+ if (!strcmp(option->keyword, name))
break;
if (i == 0)
}
+/*
+ * '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.
*/
static int /* O - Bitmask of fields read */
-ppd_read(FILE *fp, /* I - File to read from */
- char *keyword, /* O - Keyword from line */
- char *option, /* O - Option from line */
- char *text, /* O - Human-readable text from line */
- char **string, /* O - Code/string data */
- int ignoreblank) /* I - Ignore blank lines? */
+ppd_read(cups_file_t *fp, /* I - File to read from */
+ char *keyword, /* O - Keyword from line */
+ char *option, /* O - Option from line */
+ char *text, /* O - Human-readable text from line */
+ char **string, /* O - Code/string data */
+ int ignoreblank, /* I - Ignore blank lines? */
+ _cups_globals_t *cg) /* I - Global data */
{
int ch, /* Character from file */
col, /* Column in line */
colon, /* Colon seen? */
endquote, /* Waiting for an end quote */
mask, /* Mask to be returned */
- startline; /* Start line */
+ startline, /* Start line */
+ textlen; /* Length of text */
char *keyptr, /* Keyword pointer */
*optptr, /* Option pointer */
*textptr, /* Text pointer */
*strptr, /* Pointer into string */
*lineptr, /* Current position in line buffer */
- line[65536]; /* Line buffer (64k) */
-
+ *line; /* Line buffer */
+ int linesize; /* Current size of line buffer */
/*
* Range check everything...
*/
- if (fp == NULL || keyword == NULL || option == NULL || text == NULL ||
- string == NULL)
+ if (!fp || !keyword || !option || !text || !string)
return (0);
/*
*string = NULL;
col = 0;
- startline = ppd_line + 1;
+ startline = cg->ppd_line + 1;
+ linesize = 1024;
+ line = malloc(linesize);
+
+ if (!line)
+ return (0);
do
{
endquote = 0;
colon = 0;
- while ((ch = getc(fp)) != EOF &&
- (lineptr - line) < (sizeof(line) - 1))
+ while ((ch = cupsFileGetChar(fp)) != EOF)
{
+ if (lineptr >= (line + linesize - 1))
+ {
+ /*
+ * Expand the line buffer...
+ */
+
+ char *temp; /* Temporary line pointer */
+
+
+ linesize += 1024;
+ if (linesize > 262144)
+ {
+ /*
+ * Don't allow lines longer than 256k!
+ */
+
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_LINE_TOO_LONG;
+
+ free(line);
+
+ return (0);
+ }
+
+ temp = realloc(line, linesize);
+ if (!temp)
+ {
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_LINE_TOO_LONG;
+
+ free(line);
+
+ return (0);
+ }
+
+ lineptr = temp + (lineptr - line);
+ line = temp;
+ }
+
if (ch == '\r' || ch == '\n')
{
/*
* Line feed or carriage return...
*/
- ppd_line ++;
+ cg->ppd_line ++;
col = 0;
if (ch == '\r')
* Check for a trailing line feed...
*/
- if ((ch = getc(fp)) == EOF)
+ if ((ch = cupsFilePeekChar(fp)) == EOF)
+ {
+ ch = '\n';
break;
- if (ch != 0x0a)
- ungetc(ch, fp);
+ }
+
+ if (ch == 0x0a)
+ cupsFileGetChar(fp);
}
if (lineptr == line && ignoreblank)
*lineptr++ = '\n';
}
- else if (ch < ' ' && ch != '\t' && ppd_conform == PPD_CONFORM_STRICT)
+ else if (ch < ' ' && ch != '\t' && cg->ppd_conform == PPD_CONFORM_STRICT)
{
/*
* Other control characters...
*/
- ppd_line = startline;
- ppd_status = PPD_ILLEGAL_CHARACTER;
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_ILLEGAL_CHARACTER;
+
+ free(line);
return (0);
}
* Line is too long...
*/
- ppd_line = startline;
- ppd_status = PPD_LINE_TOO_LONG;
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_LINE_TOO_LONG;
+
+ free(line);
return (0);
}
* Didn't finish this quoted string...
*/
- while ((ch = getc(fp)) != EOF)
+ while ((ch = cupsFileGetChar(fp)) != EOF)
if (ch == '\"')
break;
else if (ch == '\r' || ch == '\n')
{
- ppd_line ++;
+ cg->ppd_line ++;
col = 0;
if (ch == '\r')
* Check for a trailing line feed...
*/
- if ((ch = getc(fp)) == EOF)
+ if ((ch = cupsFilePeekChar(fp)) == EOF)
break;
- if (ch != 0x0a)
- ungetc(ch, fp);
+ if (ch == 0x0a)
+ cupsFileGetChar(fp);
}
ch = '\n';
}
- else if (ch < ' ' && ch != '\t' && ppd_conform == PPD_CONFORM_STRICT)
+ else if (ch < ' ' && ch != '\t' && cg->ppd_conform == PPD_CONFORM_STRICT)
{
/*
* Other control characters...
*/
- ppd_line = startline;
- ppd_status = PPD_ILLEGAL_CHARACTER;
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_ILLEGAL_CHARACTER;
+
+ free(line);
return (0);
}
* Line is too long...
*/
- ppd_line = startline;
- ppd_status = PPD_LINE_TOO_LONG;
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_LINE_TOO_LONG;
+
+ free(line);
return (0);
}
* Didn't finish this line...
*/
- while ((ch = getc(fp)) != EOF)
+ while ((ch = cupsFileGetChar(fp)) != EOF)
if (ch == '\r' || ch == '\n')
{
/*
* Line feed or carriage return...
*/
- ppd_line ++;
+ cg->ppd_line ++;
col = 0;
if (ch == '\r')
* Check for a trailing line feed...
*/
- if ((ch = getc(fp)) == EOF)
+ if ((ch = cupsFilePeekChar(fp)) == EOF)
break;
- if (ch != 0x0a)
- ungetc(ch, fp);
+ if (ch == 0x0a)
+ cupsFileGetChar(fp);
}
break;
}
- else if (ch < ' ' && ch != '\t' && ppd_conform == PPD_CONFORM_STRICT)
+ else if (ch < ' ' && ch != '\t' && cg->ppd_conform == PPD_CONFORM_STRICT)
{
/*
* Other control characters...
*/
- ppd_line = startline;
- ppd_status = PPD_ILLEGAL_CHARACTER;
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_ILLEGAL_CHARACTER;
+
+ free(line);
return (0);
}
* Line is too long...
*/
- ppd_status = PPD_LINE_TOO_LONG;
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_LINE_TOO_LONG;
+
+ free(line);
return (0);
}
*lineptr = '\0';
- DEBUG_printf(("LINE = \"%s\"\n", line));
+/* DEBUG_printf(("LINE = \"%s\"\n", line));*/
+
+ /*
+ * The dynamically created PPDs for older style Mac OS X
+ * drivers include a large blob of data inserted as comments
+ * at the end of the file. As an optimization we can stop
+ * reading the PPD when we get to the start of this data.
+ */
+
+ if (!strcmp(line, "*%APLWORKSET START"))
+ {
+ free(line);
+ return (0);
+ }
if (ch == EOF && lineptr == line)
+ {
+ free(line);
return (0);
+ }
/*
* Now parse it...
*string = NULL;
if ((!line[0] || /* Blank line */
- strncmp(line, "*%", 2) == 0 || /* Comment line */
- strcmp(line, "*End") == 0) && /* End of multi-line string */
+ !strncmp(line, "*%", 2) || /* Comment line */
+ !strcmp(line, "*End")) && /* End of multi-line string */
ignoreblank) /* Ignore these? */
{
- startline = ppd_line + 1;
+ startline = cg->ppd_line + 1;
continue;
}
- if (strcmp(line, "*") == 0) /* (Bad) comment line */
+ if (!strcmp(line, "*")) /* (Bad) comment line */
{
- if (ppd_conform == PPD_CONFORM_RELAXED)
+ if (cg->ppd_conform == PPD_CONFORM_RELAXED)
{
- startline = ppd_line + 1;
+ startline = cg->ppd_line + 1;
continue;
}
else
{
- ppd_line = startline;
- ppd_status = PPD_ILLEGAL_MAIN_KEYWORD;
+ cg->ppd_line = startline;
+ cg->ppd_status = PPD_ILLEGAL_MAIN_KEYWORD;
+ free(line);
return (0);
}
}
if (line[0] != '*') /* All lines start with an asterisk */
{
- if (ppd_conform == PPD_CONFORM_STRICT)
- {
- ppd_status = PPD_MISSING_ASTERISK;
- return (0);
- }
-
/*
* Allow lines consisting of just whitespace...
*/
for (lineptr = line; *lineptr; lineptr ++)
- if (!isspace(*lineptr))
+ if (!isspace(*lineptr & 255))
break;
if (*lineptr)
{
- ppd_status = PPD_MISSING_ASTERISK;
+ cg->ppd_status = PPD_MISSING_ASTERISK;
+ free(line);
return (0);
}
else if (ignoreblank)
continue;
else
+ {
+ free(line);
return (0);
+ }
}
/*
keyptr = keyword;
- while (*lineptr != '\0' && *lineptr != ':' && !isspace(*lineptr))
+ while (*lineptr != '\0' && *lineptr != ':' && !isspace(*lineptr & 255))
{
if (*lineptr <= ' ' || *lineptr > 126 || *lineptr == '/' ||
(keyptr - keyword) >= (PPD_MAX_NAME - 1))
{
- ppd_status = PPD_ILLEGAL_MAIN_KEYWORD;
+ cg->ppd_status = PPD_ILLEGAL_MAIN_KEYWORD;
+ free(line);
return (0);
}
*keyptr = '\0';
- if (strcmp(keyword, "End") == 0)
+ if (!strcmp(keyword, "End"))
continue;
mask |= PPD_KEYWORD;
/* DEBUG_printf(("keyword = \"%s\", lineptr = \"%s\"\n", keyword, lineptr));*/
- if (isspace(*lineptr))
+ if (isspace(*lineptr & 255))
{
/*
* Get an option name...
*/
- while (isspace(*lineptr))
+ while (isspace(*lineptr & 255))
lineptr ++;
optptr = option;
- while (*lineptr != '\0' && !isspace(*lineptr) && *lineptr != ':' &&
+ while (*lineptr != '\0' && !isspace(*lineptr & 255) && *lineptr != ':' &&
*lineptr != '/')
{
if (*lineptr <= ' ' || *lineptr > 126 ||
(optptr - option) >= (PPD_MAX_NAME - 1))
{
- ppd_status = PPD_ILLEGAL_OPTION_KEYWORD;
+ cg->ppd_status = PPD_ILLEGAL_OPTION_KEYWORD;
+ free(line);
return (0);
}
*optptr = '\0';
- if (isspace(*lineptr) && ppd_conform == PPD_CONFORM_STRICT)
+ if (isspace(*lineptr & 255) && cg->ppd_conform == PPD_CONFORM_STRICT)
{
- ppd_status = PPD_ILLEGAL_WHITESPACE;
+ cg->ppd_status = PPD_ILLEGAL_WHITESPACE;
+ free(line);
return (0);
}
- while (isspace(*lineptr))
+ while (isspace(*lineptr & 255))
lineptr ++;
mask |= PPD_OPTION;
if (((unsigned char)*lineptr < ' ' && *lineptr != '\t') ||
(textptr - text) >= (PPD_MAX_LINE - 1))
{
- ppd_status = PPD_ILLEGAL_TRANSLATION;
+ cg->ppd_status = PPD_ILLEGAL_TRANSLATION;
+ free(line);
return (0);
}
}
*textptr = '\0';
- ppd_decode(text);
+ textlen = ppd_decode(text);
+ if (textlen > PPD_MAX_TEXT && cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ cg->ppd_status = PPD_ILLEGAL_TRANSLATION;
+ free(line);
+ return (0);
+ }
+
mask |= PPD_TEXT;
}
/* DEBUG_printf(("text = \"%s\", lineptr = \"%s\"\n", text, lineptr));*/
}
- if (isspace(*lineptr) && ppd_conform == PPD_CONFORM_STRICT)
+ if (isspace(*lineptr & 255) && cg->ppd_conform == PPD_CONFORM_STRICT)
{
- ppd_status = PPD_ILLEGAL_WHITESPACE;
+ cg->ppd_status = PPD_ILLEGAL_WHITESPACE;
+ free(line);
return (0);
}
- while (isspace(*lineptr))
+ while (isspace(*lineptr & 255))
lineptr ++;
if (*lineptr == ':')
*/
lineptr ++;
- while (isspace(*lineptr))
+ while (isspace(*lineptr & 255))
lineptr ++;
strptr = lineptr + strlen(lineptr) - 1;
- while (strptr >= lineptr && isspace(*strptr))
+ while (strptr >= lineptr && isspace(*strptr & 255))
*strptr-- = '\0';
if (*strptr == '\"')
}
while (mask == 0);
+ free(line);
+
return (mask);
}
/*
- * End of "$Id: ppd.c,v 1.51.2.60 2003/08/20 15:54:39 mike Exp $".
+ * End of "$Id$".
*/