]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/mark.c
Import CUPS 1.4svn r7023 into easysw/current.
[thirdparty/cups.git] / cups / mark.c
index 3b2226774f6ab35a01d255fadbab83684c33f422..689aefb0ffca5c8d5299b80022202f751f6bdf87 100644 (file)
@@ -1,25 +1,16 @@
 /*
- * "$Id: mark.c 5529 2006-05-15 20:06:46Z mike $"
+ * "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $"
  *
  *   Option marking routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products 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 missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636 USA
- *
- *       Voice: (301) 373-9600
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
+ *   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/".
  *
  *   PostScript is a trademark of Adobe Systems, Inc.
  *
@@ -59,18 +50,18 @@ static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g);
  * 'ppdConflicts()' - Check to see if there are any conflicts.
  */
 
-int                            /* O - Number of conflicts found */
-ppdConflicts(ppd_file_t *ppd)  /* I - PPD to check */
+int                                    /* O - Number of conflicts found */
+ppdConflicts(ppd_file_t *ppd)          /* I - PPD to check */
 {
-  int          i, j, k,        /* Looping variables */
-               conflicts;      /* Number of conflicts */
-  ppd_const_t  *c;             /* Current constraint */
-  ppd_group_t  *g, *sg;        /* Groups */
-  ppd_option_t *o1, *o2;       /* Options */
-  ppd_choice_t *c1, *c2;       /* Choices */
+  int          i,                      /* Looping variable */
+               conflicts;              /* Number of conflicts */
+  ppd_const_t  *c;                     /* Current constraint */
+  ppd_option_t *o1, *o2;               /* Options */
+  ppd_choice_t *c1, *c2;               /* Choices */
+  ppd_choice_t key;                    /* Search key */
 
 
-  if (ppd == NULL)
+  if (!ppd)
     return (0);
 
  /*
@@ -79,53 +70,55 @@ ppdConflicts(ppd_file_t *ppd)       /* I - PPD to check */
 
   conflicts = 0;
 
-  for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
-  {
-    for (j = g->num_options, o1 = g->options; j > 0; j --, o1 ++)
-      o1->conflicted = 0;
+  for (o1 = ppdFirstOption(ppd); o1; o1 = ppdNextOption(ppd))
+    o1->conflicted = 0;
 
-    for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++)
-      for (k = sg->num_options, o1 = sg->options; k > 0; k --, o1 ++)
-        o1->conflicted = 0;
-  }
+  cupsArraySave(ppd->marked);
 
  /*
   * Loop through all of the UI constraints and flag any options
   * that conflict...
   */
 
-  for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
+  for (i = ppd->num_consts, c = ppd->consts, o1 = o2 = NULL, c1 = c2 = NULL;
+       i > 0;
+       i --, c ++)
   {
    /*
     * Grab pointers to the first option...
     */
 
-    o1 = ppdFindOption(ppd, c->option1);
+    if (!o1 || strcmp(c->option1, o1->keyword))
+    {
+      o1 = ppdFindOption(ppd, c->option1);
+      c1 = NULL;
+    }
 
-    if (o1 == NULL)
+    if (!o1)
       continue;
-    else if (c->choice1[0] != '\0')
+    else if (c->choice1[0] && (!c1 || strcmp(c->choice1, c1->choice)))
     {
      /*
       * This constraint maps to a specific choice.
       */
 
-      c1 = ppdFindChoice(o1, c->choice1);
+      key.option = o1;
+
+      if ((c1 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL &&
+          (!c1->marked || strcmp(c->choice1, c1->choice)))
+        c1 = NULL;
     }
-    else
+    else if (!c1)
     {
      /*
       * This constraint applies to any choice for this option.
       */
 
-      for (j = o1->num_choices, c1 = o1->choices; j > 0; j --, c1 ++)
-        if (c1->marked)
-         break;
+      key.option = o1;
 
-      if (j == 0 ||
-          strcasecmp(c1->choice, "None") == 0 ||
-          strcasecmp(c1->choice, "Off") == 0 ||
-          strcasecmp(c1->choice, "False") == 0)
+      if ((c1 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL &&
+          (!strcasecmp(c1->choice, "None") || !strcasecmp(c1->choice, "Off") ||
+           !strcasecmp(c1->choice, "False")))
         c1 = NULL;
     }
 
@@ -133,32 +126,37 @@ ppdConflicts(ppd_file_t *ppd)     /* I - PPD to check */
     * Grab pointers to the second option...
     */
 
-    o2 = ppdFindOption(ppd, c->option2);
+    if (!o2 || strcmp(c->option2, o2->keyword))
+    {
+      o2 = ppdFindOption(ppd, c->option2);
+      c2 = NULL;
+    }
 
-    if (o2 == NULL)
+    if (!o2)
       continue;
-    else if (c->choice2[0] != '\0')
+    else if (c->choice2[0] && (!c2 || strcmp(c->choice2, c2->choice)))
     {
      /*
       * This constraint maps to a specific choice.
       */
 
-      c2 = ppdFindChoice(o2, c->choice2);
+      key.option = o2;
+
+      if ((c2 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL &&
+          (!c2->marked || strcmp(c->choice2, c2->choice)))
+        c2 = NULL;
     }
-    else
+    else if (!c2)
     {
      /*
       * This constraint applies to any choice for this option.
       */
 
-      for (j = o2->num_choices, c2 = o2->choices; j > 0; j --, c2 ++)
-        if (c2->marked)
-         break;
+      key.option = o2;
 
-      if (j == 0 ||
-          strcasecmp(c2->choice, "None") == 0 ||
-          strcasecmp(c2->choice, "Off") == 0 ||
-          strcasecmp(c2->choice, "False") == 0)
+      if ((c2 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL &&
+          (!strcasecmp(c2->choice, "None") || !strcasecmp(c2->choice, "Off") ||
+           !strcasecmp(c2->choice, "False")))
         c2 = NULL;
     }
 
@@ -166,8 +164,7 @@ ppdConflicts(ppd_file_t *ppd)       /* I - PPD to check */
     * If both options are marked then there is a conflict...
     */
 
-    if (c1 != NULL && c1->marked &&
-        c2 != NULL && c2->marked)
+    if (c1 && c1->marked && c2 && c2->marked)
     {
       DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n",
                     o1->keyword, c1->choice, o2->keyword, c2->choice,
@@ -178,6 +175,8 @@ ppdConflicts(ppd_file_t *ppd)       /* I - PPD to check */
     }
   }
 
+  cupsArrayRestore(ppd->marked);
+
  /*
   * Return the number of conflicts found...
   */
@@ -194,8 +193,8 @@ ppd_choice_t *                              /* O - Choice pointer or NULL */
 ppdFindChoice(ppd_option_t *o,         /* I - Pointer to option */
               const char   *choice)    /* I - Name of choice */
 {
-  int          i;              /* Looping var */
-  ppd_choice_t *c;             /* Current choice */
+  int          i;                      /* Looping var */
+  ppd_choice_t *c;                     /* Current choice */
 
 
   if (o == NULL || choice == NULL)
@@ -217,19 +216,13 @@ ppd_choice_t *                            /* O - Pointer to choice or NULL */
 ppdFindMarkedChoice(ppd_file_t *ppd,   /* I - PPD file */
                     const char *option)        /* I - Keyword/option name */
 {
-  int          i;              /* Looping var */
-  ppd_option_t *o;             /* Pointer to option */
-  ppd_choice_t *c;             /* Pointer to choice */
+  ppd_choice_t key;                    /* Search key for choice */
 
 
-  if ((o = ppdFindOption(ppd, option)) == NULL)
+  if ((key.option = ppdFindOption(ppd, option)) == NULL)
     return (NULL);
 
-  for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
-    if (c->marked)
-      return (c);
-
-  return (NULL);
+  return ((ppd_choice_t *)cupsArrayFind(ppd->marked, &key));
 }
 
 
@@ -288,25 +281,25 @@ ppdFindOption(ppd_file_t *ppd,            /* I - PPD file data */
  * 'ppdIsMarked()' - Check to see if an option is marked...
  */
 
-int                            /* O - Non-zero if option is marked */
-ppdIsMarked(ppd_file_t *ppd,   /* I - PPD file data */
-            const char *option,        /* I - Option/Keyword name */
-            const char *choice)        /* I - Choice name */
+int                                    /* O - Non-zero if option is marked */
+ppdIsMarked(ppd_file_t *ppd,           /* I - PPD file data */
+            const char *option,                /* I - Option/Keyword name */
+            const char *choice)                /* I - Choice name */
 {
-  ppd_option_t *o;             /* Option pointer */
-  ppd_choice_t *c;             /* Choice pointer */
+  ppd_choice_t key,                    /* Search key */
+               *c;                     /* Choice pointer */
 
 
-  if (ppd == NULL)
+  if (!ppd)
     return (0);
 
-  if ((o = ppdFindOption(ppd, option)) == NULL)
+  if ((key.option = ppdFindOption(ppd, option)) == NULL)
     return (0);
 
-  if ((c = ppdFindChoice(o, choice)) == NULL)
+  if ((c = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) == NULL)
     return (0);
 
-  return (c->marked);
+  return (!strcmp(c->choice, choice));
 }
 
 
@@ -315,15 +308,29 @@ ppdIsMarked(ppd_file_t *ppd,      /* I - PPD file data */
  */
 
 void
-ppdMarkDefaults(ppd_file_t *ppd)/* I - PPD file record */
+ppdMarkDefaults(ppd_file_t *ppd)       /* I - PPD file record */
 {
-  int          i;              /* Looping variables */
-  ppd_group_t  *g;             /* Current group */
+  int          i;                      /* Looping variables */
+  ppd_group_t  *g;                     /* Current group */
+  ppd_choice_t *c;                     /* Current choice */
 
 
-  if (ppd == NULL)
+  if (!ppd)
     return;
 
+ /*
+  * Clean out the marked array...
+  */
+
+  for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
+       c;
+       c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
+    cupsArrayRemove(ppd->marked, c);
+
+ /*
+  * Then repopulate it with the defaults...
+  */
+
   for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
     ppd_defaults(ppd, g);
 }
@@ -345,7 +352,9 @@ ppdMarkOption(ppd_file_t *ppd,              /* I - PPD file record */
 {
   int          i, j;                   /* Looping vars */
   ppd_option_t *o;                     /* Option pointer */
-  ppd_choice_t *c;                     /* Choice pointer */
+  ppd_choice_t *c,                     /* Choice pointer */
+               *oldc,                  /* Old choice pointer */
+               key;                    /* Search key for choice */
   struct lconv *loc;                   /* Locale data */
 
 
@@ -367,8 +376,14 @@ ppdMarkOption(ppd_file_t *ppd,             /* I - PPD file record */
   if (!strcasecmp(option, "AP_D_InputSlot"))
   {
     if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
-      for (i = 0; i < o->num_choices; i ++)
-       o->choices[i].marked = 0;
+    {
+      key.option = o;
+      if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
+      {
+        oldc->marked = 0;
+        cupsArrayRemove(ppd->marked, oldc);
+      }
+    }
   }
 
  /*
@@ -407,6 +422,7 @@ ppdMarkOption(ppd_file_t *ppd,              /* I - PPD file record */
       ppd_cparam_t     *cparam;        /* Custom parameter */
       char             *units;         /* Custom points units */
 
+
       if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
       {
         if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL)
@@ -417,26 +433,27 @@ ppdMarkOption(ppd_file_t *ppd,            /* I - PPD file record */
          case PPD_CUSTOM_CURVE :
          case PPD_CUSTOM_INVCURVE :
          case PPD_CUSTOM_REAL :
-             cparam->current.custom_real = _cupsStrScand(choice + 7, NULL,
-                                                         loc);
+             cparam->current.custom_real = (float)_cupsStrScand(choice + 7,
+                                                                NULL, loc);
              break;
 
          case PPD_CUSTOM_POINTS :
-             cparam->current.custom_points = _cupsStrScand(choice + 7,
-                                                           &units, loc);
+             cparam->current.custom_points = (float)_cupsStrScand(choice + 7,
+                                                                  &units,
+                                                                  loc);
 
               if (units)
              {
                if (!strcasecmp(units, "cm"))
-                 cparam->current.custom_points *= 72.0 / 2.54;       
+                 cparam->current.custom_points *= 72.0f / 2.54f;             
                else if (!strcasecmp(units, "mm"))
-                 cparam->current.custom_points *= 72.0 / 25.4;       
+                 cparam->current.custom_points *= 72.0f / 25.4f;             
                else if (!strcasecmp(units, "m"))
-                 cparam->current.custom_points *= 72.0 / 0.0254;             
+                 cparam->current.custom_points *= 72.0f / 0.0254f;           
                else if (!strcasecmp(units, "in"))
-                 cparam->current.custom_points *= 72.0             
+                 cparam->current.custom_points *= 72.0f;             
                else if (!strcasecmp(units, "ft"))
-                 cparam->current.custom_points *= 12 * 72.0;         
+                 cparam->current.custom_points *= 12.0f * 72.0f;             
               }
              break;
 
@@ -448,13 +465,19 @@ ppdMarkOption(ppd_file_t *ppd,            /* I - PPD file record */
          case PPD_CUSTOM_PASSWORD :
          case PPD_CUSTOM_STRING :
              if (cparam->current.custom_string)
-               free(cparam->current.custom_string);
+               _cupsStrFree(cparam->current.custom_string);
 
-             cparam->current.custom_string = strdup(choice + 7);
+             cparam->current.custom_string = _cupsStrAlloc(choice + 7);
              break;
        }
       }
     }
+
+   /*
+    * Make sure that we keep the option marked below...
+    */
+
+    choice = "Custom";
   }
   else if (choice[0] == '{')
   {
@@ -487,26 +510,27 @@ ppdMarkOption(ppd_file_t *ppd,            /* I - PPD file record */
          case PPD_CUSTOM_CURVE :
          case PPD_CUSTOM_INVCURVE :
          case PPD_CUSTOM_REAL :
-             cparam->current.custom_real = _cupsStrScand(val->value, NULL,
-                                                         loc);
+             cparam->current.custom_real = (float)_cupsStrScand(val->value,
+                                                                NULL, loc);
              break;
 
          case PPD_CUSTOM_POINTS :
-             cparam->current.custom_points = _cupsStrScand(val->value, &units,
-                                                           loc);
+             cparam->current.custom_points = (float)_cupsStrScand(val->value,
+                                                                  &units,
+                                                                  loc);
 
              if (units)
              {
                if (!strcasecmp(units, "cm"))
-                 cparam->current.custom_points *= 72.0 / 2.54;       
+                 cparam->current.custom_points *= 72.0f / 2.54f;
                else if (!strcasecmp(units, "mm"))
-                 cparam->current.custom_points *= 72.0 / 25.4;       
+                 cparam->current.custom_points *= 72.0f / 25.4f;
                else if (!strcasecmp(units, "m"))
-                 cparam->current.custom_points *= 72.0 / 0.0254;             
+                 cparam->current.custom_points *= 72.0f / 0.0254f;
                else if (!strcasecmp(units, "in"))
-                 cparam->current.custom_points *= 72.0;              
+                 cparam->current.custom_points *= 72.0f;
                else if (!strcasecmp(units, "ft"))
-                 cparam->current.custom_points *= 12 * 72.0;         
+                 cparam->current.custom_points *= 12.0f * 72.0f;
              }
              break;
 
@@ -518,9 +542,9 @@ ppdMarkOption(ppd_file_t *ppd,              /* I - PPD file record */
          case PPD_CUSTOM_PASSWORD :
          case PPD_CUSTOM_STRING :
              if (cparam->current.custom_string)
-               free(cparam->current.custom_string);
+               _cupsStrFree(cparam->current.custom_string);
 
-             cparam->current.custom_string = strdup(val->value);
+             cparam->current.custom_string = _cupsStrAlloc(val->value);
              break;
        }
       }
@@ -542,73 +566,97 @@ ppdMarkOption(ppd_file_t *ppd,            /* I - PPD file record */
   * Option found; mark it and then handle unmarking any other options.
   */
 
-  c->marked = 1;
-
   if (o->ui != PPD_UI_PICKMANY)
   {
    /*
     * Unmark all other choices...
     */
 
-    for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
-      if (strcasecmp(c->choice, choice))
+    if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL)
+    {
+      oldc->marked = 0;
+      cupsArrayRemove(ppd->marked, oldc);
+    }
+
+    if (!strcasecmp(option, "PageSize") || !strcasecmp(option, "PageRegion"))
+    {
+     /*
+      * Mark current page size...
+      */
+
+      for (j = 0; j < ppd->num_sizes; j ++)
+       ppd->sizes[j].marked = !strcasecmp(ppd->sizes[j].name,
+                                          choice);
+
+     /*
+      * Unmark the current PageSize or PageRegion setting, as
+      * appropriate...
+      */
+
+      if (!strcasecmp(option, "PageSize"))
+      {
+       if ((o = ppdFindOption(ppd, "PageRegion")) != NULL)
+        {
+          key.option = o;
+          if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
+          {
+            oldc->marked = 0;
+            cupsArrayRemove(ppd->marked, oldc);
+          }
+        }
+      }
+      else
       {
-        c->marked = 0;
+       if ((o = ppdFindOption(ppd, "PageSize")) != NULL)
+        {
+          key.option = o;
+          if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
+          {
+            oldc->marked = 0;
+            cupsArrayRemove(ppd->marked, oldc);
+          }
+        }
+      }
+    }
+    else if (!strcasecmp(option, "InputSlot"))
+    {
+     /*
+      * Unmark ManualFeed option...
+      */
 
-       if (!strcasecmp(option, "PageSize") ||
-           !strcasecmp(option, "PageRegion"))
-       {
-        /*
-         * Mark current page size...
-         */
-
-         for (j = 0; j < ppd->num_sizes; j ++)
-           ppd->sizes[j].marked = !strcasecmp(ppd->sizes[j].name,
-                                              choice);
-
-        /*
-         * Unmark the current PageSize or PageRegion setting, as
-         * appropriate...
-         */
-
-         if (!strcasecmp(option, "PageSize"))
-         {
-           if ((o = ppdFindOption(ppd, "PageRegion")) != NULL)
-             for (j = 0; j < o->num_choices; j ++)
-               o->choices[j].marked = 0;
-         }
-         else
-         {
-           if ((o = ppdFindOption(ppd, "PageSize")) != NULL)
-             for (j = 0; j < o->num_choices; j ++)
-               o->choices[j].marked = 0;
-         }
-       }
-       else if (!strcasecmp(option, "InputSlot"))
-       {
-        /*
-         * Unmark ManualFeed True and possibly mark ManualFeed False
-         * option...
-         */
-
-         if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL)
-           for (j = 0; j < o->num_choices; j ++)
-              o->choices[j].marked = !strcasecmp(o->choices[j].choice, "False");
-       }
-       else if (!strcasecmp(option, "ManualFeed") &&
-                !strcasecmp(choice, "True"))
-       {
-        /*
-         * Unmark InputSlot option...
-         */
+      if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL)
+      {
+        key.option = o;
+        if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
+        {
+          oldc->marked = 0;
+          cupsArrayRemove(ppd->marked, oldc);
+        }
+      }
+    }
+    else if (!strcasecmp(option, "ManualFeed") &&
+            !strcasecmp(choice, "True"))
+    {
+     /*
+      * Unmark InputSlot option...
+      */
 
-         if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
-           for (j = 0; j < o->num_choices; j ++)
-              o->choices[j].marked = 0;
-       }
+      if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
+      {
+        key.option = o;
+        if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
+        {
+          oldc->marked = 0;
+          cupsArrayRemove(ppd->marked, oldc);
+        }
       }
+    }
   }
 
+  c->marked = 1;
+
+  cupsArrayAdd(ppd->marked, c);
+
  /*
   * Return the number of conflicts...
   */
@@ -666,9 +714,6 @@ ppd_defaults(ppd_file_t  *ppd,      /* I - PPD file */
   ppd_group_t  *sg;            /* Current sub-group */
 
 
-  if (g == NULL)
-    return;
-
   for (i = g->num_options, o = g->options; i > 0; i --, o ++)
     if (strcasecmp(o->keyword, "PageRegion") != 0)
       ppdMarkOption(ppd, o->keyword, o->defchoice);
@@ -679,5 +724,5 @@ ppd_defaults(ppd_file_t  *ppd,      /* I - PPD file */
 
 
 /*
- * End of "$Id: mark.c 5529 2006-05-15 20:06:46Z mike $".
+ * End of "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $".
  */