]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - ppdc/ppdc-source.cxx
License change: Apache License, Version 2.0.
[thirdparty/cups.git] / ppdc / ppdc-source.cxx
index 55f3058a5e603f0c145d662ea6f30d1196ca530a..be24cebae893c7a02680902f1e128ccde1f7eb91 100644 (file)
@@ -1,59 +1,10 @@
 //
-// "$Id$"
-//
-//   Source class for the CUPS PPD Compiler.
-//
-//   Copyright 2007-2009 by Apple Inc.
-//   Copyright 2002-2007 by Easy Software Products.
-//
-//   These coded instructions, statements, and computer programs are the
-//   property of Apple Inc. and are protected by Federal copyright
-//   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
-//   which should have been included with this file.  If this file is
-//   file is missing or damaged, see the license at "http://www.cups.org/".
-//
-// Contents:
-//
-//   ppdcSource::ppdcSource()         - Load a driver source file.
-//   ppdcSource::~ppdcSource()        - Free a driver source file.
-//   ppdcSource::add_include()        - Add an include directory.
-//   ppdcSource::find_driver()        - Find a driver.
-//   ppdcSource::find_include()       - Find an include file.
-//   ppdcSource::find_po()            - Find a message catalog for the given
-//                                      locale...
-//   ppdcSource::find_size()          - Find a media size.
-//   ppdcSource::find_variable()      - Find a variable.
-//   ppdcSource::get_attr()           - Get an attribute.
-//   ppdcSource::get_boolean()        - Get a boolean value.
-//   ppdcSource::get_choice()         - Get a choice.
-//   ppdcSource::get_color_model()    - Get an old-style color model option.
-//   ppdcSource::get_color_order()    - Get an old-style color order value.
-//   ppdcSource::get_color_profile()  - Get a color profile definition.
-//   ppdcSource::get_color_space()    - Get an old-style colorspace value.
-//   ppdcSource::get_constraint()     - Get a constraint.
-//   ppdcSource::get_custom_size()    - Get a custom media size definition from
-//                                      a file.
-//   ppdcSource::get_duplex()         - Get a duplex option.
-//   ppdcSource::get_filter()         - Get a filter.
-//   ppdcSource::get_float()          - Get a single floating-point number.
-//   ppdcSource::get_font()           - Get a font definition.
-//   ppdcSource::get_generic()        - Get a generic old-style option.
-//   ppdcSource::get_group()          - Get an option group.
-//   ppdcSource::get_installable()    - Get an installable option.
-//   ppdcSource::get_integer()        - Get an integer value from a file.
-//   ppdcSource::get_measurement()    - Get a measurement value.
-//   ppdcSource::get_option()         - Get an option definition.
-//   ppdcSource::get_po()             - Get a message catalog.
-//   ppdcSource::get_resolution()     - Get an old-style resolution option.
-//   ppdcSource::get_simple_profile() - Get a simple color profile definition.
-//   ppdcSource::get_size()           - Get a media size definition from a file.
-//   ppdcSource::get_token()          - Get a token from a file.
-//   ppdcSource::get_variable()       - Get a variable definition.
-//   ppdcSource::quotef()             - Write a formatted, quoted string...
-//   ppdcSource::read_file()          - Read a driver source file.
-//   ppdcSource::scan_file()          - Scan a driver source file.
-//   ppdcSource::set_variable()       - Set a variable.
-//   ppdcSource::write_file()         - Write the current source data to a file.
+// Source class for the CUPS PPD Compiler.
+//
+// Copyright 2007-2014 by Apple Inc.
+// Copyright 2002-2007 by Easy Software Products.
+//
+// Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
 //
 
 //
 //
 
 #include "ppdc-private.h"
-#include <cups/globals.h>
 #include <limits.h>
 #include <math.h>
 #include <unistd.h>
 #include <cups/raster.h>
 #include "data/epson.h"
-#include "data/escp.h"
 #include "data/hp.h"
 #include "data/label.h"
-#include "data/pcl.h"
 #ifndef WIN32
 #  include <sys/utsname.h>
 #endif // !WIN32
@@ -128,8 +76,16 @@ ppdcSource::ppdcSource(const char  *f,      // I - File to read
 #else
   struct utsname name;                 // uname information
 
-  vars->add(new ppdcVariable("PLATFORM_NAME", name.sysname));
-  vars->add(new ppdcVariable("PLATFORM_ARCH", name.machine));
+  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)
@@ -182,7 +138,7 @@ ppdcSource::find_driver(const char *f)      // I - Driver file name
 
 
   for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next())
-    if (!strcasecmp(f, d->pc_file_name->value))
+    if (!_cups_strcasecmp(f, d->pc_file_name->value))
       return (d);
 
   return (NULL);
@@ -219,7 +175,7 @@ ppdcSource::find_include(
     if (*ptr != '>')
     {
       _cupsLangPrintf(stderr,
-                      _("ppdc: Invalid #include/#po filename \"%s\"!\n"), n);
+                      _("ppdc: Invalid #include/#po filename \"%s\"."), n);
       return (0);
     }
 
@@ -230,9 +186,9 @@ ppdcSource::find_include(
   {
     // Check for the local file relative to the current directory...
     if (base && *base && f[0] != '/')
-      snprintf(n, nlen, "%s/%s", base, f);
+      snprintf(n, (size_t)nlen, "%s/%s", base, f);
     else
-      strlcpy(n, f, nlen);
+      strlcpy(n, f, (size_t)nlen);
 
     if (!access(n, 0))
       return (n);
@@ -248,7 +204,7 @@ ppdcSource::find_include(
   {
     for (dir = (ppdcString *)includes->first(); dir; dir = (ppdcString *)includes->next())
     {
-      snprintf(n, nlen, "%s/%s", dir->value, f);
+      snprintf(n, (size_t)nlen, "%s/%s", dir->value, f);
       if (!access(n, 0))
         return (n);
     }
@@ -257,11 +213,11 @@ ppdcSource::find_include(
   // Search the standard include directories...
   _cups_globals_t *cg = _cupsGlobals();        // Global data
 
-  snprintf(n, nlen, "%s/ppdc/%s", cg->cups_datadir, f);
+  snprintf(n, (size_t)nlen, "%s/ppdc/%s", cg->cups_datadir, f);
   if (!access(n, 0))
     return (n);
 
-  snprintf(n, nlen, "%s/po/%s", cg->cups_datadir, f);
+  snprintf(n, (size_t)nlen, "%s/po/%s", cg->cups_datadir, f);
   if (!access(n, 0))
     return (n);
   else
@@ -270,7 +226,7 @@ ppdcSource::find_include(
 
 
 //
-// 'ppdcSource::find_po()' - Find a message catalog for the given locale...
+// 'ppdcSource::find_po()' - Find a message catalog for the given locale.
 //
 
 ppdcCatalog *                          // O - Message catalog or NULL
@@ -282,7 +238,7 @@ ppdcSource::find_po(const char *l)  // I - Locale name
   for (cat = (ppdcCatalog *)po_files->first();
        cat;
        cat = (ppdcCatalog *)po_files->next())
-    if (!strcasecmp(l, cat->locale->value))
+    if (!_cups_strcasecmp(l, cat->locale->value))
       return (cat);
 
   return (NULL);
@@ -300,7 +256,7 @@ ppdcSource::find_size(const char *s)        // I - Size name
 
 
   for (m = (ppdcMediaSize *)sizes->first(); m; m = (ppdcMediaSize *)sizes->next())
-    if (!strcasecmp(s, m->name->value))
+    if (!_cups_strcasecmp(s, m->name->value))
       return (m);
 
   return (NULL);
@@ -318,7 +274,7 @@ ppdcSource::find_variable(const char *n)// I - Variable name
 
 
   for (v = (ppdcVariable *)vars->first(); v; v = (ppdcVariable *)vars->next())
-    if (!strcasecmp(n, v->name->value))
+    if (!_cups_strcasecmp(n, v->name->value))
       return (v);
 
   return (NULL);
@@ -345,7 +301,7 @@ ppdcSource::get_attr(ppdcFile *fp,  // I - File to read
   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."),
                    loc ? "LocAttribute" : "Attribute", fp->line, fp->filename);
     return (0);
   }
@@ -353,7 +309,7 @@ ppdcSource::get_attr(ppdcFile *fp,  // I - File to read
   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."),
                    loc ? "LocAttribute" : "Attribute", fp->line, fp->filename);
     return (0);
   }
@@ -364,7 +320,7 @@ ppdcSource::get_attr(ppdcFile *fp,  // I - File to read
   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."),
                    loc ? "LocAttribute" : "Attribute", fp->line, fp->filename);
     return (0);
   }
@@ -386,23 +342,23 @@ ppdcSource::get_boolean(ppdcFile *fp)     // I - File to read
   if (!get_token(fp, buffer, sizeof(buffer)))
   {
     _cupsLangPrintf(stderr,
-                    _("ppdc: Expected boolean value on line %d of %s.\n"),
+                    _("ppdc: Expected boolean value on line %d of %s."),
                    fp->line, fp->filename);
     return (-1);
   }
 
-  if (!strcasecmp(buffer, "on") ||
-      !strcasecmp(buffer, "yes") ||
-      !strcasecmp(buffer, "true"))
+  if (!_cups_strcasecmp(buffer, "on") ||
+      !_cups_strcasecmp(buffer, "yes") ||
+      !_cups_strcasecmp(buffer, "true"))
     return (1);
-  else if (!strcasecmp(buffer, "off") ||
-          !strcasecmp(buffer, "no") ||
-          !strcasecmp(buffer, "false"))
+  else if (!_cups_strcasecmp(buffer, "off") ||
+          !_cups_strcasecmp(buffer, "no") ||
+          !_cups_strcasecmp(buffer, "false"))
     return (0);
   else
   {
     _cupsLangPrintf(stderr,
-                    _("ppdc: Bad boolean value (%s) on line %d of %s.\n"),
+                    _("ppdc: Bad boolean value (%s) on line %d of %s."),
                    buffer, fp->line, fp->filename);
     return (-1);
   }
@@ -427,7 +383,7 @@ ppdcSource::get_choice(ppdcFile *fp)        // I - File to read
   if (!get_token(fp, name, sizeof(name)))
   {
     _cupsLangPrintf(stderr,
-                    _("ppdc: Expected choice name/text on line %d of %s.\n"),
+                    _("ppdc: Expected choice name/text on line %d of %s."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -439,7 +395,7 @@ ppdcSource::get_choice(ppdcFile *fp)        // I - File to read
 
   if (!get_token(fp, code, sizeof(code)))
   {
-    _cupsLangPrintf(stderr, _("ppdc: Expected choice code on line %d of %s.\n"),
+    _cupsLangPrintf(stderr, _("ppdc: Expected choice code on line %d of %s."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -472,7 +428,7 @@ ppdcSource::get_color_model(ppdcFile *fp)
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected name/text combination for ColorModel on "
-                     "line %d of %s!\n"), fp->line, fp->filename);
+                     "line %d of %s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -485,7 +441,7 @@ ppdcSource::get_color_model(ppdcFile *fp)
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected colorspace for ColorModel on line %d of "
-                     "%s!\n"), fp->line, fp->filename);
+                     "%s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -496,7 +452,7 @@ ppdcSource::get_color_model(ppdcFile *fp)
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected color order for ColorModel on line %d of "
-                     "%s!\n"), fp->line, fp->filename);
+                     "%s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -507,7 +463,7 @@ ppdcSource::get_color_model(ppdcFile *fp)
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected compression for ColorModel on line %d of "
-                     "%s!\n"), fp->line, fp->filename);
+                     "%s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -530,12 +486,12 @@ int                                       // O - Color order value
 ppdcSource::get_color_order(
     const char *co)                    // I - Color order string
 {
-  if (!strcasecmp(co, "chunked") ||
-      !strcasecmp(co, "chunky"))
+  if (!_cups_strcasecmp(co, "chunked") ||
+      !_cups_strcasecmp(co, "chunky"))
     return (CUPS_ORDER_CHUNKED);
-  else if (!strcasecmp(co, "banded"))
+  else if (!_cups_strcasecmp(co, "banded"))
     return (CUPS_ORDER_BANDED);
-  else if (!strcasecmp(co, "planar"))
+  else if (!_cups_strcasecmp(co, "planar"))
     return (CUPS_ORDER_PLANAR);
   else
     return (-1);
@@ -565,7 +521,7 @@ ppdcSource::get_color_profile(
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected resolution/mediatype following "
-                     "ColorProfile on line %d of %s!\n"),
+                     "ColorProfile on line %d of %s."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -592,71 +548,71 @@ int                                       // O - Colorspace value
 ppdcSource::get_color_space(
     const char *cs)                    // I - Colorspace string
 {
-  if (!strcasecmp(cs, "w"))
+  if (!_cups_strcasecmp(cs, "w"))
     return (CUPS_CSPACE_W);
-  else if (!strcasecmp(cs, "rgb"))
+  else if (!_cups_strcasecmp(cs, "rgb"))
     return (CUPS_CSPACE_RGB);
-  else if (!strcasecmp(cs, "rgba"))
+  else if (!_cups_strcasecmp(cs, "rgba"))
     return (CUPS_CSPACE_RGBA);
-  else if (!strcasecmp(cs, "k"))
+  else if (!_cups_strcasecmp(cs, "k"))
     return (CUPS_CSPACE_K);
-  else if (!strcasecmp(cs, "cmy"))
+  else if (!_cups_strcasecmp(cs, "cmy"))
     return (CUPS_CSPACE_CMY);
-  else if (!strcasecmp(cs, "ymc"))
+  else if (!_cups_strcasecmp(cs, "ymc"))
     return (CUPS_CSPACE_YMC);
-  else if (!strcasecmp(cs, "cmyk"))
+  else if (!_cups_strcasecmp(cs, "cmyk"))
     return (CUPS_CSPACE_CMYK);
-  else if (!strcasecmp(cs, "ymck"))
+  else if (!_cups_strcasecmp(cs, "ymck"))
     return (CUPS_CSPACE_YMCK);
-  else if (!strcasecmp(cs, "kcmy"))
+  else if (!_cups_strcasecmp(cs, "kcmy"))
     return (CUPS_CSPACE_KCMY);
-  else if (!strcasecmp(cs, "kcmycm"))
+  else if (!_cups_strcasecmp(cs, "kcmycm"))
     return (CUPS_CSPACE_KCMYcm);
-  else if (!strcasecmp(cs, "gmck"))
+  else if (!_cups_strcasecmp(cs, "gmck"))
     return (CUPS_CSPACE_GMCK);
-  else if (!strcasecmp(cs, "gmcs"))
+  else if (!_cups_strcasecmp(cs, "gmcs"))
     return (CUPS_CSPACE_GMCS);
-  else if (!strcasecmp(cs, "white"))
+  else if (!_cups_strcasecmp(cs, "white"))
     return (CUPS_CSPACE_WHITE);
-  else if (!strcasecmp(cs, "gold"))
+  else if (!_cups_strcasecmp(cs, "gold"))
     return (CUPS_CSPACE_GOLD);
-  else if (!strcasecmp(cs, "silver"))
+  else if (!_cups_strcasecmp(cs, "silver"))
     return (CUPS_CSPACE_SILVER);
-  else if (!strcasecmp(cs, "CIEXYZ"))
+  else if (!_cups_strcasecmp(cs, "CIEXYZ"))
     return (CUPS_CSPACE_CIEXYZ);
-  else if (!strcasecmp(cs, "CIELab"))
+  else if (!_cups_strcasecmp(cs, "CIELab"))
     return (CUPS_CSPACE_CIELab);
-  else if (!strcasecmp(cs, "RGBW"))
+  else if (!_cups_strcasecmp(cs, "RGBW"))
     return (CUPS_CSPACE_RGBW);
-  else if (!strcasecmp(cs, "ICC1"))
+  else if (!_cups_strcasecmp(cs, "ICC1"))
     return (CUPS_CSPACE_ICC1);
-  else if (!strcasecmp(cs, "ICC2"))
+  else if (!_cups_strcasecmp(cs, "ICC2"))
     return (CUPS_CSPACE_ICC2);
-  else if (!strcasecmp(cs, "ICC3"))
+  else if (!_cups_strcasecmp(cs, "ICC3"))
     return (CUPS_CSPACE_ICC3);
-  else if (!strcasecmp(cs, "ICC4"))
+  else if (!_cups_strcasecmp(cs, "ICC4"))
     return (CUPS_CSPACE_ICC4);
-  else if (!strcasecmp(cs, "ICC5"))
+  else if (!_cups_strcasecmp(cs, "ICC5"))
     return (CUPS_CSPACE_ICC5);
-  else if (!strcasecmp(cs, "ICC6"))
+  else if (!_cups_strcasecmp(cs, "ICC6"))
     return (CUPS_CSPACE_ICC6);
-  else if (!strcasecmp(cs, "ICC7"))
+  else if (!_cups_strcasecmp(cs, "ICC7"))
     return (CUPS_CSPACE_ICC7);
-  else if (!strcasecmp(cs, "ICC8"))
+  else if (!_cups_strcasecmp(cs, "ICC8"))
     return (CUPS_CSPACE_ICC8);
-  else if (!strcasecmp(cs, "ICC9"))
+  else if (!_cups_strcasecmp(cs, "ICC9"))
     return (CUPS_CSPACE_ICC9);
-  else if (!strcasecmp(cs, "ICCA"))
+  else if (!_cups_strcasecmp(cs, "ICCA"))
     return (CUPS_CSPACE_ICCA);
-  else if (!strcasecmp(cs, "ICCB"))
+  else if (!_cups_strcasecmp(cs, "ICCB"))
     return (CUPS_CSPACE_ICCB);
-  else if (!strcasecmp(cs, "ICCC"))
+  else if (!_cups_strcasecmp(cs, "ICCC"))
     return (CUPS_CSPACE_ICCC);
-  else if (!strcasecmp(cs, "ICCD"))
+  else if (!_cups_strcasecmp(cs, "ICCD"))
     return (CUPS_CSPACE_ICCD);
-  else if (!strcasecmp(cs, "ICCE"))
+  else if (!_cups_strcasecmp(cs, "ICCE"))
     return (CUPS_CSPACE_ICCE);
-  else if (!strcasecmp(cs, "ICCF"))
+  else if (!_cups_strcasecmp(cs, "ICCF"))
     return (CUPS_CSPACE_ICCF);
   else
     return (-1);
@@ -688,7 +644,7 @@ ppdcSource::get_constraint(ppdcFile *fp)// I - File to read
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected constraints string for UIConstraints on "
-                     "line %d of %s!\n"), fp->line, fp->filename);
+                     "line %d of %s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -697,7 +653,7 @@ ppdcSource::get_constraint(ppdcFile *fp)// I - File to read
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -720,7 +676,7 @@ ppdcSource::get_constraint(ppdcFile *fp)// I - File to read
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -819,15 +775,15 @@ ppdcSource::get_duplex(ppdcFile   *fp,    // I - File to read from
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected duplex type after Duplex on line %d of "
-                     "%s!\n"), fp->line, fp->filename);
+                     "%s."), fp->line, fp->filename);
     return;
   }
 
   if (cond_state)
     return;
 
-  if (!strcasecmp(temp, "none") || !strcasecmp(temp, "false") ||
-      !strcasecmp(temp, "no") || !strcasecmp(temp, "off"))
+  if (!_cups_strcasecmp(temp, "none") || !_cups_strcasecmp(temp, "false") ||
+      !_cups_strcasecmp(temp, "no") || !_cups_strcasecmp(temp, "off"))
   {
     g = d->find_group("General");
     if ((o = g->find_option("Duplex")) != NULL)
@@ -842,10 +798,10 @@ ppdcSource::get_duplex(ppdcFile   *fp,    // I - File to read from
        break;
       }
   }
-  else if (!strcasecmp(temp, "normal") || !strcasecmp(temp, "true") ||
-          !strcasecmp(temp, "yes") || !strcasecmp(temp, "on") ||
-          !strcasecmp(temp, "flip") || !strcasecmp(temp, "rotated") ||
-          !strcasecmp(temp, "manualtumble"))
+  else if (!_cups_strcasecmp(temp, "normal") || !_cups_strcasecmp(temp, "true") ||
+          !_cups_strcasecmp(temp, "yes") || !_cups_strcasecmp(temp, "on") ||
+          !_cups_strcasecmp(temp, "flip") || !_cups_strcasecmp(temp, "rotated") ||
+          !_cups_strcasecmp(temp, "manualtumble"))
   {
     g = d->find_group("General");
     o = g->find_option("Duplex");
@@ -853,7 +809,7 @@ ppdcSource::get_duplex(ppdcFile   *fp,      // I - File to read from
     if (!o)
     {
       o = new ppdcOption(PPDC_PICKONE, "Duplex", "2-Sided Printing",
-                        !strcasecmp(temp, "flip") ? PPDC_SECTION_PAGE :
+                        !_cups_strcasecmp(temp, "flip") ? PPDC_SECTION_PAGE :
                                                     PPDC_SECTION_ANY, 10.0f);
       o->add_choice(new ppdcChoice("None", "Off (1-Sided)",
                                   "<</Duplex false>>setpagedevice"));
@@ -870,12 +826,12 @@ ppdcSource::get_duplex(ppdcFile   *fp,    // I - File to read from
         attr = (ppdcAttr *)d->attrs->next())
       if (!strcmp(attr->name->value, "cupsFlipDuplex"))
       {
-        if (strcasecmp(temp, "flip"))
+        if (_cups_strcasecmp(temp, "flip"))
           d->attrs->remove(attr);
        break;
       }
 
-    if (!strcasecmp(temp, "flip") && !attr)
+    if (!_cups_strcasecmp(temp, "flip") && !attr)
       d->add_attr(new ppdcAttr("cupsFlipDuplex", NULL, NULL, "true"));
 
     for (attr = (ppdcAttr *)d->attrs->first();
@@ -887,18 +843,18 @@ ppdcSource::get_duplex(ppdcFile   *fp,    // I - File to read from
        break;
       }
 
-    if (!strcasecmp(temp, "flip"))
+    if (!_cups_strcasecmp(temp, "flip"))
       d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "Flipped"));
-    else if (!strcasecmp(temp, "rotated"))
+    else if (!_cups_strcasecmp(temp, "rotated"))
       d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "Rotated"));
-    else if (!strcasecmp(temp, "manualtumble"))
+    else if (!_cups_strcasecmp(temp, "manualtumble"))
       d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "ManualTumble"));
     else
       d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "Normal"));
   }
   else
     _cupsLangPrintf(stderr,
-                    _("ppdc: Unknown duplex type \"%s\" on line %d of %s!\n"),
+                    _("ppdc: Unknown duplex type \"%s\" on line %d of %s."),
                    temp, fp->line, fp->filename);
 }
 
@@ -924,7 +880,7 @@ ppdcSource::get_filter(ppdcFile *fp)        // I - File to read
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -938,7 +894,7 @@ ppdcSource::get_filter(ppdcFile *fp)        // I - File to read
     while (isspace(*ptr))
       ptr ++;
 
-    strcpy(program, ptr);
+    strlcpy(program, ptr, sizeof(program));
   }
   else
   {
@@ -947,7 +903,7 @@ ppdcSource::get_filter(ppdcFile *fp)        // I - File to read
     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."),
                      fp->line, fp->filename);
       return (NULL);
     }
@@ -957,14 +913,14 @@ ppdcSource::get_filter(ppdcFile *fp)      // I - File to read
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Invalid empty MIME type for filter on line %d of "
-                     "%s!\n"), fp->line, fp->filename);
+                     "%s."), 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."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -973,7 +929,7 @@ ppdcSource::get_filter(ppdcFile *fp)        // I - File to read
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Invalid empty program name for filter on line %d "
-                     "of %s!\n"), fp->line, fp->filename);
+                     "of %s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -996,7 +952,7 @@ ppdcSource::get_float(ppdcFile *fp) // I - File to read
   // 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."),
                    fp->line, fp->filename);
     return (-1.0f);
   }
@@ -1007,7 +963,7 @@ ppdcSource::get_float(ppdcFile *fp)        // I - File to read
   {
     _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."), temp, fp->line, fp->filename);
     return (-1.0f);
   }
   else
@@ -1050,7 +1006,7 @@ ppdcSource::get_font(ppdcFile *fp)        // I - File to read
   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."),
                    fp->line, fp->filename);
     return (0);
   }
@@ -1070,7 +1026,7 @@ ppdcSource::get_font(ppdcFile *fp)        // I - File to read
     {
       _cupsLangPrintf(stderr,
                       _("ppdc: Expected encoding after Font on line %d of "
-                       "%s!\n"), fp->line, fp->filename);
+                       "%s."), fp->line, fp->filename);
       return (0);
     }
 
@@ -1078,7 +1034,7 @@ ppdcSource::get_font(ppdcFile *fp)        // I - File to read
     {
       _cupsLangPrintf(stderr,
                       _("ppdc: Expected version after Font on line %d of "
-                       "%s!\n"), fp->line, fp->filename);
+                       "%s."), fp->line, fp->filename);
       return (0);
     }
 
@@ -1086,26 +1042,26 @@ ppdcSource::get_font(ppdcFile *fp)      // I - File to read
     {
       _cupsLangPrintf(stderr,
                       _("ppdc: Expected charset after Font on line %d of "
-                       "%s!\n"), fp->line, fp->filename);
+                       "%s."), 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."),
                      fp->line, fp->filename);
       return (0);
     }
 
-    if (!strcasecmp(temp, "ROM"))
+    if (!_cups_strcasecmp(temp, "ROM"))
       status = PPDC_FONT_ROM;
-    else if (!strcasecmp(temp, "Disk"))
+    else if (!_cups_strcasecmp(temp, "Disk"))
       status = PPDC_FONT_DISK;
     else
     {
       _cupsLangPrintf(stderr,
-                      _("ppdc: Bad status keyword %s on line %d of %s!\n"),
+                      _("ppdc: Bad status keyword %s on line %d of %s."),
                      temp, fp->line, fp->filename);
       return (0);
     }
@@ -1148,7 +1104,7 @@ ppdcSource::get_generic(ppdcFile   *fp,   // I - File to read
   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."),
                    keyword, fp->line, fp->filename);
     return (NULL);
   }
@@ -1197,7 +1153,7 @@ ppdcSource::get_group(ppdcFile   *fp,     // I - File to read
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -1238,7 +1194,7 @@ ppdcSource::get_installable(ppdcFile *fp)
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected name/text after Installable on line %d "
-                     "of %s!\n"), fp->line, fp->filename);
+                     "of %s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -1313,7 +1269,7 @@ ppdcSource::get_integer(const char *v)    // I - Value string
     while (*v && *v != ')')
     {
       // Skip leading whitespace...
-      while (*v && isspace(*v & 255));
+      while (*v && isspace(*v & 255))
         v ++;
 
       if (!*v || *v == ')')
@@ -1333,7 +1289,8 @@ ppdcSource::get_integer(const char *v)    // I - Value string
         // NAME logicop value
        for (newv = (char *)v + 1;
             *newv && (isalnum(*newv & 255) || *newv == '_');
-            newv ++);
+            newv ++)
+         /* do nothing */;
 
         ch    = *newv;
        *newv = '\0';
@@ -1356,17 +1313,17 @@ ppdcSource::get_integer(const char *v)  // I - Value string
        while (isspace(*newv & 255))
          newv ++;
 
-        if (strncmp(newv, "==", 2))
+        if (!strncmp(newv, "==", 2))
        {
          compop = PPDC_EQ;
          newv += 2;
        }
-        else if (strncmp(newv, "!=", 2))
+        else if (!strncmp(newv, "!=", 2))
         {
          compop = PPDC_NE;
          newv += 2;
        }
-        else if (strncmp(newv, "<=", 2))
+        else if (!strncmp(newv, "<=", 2))
         {
          compop = PPDC_LE;
          newv += 2;
@@ -1376,7 +1333,7 @@ ppdcSource::get_integer(const char *v)    // I - Value string
          compop = PPDC_LT;
          newv ++;
        }
-        else if (strncmp(newv, ">=", 2))
+        else if (!strncmp(newv, ">=", 2))
         {
          compop = PPDC_GE;
          newv += 2;
@@ -1397,7 +1354,7 @@ ppdcSource::get_integer(const char *v)    // I - Value string
           if (*newv == ')' || !*newv)
            return (-1);
 
-         if (isdigit(*v & 255) || *v == '-' || *v == '+')
+         if (isdigit(*newv & 255) || *newv == '-' || *newv == '+')
          {
            // Get the second number...
            temp2 = strtol(newv, &newv, 0);
@@ -1493,7 +1450,7 @@ ppdcSource::get_integer(ppdcFile *fp)     // I - File to read
 
   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."),
                    fp->line, fp->filename);
     return (-1);
   }
@@ -1523,17 +1480,17 @@ ppdcSource::get_measurement(ppdcFile *fp)
   val = (float)strtod(buffer, &ptr);
 
   // Check for a trailing unit specifier...
-  if (!strcasecmp(ptr, "mm"))
+  if (!_cups_strcasecmp(ptr, "mm"))
     val *= 72.0f / 25.4f;
-  else if (!strcasecmp(ptr, "cm"))
+  else if (!_cups_strcasecmp(ptr, "cm"))
     val *= 72.0f / 2.54f;
-  else if (!strcasecmp(ptr, "m"))
+  else if (!_cups_strcasecmp(ptr, "m"))
     val *= 72.0f / 0.0254f;
-  else if (!strcasecmp(ptr, "in"))
+  else if (!_cups_strcasecmp(ptr, "in"))
     val *= 72.0f;
-  else if (!strcasecmp(ptr, "ft"))
+  else if (!_cups_strcasecmp(ptr, "ft"))
     val *= 72.0f * 12.0f;
-  else if (strcasecmp(ptr, "pt") && *ptr)
+  else if (_cups_strcasecmp(ptr, "pt") && *ptr)
     return (-1.0f);
 
   return (val);
@@ -1556,6 +1513,7 @@ ppdcSource::get_option(ppdcFile   *fp,    // I - File to read
   ppdcOptSection section;              // Option section
   float                order;                  // Option order
   ppdcOption   *o;                     // Option
+  ppdcGroup    *mg;                    // Matching group, if any
 
 
   // Read the Option parameters:
@@ -1564,7 +1522,7 @@ ppdcSource::get_option(ppdcFile   *fp,    // I - File to read
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -1576,21 +1534,21 @@ ppdcSource::get_option(ppdcFile   *fp,  // I - File to read
 
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
 
-  if (!strcasecmp(type, "boolean"))
+  if (!_cups_strcasecmp(type, "boolean"))
     ot = PPDC_BOOLEAN;
-  else if (!strcasecmp(type, "pickone"))
+  else if (!_cups_strcasecmp(type, "pickone"))
     ot = PPDC_PICKONE;
-  else if (!strcasecmp(type, "pickmany"))
+  else if (!_cups_strcasecmp(type, "pickmany"))
     ot = PPDC_PICKMANY;
   else
   {
     _cupsLangPrintf(stderr,
-                    _("ppdc: Invalid option type \"%s\" on line %d of %s!\n"),
+                    _("ppdc: Invalid option type \"%s\" on line %d of %s."),
                    type, fp->line, fp->filename);
     return (NULL);
   }
@@ -1598,35 +1556,35 @@ ppdcSource::get_option(ppdcFile   *fp,  // I - File to read
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
 
-  if (!strcasecmp(type, "AnySetup"))
+  if (!_cups_strcasecmp(type, "AnySetup"))
     section = PPDC_SECTION_ANY;
-  else if (!strcasecmp(type, "DocumentSetup"))
+  else if (!_cups_strcasecmp(type, "DocumentSetup"))
     section = PPDC_SECTION_DOCUMENT;
-  else if (!strcasecmp(type, "ExitServer"))
+  else if (!_cups_strcasecmp(type, "ExitServer"))
     section = PPDC_SECTION_EXIT;
-  else if (!strcasecmp(type, "JCLSetup"))
+  else if (!_cups_strcasecmp(type, "JCLSetup"))
     section = PPDC_SECTION_JCL;
-  else if (!strcasecmp(type, "PageSetup"))
+  else if (!_cups_strcasecmp(type, "PageSetup"))
     section = PPDC_SECTION_PAGE;
-  else if (!strcasecmp(type, "Prolog"))
+  else if (!_cups_strcasecmp(type, "Prolog"))
     section = PPDC_SECTION_PROLOG;
   else
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Invalid option section \"%s\" on line %d of "
-                     "%s!\n"), type, fp->line, fp->filename);
+                     "%s."), 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);
@@ -1635,7 +1593,14 @@ ppdcSource::get_option(ppdcFile   *fp,   // I - File to read
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Option %s redefined with a different type on line "
-                     "%d of %s!\n"), name, fp->line, fp->filename);
+                     "%d of %s."), 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."), name, fp->line, fp->filename);
     return (NULL);
   }
 
@@ -1664,7 +1629,7 @@ ppdcSource::get_po(ppdcFile *fp)  // I - File to read
   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."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -1673,7 +1638,7 @@ ppdcSource::get_po(ppdcFile *fp)  // I - File to read
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected filename after #po %s on line %d of "
-                     "%s!\n"), locale, fp->line, fp->filename);
+                     "%s."), locale, fp->line, fp->filename);
     return (NULL);
   }
 
@@ -1681,7 +1646,7 @@ ppdcSource::get_po(ppdcFile *fp)  // I - File to read
   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."),
                    locale, fp->line, fp->filename);
     return (NULL);
   }
@@ -1692,7 +1657,7 @@ ppdcSource::get_po(ppdcFile *fp)  // I - File to read
   if ((baseptr = strrchr(basedir, '/')) != NULL)
     *baseptr = '\0';
   else
-    strcpy(basedir, ".");
+    strlcpy(basedir, ".", sizeof(basedir));
 
   // Find the po file...
   pofilename[0] = '\0';
@@ -1713,7 +1678,7 @@ ppdcSource::get_po(ppdcFile *fp)  // I - File to read
   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."),
                    poname, fp->line, fp->filename);
     return (NULL);
   }
@@ -1749,7 +1714,7 @@ ppdcSource::get_resolution(ppdcFile *fp)// I - File to read
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected override field after Resolution on line "
-                     "%d of %s!\n"), fp->line, fp->filename);
+                     "%d of %s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -1766,7 +1731,7 @@ ppdcSource::get_resolution(ppdcFile *fp)// I - File to read
   {
     _cupsLangPrintf(stderr,
                    _("ppdc: Expected name/text after Resolution on line %d of "
-                     "%s!\n"), fp->line, fp->filename);
+                     "%s."), fp->line, fp->filename);
     return (NULL);
   }
 
@@ -1780,7 +1745,7 @@ ppdcSource::get_resolution(ppdcFile *fp)// I - File to read
     case 0 :
         _cupsLangPrintf(stderr,
                        _("ppdc: Bad resolution name \"%s\" on line %d of "
-                         "%s!\n"), name, fp->line, fp->filename);
+                         "%s."), name, fp->line, fp->filename);
         break;
     case 1 :
         ydpi = xdpi;
@@ -1796,26 +1761,26 @@ ppdcSource::get_resolution(ppdcFile *fp)// I - File to read
 
   if (color_order >= 0)
   {
-    snprintf(commptr, sizeof(command) - (commptr - command),
+    snprintf(commptr, sizeof(command) - (size_t)(commptr - command),
              "/cupsColorOrder %d", color_order);
     commptr += strlen(commptr);
   }
 
   if (color_space >= 0)
   {
-    snprintf(commptr, sizeof(command) - (commptr - command),
+    snprintf(commptr, sizeof(command) - (size_t)(commptr - command),
              "/cupsColorSpace %d", color_space);
     commptr += strlen(commptr);
   }
 
   if (compression >= 0)
   {
-    snprintf(commptr, sizeof(command) - (commptr - command),
+    snprintf(commptr, sizeof(command) - (size_t)(commptr - command),
              "/cupsCompression %d", compression);
     commptr += strlen(commptr);
   }
 
-  snprintf(commptr, sizeof(command) - (commptr - command), ">>setpagedevice");
+  snprintf(commptr, sizeof(command) - (size_t)(commptr - command), ">>setpagedevice");
 
   // Return the new choice...
   return (new ppdcChoice(name, text, command));
@@ -1847,7 +1812,7 @@ ppdcSource::get_simple_profile(ppdcFile *fp)
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Expected resolution/mediatype following "
-                     "SimpleColorProfile on line %d of %s!\n"),
+                     "SimpleColorProfile on line %d of %s."),
                    fp->line, fp->filename);
     return (NULL);
   }
@@ -2000,7 +1965,7 @@ ppdcSource::get_token(ppdcFile *fp,       // I - File to read
         if (!isalnum(ch) && ch != '_')
          break;
        else if (nameptr < (name + sizeof(name) - 1))
-         *nameptr++ = fp->get();
+         *nameptr++ = (char)fp->get();
       }
 
       if (nameptr == name)
@@ -2010,14 +1975,14 @@ ppdcSource::get_token(ppdcFile *fp,     // I - File to read
        {
          // $$ = $
          if (bufptr < bufend)
-           *bufptr++ = fp->get();
+           *bufptr++ = (char)fp->get();
        }
        else
        {
          // $ch = $ch
           _cupsLangPrintf(stderr,
                          _("ppdc: Bad variable substitution ($%c) on line %d "
-                           "of %s.\n"), ch, fp->line, fp->filename);
+                           "of %s."), ch, fp->line, fp->filename);
 
          if (bufptr < bufend)
            *bufptr++ = '$';
@@ -2030,16 +1995,18 @@ ppdcSource::get_token(ppdcFile *fp,     // I - File to read
        var = find_variable(name);
        if (var)
        {
-         strncpy(bufptr, var->value->value, bufend - bufptr);
-         bufptr += strlen(var->value->value);
+         strlcpy(bufptr, var->value->value, (size_t)(bufend - bufptr + 1));
+         bufptr += strlen(bufptr);
        }
        else
        {
-         _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;
+         if (!(cond_state & PPDC_COND_SKIP))
+           _cupsLangPrintf(stderr,
+                           _("ppdc: Undefined variable (%s) on line %d of "
+                             "%s."), name, fp->line, fp->filename);
+
+         snprintf(bufptr, (size_t)(bufend - bufptr + 1), "$%s", name);
+         bufptr += strlen(bufptr);
        }
       }
     }
@@ -2080,7 +2047,7 @@ ppdcSource::get_token(ppdcFile *fp,       // I - File to read
         empty = 0;
 
        if (bufptr < bufend)
-         *bufptr++ = ch;
+         *bufptr++ = (char)ch;
       }
     }
     else if (ch == '\'' || ch == '\"')
@@ -2096,7 +2063,7 @@ ppdcSource::get_token(ppdcFile *fp,       // I - File to read
       {
         // Insert the opposing quote char...
        if (bufptr < bufend)
-          *bufptr++ = ch;
+          *bufptr++ = (char)ch;
       }
       else
       {
@@ -2112,14 +2079,14 @@ ppdcSource::get_token(ppdcFile *fp,     // I - File to read
       startline = fp->line;
 
       if (bufptr < bufend)
-       *bufptr++ = ch;
+       *bufptr++ = (char)ch;
     }
     else if ((ch == ')' && quote == '(') || (ch == '>' && quote == '<'))
     {
       quote = 0;
 
       if (bufptr < bufend)
-       *bufptr++ = ch;
+       *bufptr++ = (char)ch;
     }
     else if (ch == '\\')
     {
@@ -2129,13 +2096,13 @@ ppdcSource::get_token(ppdcFile *fp,     // I - File to read
         break;
 
       if (bufptr < bufend)
-        *bufptr++ = ch;
+        *bufptr++ = (char)ch;
     }
     else if (bufptr < bufend)
     {
       empty = 0;
 
-      *bufptr++ = ch;
+      *bufptr++ = (char)ch;
 
       if ((ch == '{' || ch == '}') && !quote)
         break;
@@ -2146,7 +2113,7 @@ ppdcSource::get_token(ppdcFile *fp,       // I - File to read
   {
     _cupsLangPrintf(stderr,
                     _("ppdc: Unterminated string starting with %c on line %d "
-                     "of %s!\n"), quote, startline, fp->filename);
+                     "of %s."), quote, startline, fp->filename);
     return (NULL);
   }
 
@@ -2155,7 +2122,6 @@ ppdcSource::get_token(ppdcFile *fp,       // I - File to read
   else
   {
     *bufptr = '\0';
-//    puts(buffer);
     return (buffer);
   }
 }
@@ -2258,6 +2224,8 @@ ppdcSource::quotef(cups_file_t *fp,       // I - File to write to
       }
       else if (*format == 'h' || *format == 'l' || *format == 'L')
         size = *format++;
+      else
+        size = '\0';
 
       if (!*format)
         break;
@@ -2274,7 +2242,7 @@ ppdcSource::quotef(cups_file_t *fp,       // I - File to write to
            if ((format - bufformat + 1) > (int)sizeof(tformat))
              break;
 
-           strncpy(tformat, bufformat, format - bufformat);
+           memcpy(tformat, bufformat, (size_t)(format - bufformat));
            tformat[format - bufformat] = '\0';
 
            bytes += cupsFilePrintf(fp, tformat, va_arg(ap, double));
@@ -2291,17 +2259,25 @@ ppdcSource::quotef(cups_file_t *fp,     // I - File to write to
            if ((format - bufformat + 1) > (int)sizeof(tformat))
              break;
 
-           strncpy(tformat, bufformat, format - bufformat);
+           memcpy(tformat, bufformat, (size_t)(format - bufformat));
            tformat[format - bufformat] = '\0';
 
-           bytes += cupsFilePrintf(fp, tformat, va_arg(ap, int));
+#  ifdef HAVE_LONG_LONG
+            if (size == 'L')
+             bytes += cupsFilePrintf(fp, tformat, va_arg(ap, long long));
+           else
+#  endif /* HAVE_LONG_LONG */
+            if (size == 'l')
+             bytes += cupsFilePrintf(fp, tformat, va_arg(ap, long));
+           else
+             bytes += cupsFilePrintf(fp, tformat, va_arg(ap, int));
            break;
-           
+
        case 'p' : // Pointer value
            if ((format - bufformat + 1) > (int)sizeof(tformat))
              break;
 
-           strncpy(tformat, bufformat, format - bufformat);
+           memcpy(tformat, bufformat, (size_t)(format - bufformat));
            tformat[format - bufformat] = '\0';
 
            bytes += cupsFilePrintf(fp, tformat, va_arg(ap, void *));
@@ -2315,7 +2291,7 @@ ppdcSource::quotef(cups_file_t *fp,       // I - File to write to
            }
            else
            {
-             cupsFileWrite(fp, va_arg(ap, char *), width);
+             cupsFileWrite(fp, va_arg(ap, char *), (size_t)width);
              bytes += width;
            }
            break;
@@ -2324,7 +2300,7 @@ ppdcSource::quotef(cups_file_t *fp,       // I - File to write to
            if ((s = va_arg(ap, char *)) == NULL)
              s = (char *)"(nil)";
 
-           slen = strlen(s);
+           slen = (int)strlen(s);
            if (slen > width && prec != width)
              width = slen;
 
@@ -2383,7 +2359,7 @@ ppdcSource::read_file(const char  *f,     // I - File to read
   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\"."), f);
 }
 
 
@@ -2398,6 +2374,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 {
   ppdcDriver   *d;                     // Current driver
   ppdcGroup    *g,                     // Current group
+               *mg,                    // Matching group
                *general,               // General options group
                *install;               // Installable options group
   ppdcOption   *o;                     // Current option
@@ -2409,7 +2386,10 @@ ppdcSource::scan_file(ppdcFile   *fp,    // I - File to read
 
   // Initialize things as needed...
   if (inc && td)
+  {
     d = td;
+    d->retain();
+  }
   else
     d = new ppdcDriver(td);
 
@@ -2447,28 +2427,28 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
       isdefault = 0;
     }
 
-    if (!strcasecmp(temp, "}"))
+    if (!_cups_strcasecmp(temp, "}"))
     {
       // Close this one out...
       break;
     }
-    else if (!strcasecmp(temp, "{"))
+    else if (!_cups_strcasecmp(temp, "{"))
     {
       // Open a new child...
       scan_file(fp, d);
     }
-    else if (!strcasecmp(temp, "#if"))
+    else if (!_cups_strcasecmp(temp, "#if"))
     {
       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."),
                        fp->line, fp->filename);
        break;
       }
 
       cond_current ++;
-      if (get_integer(fp))
+      if (get_integer(fp) > 0)
         *cond_current = PPDC_COND_SATISFIED;
       else
       {
@@ -2476,11 +2456,11 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
        cond_state    |= PPDC_COND_SKIP;
       }
     }
-    else if (!strcasecmp(temp, "#elif"))
+    else if (!_cups_strcasecmp(temp, "#elif"))
     {
       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."),
                        fp->line, fp->filename);
         break;
       }
@@ -2490,7 +2470,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
         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;
@@ -2511,11 +2491,11 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
        else
          cond_temp --;
     }
-    else if (!strcasecmp(temp, "#else"))
+    else if (!_cups_strcasecmp(temp, "#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."),
                        fp->line, fp->filename);
         break;
       }
@@ -2541,11 +2521,11 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
        else
          cond_temp --;
     }
-    else if (!strcasecmp(temp, "#endif"))
+    else if (!_cups_strcasecmp(temp, "#endif"))
     {
       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."),
                        fp->line, fp->filename);
         break;
       }
@@ -2565,12 +2545,12 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
        else
          cond_temp --;
     }
-    else if (!strcasecmp(temp, "#define"))
+    else if (!_cups_strcasecmp(temp, "#define"))
     {
       // Get the variable...
       get_variable(fp);
     }
-    else if (!strcasecmp(temp, "#include"))
+    else if (!_cups_strcasecmp(temp, "#include"))
     {
       // #include filename
       char     basedir[1024],          // Base directory
@@ -2587,7 +2567,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected include filename on line %d of "
-                         "%s!\n"), fp->line, fp->filename);
+                         "%s."), fp->line, fp->filename);
         break;
       }
 
@@ -2600,7 +2580,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       if ((baseptr = strrchr(basedir, '/')) != NULL)
        *baseptr = '\0';
       else
-       strcpy(basedir, ".");
+       strlcpy(basedir, ".", sizeof(basedir));
 
       // Find the include file...
       if (find_include(inctemp, basedir, incname, sizeof(incname)))
@@ -2611,7 +2591,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
        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\"."),
                          incname);
       }
       else
@@ -2619,11 +2599,11 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
        // 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."), inctemp, fp->line, fp->filename);
        break;
       }
     }
-    else if (!strcasecmp(temp, "#media"))
+    else if (!_cups_strcasecmp(temp, "#media"))
     {
       ppdcMediaSize    *m;             // Media size
 
@@ -2638,7 +2618,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
           sizes->add(m);
       }
     }
-    else if (!strcasecmp(temp, "#po"))
+    else if (!_cups_strcasecmp(temp, "#po"))
     {
       ppdcCatalog      *cat;           // Message catalog
 
@@ -2653,14 +2633,14 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
          po_files->add(cat);
       }
     }
-    else if (!strcasecmp(temp, "Attribute") ||
-             !strcasecmp(temp, "LocAttribute"))
+    else if (!_cups_strcasecmp(temp, "Attribute") ||
+             !_cups_strcasecmp(temp, "LocAttribute"))
     {
       ppdcAttr *a;                     // Attribute
 
 
       // Get an attribute...
-      a = get_attr(fp, !strcasecmp(temp, "LocAttribute"));
+      a = get_attr(fp, !_cups_strcasecmp(temp, "LocAttribute"));
       if (a)
       {
         if (cond_state)
@@ -2669,7 +2649,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
           d->add_attr(a);
       }
     }
-    else if (!strcasecmp(temp, "Choice"))
+    else if (!_cups_strcasecmp(temp, "Choice"))
     {
       // Get a choice...
       c = get_choice(fp);
@@ -2687,7 +2667,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Choice found on line %d of %s with no "
-                         "Option!\n"), fp->line, fp->filename);
+                         "Option."), fp->line, fp->filename);
         break;
       }
 
@@ -2696,7 +2676,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       if (isdefault)
         o->set_defchoice(c);
     }
-    else if (!strcasecmp(temp, "ColorDevice"))
+    else if (!_cups_strcasecmp(temp, "ColorDevice"))
     {
       // ColorDevice boolean
       if (cond_state)
@@ -2704,7 +2684,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       else
         d->color_device = get_boolean(fp);
     }
-    else if (!strcasecmp(temp, "ColorModel"))
+    else if (!_cups_strcasecmp(temp, "ColorModel"))
     {
       // Get the color model
       c = get_color_model(fp);
@@ -2733,7 +2713,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 
       o = NULL;
     }
-    else if (!strcasecmp(temp, "ColorProfile"))
+    else if (!_cups_strcasecmp(temp, "ColorProfile"))
     {
       ppdcProfile      *p;             // Color profile
 
@@ -2749,7 +2729,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
           d->profiles->add(p);
       }
     }
-    else if (!strcasecmp(temp, "Copyright"))
+    else if (!_cups_strcasecmp(temp, "Copyright"))
     {
       // Copyright string
       char     copytemp[8192],         // Copyright string
@@ -2762,7 +2742,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected string after Copyright on line %d "
-                         "of %s!\n"), fp->line, fp->filename);
+                         "of %s."), fp->line, fp->filename);
        break;
       }
 
@@ -2778,7 +2758,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
         d->copyright->add(new ppdcString(copyptr));
       }
     }
-    else if (!strcasecmp(temp, "CustomMedia"))
+    else if (!_cups_strcasecmp(temp, "CustomMedia"))
     {
       ppdcMediaSize    *m;             // Media size
 
@@ -2798,7 +2778,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       if (isdefault)
         d->set_default_size(m);
     }
-    else if (!strcasecmp(temp, "Cutter"))
+    else if (!_cups_strcasecmp(temp, "Cutter"))
     {
       // Cutter boolean
       int      have_cutter;            // Have a paper cutter?
@@ -2825,7 +2805,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 
       o = NULL;
     }
-    else if (!strcasecmp(temp, "Darkness"))
+    else if (!_cups_strcasecmp(temp, "Darkness"))
     {
       // Get the darkness choice...
       c = get_generic(fp, "Darkness", NULL, "cupsCompression");
@@ -2839,13 +2819,22 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
       }
 
       // 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."), "cupsDarkness", fp->line,
+                       fp->filename);
+       c->release();
+       continue;
+      }
 
       o->add_choice(c);
 
@@ -2854,7 +2843,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 
       o = NULL;
     }
-    else if (!strcasecmp(temp, "DriverType"))
+    else if (!_cups_strcasecmp(temp, "DriverType"))
     {
       int      i;                      // Looping var
 
@@ -2864,7 +2853,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected driver type keyword following "
-                         "DriverType on line %d of %s!\n"),
+                         "DriverType on line %d of %s."),
                        fp->line, fp->filename);
         continue;
       }
@@ -2873,21 +2862,21 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
         continue;
 
       for (i = 0; i < (int)(sizeof(driver_types) / sizeof(driver_types[0])); i ++)
-        if (!strcasecmp(temp, driver_types[i]))
+        if (!_cups_strcasecmp(temp, driver_types[i]))
          break;
 
       if (i < (int)(sizeof(driver_types) / sizeof(driver_types[0])))
         d->type = (ppdcDrvType)i;
-      else if (!strcasecmp(temp, "dymo"))
+      else if (!_cups_strcasecmp(temp, "dymo"))
         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."),
                        temp, fp->line, fp->filename);
     }
-    else if (!strcasecmp(temp, "Duplex"))
+    else if (!_cups_strcasecmp(temp, "Duplex"))
       get_duplex(fp, d);
-    else if (!strcasecmp(temp, "Filter"))
+    else if (!_cups_strcasecmp(temp, "Filter"))
     {
       ppdcFilter       *f;             // Filter
 
@@ -2902,7 +2891,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
           d->filters->add(f);
       }
     }
-    else if (!strcasecmp(temp, "Finishing"))
+    else if (!_cups_strcasecmp(temp, "Finishing"))
     {
       // Get the finishing choice...
       c = get_generic(fp, "Finishing", "OutputType", NULL);
@@ -2916,13 +2905,22 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
       }
 
       // 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."), "cupsFinishing", fp->line,
+                       fp->filename);
+       c->release();
+       continue;
+      }
 
       o->add_choice(c);
 
@@ -2931,8 +2929,8 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 
       o = NULL;
     }
-    else if (!strcasecmp(temp, "Font") ||
-             !strcasecmp(temp, "#font"))
+    else if (!_cups_strcasecmp(temp, "Font") ||
+             !_cups_strcasecmp(temp, "#font"))
     {
       ppdcFont *f;                     // Font
 
@@ -2945,7 +2943,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
          f->release();
        else
        {
-         if (!strcasecmp(temp, "#font"))
+         if (!_cups_strcasecmp(temp, "#font"))
            base_fonts->add(f);
          else
            d->add_font(f);
@@ -2955,7 +2953,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
        }
       }
     }
-    else if (!strcasecmp(temp, "Group"))
+    else if (!_cups_strcasecmp(temp, "Group"))
     {
       // Get a group...
       ppdcGroup *tempg = get_group(fp, d);
@@ -2976,7 +2974,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
         g = tempg;
       }
     }
-    else if (!strcasecmp(temp, "HWMargins"))
+    else if (!_cups_strcasecmp(temp, "HWMargins"))
     {
       // HWMargins left bottom right top
       d->left_margin   = get_measurement(fp);
@@ -2984,7 +2982,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       d->right_margin  = get_measurement(fp);
       d->top_margin    = get_measurement(fp);
     }
-    else if (!strcasecmp(temp, "InputSlot"))
+    else if (!_cups_strcasecmp(temp, "InputSlot"))
     {
       // Get the input slot choice...
       c = get_generic(fp, "InputSlot", NULL, "MediaPosition");
@@ -2998,7 +2996,8 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       }
 
       // 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",
@@ -3006,6 +3005,15 @@ ppdcSource::scan_file(ppdcFile   *fp,    // I - File to read
        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."), "InputSlot", fp->line,
+                       fp->filename);
+       c->release();
+       continue;
+      }
 
       o->add_choice(c);
 
@@ -3014,7 +3022,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 
       o = NULL;
     }
-    else if (!strcasecmp(temp, "Installable"))
+    else if (!_cups_strcasecmp(temp, "Installable"))
     {
       // Get the installable option...
       o = get_installable(fp);
@@ -3030,7 +3038,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
         o = NULL;
       }
     }
-    else if (!strcasecmp(temp, "ManualCopies"))
+    else if (!_cups_strcasecmp(temp, "ManualCopies"))
     {
       // ManualCopies boolean
       if (cond_state)
@@ -3038,7 +3046,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       else
         d->manual_copies = get_boolean(fp);
     }
-    else if (!strcasecmp(temp, "Manufacturer"))
+    else if (!_cups_strcasecmp(temp, "Manufacturer"))
     {
       // Manufacturer name
       char     name[256];              // Model name string
@@ -3048,14 +3056,14 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected name after Manufacturer on line %d "
-                         "of %s!\n"), fp->line, fp->filename);
+                         "of %s."), fp->line, fp->filename);
        break;
       }
 
       if (!cond_state)
         d->set_manufacturer(name);
     }
-    else if (!strcasecmp(temp, "MaxSize"))
+    else if (!_cups_strcasecmp(temp, "MaxSize"))
     {
       // MaxSize width length
       if (cond_state)
@@ -3069,7 +3077,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
        d->max_length = get_measurement(fp);
       }
     }
-    else if (!strcasecmp(temp, "MediaSize"))
+    else if (!_cups_strcasecmp(temp, "MediaSize"))
     {
       // MediaSize keyword
       char             name[41];       // Media size name
@@ -3081,7 +3089,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected name after MediaSize on line %d of "
-                         "%s!\n"), fp->line, fp->filename);
+                         "%s."), fp->line, fp->filename);
        break;
       }
 
@@ -3094,7 +3102,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Unknown media size \"%s\" on line %d of "
-                         "%s!\n"), name, fp->line, fp->filename);
+                         "%s."), name, fp->line, fp->filename);
        break;
       }
 
@@ -3108,7 +3116,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       if (isdefault)
         d->set_default_size(dm);
     }
-    else if (!strcasecmp(temp, "MediaType"))
+    else if (!_cups_strcasecmp(temp, "MediaType"))
     {
       // Get the media type choice...
       c = get_generic(fp, "MediaType", "MediaType", "cupsMediaType");
@@ -3122,7 +3130,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       }
 
       // 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",
@@ -3130,6 +3138,15 @@ ppdcSource::scan_file(ppdcFile   *fp,    // I - File to read
        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."), "MediaType", fp->line,
+                       fp->filename);
+       c->release();
+       continue;
+      }
 
       o->add_choice(c);
 
@@ -3138,7 +3155,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 
       o = NULL;
     }
-    else if (!strcasecmp(temp, "MinSize"))
+    else if (!_cups_strcasecmp(temp, "MinSize"))
     {
       // MinSize width length
       if (cond_state)
@@ -3152,7 +3169,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
        d->min_length = get_measurement(fp);
       }
     }
-    else if (!strcasecmp(temp, "ModelName"))
+    else if (!_cups_strcasecmp(temp, "ModelName"))
     {
       // ModelName name
       char     name[256];              // Model name string
@@ -3162,14 +3179,14 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected name after ModelName on line %d of "
-                         "%s!\n"), fp->line, fp->filename);
+                         "%s."), fp->line, fp->filename);
        break;
       }
 
       if (!cond_state)
         d->set_model_name(name);
     }
-    else if (!strcasecmp(temp, "ModelNumber"))
+    else if (!_cups_strcasecmp(temp, "ModelNumber"))
     {
       // ModelNumber number
       if (cond_state)
@@ -3177,7 +3194,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       else
         d->model_number = get_integer(fp);
     }
-    else if (!strcasecmp(temp, "Option"))
+    else if (!_cups_strcasecmp(temp, "Option"))
     {
       // Get an option...
       ppdcOption *tempo = get_option(fp, d, g);
@@ -3198,7 +3215,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
         o = tempo;
       }
     }
-    else if (!strcasecmp(temp, "FileName"))
+    else if (!_cups_strcasecmp(temp, "FileName"))
     {
       // FileName name
       char     name[256];              // Filename string
@@ -3208,14 +3225,14 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected name after FileName on line %d of "
-                         "%s!\n"), fp->line, fp->filename);
+                         "%s."), fp->line, fp->filename);
        break;
       }
 
       if (!cond_state)
         d->set_file_name(name);
     }
-    else if (!strcasecmp(temp, "PCFileName"))
+    else if (!_cups_strcasecmp(temp, "PCFileName"))
     {
       // PCFileName name
       char     name[256];              // PC filename string
@@ -3225,14 +3242,14 @@ ppdcSource::scan_file(ppdcFile   *fp,   // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected name after PCFileName on line %d of "
-                         "%s!\n"), fp->line, fp->filename);
+                         "%s."), fp->line, fp->filename);
        break;
       }
 
       if (!cond_state)
         d->set_pc_file_name(name);
     }
-    else if (!strcasecmp(temp, "Resolution"))
+    else if (!_cups_strcasecmp(temp, "Resolution"))
     {
       // Get the resolution choice...
       c = get_resolution(fp);
@@ -3246,7 +3263,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       }
 
       // 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,
@@ -3254,6 +3271,15 @@ ppdcSource::scan_file(ppdcFile   *fp,    // I - File to read
        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."), "Resolution", fp->line,
+                       fp->filename);
+       c->release();
+       continue;
+      }
 
       o->add_choice(c);
 
@@ -3262,7 +3288,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
 
       o = NULL;
     }
-    else if (!strcasecmp(temp, "SimpleColorProfile"))
+    else if (!_cups_strcasecmp(temp, "SimpleColorProfile"))
     {
       ppdcProfile      *p;             // Color profile
 
@@ -3278,7 +3304,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
           d->profiles->add(p);
       }
     }
-    else if (!strcasecmp(temp, "Throughput"))
+    else if (!_cups_strcasecmp(temp, "Throughput"))
     {
       // Throughput number
       if (cond_state)
@@ -3286,7 +3312,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       else
         d->throughput = get_integer(fp);
     }
-    else if (!strcasecmp(temp, "UIConstraints"))
+    else if (!_cups_strcasecmp(temp, "UIConstraints"))
     {
       ppdcConstraint   *con;           // Constraint
 
@@ -3301,7 +3327,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
          d->constraints->add(con);
       }
     }
-    else if (!strcasecmp(temp, "VariablePaperSize"))
+    else if (!_cups_strcasecmp(temp, "VariablePaperSize"))
     {
       // VariablePaperSize boolean
       if (cond_state)
@@ -3309,7 +3335,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       else
        d->variable_paper_size = get_boolean(fp);
     }
-    else if (!strcasecmp(temp, "Version"))
+    else if (!_cups_strcasecmp(temp, "Version"))
     {
       // Version string
       char     name[256];              // Model name string
@@ -3319,7 +3345,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       {
         _cupsLangPrintf(stderr,
                        _("ppdc: Expected string after Version on line %d of "
-                         "%s!\n"), fp->line, fp->filename);
+                         "%s."), fp->line, fp->filename);
        break;
       }
 
@@ -3329,7 +3355,7 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
     else
     {
       _cupsLangPrintf(stderr,
-                      _("ppdc: Unknown token \"%s\" seen on line %d of %s!\n"),
+                      _("ppdc: Unknown token \"%s\" seen on line %d of %s."),
                      temp, fp->line, fp->filename);
       break;
     }
@@ -3350,6 +3376,8 @@ ppdcSource::scan_file(ppdcFile   *fp,     // I - File to read
       drivers->add(d);
     }
   }
+  else if (inc && td)
+    td->release();
 }
 
 
@@ -3444,7 +3472,8 @@ ppdcSource::write_file(const char *f)     // I - File to write
   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...
@@ -3471,64 +3500,6 @@ ppdcSource::write_file(const char *f)    // I - File to write
     {
       switch (d->type)
       {
-        case PPDC_DRIVER_ESCP :
-           cupsFilePuts(fp, "  ModelNumber (");
-
-           if (d->model_number & ESCP_DOTMATRIX)
-             cupsFilePuts(fp, " $ESCP_DOTMATRIX");
-           if (d->model_number & ESCP_MICROWEAVE)
-             cupsFilePuts(fp, " $ESCP_MICROWEAVE");
-           if (d->model_number & ESCP_STAGGER)
-             cupsFilePuts(fp, " $ESCP_STAGGER");
-           if (d->model_number & ESCP_ESCK)
-             cupsFilePuts(fp, " $ESCP_ESCK");
-           if (d->model_number & ESCP_EXT_UNITS)
-             cupsFilePuts(fp, " $ESCP_EXT_UNITS");
-           if (d->model_number & ESCP_EXT_MARGINS)
-             cupsFilePuts(fp, " $ESCP_EXT_MARGINS");
-           if (d->model_number & ESCP_USB)
-             cupsFilePuts(fp, " $ESCP_USB");
-           if (d->model_number & ESCP_PAGE_SIZE)
-             cupsFilePuts(fp, " $ESCP_PAGE_SIZE");
-           if (d->model_number & ESCP_RASTER_ESCI)
-             cupsFilePuts(fp, " $ESCP_RASTER_ESCI");
-           if (d->model_number & ESCP_REMOTE)
-             cupsFilePuts(fp, " $ESCP_REMOTE");
-
-           cupsFilePuts(fp, ")\n");
-           break;
-
-       case PPDC_DRIVER_PCL :
-           cupsFilePuts(fp, "  ModelNumber (");
-
-           if (d->model_number & PCL_PAPER_SIZE)
-             cupsFilePuts(fp, " $PCL_PAPER_SIZE");
-           if (d->model_number & PCL_INKJET)
-             cupsFilePuts(fp, " $PCL_INKJET");
-           if (d->model_number & PCL_RASTER_END_COLOR)
-             cupsFilePuts(fp, " $PCL_RASTER_END_COLOR");
-           if (d->model_number & PCL_RASTER_CID)
-             cupsFilePuts(fp, " $PCL_RASTER_CID");
-           if (d->model_number & PCL_RASTER_CRD)
-             cupsFilePuts(fp, " $PCL_RASTER_CRD");
-           if (d->model_number & PCL_RASTER_SIMPLE)
-             cupsFilePuts(fp, " $PCL_RASTER_SIMPLE");
-           if (d->model_number & PCL_RASTER_RGB24)
-             cupsFilePuts(fp, " $PCL_RASTER_RGB24");
-           if (d->model_number & PCL_PJL)
-             cupsFilePuts(fp, " $PCL_PJL");
-           if (d->model_number & PCL_PJL_PAPERWIDTH)
-             cupsFilePuts(fp, " $PCL_PJL_PAPERWIDTH");
-           if (d->model_number & PCL_PJL_HPGL2)
-             cupsFilePuts(fp, " $PCL_PJL_HPGL2");
-           if (d->model_number & PCL_PJL_PCL3GUI)
-             cupsFilePuts(fp, " $PCL_PJL_PCL3GUI");
-           if (d->model_number & PCL_PJL_RESOLUTION)
-             cupsFilePuts(fp, " $PCL_PJL_RESOLUTION");
-
-           cupsFilePuts(fp, ")\n");
-           break;
-
        case PPDC_DRIVER_LABEL :
            cupsFilePuts(fp, "  ModelNumber ");
 
@@ -3823,8 +3794,3 @@ ppdcSource::write_file(const char *f)     // I - File to write
 
   return (0);
 }
-
-
-//
-// End of "$Id$".
-//