]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/ppd.c
Update ipp documentation to reflect the behavior of configuring WiFi on IPP USB printers.
[thirdparty/cups.git] / cups / ppd.c
index f958728cbb62ec1eddb714ea4e5c012b53526a8c..ac5dbc62bb8d78aa8de022f8f9bb854d4525eaa8 100644 (file)
@@ -125,6 +125,7 @@ ppdClose(ppd_file_t *ppd)           /* I - PPD file record */
   free(ppd->lang_encoding);
   free(ppd->nickname);
   free(ppd->patches);
+  free(ppd->emulations);
   free(ppd->jcl_begin);
   free(ppd->jcl_end);
   free(ppd->jcl_ps);
@@ -611,8 +612,6 @@ _ppdOpen(
 
   DEBUG_printf(("2_ppdOpen: keyword=%s, string=%p", keyword, string));
 
-  free(string);
-
  /*
   * Allocate memory for the PPD file record...
   */
@@ -627,12 +626,14 @@ _ppdOpen(
     return (NULL);
   }
 
+  free(string);
+  string = NULL;
+
   ppd->language_level = 2;
   ppd->color_device   = 0;
   ppd->colorspace     = PPD_CS_N;
   ppd->landscape      = -90;
-  ppd->coptions       = cupsArrayNew((cups_array_func_t)ppd_compare_coptions,
-                                     NULL);
+  ppd->coptions       = cupsArrayNew((cups_array_func_t)ppd_compare_coptions, NULL);
 
  /*
   * Read lines from the PPD file and add them to the file record...
@@ -705,6 +706,8 @@ _ppdOpen(
           strncmp(ll, keyword, ll_len)))
       {
        DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword));
+       free(string);
+       string = NULL;
        continue;
       }
       else if (localization == _PPD_LOCALIZATION_ICC_PROFILES)
@@ -724,6 +727,8 @@ _ppdOpen(
        if (i >= (int)(sizeof(color_keywords) / sizeof(color_keywords[0])))
        {
          DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword));
+         free(string);
+         string = NULL;
          continue;
        }
       }
@@ -867,15 +872,15 @@ _ppdOpen(
       ppd_decode(ppd->jcl_ps);         /* Decode quoted string */
     }
     else if (!strcmp(keyword, "AccurateScreensSupport"))
-      ppd->accurate_screens = !strcmp(string, "True");
+      ppd->accurate_screens = !strcasecmp(string, "True");
     else if (!strcmp(keyword, "ColorDevice"))
-      ppd->color_device = !strcmp(string, "True");
+      ppd->color_device = !strcasecmp(string, "True");
     else if (!strcmp(keyword, "ContoneOnly"))
-      ppd->contone_only = !strcmp(string, "True");
+      ppd->contone_only = !strcasecmp(string, "True");
     else if (!strcmp(keyword, "cupsFlipDuplex"))
-      ppd->flip_duplex = !strcmp(string, "True");
+      ppd->flip_duplex = !strcasecmp(string, "True");
     else if (!strcmp(keyword, "cupsManualCopies"))
-      ppd->manual_copies = !strcmp(string, "True");
+      ppd->manual_copies = !strcasecmp(string, "True");
     else if (!strcmp(keyword, "cupsModelNumber"))
       ppd->model_number = atoi(string);
     else if (!strcmp(keyword, "cupsColorProfile"))
@@ -988,6 +993,13 @@ _ppdOpen(
        goto error;
       }
 
+      if (cparam->type != PPD_CUSTOM_UNKNOWN)
+      {
+        pg->ppd_status = PPD_BAD_CUSTOM_PARAM;
+
+        goto error;
+      }
+
      /*
       * Get the parameter data...
       */
@@ -1485,6 +1497,27 @@ _ppdOpen(
        goto error;
       }
 
+      if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7)))
+      {
+       /*
+       * "*DefaultOption: Custom..." may set the default to a custom value
+       * or (for a very small number of incompatible PPD files) select a
+       * standard choice for the option, which CUPS renames to "_Custom..."
+       * to avoid compatibility issues.  See which this is...
+       */
+
+        char tchoice[PPD_MAX_NAME];    /* Temporary choice name */
+
+       snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice);
+
+       if (ppdFindChoice(option, tchoice))
+       {
+         strlcpy(option->defchoice, tchoice, sizeof(option->defchoice));
+
+         DEBUG_printf(("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice));
+       }
+      }
+
       option = NULL;
 
       free(string);
@@ -1499,6 +1532,27 @@ _ppdOpen(
        goto error;
       }
 
+      if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7)))
+      {
+       /*
+       * "*DefaultOption: Custom..." may set the default to a custom value
+       * or (for a very small number of incompatible PPD files) select a
+       * standard choice for the option, which CUPS renames to "_Custom..."
+       * to avoid compatibility issues.  See which this is...
+       */
+
+        char tchoice[PPD_MAX_NAME];    /* Temporary choice name */
+
+       snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice);
+
+       if (ppdFindChoice(option, tchoice))
+       {
+         strlcpy(option->defchoice, tchoice, sizeof(option->defchoice));
+
+         DEBUG_printf(("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice));
+       }
+      }
+
       option = NULL;
 
       free(string);
@@ -1657,11 +1711,9 @@ _ppdOpen(
         * Set the default as part of the current option...
        */
 
-        DEBUG_printf(("2_ppdOpen: Setting %s to %s...", keyword, string));
+       strlcpy(option->defchoice, string, sizeof(option->defchoice));
 
-        strlcpy(option->defchoice, string, sizeof(option->defchoice));
-
-        DEBUG_printf(("2_ppdOpen: %s is now %s...", keyword, option->defchoice));
+        DEBUG_printf(("2_ppdOpen: Set %s to %s...", keyword, option->defchoice));
       }
       else
       {
@@ -1671,11 +1723,27 @@ _ppdOpen(
 
         ppd_option_t   *toption;       /* Temporary option */
 
-
         if ((toption = ppdFindOption(ppd, keyword + 7)) != NULL)
        {
-         DEBUG_printf(("2_ppdOpen: Setting %s to %s...", keyword, string));
-         strlcpy(toption->defchoice, string, sizeof(toption->defchoice));
+         if (!_cups_strcasecmp(string, "custom") || !_cups_strncasecmp(string, "custom.", 7))
+         {
+          /*
+           * "*DefaultOption: Custom..." may set the default to a custom value
+           * or (for a very small number of incompatible PPD files) select a
+           * standard choice for the option, which CUPS renames to "_Custom..."
+           * to avoid compatibility issues.  See which this is...
+           */
+
+           snprintf(toption->defchoice, sizeof(toption->defchoice), "_%s", string);
+           if (!ppdFindChoice(toption, toption->defchoice))
+             strlcpy(toption->defchoice, string, sizeof(toption->defchoice));
+         }
+         else
+         {
+           strlcpy(toption->defchoice, string, sizeof(toption->defchoice));
+         }
+
+         DEBUG_printf(("2_ppdOpen: Set %s to %s...", keyword, toption->defchoice));
        }
       }
     }
@@ -1708,8 +1776,7 @@ _ppdOpen(
                      constraint->choice1, constraint->option2,
                     constraint->choice2))
       {
-        case 0 : /* Error */
-       case 1 : /* Error */
+        default : /* Error */
            pg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
            goto error;
 
@@ -1861,6 +1928,13 @@ _ppdOpen(
     }
     else if (!strcmp(keyword, "PaperDimension"))
     {
+      if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7))
+      {
+        char cname[PPD_MAX_NAME];      /* Rewrite with a leading underscore */
+        snprintf(cname, sizeof(cname), "_%s", name);
+        strlcpy(name, cname, sizeof(name));
+      }
+
       if ((size = ppdPageSize(ppd, name)) == NULL)
        size = ppd_add_size(ppd, name);
 
@@ -1883,6 +1957,13 @@ _ppdOpen(
     }
     else if (!strcmp(keyword, "ImageableArea"))
     {
+      if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7))
+      {
+        char cname[PPD_MAX_NAME];      /* Rewrite with a leading underscore */
+        snprintf(cname, sizeof(cname), "_%s", name);
+        strlcpy(name, cname, sizeof(name));
+      }
+
       if ((size = ppdPageSize(ppd, name)) == NULL)
        size = ppd_add_size(ppd, name);
 
@@ -1912,6 +1993,13 @@ _ppdOpen(
     {
       DEBUG_printf(("2_ppdOpen: group=%p, subgroup=%p", group, subgroup));
 
+      if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7))
+      {
+        char cname[PPD_MAX_NAME];      /* Rewrite with a leading underscore */
+        snprintf(cname, sizeof(cname), "_%s", name);
+        strlcpy(name, cname, sizeof(name));
+      }
+
       if (!strcmp(keyword, "PageSize"))
       {
        /*
@@ -2304,8 +2392,16 @@ ppd_add_attr(ppd_file_t *ppd,            /* I - PPD file data */
   * Copy data over...
   */
 
+  if (!_cups_strcasecmp(spec, "custom") || !_cups_strncasecmp(spec, "custom.", 7))
+  {
+    temp->spec[0] = '_';
+    strlcpy(temp->spec + 1, spec, sizeof(temp->spec) - 1);
+  }
+  else {
+      strlcpy(temp->spec, spec, sizeof(temp->spec));
+  }
+
   strlcpy(temp->name, name, sizeof(temp->name));
-  strlcpy(temp->spec, spec, sizeof(temp->spec));
   strlcpy(temp->text, text, sizeof(temp->text));
   temp->value = (char *)value;
 
@@ -2636,6 +2732,7 @@ ppd_get_cparam(ppd_coption_t *opt,        /* I - PPD file */
   if ((cparam = calloc(1, sizeof(ppd_cparam_t))) == NULL)
     return (NULL);
 
+  cparam->type = PPD_CUSTOM_UNKNOWN;
   strlcpy(cparam->name, param, sizeof(cparam->name));
   strlcpy(cparam->text, text[0] ? text : param, sizeof(cparam->text));
 
@@ -2807,7 +2904,7 @@ ppd_hash_option(ppd_option_t *option)     /* I - Option */
 
 
   for (hash = option->keyword[0], k = option->keyword + 1; *k;)
-    hash = 33 * hash + *k++;
+    hash = (int)(33U * (unsigned)hash) + *k++;
 
   return (hash & 511);
 }