]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - ppdc/ppdc-driver.cxx
Full sweep of all Clang warnings, plus some bug fixes for incorrect memcpy usage.
[thirdparty/cups.git] / ppdc / ppdc-driver.cxx
index 8453cce3075bbbc1b019803c05352269d5fe0fda..f70da00960ef964dec72e1c8568d80f79568a1e4 100644 (file)
@@ -1,41 +1,23 @@
 //
 // "$Id$"
 //
-//   PPD file compiler definitions for the CUPS PPD Compiler.
+// PPD file compiler definitions for the CUPS PPD Compiler.
 //
-//   Copyright 2007-2009 by Apple Inc.
-//   Copyright 2002-2006 by Easy Software Products.
+// Copyright 2007-2014 by Apple Inc.
+// Copyright 2002-2006 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:
-//
-//   ppdcDriver::ppdcDriver()           - Create a new printer driver.
-//   ppdcDriver::~ppdcDriver()          - Destroy a printer driver.
-//   ppdcDriver::find_attr()            - Find an attribute.
-//   ppdcDriver::find_group()           - Find a group.
-//   ppdcDriver::find_option()          - Find an option.
-//   ppdcDriver::set_custom_size_code() - Set the custom page size code.
-//   ppdcDriver::set_default_font()     - Set the default font name.
-//   ppdcDriver::set_default_size()     - Set the default size name.
-//   ppdcDriver::set_file_name()        - Set the full filename.
-//   ppdcDriver::set_manufacturer()     - Set the manufacturer name.
-//   ppdcDriver::set_model_name()       - Set the model name.
-//   ppdcDriver::set_pc_file_name()     - Set the PC filename.
-//   ppdcDriver::set_version()          - Set the version string.
-//   ppdcDriver::write_ppd_file()       - Write a PPD file...
+// 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/".
 //
 
 //
 // Include necessary headers...
 //
 
-#include "ppdc.h"
-#include <cups/globals.h>
+#include "ppdc-private.h"
 
 
 //
@@ -190,7 +172,7 @@ ppdcDriver::find_attr(const char *k,        // I - Keyword string
   for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
     if (!strcmp(a->name->value, k) &&
         ((!s && (!a->selector->value || !a->selector->value[0])) ||
-        (!s && !a->selector->value && !strcmp(a->selector->value, s))))
+        (s && a->selector->value && !strcmp(a->selector->value, s))))
       return (a);
 
   return (NULL);
@@ -208,7 +190,7 @@ ppdcDriver::find_group(const char *n)       // I - Group name
 
 
   for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
-    if (!strcasecmp(n, g->name->value))
+    if (!_cups_strcasecmp(n, g->name->value))
       return (g);
 
   return (0);
@@ -221,6 +203,19 @@ ppdcDriver::find_group(const char *n)      // I - Group name
 
 ppdcOption *                           // O - Matching option or NULL
 ppdcDriver::find_option(const char *n) // I - Option name
+{
+  return (find_option_group(n, (ppdcGroup **)0));
+}
+
+
+//
+// 'ppdcDriver::find_option_group()' - Find an option and its group.
+//
+
+ppdcOption *                           // O - Matching option or NULL
+ppdcDriver::find_option_group(
+    const char *n,                     // I - Option name
+    ppdcGroup  **mg)                   // O - Matching group or NULL
 {
   ppdcGroup    *g;                     // Current group
   ppdcOption   *o;                     // Current option
@@ -228,8 +223,16 @@ ppdcDriver::find_option(const char *n)     // I - Option name
 
   for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
     for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
-      if (!strcasecmp(n, o->name->value))
+      if (!_cups_strcasecmp(n, o->name->value))
+      {
+        if (mg)
+         *mg = g;
+
         return (o);
+      }
+
+  if (mg)
+    *mg = (ppdcGroup *)0;
 
   return (0);
 }
@@ -378,7 +381,8 @@ ppdcDriver::write_ppd_file(
     ppdcLineEnding le)                 // I - Line endings to use
 {
   bool                 delete_cat;     // Delete the catalog when we are done?
-  char                 query[42];      // Query attribute
+  char                 query[42],      // Query attribute
+                       custom[42];     // Custom attribute
   ppdcString           *s;             // Copyright string
   ppdcGroup            *g;             // Current group
   ppdcOption           *o;             // Current option
@@ -412,10 +416,11 @@ ppdcDriver::write_ppd_file(
 
   // Write the standard header stuff...
   cupsFilePrintf(fp, "*PPD-Adobe: \"4.3\"%s", lf);
-  cupsFilePrintf(fp, "*%% PPD file for %s with CUPS.%s", model_name->value, lf);
+  cupsFilePrintf(fp, "*%%%%%%%% PPD file for %s with CUPS.%s",
+                 model_name->value, lf);
   cupsFilePrintf(fp,
-                 "*%% Created by the CUPS PPD Compiler " CUPS_SVERSION ".%s",
-                lf);
+                 "*%%%%%%%% Created by the CUPS PPD Compiler " CUPS_SVERSION
+                ".%s", lf);
   for (s = (ppdcString *)copyright->first();
        s;
        s = (ppdcString *)copyright->next())
@@ -452,7 +457,7 @@ ppdcDriver::write_ppd_file(
   if ((a = find_attr("ModelName", NULL)) != NULL)
     cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
                   catalog->find_message(a->value->value), lf);
-  else if (strncasecmp(model_name->value, manufacturer->value,
+  else if (_cups_strncasecmp(model_name->value, manufacturer->value,
                        strlen(manufacturer->value)))
     cupsFilePrintf(fp, "*ModelName: \"%s %s\"%s",
                   catalog->find_message(manufacturer->value),
@@ -464,7 +469,7 @@ ppdcDriver::write_ppd_file(
   if ((a = find_attr("ShortNickName", NULL)) != NULL)
     cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
                   catalog->find_message(a->value->value), lf);
-  else if (strncasecmp(model_name->value, manufacturer->value,
+  else if (_cups_strncasecmp(model_name->value, manufacturer->value,
                        strlen(manufacturer->value)))
     cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"%s",
                   catalog->find_message(manufacturer->value),
@@ -476,7 +481,7 @@ ppdcDriver::write_ppd_file(
   if ((a = find_attr("NickName", NULL)) != NULL)
     cupsFilePrintf(fp, "*NickName: \"%s\"%s",
                   catalog->find_message(a->value->value), lf);
-  else if (strncasecmp(model_name->value, manufacturer->value,
+  else if (_cups_strncasecmp(model_name->value, manufacturer->value,
                        strlen(manufacturer->value)))
     cupsFilePrintf(fp, "*NickName: \"%s %s, %s\"%s",
                   catalog->find_message(manufacturer->value),
@@ -530,6 +535,8 @@ ppdcDriver::write_ppd_file(
   else if (type != PPDC_DRIVER_PS)
     cupsFilePrintf(fp, "*TTRasterizer: Type42%s", lf);
 
+  struct lconv *loc = localeconv();
+
   if (attrs->count)
   {
     // Write driver-defined attributes...
@@ -559,6 +566,14 @@ ppdcDriver::write_ppd_file(
           !strcmp(a->name->value, "?PaperDimension")))
         continue;
 
+      if (!strncmp(a->name->value, "Custom", 6) &&
+          find_option(a->name->value + 6))
+       continue;
+
+      if (!strncmp(a->name->value, "ParamCustom", 11) &&
+          find_option(a->name->value + 11))
+       continue;
+
       if (!a->selector->value || !a->selector->value[0])
        cupsFilePrintf(fp, "*%s", a->name->value);
       else if (!a->text->value || !a->text->value[0])
@@ -579,7 +594,7 @@ ppdcDriver::write_ppd_file(
       {
        cupsFilePrintf(fp, ": \"%s\"%s", a->value->value, lf);
 
-       if (strchr(a->value->value, '\n'))
+       if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
           cupsFilePrintf(fp, "*End%s", lf);
       }
       else
@@ -647,16 +662,23 @@ ppdcDriver::write_ppd_file(
     for (p = (ppdcProfile *)profiles->first();
          p;
         p = (ppdcProfile *)profiles->next())
+    {
+      char density[255], gamma[255], profile[9][255];
+
+      _cupsStrFormatd(density, density + sizeof(density), p->density, loc);
+      _cupsStrFormatd(gamma, gamma + sizeof(gamma), p->gamma, loc);
+
+      for (int i = 0; i < 9; i ++)
+       _cupsStrFormatd(profile[i], profile[i] + sizeof(profile[0]),
+                       p->profile[i], loc);
+
       cupsFilePrintf(fp,
-                     "*cupsColorProfile %s/%s: \"%.3f %.3f %.3f %.3f %.3f %.3f "
-                    "%.3f %.3f %.3f %.3f %.3f\"%s",
-                    p->resolution->value, p->media_type->value,
-                    p->density, p->gamma,
-                    p->profile[0], p->profile[1],
-                    p->profile[2], p->profile[3],
-                    p->profile[4], p->profile[5],
-                    p->profile[6], p->profile[7],
-                    p->profile[8], lf);
+                     "*cupsColorProfile %s/%s: \"%s %s %s %s %s %s %s %s %s %s "
+                    "%s\"%s", p->resolution->value, p->media_type->value,
+                    density, gamma, profile[0], profile[1], profile[2],
+                    profile[3], profile[4], profile[5], profile[6], profile[7],
+                    profile[8], lf);
+    }
   }
 
   if (locales)
@@ -688,7 +710,7 @@ ppdcDriver::write_ppd_file(
          // No, skip this one...
           _cupsLangPrintf(stderr,
                          _("ppdc: No message catalog provided for locale "
-                           "%s!\n"), locale->value);
+                           "%s."), locale->value);
           continue;
        }
 
@@ -839,13 +861,21 @@ ppdcDriver::write_ppd_file(
   cupsFilePrintf(fp, "*DefaultImageableArea: %s%s",
                  default_size ? default_size->value : "Letter", lf);
 
+  char left[255], right[255], bottom[255], top[255];
+
   for (m = (ppdcMediaSize *)sizes->first();
        m;
        m = (ppdcMediaSize *)sizes->next())
-    cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%.2f %.2f %.2f %.2f\"%s",
+  {
+    _cupsStrFormatd(left, left + sizeof(left), m->left, loc);
+    _cupsStrFormatd(bottom, bottom + sizeof(bottom), m->bottom, loc);
+    _cupsStrFormatd(right, right + sizeof(right), m->width - m->right, loc);
+    _cupsStrFormatd(top, top + sizeof(top), m->length - m->top, loc);
+
+    cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%s %s %s %s\"%s",
                    m->name->value, catalog->find_message(m->text->value),
-                  m->left, m->bottom, m->width - m->right, m->length - m->top,
-                  lf);
+                  left, bottom, right, top, lf);
+  }
 
   if ((a = find_attr("?ImageableArea", NULL)) != NULL)
   {
@@ -860,12 +890,19 @@ ppdcDriver::write_ppd_file(
   cupsFilePrintf(fp, "*DefaultPaperDimension: %s%s",
                  default_size ? default_size->value : "Letter", lf);
 
+  char width[255], length[255];
+
   for (m = (ppdcMediaSize *)sizes->first();
        m;
        m = (ppdcMediaSize *)sizes->next())
-    cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%.2f %.2f\"%s",
+  {
+    _cupsStrFormatd(width, width + sizeof(width), m->width, loc);
+    _cupsStrFormatd(length, length + sizeof(length), m->length, loc);
+
+    cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%s %s\"%s",
                    m->name->value, catalog->find_message(m->text->value),
-                  m->width, m->length, lf);
+                  width, length, lf);
+  }
 
   if ((a = find_attr("?PaperDimension", NULL)) != NULL)
   {
@@ -879,10 +916,18 @@ ppdcDriver::write_ppd_file(
   // Custom size support...
   if (variable_paper_size)
   {
-    cupsFilePrintf(fp, "*MaxMediaWidth: \"%.2f\"%s", max_width, lf);
-    cupsFilePrintf(fp, "*MaxMediaHeight: \"%.2f\"%s", max_length, lf);
-    cupsFilePrintf(fp, "*HWMargins: %.2f %.2f %.2f %.2f\n",
-                  left_margin, bottom_margin, right_margin, top_margin);
+    _cupsStrFormatd(width, width + sizeof(width), max_width, loc);
+    _cupsStrFormatd(length, length + sizeof(length), max_length, loc);
+
+    _cupsStrFormatd(left, left + sizeof(left), left_margin, loc);
+    _cupsStrFormatd(bottom, bottom + sizeof(bottom), bottom_margin, loc);
+    _cupsStrFormatd(right, right + sizeof(right), right_margin, loc);
+    _cupsStrFormatd(top, top + sizeof(top), top_margin, loc);
+
+    cupsFilePrintf(fp, "*MaxMediaWidth: \"%s\"%s", width, lf);
+    cupsFilePrintf(fp, "*MaxMediaHeight: \"%s\"%s", length, lf);
+    cupsFilePrintf(fp, "*HWMargins: %s %s %s %s%s", left, bottom, right, top,
+                   lf);
 
     if (custom_size_code && custom_size_code->value)
     {
@@ -902,15 +947,29 @@ ppdcDriver::write_ppd_file(
       cupsFilePrintf(fp, "*ParamCustomPageSize Width: %s%s", a->value->value,
                     lf);
     else
-      cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %.2f %.2f%s",
-                     min_width, max_width, lf);
+    {
+      char width0[255];
+
+      _cupsStrFormatd(width0, width0 + sizeof(width0), min_width, loc);
+      _cupsStrFormatd(width, width + sizeof(width), max_width, loc);
+
+      cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s%s",
+                     width0, width, lf);
+    }
 
     if ((a = find_attr("ParamCustomPageSize", "Height")) != NULL)
       cupsFilePrintf(fp, "*ParamCustomPageSize Height: %s%s", a->value->value,
                     lf);
     else
-      cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %.2f %.2f%s",
-                     min_length, max_length, lf);
+    {
+      char length0[255];
+
+      _cupsStrFormatd(length0, length0 + sizeof(length0), min_length, loc);
+      _cupsStrFormatd(length, length + sizeof(length), max_length, loc);
+
+      cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s%s",
+                     length0, length, lf);
+    }
 
     if ((a = find_attr("ParamCustomPageSize", "WidthOffset")) != NULL)
       cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: %s%s",
@@ -931,16 +990,13 @@ ppdcDriver::write_ppd_file(
       cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf);
   }
 
-  if (type != PPDC_DRIVER_PS && !find_attr("RequiresPageRegion", NULL))
-    cupsFilePrintf(fp, "*RequiresPageRegion All: True%s", lf);
-
   // All other options...
   for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
   {
     if (!g->options->count)
       continue;
 
-    if (strcasecmp(g->name->value, "General"))
+    if (_cups_strcasecmp(g->name->value, "General"))
       cupsFilePrintf(fp, "*OpenGroup: %s/%s%s", g->name->value,
                      catalog->find_message(g->text->value), lf);
 
@@ -951,7 +1007,16 @@ ppdcDriver::write_ppd_file(
       if (!o->choices->count)
         continue;
 
-      if (!o->text->value || !strcmp(o->name->value, o->text->value))
+      if (o->section == PPDC_SECTION_JCL)
+      {
+       if (!o->text->value)
+         cupsFilePrintf(fp, "*JCLOpenUI *%s/%s: ", o->name->value,
+                        catalog->find_message(o->name->value));
+       else
+         cupsFilePrintf(fp, "*JCLOpenUI *%s/%s: ", o->name->value,
+                        catalog->find_message(o->text->value));
+      }
+      else if (!o->text->value)
        cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value,
                       catalog->find_message(o->name->value));
       else
@@ -971,7 +1036,10 @@ ppdcDriver::write_ppd_file(
            break;
       }
 
-      cupsFilePrintf(fp, "*OrderDependency: %.1f ", o->order);
+      char order[255];
+      _cupsStrFormatd(order, order + sizeof(order), o->order, loc);
+
+      cupsFilePrintf(fp, "*OrderDependency: %s ", order);
       switch (o->section)
       {
         default :
@@ -1015,9 +1083,9 @@ ppdcDriver::write_ppd_file(
           c = (ppdcChoice *)o->choices->next())
       {
         // Write this choice...
-       if (!c->text->value || !strcmp(c->name->value, c->text->value))
-          cupsFilePrintf(fp, "*%s %s: \"%s\"%s", o->name->value,
-                        catalog->find_message(c->name->value),
+       if (!c->text->value)
+          cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value,
+                         c->name->value, catalog->find_message(c->name->value),
                         c->code->value, lf);
         else
           cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value,
@@ -1034,7 +1102,7 @@ ppdcDriver::write_ppd_file(
 
       if ((a = find_attr(query, NULL)) != NULL)
       {
-       cupsFilePrintf(fp, "*%s: \"%s\"\n", query, a->value->value);
+       cupsFilePrintf(fp, "*%s: \"%s\"%s", query, a->value->value, lf);
 
        if (strchr(a->value->value, '\n') ||
             strchr(a->value->value, '\r'))
@@ -1042,9 +1110,36 @@ ppdcDriver::write_ppd_file(
       }
 
       cupsFilePrintf(fp, "*CloseUI: *%s%s", o->name->value, lf);
+
+      snprintf(custom, sizeof(custom), "Custom%s", o->name->value);
+      if ((a = find_attr(custom, "True")) != NULL)
+      {
+        // Output custom option information...
+        cupsFilePrintf(fp, "*%s True: \"%s\"%s", custom, a->value->value, lf);
+       if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
+         cupsFilePrintf(fp, "*End%s", lf);
+
+        snprintf(custom, sizeof(custom), "ParamCustom%s", o->name->value);
+       for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+       {
+         if (strcmp(a->name->value, custom))
+           continue;
+
+         if (!a->selector->value || !a->selector->value[0])
+           cupsFilePrintf(fp, "*%s", a->name->value);
+         else if (!a->text->value || !a->text->value[0])
+           cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
+                          catalog->find_message(a->selector->value));
+         else
+           cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
+                          catalog->find_message(a->text->value));
+
+          cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
+       }
+      }
     }
 
-    if (strcasecmp(g->name->value, "General"))
+    if (_cups_strcasecmp(g->name->value, "General"))
       cupsFilePrintf(fp, "*CloseGroup: %s%s", g->name->value, lf);
   }
 
@@ -1077,7 +1172,7 @@ ppdcDriver::write_ppd_file(
        cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
                        locale->value,
                       locatalog->find_message(a->value->value), lf);
-      else if (strncasecmp(model_name->value, manufacturer->value,
+      else if (_cups_strncasecmp(model_name->value, manufacturer->value,
                           strlen(manufacturer->value)))
        cupsFilePrintf(fp, "*%s.Translation ModelName/%s %s: \"\"%s",
                        locale->value,
@@ -1092,7 +1187,7 @@ ppdcDriver::write_ppd_file(
        cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
                        locale->value,
                       locatalog->find_message(a->value->value), lf);
-      else if (strncasecmp(model_name->value, manufacturer->value,
+      else if (_cups_strncasecmp(model_name->value, manufacturer->value,
                           strlen(manufacturer->value)))
        cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s %s: \"\"%s",
                        locale->value,
@@ -1107,7 +1202,7 @@ ppdcDriver::write_ppd_file(
        cupsFilePrintf(fp, "*%s.Translation NickName/%s: \"\"%s",
                        locale->value,
                       locatalog->find_message(a->value->value), lf);
-      else if (strncasecmp(model_name->value, manufacturer->value,
+      else if (_cups_strncasecmp(model_name->value, manufacturer->value,
                           strlen(manufacturer->value)))
        cupsFilePrintf(fp, "*%s.Translation NickName/%s %s, %s: \"\"%s",
                        locale->value,
@@ -1139,7 +1234,7 @@ ppdcDriver::write_ppd_file(
        if (!g->options->count)
          continue;
 
-       if (strcasecmp(g->name->value, "General"))
+       if (_cups_strcasecmp(g->name->value, "General"))
          cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
                         g->name->value,
                         locatalog->find_message(g->text->value), lf);
@@ -1174,12 +1269,8 @@ ppdcDriver::write_ppd_file(
       // Finally the localizable attributes...
       for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
       {
-        if ((!a->text || !a->text->value || !a->text->value[0]) &&
-           strncmp(a->name->value, "Custom", 6) &&
-           strncmp(a->name->value, "ParamCustom", 11))
-         continue;
-
         if (!a->localizable &&
+           (!a->text || !a->text->value || !a->text->value[0]) &&
            strcmp(a->name->value, "APCustomColorMatchingName") &&
            strcmp(a->name->value, "APPrinterPreset") &&
            strcmp(a->name->value, "cupsICCProfile") &&
@@ -1187,7 +1278,7 @@ ppdcDriver::write_ppd_file(
            strcmp(a->name->value, "cupsMarkerName") &&
            strncmp(a->name->value, "Custom", 6) &&
            strncmp(a->name->value, "ParamCustom", 11))
-          continue;
+         continue;
 
         cupsFilePrintf(fp, "*%s.%s %s/%s: \"%s\"%s", locale->value,
                       a->name->value, a->selector->value,
@@ -1224,7 +1315,7 @@ ppdcDriver::write_ppd_file(
                     fn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
 
   cupsFilePrintf(fp, "*%% End of %s, %05d bytes.%s", pc_file_name->value,
-                (int)(cupsFileTell(fp) + 25 + strlen(pc_file_name->value)),
+                (int)((size_t)cupsFileTell(fp) + 25 + strlen(pc_file_name->value)),
                 lf);
 
   if (delete_cat)