]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/options.c
Merge changes from CUPS 1.4svn-r7282.
[thirdparty/cups.git] / cups / options.c
index f04138497dd1e10a29185f86a26315bd72c7877f..4ffb39f8244aa05359fb4b0078b9cf18df6c1278 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: options.c 6943 2007-09-10 23:00:33Z mike $"
+ * "$Id: options.c 7278 2008-01-31 01:23:09Z mike $"
  *
  *   Option routines for the Common UNIX Printing System (CUPS).
  *
  *
  * Contents:
  *
- *   cupsAddOption()     - Add an option to an option array.
- *   cupsFreeOptions()   - Free all memory used by options.
- *   cupsGetOption()     - Get an option value.
- *   cupsMarkOptions()   - Mark command-line options in a PPD file.
- *   cupsParseOptions()  - Parse options from a command-line argument.
- *   cupsRemoveOptions() - Remove an option from an option array.
- *   debug_marked()      - Output the marked array to stdout...
- *   ppd_mark_choices()  - Mark one or more option choices from a string.
+ *   cupsAddOption()    - Add an option to an option array.
+ *   cupsFreeOptions()  - Free all memory used by options.
+ *   cupsGetOption()    - Get an option value.
+ *   cupsParseOptions() - Parse options from a command-line argument.
+ *   cupsRemoveOption() - Remove an option from an option array.
  */
 
 /*
 #include "debug.h"
 
 
-/*
- * Local functions...
- */
-
-#ifdef DEBUG
-static void    debug_marked(ppd_file_t *ppd, const char *title);
-#else
-#  define debug_marked(ppd,title)
-#endif /* DEBUG */
-static int     ppd_mark_choices(ppd_file_t *ppd, const char *options);
-
-
 /*
  * 'cupsAddOption()' - Add an option to an option array.
+ *
+ * New option arrays can be initialized simply by passing 0 for the
+ * "num_options" parameter.
  */
 
-int                                    /* O - Number of options */
-cupsAddOption(const char    *name,     /* I - Name of option */
-              const char    *value,    /* I - Value of option */
-             int           num_options,/* I - Number of options */
+int                                    /* O  - Number of options */
+cupsAddOption(const char    *name,     /* I  - Name of option */
+              const char    *value,    /* I  - Value of option */
+             int           num_options,/* I  - Number of options */
               cups_option_t **options) /* IO - Pointer to options */
 {
   int          i;                      /* Looping var */
@@ -139,7 +127,7 @@ cupsFreeOptions(
  * 'cupsGetOption()' - Get an option value.
  */
 
-const char *                           /* O - Option value or NULL */
+const char *                           /* O - Option value or @code NULL@ */
 cupsGetOption(const char    *name,     /* I - Name of option */
               int           num_options,/* I - Number of options */
               cups_option_t *options)  /* I - Options */
@@ -158,307 +146,14 @@ cupsGetOption(const char    *name,       /* I - Name of option */
 }
 
 
-/*
- * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
- */
-
-int                                    /* O - 1 if conflicting */
-cupsMarkOptions(
-    ppd_file_t    *ppd,                        /* I - PPD file */
-    int           num_options,         /* I - Number of options */
-    cups_option_t *options)            /* I - Options */
-{
-  int          i, j, k;                /* Looping vars */
-  int          conflict;               /* Option conflicts */
-  char         *val,                   /* Pointer into value */
-               *ptr,                   /* Pointer into string */
-               s[255];                 /* Temporary string */
-  const char   *page_size;             /* PageSize option */
-  cups_option_t        *optptr;                /* Current option */
-  ppd_option_t *option;                /* PPD option */
-  ppd_attr_t   *attr;                  /* PPD attribute */
-  static const char * const duplex_options[] =
-               {                       /* Duplex option names */
-                 "Duplex",             /* Adobe */
-                 "EFDuplex",           /* EFI */
-                 "EFDuplexing",        /* EFI */
-                 "KD03Duplex",         /* Kodak */
-                 "JCLDuplex"           /* Samsung */
-               };
-  static const char * const duplex_one[] =
-               {                       /* one-sided names */
-                 "None",
-                 "False"
-               };
-  static const char * const duplex_two_long[] =
-               {                       /* two-sided-long-edge names */
-                 "DuplexNoTumble",     /* Adobe */
-                 "LongEdge",           /* EFI */
-                 "Top"                 /* EFI */
-               };
-  static const char * const duplex_two_short[] =
-               {                       /* two-sided-long-edge names */
-                 "DuplexTumble",       /* Adobe */
-                 "ShortEdge",          /* EFI */
-                 "Bottom"              /* EFI */
-               };
-
-
- /*
-  * Check arguments...
-  */
-
-  if (ppd == NULL || num_options <= 0 || options == NULL)
-    return (0);
-
-  debug_marked(ppd, "Before...");
-
- /*
-  * Mark options...
-  */
-
-  conflict  = 0;
-
-  for (i = num_options, optptr = options; i > 0; i --, optptr ++)
-    if (!strcasecmp(optptr->name, "media"))
-    {
-     /*
-      * Loop through the option string, separating it at commas and
-      * marking each individual option as long as the corresponding
-      * PPD option (PageSize, InputSlot, etc.) is not also set.
-      *
-      * For PageSize, we also check for an empty option value since
-      * some versions of MacOS X use it to specify auto-selection
-      * of the media based solely on the size.
-      */
-
-      page_size = cupsGetOption("PageSize", num_options, options);
-
-      for (val = optptr->value; *val;)
-      {
-       /*
-        * Extract the sub-option from the string...
-       */
-
-        for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);)
-         *ptr++ = *val++;
-       *ptr++ = '\0';
-
-       if (*val == ',')
-         val ++;
-
-       /*
-        * Mark it...
-       */
-
-        if (!page_size || !page_size[0])
-         if (ppdMarkOption(ppd, "PageSize", s))
-            conflict = 1;
-
-        if (cupsGetOption("InputSlot", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "InputSlot", s))
-            conflict = 1;
-
-        if (cupsGetOption("MediaType", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "MediaType", s))
-            conflict = 1;
-
-        if (cupsGetOption("EFMediaType", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "EFMediaType", s))             /* EFI */
-            conflict = 1;
-
-        if (cupsGetOption("EFMediaQualityMode", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "EFMediaQualityMode", s))      /* EFI */
-            conflict = 1;
-
-       if (strcasecmp(s, "manual") == 0 &&
-           cupsGetOption("ManualFeed", num_options, options) == NULL)
-          if (ppdMarkOption(ppd, "ManualFeed", "True"))
-           conflict = 1;
-      }
-    }
-    else if (!strcasecmp(optptr->name, "sides"))
-    {
-      for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-        if (cupsGetOption(duplex_options[j], num_options, options) != NULL)
-         break;
-
-      if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-      {
-       /*
-        * Don't override the PPD option with the IPP attribute...
-       */
-
-        continue;
-      }
-
-      if (!strcasecmp(optptr->value, "one-sided"))
-      {
-       /*
-        * Mark the appropriate duplex option for one-sided output...
-       */
-
-        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
-           break;
-
-       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-       {
-          for (k = 0; k < (int)(sizeof(duplex_one) / sizeof(duplex_one[0])); k ++)
-            if (ppdFindChoice(option, duplex_one[k]))
-           {
-             if (ppdMarkOption(ppd, duplex_options[j], duplex_one[k]))
-               conflict = 1;
-
-             break;
-            }
-        }
-      }
-      else if (!strcasecmp(optptr->value, "two-sided-long-edge"))
-      {
-       /*
-        * Mark the appropriate duplex option for two-sided-long-edge output...
-       */
-
-        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
-           break;
-
-       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-       {
-          for (k = 0; k < (int)(sizeof(duplex_two_long) / sizeof(duplex_two_long[0])); k ++)
-            if (ppdFindChoice(option, duplex_two_long[k]))
-           {
-             if (ppdMarkOption(ppd, duplex_options[j], duplex_two_long[k]))
-               conflict = 1;
-
-             break;
-            }
-        }
-      }
-      else if (!strcasecmp(optptr->value, "two-sided-short-edge"))
-      {
-       /*
-        * Mark the appropriate duplex option for two-sided-short-edge output...
-       */
-
-        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
-           break;
-
-       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-       {
-          for (k = 0; k < (int)(sizeof(duplex_two_short) / sizeof(duplex_two_short[0])); k ++)
-            if (ppdFindChoice(option, duplex_two_short[k]))
-           {
-             if (ppdMarkOption(ppd, duplex_options[j], duplex_two_short[k]))
-               conflict = 1;
-
-             break;
-            }
-        }
-      }
-    }
-    else if (!strcasecmp(optptr->name, "resolution") ||
-             !strcasecmp(optptr->name, "printer-resolution"))
-    {
-      if (ppdMarkOption(ppd, "Resolution", optptr->value))
-        conflict = 1;
-      if (ppdMarkOption(ppd, "SetResolution", optptr->value))
-       /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
-        conflict = 1;
-      if (ppdMarkOption(ppd, "JCLResolution", optptr->value))  /* HP */
-        conflict = 1;
-      if (ppdMarkOption(ppd, "CNRes_PGP", optptr->value))      /* Canon */
-        conflict = 1;
-    }
-    else if (!strcasecmp(optptr->name, "output-bin"))
-    {
-      if (!cupsGetOption("OutputBin", num_options, options))
-        if (ppdMarkOption(ppd, "OutputBin", optptr->value))
-          conflict = 1;
-    }
-    else if (!strcasecmp(optptr->name, "multiple-document-handling"))
-    {
-      if (!cupsGetOption("Collate", num_options, options) &&
-          ppdFindOption(ppd, "Collate"))
-      {
-        if (strcasecmp(optptr->value, "separate-documents-uncollated-copies"))
-       {
-         if (ppdMarkOption(ppd, "Collate", "True"))
-            conflict = 1;
-        }
-       else
-       {
-         if (ppdMarkOption(ppd, "Collate", "False"))
-            conflict = 1;
-        }
-      }
-    }
-    else if (!strcasecmp(optptr->name, "finishings"))
-    {
-     /*
-      * Lookup cupsIPPFinishings attributes for each value...
-      */
-
-      for (ptr = optptr->value; *ptr;)
-      {
-       /*
-        * Get the next finishings number...
-       */
-
-        if (!isdigit(*ptr & 255))
-         break;
-
-        if ((j = strtol(ptr, &ptr, 10)) < 3)
-         break;
-
-       /*
-        * Skip separator as needed...
-       */
-
-        if (*ptr == ',')
-         ptr ++;
-
-       /*
-        * Look it up in the PPD file...
-       */
-
-       sprintf(s, "%d", j);
-
-        if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL)
-         continue;
-
-       /*
-        * Apply "*Option Choice" settings from the attribute value...
-       */
-
-        if (ppd_mark_choices(ppd, attr->value))
-         conflict = 1;
-      }
-    }
-    else if (!strcasecmp(optptr->name, "mirror"))
-    {
-      if (ppdMarkOption(ppd, "MirrorPrint", optptr->value))
-       conflict = 1;
-    }
-    else if (ppdMarkOption(ppd, optptr->name, optptr->value))
-      conflict = 1;
-
-  debug_marked(ppd, "After...");
-
-  return (conflict);
-}
-
-
 /*
  * 'cupsParseOptions()' - Parse options from a command-line argument.
  *
  * This function converts space-delimited name/value pairs according
  * to the PAPI text option ABNF specification. Collection values
  * ("name={a=... b=... c=...}") are stored with the curley brackets
- * intact - use cupsParseOptions() on the value to extract the collection
- * attributes.
+ * intact - use @code cupsParseOptions@ on the value to extract the
+ * collection attributes.
  */
 
 int                                    /* O - Number of options found */
@@ -470,7 +165,8 @@ cupsParseOptions(
   char *copyarg,                       /* Copy of input string */
        *ptr,                           /* Pointer into string */
        *name,                          /* Pointer to name */
-       *value;                         /* Pointer to value */
+       *value,                         /* Pointer to value */
+       quote;                          /* Quote character */
 
 
  /*
@@ -510,7 +206,7 @@ cupsParseOptions(
     */
 
     name = ptr;
-    while (!isspace(*ptr & 255) && *ptr != '=' && *ptr != '\0')
+    while (!isspace(*ptr & 255) && *ptr != '=' && *ptr)
       ptr ++;
 
    /*
@@ -530,10 +226,10 @@ cupsParseOptions(
     if (*ptr != '=')
     {
      /*
-      * Start of another option...
+      * Boolean option...
       */
 
-      if (strncasecmp(name, "no", 2) == 0)
+      if (!strncasecmp(name, "no", 2))
         num_options = cupsAddOption(name + 2, "false", num_options,
                                    options);
       else
@@ -548,38 +244,18 @@ cupsParseOptions(
 
     *ptr++ = '\0';
 
-    if (*ptr == '\'')
+    if (*ptr == '\'' || *ptr == '\"')
     {
      /*
       * Quoted string constant...
       */
 
-      ptr ++;
-      value = ptr;
-
-      while (*ptr != '\'' && *ptr != '\0')
-      {
-        if (*ptr == '\\')
-         _cups_strcpy(ptr, ptr + 1);
-
-        ptr ++;
-      }
-
-      if (*ptr != '\0')
-        *ptr++ = '\0';
-    }
-    else if (*ptr == '\"')
-    {
-     /*
-      * Double-quoted string constant...
-      */
-
-      ptr ++;
+      quote = *ptr++;
       value = ptr;
 
-      while (*ptr != '\"' && *ptr != '\0')
+      while (*ptr != quote && *ptr)
       {
-        if (*ptr == '\\')
+        if (*ptr == '\\' && ptr[1])
          _cups_strcpy(ptr, ptr + 1);
 
         ptr ++;
@@ -612,7 +288,7 @@ cupsParseOptions(
              break;
          }
         }
-        else if (*ptr == '\\')
+        else if (*ptr == '\\' && ptr[1])
          _cups_strcpy(ptr, ptr + 1);
 
       if (*ptr != '\0')
@@ -626,9 +302,9 @@ cupsParseOptions(
 
       value = ptr;
 
-      while (!isspace(*ptr & 255) && *ptr != '\0')
+      while (!isspace(*ptr & 255) && *ptr)
       {
-        if (*ptr == '\\')
+        if (*ptr == '\\' && ptr[1])
          _cups_strcpy(ptr, ptr + 1);
 
         ptr ++;
@@ -715,110 +391,6 @@ cupsRemoveOption(
 }
 
 
-#ifdef DEBUG
-/*
- * 'debug_marked()' - Output the marked array to stdout...
- */
-
-static void
-debug_marked(ppd_file_t *ppd,          /* I - PPD file data */
-             const char *title)                /* I - Title for list */
-{
-  ppd_choice_t *c;                     /* Current choice */
-
-
-  printf("cupsMarkOptions: %s\n", title);
-
-  for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
-       c;
-       c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
-    printf("cupsMarkOptions: %s=%s\n", c->option->keyword, c->choice);
-}
-#endif /* DEBUG */
-
-
-/*
- * 'ppd_mark_choices()' - Mark one or more option choices from a string.
- */
-
-static int                             /* O - 1 if there are conflicts, 0 otherwise */
-ppd_mark_choices(ppd_file_t *ppd,      /* I - PPD file */
-                 const char *options)  /* I - "*Option Choice ..." string */
-{
-  char option[PPD_MAX_NAME],           /* Current option */
-       choice[PPD_MAX_NAME],           /* Current choice */
-       *ptr;                           /* Pointer into option or choice */
-  int  conflict = 0;                   /* Do we have a conflict? */
-
-
-  if (!options)
-    return (0);
-
- /*
-  * Read all of the "*Option Choice" pairs from the string, marking PPD
-  * options as we go...
-  */
-
-  while (*options)
-  {
-   /*
-    * Skip leading whitespace...
-    */
-
-    while (isspace(*options & 255))
-      options ++;
-
-    if (*options != '*')
-      break;
-
-   /*
-    * Get the option name...
-    */
-
-    options ++;
-    ptr = option;
-    while (*options && !isspace(*options & 255) &&
-              ptr < (option + sizeof(option) - 1))
-      *ptr++ = *options++;
-
-    if (ptr == option)
-      break;
-
-    *ptr = '\0';
-
-   /*
-    * Get the choice...
-    */
-
-    while (isspace(*options & 255))
-      options ++;
-
-    if (!*options)
-      break;
-
-    ptr = choice;
-    while (*options && !isspace(*options & 255) &&
-              ptr < (choice + sizeof(choice) - 1))
-      *ptr++ = *options++;
-
-    *ptr = '\0';
-
-   /*
-    * Mark the option...
-    */
-
-    if (ppdMarkOption(ppd, option, choice))
-      conflict = 1;
-  }
-
- /*
-  * Return whether we had any conflicts...
-  */
-
-  return (conflict);
-}
-
-
 /*
- * End of "$Id: options.c 6943 2007-09-10 23:00:33Z mike $".
+ * End of "$Id: options.c 7278 2008-01-31 01:23:09Z mike $".
  */