//
// Source class for the CUPS PPD Compiler.
//
-// Copyright 2007-2009 by Apple Inc.
+// Copyright 2007-2010 by Apple Inc.
// Copyright 2002-2007 by Easy Software Products.
//
// These coded instructions, statements, and computer programs are the
#include "data/hp.h"
#include "data/label.h"
#include "data/pcl.h"
+#ifndef WIN32
+# include <sys/utsname.h>
+#endif // !WIN32
//
cond_current = cond_stack;
cond_stack[0] = PPDC_COND_NORMAL;
+ // Add standard #define variables...
+#define MAKE_STRING(x) #x
+
+ vars->add(new ppdcVariable("CUPS_VERSION", MAKE_STRING(CUPS_VERSION)));
+ vars->add(new ppdcVariable("CUPS_VERSION_MAJOR", MAKE_STRING(CUPS_VERSION_MAJOR)));
+ vars->add(new ppdcVariable("CUPS_VERSION_MINOR", MAKE_STRING(CUPS_VERSION_MINOR)));
+ vars->add(new ppdcVariable("CUPS_VERSION_PATCH", MAKE_STRING(CUPS_VERSION_PATCH)));
+
+#ifdef WIN32
+ vars->add(new ppdcVariable("PLATFORM_NAME", "Windows"));
+ vars->add(new ppdcVariable("PLATFORM_ARCH", "X86"));
+
+#else
+ struct utsname name; // uname information
+
+ if (!uname(&name))
+ {
+ vars->add(new ppdcVariable("PLATFORM_NAME", name.sysname));
+ vars->add(new ppdcVariable("PLATFORM_ARCH", name.machine));
+ }
+ else
+ {
+ vars->add(new ppdcVariable("PLATFORM_NAME", "unknown"));
+ vars->add(new ppdcVariable("PLATFORM_ARCH", "unknown"));
+ }
+#endif // WIN32
+
if (f)
read_file(f, ffp);
}
if (*ptr != '>')
{
_cupsLangPrintf(stderr,
- _("ppdc: Invalid #include/#po filename \"%s\"!\n"), n);
+ _("ppdc: Invalid #include/#po filename \"%s\"\n"), n);
return (0);
}
if (!get_token(fp, name, sizeof(name)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected name after %s on line %d of %s!\n"),
+ _("ppdc: Expected name after %s on line %d of %s\n"),
loc ? "LocAttribute" : "Attribute", fp->line, fp->filename);
return (0);
}
if (!get_token(fp, selector, sizeof(selector)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected selector after %s on line %d of %s!\n"),
+ _("ppdc: Expected selector after %s on line %d of %s\n"),
loc ? "LocAttribute" : "Attribute", fp->line, fp->filename);
return (0);
}
if (!get_token(fp, value, sizeof(value)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected value after %s on line %d of %s!\n"),
+ _("ppdc: Expected value after %s on line %d of %s\n"),
loc ? "LocAttribute" : "Attribute", fp->line, fp->filename);
return (0);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name/text combination for ColorModel on "
- "line %d of %s!\n"), fp->line, fp->filename);
+ "line %d of %s\n"), fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected colorspace for ColorModel on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected color order for ColorModel on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected compression for ColorModel on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected resolution/mediatype following "
- "ColorProfile on line %d of %s!\n"),
+ "ColorProfile on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected constraints string for UIConstraints on "
- "line %d of %s!\n"), fp->line, fp->filename);
+ "line %d of %s\n"), fp->line, fp->filename);
return (NULL);
}
if (*ptr != '*')
{
_cupsLangPrintf(stderr,
- _("ppdc: Option constraint must *name on line %d of %s!\n"),
+ _("ppdc: Option constraint must *name on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
if (*ptr != '*')
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected two option names on line %d of %s!\n"),
+ _("ppdc: Expected two option names on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected duplex type after Duplex on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return;
}
}
else
_cupsLangPrintf(stderr,
- _("ppdc: Unknown duplex type \"%s\" on line %d of %s!\n"),
+ _("ppdc: Unknown duplex type \"%s\" on line %d of %s\n"),
temp, fp->line, fp->filename);
}
if (!get_token(fp, type, sizeof(type)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected a filter definition on line %d of %s!\n"),
+ _("ppdc: Expected a filter definition on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
if (!get_token(fp, program, sizeof(program)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected a program name on line %d of %s!\n"),
+ _("ppdc: Expected a program name on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Invalid empty MIME type for filter on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (NULL);
}
if (cost < 0 || cost > 200)
{
_cupsLangPrintf(stderr,
- _("ppdc: Invalid cost for filter on line %d of %s!\n"),
+ _("ppdc: Invalid cost for filter on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Invalid empty program name for filter on line %d "
- "of %s!\n"), fp->line, fp->filename);
+ "of %s\n"), fp->line, fp->filename);
return (NULL);
}
// Get the number from the file and range-check...
if (!get_token(fp, temp, sizeof(temp)))
{
- _cupsLangPrintf(stderr, _("ppdc: Expected real number on line %d of %s!\n"),
+ _cupsLangPrintf(stderr, _("ppdc: Expected real number on line %d of %s\n"),
fp->line, fp->filename);
return (-1.0f);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Unknown trailing characters in real number \"%s\" "
- "on line %d of %s!\n"), temp, fp->line, fp->filename);
+ "on line %d of %s\n"), temp, fp->line, fp->filename);
return (-1.0f);
}
else
if (!get_token(fp, name, sizeof(name)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected name after Font on line %d of %s!\n"),
+ _("ppdc: Expected name after Font on line %d of %s\n"),
fp->line, fp->filename);
return (0);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected encoding after Font on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (0);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected version after Font on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (0);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected charset after Font on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (0);
}
if (!get_token(fp, temp, sizeof(temp)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected status after Font on line %d of %s!\n"),
+ _("ppdc: Expected status after Font on line %d of %s\n"),
fp->line, fp->filename);
return (0);
}
else
{
_cupsLangPrintf(stderr,
- _("ppdc: Bad status keyword %s on line %d of %s!\n"),
+ _("ppdc: Bad status keyword %s on line %d of %s\n"),
temp, fp->line, fp->filename);
return (0);
}
if (!get_token(fp, name, sizeof(name)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected name/text after %s on line %d of %s!\n"),
+ _("ppdc: Expected name/text after %s on line %d of %s\n"),
keyword, fp->line, fp->filename);
return (NULL);
}
if (!get_token(fp, name, sizeof(name)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected group name/text on line %d of %s!\n"),
+ _("ppdc: Expected group name/text on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name/text after Installable on line %d "
- "of %s!\n"), fp->line, fp->filename);
+ "of %s\n"), fp->line, fp->filename);
return (NULL);
}
while (*v && *v != ')')
{
// Skip leading whitespace...
- while (*v && isspace(*v & 255));
+ while (*v && isspace(*v & 255))
v ++;
if (!*v || *v == ')')
if (!get_token(fp, temp, sizeof(temp)))
{
- _cupsLangPrintf(stderr, _("ppdc: Expected integer on line %d of %s!\n"),
+ _cupsLangPrintf(stderr, _("ppdc: Expected integer on line %d of %s\n"),
fp->line, fp->filename);
return (-1);
}
ppdcOptSection section; // Option section
float order; // Option order
ppdcOption *o; // Option
+ ppdcGroup *mg; // Matching group, if any
// Read the Option parameters:
if (!get_token(fp, name, sizeof(name)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected option name/text on line %d of %s!\n"),
+ _("ppdc: Expected option name/text on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
if (!get_token(fp, type, sizeof(type)))
{
- _cupsLangPrintf(stderr, _("ppdc: Expected option type on line %d of %s!\n"),
+ _cupsLangPrintf(stderr, _("ppdc: Expected option type on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
else
{
_cupsLangPrintf(stderr,
- _("ppdc: Invalid option type \"%s\" on line %d of %s!\n"),
+ _("ppdc: Invalid option type \"%s\" on line %d of %s\n"),
type, fp->line, fp->filename);
return (NULL);
}
if (!get_token(fp, type, sizeof(type)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected option section on line %d of %s!\n"),
+ _("ppdc: Expected option section on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Invalid option section \"%s\" on line %d of "
- "%s!\n"), type, fp->line, fp->filename);
+ "%s\n"), type, fp->line, fp->filename);
return (NULL);
}
order = get_float(fp);
// See if the option already exists...
- if ((o = d->find_option(name)) == NULL)
+ if ((o = d->find_option_group(name, &mg)) == NULL)
{
// Nope, add a new one...
o = new ppdcOption(ot, name, text, section, order);
{
_cupsLangPrintf(stderr,
_("ppdc: Option %s redefined with a different type on line "
- "%d of %s!\n"), name, fp->line, fp->filename);
+ "%d of %s\n"), name, fp->line, fp->filename);
+ return (NULL);
+ }
+ else if (g != mg)
+ {
+ _cupsLangPrintf(stderr,
+ _("ppdc: Option %s defined in two different groups on line "
+ "%d of %s\n"), name, fp->line, fp->filename);
return (NULL);
}
if (!get_token(fp, locale, sizeof(locale)))
{
_cupsLangPrintf(stderr,
- _("ppdc: Expected locale after #po on line %d of %s!\n"),
+ _("ppdc: Expected locale after #po on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected filename after #po %s on line %d of "
- "%s!\n"), locale, fp->line, fp->filename);
+ "%s\n"), locale, fp->line, fp->filename);
return (NULL);
}
if (find_po(locale))
{
_cupsLangPrintf(stderr,
- _("ppdc: Duplicate #po for locale %s on line %d of %s!\n"),
+ _("ppdc: Duplicate #po for locale %s on line %d of %s\n"),
locale, fp->line, fp->filename);
return (NULL);
}
else
{
_cupsLangPrintf(stderr,
- _("ppdc: Unable to find #po file %s on line %d of %s!\n"),
+ _("ppdc: Unable to find #po file %s on line %d of %s\n"),
poname, fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected override field after Resolution on line "
- "%d of %s!\n"), fp->line, fp->filename);
+ "%d of %s\n"), fp->line, fp->filename);
return (NULL);
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name/text after Resolution on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
return (NULL);
}
case 0 :
_cupsLangPrintf(stderr,
_("ppdc: Bad resolution name \"%s\" on line %d of "
- "%s!\n"), name, fp->line, fp->filename);
+ "%s\n"), name, fp->line, fp->filename);
break;
case 1 :
ydpi = xdpi;
{
_cupsLangPrintf(stderr,
_("ppdc: Expected resolution/mediatype following "
- "SimpleColorProfile on line %d of %s!\n"),
+ "SimpleColorProfile on line %d of %s\n"),
fp->line, fp->filename);
return (NULL);
}
}
else
{
- _cupsLangPrintf(stderr,
- _("ppdc: Undefined variable (%s) on line %d of "
- "%s.\n"), name, fp->line, fp->filename);
+ if (!(cond_state & PPDC_COND_SKIP))
+ _cupsLangPrintf(stderr,
+ _("ppdc: Undefined variable (%s) on line %d of "
+ "%s.\n"), name, fp->line, fp->filename);
+
snprintf(bufptr, bufend - bufptr + 1, "$%s", name);
bufptr += strlen(name) + 1;
}
{
_cupsLangPrintf(stderr,
_("ppdc: Unterminated string starting with %c on line %d "
- "of %s!\n"), quote, startline, fp->filename);
+ "of %s\n"), quote, startline, fp->filename);
return (NULL);
}
delete fp;
if (cond_current != cond_stack)
- _cupsLangPrintf(stderr, _("ppdc: Missing #endif at end of \"%s\"!\n"), f);
+ _cupsLangPrintf(stderr, _("ppdc: Missing #endif at end of \"%s\"\n"), f);
}
{
ppdcDriver *d; // Current driver
ppdcGroup *g, // Current group
+ *mg, // Matching group
*general, // General options group
*install; // Installable options group
ppdcOption *o; // Current option
// Initialize things as needed...
if (inc && td)
+ {
d = td;
+ d->retain();
+ }
else
d = new ppdcDriver(td);
if ((cond_current - cond_stack) >= 100)
{
_cupsLangPrintf(stderr,
- _("ppdc: Too many nested #if's on line %d of %s!\n"),
+ _("ppdc: Too many nested #if's on line %d of %s\n"),
fp->line, fp->filename);
break;
}
cond_current ++;
- if (get_integer(fp))
+ if (get_integer(fp) > 0)
*cond_current = PPDC_COND_SATISFIED;
else
{
{
if (cond_current == cond_stack)
{
- _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s!\n"),
+ _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s\n"),
fp->line, fp->filename);
break;
}
get_integer(fp);
*cond_current |= PPDC_COND_SKIP;
}
- else if (get_integer(fp))
+ else if (get_integer(fp) > 0)
{
*cond_current |= PPDC_COND_SATISFIED;
*cond_current &= ~PPDC_COND_SKIP;
{
if (cond_current == cond_stack)
{
- _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s!\n"),
+ _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s\n"),
fp->line, fp->filename);
break;
}
{
if (cond_current == cond_stack)
{
- _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s!\n"),
+ _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s\n"),
fp->line, fp->filename);
break;
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected include filename on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
break;
}
delete incfile;
if (cond_current != old_current)
- _cupsLangPrintf(stderr, _("ppdc: Missing #endif at end of \"%s\"!\n"),
+ _cupsLangPrintf(stderr, _("ppdc: Missing #endif at end of \"%s\"\n"),
incname);
}
else
// Can't find it!
_cupsLangPrintf(stderr,
_("ppdc: Unable to find include file \"%s\" on line %d "
- "of %s!\n"), inctemp, fp->line, fp->filename);
+ "of %s\n"), inctemp, fp->line, fp->filename);
break;
}
}
{
_cupsLangPrintf(stderr,
_("ppdc: Choice found on line %d of %s with no "
- "Option!\n"), fp->line, fp->filename);
+ "Option\n"), fp->line, fp->filename);
break;
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected string after Copyright on line %d "
- "of %s!\n"), fp->line, fp->filename);
+ "of %s\n"), fp->line, fp->filename);
break;
}
}
// Add the choice to the cupsDarkness option...
- if ((o = d->find_option("cupsDarkness")) == NULL)
+ if ((o = d->find_option_group("cupsDarkness", &mg)) == NULL)
{
// Create the cupsDarkness option...
o = new ppdcOption(PPDC_PICKONE, "cupsDarkness", "Darkness", PPDC_SECTION_ANY, 10.0f);
g = general;
g->add_option(o);
}
+ else if (mg != general)
+ {
+ _cupsLangPrintf(stderr,
+ _("ppdc: Option %s defined in two different groups on "
+ "line %d of %s\n"), "cupsDarkness", fp->line,
+ fp->filename);
+ c->release();
+ continue;
+ }
o->add_choice(c);
{
_cupsLangPrintf(stderr,
_("ppdc: Expected driver type keyword following "
- "DriverType on line %d of %s!\n"),
+ "DriverType on line %d of %s\n"),
fp->line, fp->filename);
continue;
}
d->type = PPDC_DRIVER_LABEL;
else
_cupsLangPrintf(stderr,
- _("ppdc: Unknown driver type %s on line %d of %s!\n"),
+ _("ppdc: Unknown driver type %s on line %d of %s\n"),
temp, fp->line, fp->filename);
}
else if (!strcasecmp(temp, "Duplex"))
}
// Add the choice to the cupsFinishing option...
- if ((o = d->find_option("cupsFinishing")) == NULL)
+ if ((o = d->find_option_group("cupsFinishing", &mg)) == NULL)
{
// Create the cupsFinishing option...
o = new ppdcOption(PPDC_PICKONE, "cupsFinishing", "Finishing", PPDC_SECTION_ANY, 10.0f);
g = general;
g->add_option(o);
}
+ else if (mg != general)
+ {
+ _cupsLangPrintf(stderr,
+ _("ppdc: Option %s defined in two different groups on "
+ "line %d of %s\n"), "cupsFinishing", fp->line,
+ fp->filename);
+ c->release();
+ continue;
+ }
o->add_choice(c);
}
// Add the choice to the InputSlot option...
- if ((o = d->find_option("InputSlot")) == NULL)
+
+ if ((o = d->find_option_group("InputSlot", &mg)) == NULL)
{
// Create the InputSlot option...
o = new ppdcOption(PPDC_PICKONE, "InputSlot", "Media Source",
g = general;
g->add_option(o);
}
+ else if (mg != general)
+ {
+ _cupsLangPrintf(stderr,
+ _("ppdc: Option %s defined in two different groups on "
+ "line %d of %s\n"), "InputSlot", fp->line,
+ fp->filename);
+ c->release();
+ continue;
+ }
o->add_choice(c);
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name after Manufacturer on line %d "
- "of %s!\n"), fp->line, fp->filename);
+ "of %s\n"), fp->line, fp->filename);
break;
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name after MediaSize on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
break;
}
{
_cupsLangPrintf(stderr,
_("ppdc: Unknown media size \"%s\" on line %d of "
- "%s!\n"), name, fp->line, fp->filename);
+ "%s\n"), name, fp->line, fp->filename);
break;
}
}
// Add the choice to the MediaType option...
- if ((o = d->find_option("MediaType")) == NULL)
+ if ((o = d->find_option_group("MediaType", &mg)) == NULL)
{
// Create the MediaType option...
o = new ppdcOption(PPDC_PICKONE, "MediaType", "Media Type",
g = general;
g->add_option(o);
}
+ else if (mg != general)
+ {
+ _cupsLangPrintf(stderr,
+ _("ppdc: Option %s defined in two different groups on "
+ "line %d of %s\n"), "MediaType", fp->line,
+ fp->filename);
+ c->release();
+ continue;
+ }
o->add_choice(c);
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name after ModelName on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
break;
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name after FileName on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
break;
}
{
_cupsLangPrintf(stderr,
_("ppdc: Expected name after PCFileName on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
break;
}
}
// Add the choice to the Resolution option...
- if ((o = d->find_option("Resolution")) == NULL)
+ if ((o = d->find_option_group("Resolution", &mg)) == NULL)
{
// Create the Resolution option...
o = new ppdcOption(PPDC_PICKONE, "Resolution", NULL, PPDC_SECTION_ANY,
g = general;
g->add_option(o);
}
+ else if (mg != general)
+ {
+ _cupsLangPrintf(stderr,
+ _("ppdc: Option %s defined in two different groups on "
+ "line %d of %s\n"), "Resolution", fp->line,
+ fp->filename);
+ c->release();
+ continue;
+ }
o->add_choice(c);
{
_cupsLangPrintf(stderr,
_("ppdc: Expected string after Version on line %d of "
- "%s!\n"), fp->line, fp->filename);
+ "%s\n"), fp->line, fp->filename);
break;
}
else
{
_cupsLangPrintf(stderr,
- _("ppdc: Unknown token \"%s\" seen on line %d of %s!\n"),
+ _("ppdc: Unknown token \"%s\" seen on line %d of %s\n"),
temp, fp->line, fp->filename);
break;
}
drivers->add(d);
}
}
+ else if (inc && td)
+ td->release();
}
for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next())
{
// Start the driver...
- cupsFilePrintf(fp, "\n// %s %s\n", d->manufacturer->value, d->model_name->value);
+ cupsFilePrintf(fp, "\n// %s %s\n", d->manufacturer->value,
+ d->model_name->value);
cupsFilePuts(fp, "{\n");
// Write the copyright stings...