]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/mark.c
2 * "$Id: mark.c 7605 2008-05-21 00:36:25Z mike $"
4 * Option marking routines for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * PostScript is a trademark of Adobe Systems, Inc.
17 * This file is subject to the Apple OS-Developed Software exception.
21 * cupsMarkOptions() - Mark command-line options in a PPD file.
22 * ppdConflicts() - Check to see if there are any conflicts among the
23 * marked option choices.
24 * ppdFindChoice() - Return a pointer to an option choice.
25 * ppdFindMarkedChoice() - Return the marked choice for the specified option.
26 * ppdFindOption() - Return a pointer to the specified option.
27 * ppdIsMarked() - Check to see if an option is marked.
28 * ppdMarkDefaults() - Mark all default options in the PPD file.
29 * ppdMarkOption() - Mark an option in a PPD file.
30 * ppdFirstOption() - Return the first option in the PPD file.
31 * ppdNextOption() - Return the next option in the PPD file.
32 * debug_marked() - Output the marked array to stdout...
33 * ppd_defaults() - Set the defaults for this group and all sub-groups.
34 * ppd_mark_choices() - Mark one or more option choices from a string.
38 * Include necessary headers...
51 static void debug_marked(ppd_file_t
*ppd
, const char *title
);
53 # define debug_marked(ppd,title)
55 static void ppd_defaults(ppd_file_t
*ppd
, ppd_group_t
*g
);
56 static int ppd_mark_choices(ppd_file_t
*ppd
, const char *options
);
60 * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
62 * This function maps the IPP "finishings", "media", "mirror",
63 * "multiple-document-handling", "output-bin", "printer-resolution", and
64 * "sides" attributes to their corresponding PPD options and choices.
67 int /* O - 1 if conflicting */
69 ppd_file_t
*ppd
, /* I - PPD file */
70 int num_options
, /* I - Number of options */
71 cups_option_t
*options
) /* I - Options */
73 int i
, j
, k
; /* Looping vars */
74 int conflict
; /* Option conflicts */
75 char *val
, /* Pointer into value */
76 *ptr
, /* Pointer into string */
77 s
[255]; /* Temporary string */
78 const char *page_size
; /* PageSize option */
79 cups_option_t
*optptr
; /* Current option */
80 ppd_option_t
*option
; /* PPD option */
81 ppd_attr_t
*attr
; /* PPD attribute */
82 static const char * const duplex_options
[] =
83 { /* Duplex option names */
86 "EFDuplexing", /* EFI */
87 "KD03Duplex", /* Kodak */
88 "JCLDuplex" /* Samsung */
90 static const char * const duplex_one
[] =
91 { /* one-sided names */
95 static const char * const duplex_two_long
[] =
96 { /* two-sided-long-edge names */
97 "DuplexNoTumble", /* Adobe */
101 static const char * const duplex_two_short
[] =
102 { /* two-sided-long-edge names */
103 "DuplexTumble", /* Adobe */
104 "ShortEdge", /* EFI */
113 if (!ppd
|| num_options
<= 0 || !options
)
116 debug_marked(ppd
, "Before...");
124 for (i
= num_options
, optptr
= options
; i
> 0; i
--, optptr
++)
125 if (!strcasecmp(optptr
->name
, "media"))
128 * Loop through the option string, separating it at commas and
129 * marking each individual option as long as the corresponding
130 * PPD option (PageSize, InputSlot, etc.) is not also set.
132 * For PageSize, we also check for an empty option value since
133 * some versions of MacOS X use it to specify auto-selection
134 * of the media based solely on the size.
137 page_size
= cupsGetOption("PageSize", num_options
, options
);
139 for (val
= optptr
->value
; *val
;)
142 * Extract the sub-option from the string...
145 for (ptr
= s
; *val
&& *val
!= ',' && (ptr
- s
) < (sizeof(s
) - 1);)
156 if (!page_size
|| !page_size
[0])
157 if (ppdMarkOption(ppd
, "PageSize", s
))
160 if (cupsGetOption("InputSlot", num_options
, options
) == NULL
)
161 if (ppdMarkOption(ppd
, "InputSlot", s
))
164 if (cupsGetOption("MediaType", num_options
, options
) == NULL
)
165 if (ppdMarkOption(ppd
, "MediaType", s
))
168 if (cupsGetOption("EFMediaType", num_options
, options
) == NULL
)
169 if (ppdMarkOption(ppd
, "EFMediaType", s
)) /* EFI */
172 if (cupsGetOption("EFMediaQualityMode", num_options
, options
) == NULL
)
173 if (ppdMarkOption(ppd
, "EFMediaQualityMode", s
)) /* EFI */
176 if (strcasecmp(s
, "manual") == 0 &&
177 cupsGetOption("ManualFeed", num_options
, options
) == NULL
)
178 if (ppdMarkOption(ppd
, "ManualFeed", "True"))
182 else if (!strcasecmp(optptr
->name
, "sides"))
184 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
185 if (cupsGetOption(duplex_options
[j
], num_options
, options
) != NULL
)
188 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
191 * Don't override the PPD option with the IPP attribute...
197 if (!strcasecmp(optptr
->value
, "one-sided"))
200 * Mark the appropriate duplex option for one-sided output...
203 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
204 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
207 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
209 for (k
= 0; k
< (int)(sizeof(duplex_one
) / sizeof(duplex_one
[0])); k
++)
210 if (ppdFindChoice(option
, duplex_one
[k
]))
212 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_one
[k
]))
219 else if (!strcasecmp(optptr
->value
, "two-sided-long-edge"))
222 * Mark the appropriate duplex option for two-sided-long-edge output...
225 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
226 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
229 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
231 for (k
= 0; k
< (int)(sizeof(duplex_two_long
) / sizeof(duplex_two_long
[0])); k
++)
232 if (ppdFindChoice(option
, duplex_two_long
[k
]))
234 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_two_long
[k
]))
241 else if (!strcasecmp(optptr
->value
, "two-sided-short-edge"))
244 * Mark the appropriate duplex option for two-sided-short-edge output...
247 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
248 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
251 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
253 for (k
= 0; k
< (int)(sizeof(duplex_two_short
) / sizeof(duplex_two_short
[0])); k
++)
254 if (ppdFindChoice(option
, duplex_two_short
[k
]))
256 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_two_short
[k
]))
264 else if (!strcasecmp(optptr
->name
, "resolution") ||
265 !strcasecmp(optptr
->name
, "printer-resolution"))
267 if (ppdMarkOption(ppd
, "Resolution", optptr
->value
))
269 if (ppdMarkOption(ppd
, "SetResolution", optptr
->value
))
270 /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
272 if (ppdMarkOption(ppd
, "JCLResolution", optptr
->value
)) /* HP */
274 if (ppdMarkOption(ppd
, "CNRes_PGP", optptr
->value
)) /* Canon */
277 else if (!strcasecmp(optptr
->name
, "output-bin"))
279 if (!cupsGetOption("OutputBin", num_options
, options
))
280 if (ppdMarkOption(ppd
, "OutputBin", optptr
->value
))
283 else if (!strcasecmp(optptr
->name
, "multiple-document-handling"))
285 if (!cupsGetOption("Collate", num_options
, options
) &&
286 ppdFindOption(ppd
, "Collate"))
288 if (strcasecmp(optptr
->value
, "separate-documents-uncollated-copies"))
290 if (ppdMarkOption(ppd
, "Collate", "True"))
295 if (ppdMarkOption(ppd
, "Collate", "False"))
300 else if (!strcasecmp(optptr
->name
, "finishings"))
303 * Lookup cupsIPPFinishings attributes for each value...
306 for (ptr
= optptr
->value
; *ptr
;)
309 * Get the next finishings number...
312 if (!isdigit(*ptr
& 255))
315 if ((j
= strtol(ptr
, &ptr
, 10)) < 3)
319 * Skip separator as needed...
326 * Look it up in the PPD file...
331 if ((attr
= ppdFindAttr(ppd
, "cupsIPPFinishings", s
)) == NULL
)
335 * Apply "*Option Choice" settings from the attribute value...
338 if (ppd_mark_choices(ppd
, attr
->value
))
342 else if (!strcasecmp(optptr
->name
, "mirror"))
344 if (ppdMarkOption(ppd
, "MirrorPrint", optptr
->value
))
347 else if (ppdMarkOption(ppd
, optptr
->name
, optptr
->value
))
350 debug_marked(ppd
, "After...");
357 * 'ppdConflicts()' - Check to see if there are any conflicts among the
358 * marked option choices.
360 * The returned value is the same as returned by @link ppdMarkOption@.
363 int /* O - Number of conflicts found */
364 ppdConflicts(ppd_file_t
*ppd
) /* I - PPD to check */
366 int i
, /* Looping variable */
367 conflicts
; /* Number of conflicts */
368 ppd_const_t
*c
; /* Current constraint */
369 ppd_option_t
*o1
, *o2
; /* Options */
370 ppd_choice_t
*c1
, *c2
; /* Choices */
371 ppd_choice_t key
; /* Search key */
378 * Clear all conflicts...
383 for (o1
= ppdFirstOption(ppd
); o1
; o1
= ppdNextOption(ppd
))
386 cupsArraySave(ppd
->marked
);
389 * Loop through all of the UI constraints and flag any options
393 for (i
= ppd
->num_consts
, c
= ppd
->consts
, o1
= o2
= NULL
, c1
= c2
= NULL
;
398 * Grab pointers to the first option...
401 if (!o1
|| strcmp(c
->option1
, o1
->keyword
))
403 o1
= ppdFindOption(ppd
, c
->option1
);
409 else if (c
->choice1
[0] && (!c1
|| strcmp(c
->choice1
, c1
->choice
)))
412 * This constraint maps to a specific choice.
417 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
418 (!c1
->marked
|| strcmp(c
->choice1
, c1
->choice
)))
424 * This constraint applies to any choice for this option.
429 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
430 (!strcasecmp(c1
->choice
, "None") || !strcasecmp(c1
->choice
, "Off") ||
431 !strcasecmp(c1
->choice
, "False")))
436 * Grab pointers to the second option...
439 if (!o2
|| strcmp(c
->option2
, o2
->keyword
))
441 o2
= ppdFindOption(ppd
, c
->option2
);
447 else if (c
->choice2
[0] && (!c2
|| strcmp(c
->choice2
, c2
->choice
)))
450 * This constraint maps to a specific choice.
455 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
456 (!c2
->marked
|| strcmp(c
->choice2
, c2
->choice
)))
462 * This constraint applies to any choice for this option.
467 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
468 (!strcasecmp(c2
->choice
, "None") || !strcasecmp(c2
->choice
, "Off") ||
469 !strcasecmp(c2
->choice
, "False")))
474 * If both options are marked then there is a conflict...
477 if (c1
&& c1
->marked
&& c2
&& c2
->marked
)
479 DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n",
480 o1
->keyword
, c1
->choice
, o2
->keyword
, c2
->choice
,
481 c
->option1
, c
->choice1
, c
->option2
, c
->choice2
));
488 cupsArrayRestore(ppd
->marked
);
491 * Return the number of conflicts found...
499 * 'ppdFindChoice()' - Return a pointer to an option choice.
502 ppd_choice_t
* /* O - Choice pointer or @code NULL@ */
503 ppdFindChoice(ppd_option_t
*o
, /* I - Pointer to option */
504 const char *choice
) /* I - Name of choice */
506 int i
; /* Looping var */
507 ppd_choice_t
*c
; /* Current choice */
513 if (choice
[0] == '{' || !strncasecmp(choice
, "Custom.", 7))
516 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
517 if (!strcasecmp(c
->choice
, choice
))
525 * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
528 ppd_choice_t
* /* O - Pointer to choice or @code NULL@ */
529 ppdFindMarkedChoice(ppd_file_t
*ppd
, /* I - PPD file */
530 const char *option
) /* I - Keyword/option name */
532 ppd_choice_t key
; /* Search key for choice */
535 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
538 return ((ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
));
543 * 'ppdFindOption()' - Return a pointer to the specified option.
546 ppd_option_t
* /* O - Pointer to option or @code NULL@ */
547 ppdFindOption(ppd_file_t
*ppd
, /* I - PPD file data */
548 const char *option
) /* I - Option/Keyword name */
551 * Range check input...
560 * Search in the array...
563 ppd_option_t key
; /* Option search key */
566 strlcpy(key
.keyword
, option
, sizeof(key
.keyword
));
568 return ((ppd_option_t
*)cupsArrayFind(ppd
->options
, &key
));
573 * Search in each group...
576 int i
, j
; /* Looping vars */
577 ppd_group_t
*group
; /* Current group */
578 ppd_option_t
*optptr
; /* Current option */
581 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
582 for (j
= group
->num_options
, optptr
= group
->options
;
585 if (!strcasecmp(optptr
->keyword
, option
))
594 * 'ppdIsMarked()' - Check to see if an option is marked.
597 int /* O - Non-zero if option is marked */
598 ppdIsMarked(ppd_file_t
*ppd
, /* I - PPD file data */
599 const char *option
, /* I - Option/Keyword name */
600 const char *choice
) /* I - Choice name */
602 ppd_choice_t key
, /* Search key */
603 *c
; /* Choice pointer */
609 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
612 if ((c
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) == NULL
)
615 return (!strcmp(c
->choice
, choice
));
620 * 'ppdMarkDefaults()' - Mark all default options in the PPD file.
624 ppdMarkDefaults(ppd_file_t
*ppd
) /* I - PPD file record */
626 int i
; /* Looping variables */
627 ppd_group_t
*g
; /* Current group */
628 ppd_choice_t
*c
; /* Current choice */
635 * Clean out the marked array...
638 for (c
= (ppd_choice_t
*)cupsArrayFirst(ppd
->marked
);
640 c
= (ppd_choice_t
*)cupsArrayNext(ppd
->marked
))
641 cupsArrayRemove(ppd
->marked
, c
);
644 * Then repopulate it with the defaults...
647 for (i
= ppd
->num_groups
, g
= ppd
->groups
; i
> 0; i
--, g
++)
648 ppd_defaults(ppd
, g
);
653 * 'ppdMarkOption()' - Mark an option in a PPD file.
656 int /* O - Number of conflicts */
657 ppdMarkOption(ppd_file_t
*ppd
, /* I - PPD file record */
658 const char *option
, /* I - Keyword */
659 const char *choice
) /* I - Option name */
661 int i
, j
; /* Looping vars */
662 ppd_option_t
*o
; /* Option pointer */
663 ppd_choice_t
*c
, /* Choice pointer */
664 *oldc
, /* Old choice pointer */
665 key
; /* Search key for choice */
666 struct lconv
*loc
; /* Locale data */
669 DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")\n",
670 ppd
, option
, choice
));
673 * Range check input...
676 if (!ppd
|| !option
|| !choice
)
680 * AP_D_InputSlot is the "default input slot" on MacOS X, and setting
681 * it clears the regular InputSlot choices...
684 if (!strcasecmp(option
, "AP_D_InputSlot"))
686 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
689 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
692 cupsArrayRemove(ppd
->marked
, oldc
);
698 * Check for custom options...
701 if ((o
= ppdFindOption(ppd
, option
)) == NULL
)
706 if (!strncasecmp(choice
, "Custom.", 7))
709 * Handle a custom option...
712 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
715 if (!strcasecmp(option
, "PageSize"))
718 * Handle custom page sizes...
721 ppdPageSize(ppd
, choice
);
726 * Handle other custom options...
729 ppd_coption_t
*coption
; /* Custom option */
730 ppd_cparam_t
*cparam
; /* Custom parameter */
731 char *units
; /* Custom points units */
734 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
736 if ((cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
)) == NULL
)
739 switch (cparam
->type
)
741 case PPD_CUSTOM_CURVE
:
742 case PPD_CUSTOM_INVCURVE
:
743 case PPD_CUSTOM_REAL
:
744 cparam
->current
.custom_real
= (float)_cupsStrScand(choice
+ 7,
748 case PPD_CUSTOM_POINTS
:
749 cparam
->current
.custom_points
= (float)_cupsStrScand(choice
+ 7,
755 if (!strcasecmp(units
, "cm"))
756 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
757 else if (!strcasecmp(units
, "mm"))
758 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
759 else if (!strcasecmp(units
, "m"))
760 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
761 else if (!strcasecmp(units
, "in"))
762 cparam
->current
.custom_points
*= 72.0f
;
763 else if (!strcasecmp(units
, "ft"))
764 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
768 case PPD_CUSTOM_INT
:
769 cparam
->current
.custom_int
= atoi(choice
+ 7);
772 case PPD_CUSTOM_PASSCODE
:
773 case PPD_CUSTOM_PASSWORD
:
774 case PPD_CUSTOM_STRING
:
775 if (cparam
->current
.custom_string
)
776 _cupsStrFree(cparam
->current
.custom_string
);
778 cparam
->current
.custom_string
= _cupsStrAlloc(choice
+ 7);
785 * Make sure that we keep the option marked below...
790 else if (choice
[0] == '{')
793 * Handle multi-value custom options...
796 ppd_coption_t
*coption
; /* Custom option */
797 ppd_cparam_t
*cparam
; /* Custom parameter */
798 char *units
; /* Custom points units */
799 int num_vals
; /* Number of values */
800 cups_option_t
*vals
, /* Values */
804 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
807 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
809 num_vals
= cupsParseOptions(choice
+ 1, 0, &vals
);
811 for (i
= 0, val
= vals
; i
< num_vals
; i
++, val
++)
813 if ((cparam
= ppdFindCustomParam(coption
, val
->name
)) == NULL
)
816 switch (cparam
->type
)
818 case PPD_CUSTOM_CURVE
:
819 case PPD_CUSTOM_INVCURVE
:
820 case PPD_CUSTOM_REAL
:
821 cparam
->current
.custom_real
= (float)_cupsStrScand(val
->value
,
825 case PPD_CUSTOM_POINTS
:
826 cparam
->current
.custom_points
= (float)_cupsStrScand(val
->value
,
832 if (!strcasecmp(units
, "cm"))
833 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
834 else if (!strcasecmp(units
, "mm"))
835 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
836 else if (!strcasecmp(units
, "m"))
837 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
838 else if (!strcasecmp(units
, "in"))
839 cparam
->current
.custom_points
*= 72.0f
;
840 else if (!strcasecmp(units
, "ft"))
841 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
845 case PPD_CUSTOM_INT
:
846 cparam
->current
.custom_int
= atoi(val
->value
);
849 case PPD_CUSTOM_PASSCODE
:
850 case PPD_CUSTOM_PASSWORD
:
851 case PPD_CUSTOM_STRING
:
852 if (cparam
->current
.custom_string
)
853 _cupsStrFree(cparam
->current
.custom_string
);
855 cparam
->current
.custom_string
= _cupsStrAlloc(val
->value
);
860 cupsFreeOptions(num_vals
, vals
);
865 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
866 if (!strcasecmp(c
->choice
, choice
))
874 * Option found; mark it and then handle unmarking any other options.
877 if (o
->ui
!= PPD_UI_PICKMANY
)
880 * Unmark all other choices...
883 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, c
)) != NULL
)
886 cupsArrayRemove(ppd
->marked
, oldc
);
889 if (!strcasecmp(option
, "PageSize") || !strcasecmp(option
, "PageRegion"))
892 * Mark current page size...
895 for (j
= 0; j
< ppd
->num_sizes
; j
++)
896 ppd
->sizes
[j
].marked
= !strcasecmp(ppd
->sizes
[j
].name
,
900 * Unmark the current PageSize or PageRegion setting, as
904 if (!strcasecmp(option
, "PageSize"))
906 if ((o
= ppdFindOption(ppd
, "PageRegion")) != NULL
)
909 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
912 cupsArrayRemove(ppd
->marked
, oldc
);
918 if ((o
= ppdFindOption(ppd
, "PageSize")) != NULL
)
921 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
924 cupsArrayRemove(ppd
->marked
, oldc
);
929 else if (!strcasecmp(option
, "InputSlot"))
932 * Unmark ManualFeed option...
935 if ((o
= ppdFindOption(ppd
, "ManualFeed")) != NULL
)
938 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
941 cupsArrayRemove(ppd
->marked
, oldc
);
945 else if (!strcasecmp(option
, "ManualFeed") &&
946 !strcasecmp(choice
, "True"))
949 * Unmark InputSlot option...
952 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
955 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
958 cupsArrayRemove(ppd
->marked
, oldc
);
966 cupsArrayAdd(ppd
->marked
, c
);
969 * Return the number of conflicts...
972 return (ppdConflicts(ppd
));
977 * 'ppdFirstOption()' - Return the first option in the PPD file.
979 * Options are returned from all groups in ascending alphanumeric order.
984 ppd_option_t
* /* O - First option or @code NULL@ */
985 ppdFirstOption(ppd_file_t
*ppd
) /* I - PPD file */
990 return ((ppd_option_t
*)cupsArrayFirst(ppd
->options
));
995 * 'ppdNextOption()' - Return the next option in the PPD file.
997 * Options are returned from all groups in ascending alphanumeric order.
1002 ppd_option_t
* /* O - Next option or @code NULL@ */
1003 ppdNextOption(ppd_file_t
*ppd
) /* I - PPD file */
1008 return ((ppd_option_t
*)cupsArrayNext(ppd
->options
));
1014 * 'debug_marked()' - Output the marked array to stdout...
1018 debug_marked(ppd_file_t
*ppd
, /* I - PPD file data */
1019 const char *title
) /* I - Title for list */
1021 ppd_choice_t
*c
; /* Current choice */
1024 DEBUG_printf(("cupsMarkOptions: %s\n", title
));
1026 for (c
= (ppd_choice_t
*)cupsArrayFirst(ppd
->marked
);
1028 c
= (ppd_choice_t
*)cupsArrayNext(ppd
->marked
))
1029 DEBUG_printf(("cupsMarkOptions: %s=%s\n", c
->option
->keyword
, c
->choice
));
1035 * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
1039 ppd_defaults(ppd_file_t
*ppd
, /* I - PPD file */
1040 ppd_group_t
*g
) /* I - Group to default */
1042 int i
; /* Looping var */
1043 ppd_option_t
*o
; /* Current option */
1044 ppd_group_t
*sg
; /* Current sub-group */
1047 for (i
= g
->num_options
, o
= g
->options
; i
> 0; i
--, o
++)
1048 if (strcasecmp(o
->keyword
, "PageRegion") != 0)
1049 ppdMarkOption(ppd
, o
->keyword
, o
->defchoice
);
1051 for (i
= g
->num_subgroups
, sg
= g
->subgroups
; i
> 0; i
--, sg
++)
1052 ppd_defaults(ppd
, sg
);
1057 * 'ppd_mark_choices()' - Mark one or more option choices from a string.
1060 static int /* O - 1 if there are conflicts, 0 otherwise */
1061 ppd_mark_choices(ppd_file_t
*ppd
, /* I - PPD file */
1062 const char *options
) /* I - "*Option Choice ..." string */
1064 char option
[PPD_MAX_NAME
], /* Current option */
1065 choice
[PPD_MAX_NAME
], /* Current choice */
1066 *ptr
; /* Pointer into option or choice */
1067 int conflict
= 0; /* Do we have a conflict? */
1074 * Read all of the "*Option Choice" pairs from the string, marking PPD
1075 * options as we go...
1081 * Skip leading whitespace...
1084 while (isspace(*options
& 255))
1087 if (*options
!= '*')
1091 * Get the option name...
1096 while (*options
&& !isspace(*options
& 255) &&
1097 ptr
< (option
+ sizeof(option
) - 1))
1098 *ptr
++ = *options
++;
1109 while (isspace(*options
& 255))
1116 while (*options
&& !isspace(*options
& 255) &&
1117 ptr
< (choice
+ sizeof(choice
) - 1))
1118 *ptr
++ = *options
++;
1123 * Mark the option...
1126 if (ppdMarkOption(ppd
, option
, choice
))
1131 * Return whether we had any conflicts...
1139 * End of "$Id: mark.c 7605 2008-05-21 00:36:25Z mike $".