]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/mark.c
2 * "$Id: mark.c 7278 2008-01-31 01:23:09Z 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 */
510 if (o
== NULL
|| choice
== NULL
)
513 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
514 if (strcasecmp(c
->choice
, choice
) == 0)
522 * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
525 ppd_choice_t
* /* O - Pointer to choice or @code NULL@ */
526 ppdFindMarkedChoice(ppd_file_t
*ppd
, /* I - PPD file */
527 const char *option
) /* I - Keyword/option name */
529 ppd_choice_t key
; /* Search key for choice */
532 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
535 return ((ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
));
540 * 'ppdFindOption()' - Return a pointer to the specified option.
543 ppd_option_t
* /* O - Pointer to option or @code NULL@ */
544 ppdFindOption(ppd_file_t
*ppd
, /* I - PPD file data */
545 const char *option
) /* I - Option/Keyword name */
548 * Range check input...
557 * Search in the array...
560 ppd_option_t key
; /* Option search key */
563 strlcpy(key
.keyword
, option
, sizeof(key
.keyword
));
565 return ((ppd_option_t
*)cupsArrayFind(ppd
->options
, &key
));
570 * Search in each group...
573 int i
, j
; /* Looping vars */
574 ppd_group_t
*group
; /* Current group */
575 ppd_option_t
*optptr
; /* Current option */
578 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
579 for (j
= group
->num_options
, optptr
= group
->options
;
582 if (!strcasecmp(optptr
->keyword
, option
))
591 * 'ppdIsMarked()' - Check to see if an option is marked.
594 int /* O - Non-zero if option is marked */
595 ppdIsMarked(ppd_file_t
*ppd
, /* I - PPD file data */
596 const char *option
, /* I - Option/Keyword name */
597 const char *choice
) /* I - Choice name */
599 ppd_choice_t key
, /* Search key */
600 *c
; /* Choice pointer */
606 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
609 if ((c
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) == NULL
)
612 return (!strcmp(c
->choice
, choice
));
617 * 'ppdMarkDefaults()' - Mark all default options in the PPD file.
621 ppdMarkDefaults(ppd_file_t
*ppd
) /* I - PPD file record */
623 int i
; /* Looping variables */
624 ppd_group_t
*g
; /* Current group */
625 ppd_choice_t
*c
; /* Current choice */
632 * Clean out the marked array...
635 for (c
= (ppd_choice_t
*)cupsArrayFirst(ppd
->marked
);
637 c
= (ppd_choice_t
*)cupsArrayNext(ppd
->marked
))
638 cupsArrayRemove(ppd
->marked
, c
);
641 * Then repopulate it with the defaults...
644 for (i
= ppd
->num_groups
, g
= ppd
->groups
; i
> 0; i
--, g
++)
645 ppd_defaults(ppd
, g
);
650 * 'ppdMarkOption()' - Mark an option in a PPD file.
653 int /* O - Number of conflicts */
654 ppdMarkOption(ppd_file_t
*ppd
, /* I - PPD file record */
655 const char *option
, /* I - Keyword */
656 const char *choice
) /* I - Option name */
658 int i
, j
; /* Looping vars */
659 ppd_option_t
*o
; /* Option pointer */
660 ppd_choice_t
*c
, /* Choice pointer */
661 *oldc
, /* Old choice pointer */
662 key
; /* Search key for choice */
663 struct lconv
*loc
; /* Locale data */
666 DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")\n",
667 ppd
, option
, choice
));
670 * Range check input...
673 if (!ppd
|| !option
|| !choice
)
677 * AP_D_InputSlot is the "default input slot" on MacOS X, and setting
678 * it clears the regular InputSlot choices...
681 if (!strcasecmp(option
, "AP_D_InputSlot"))
683 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
686 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
689 cupsArrayRemove(ppd
->marked
, oldc
);
695 * Check for custom options...
698 if ((o
= ppdFindOption(ppd
, option
)) == NULL
)
703 if (!strncasecmp(choice
, "Custom.", 7))
706 * Handle a custom option...
709 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
712 if (!strcasecmp(option
, "PageSize"))
715 * Handle custom page sizes...
718 ppdPageSize(ppd
, choice
);
723 * Handle other custom options...
726 ppd_coption_t
*coption
; /* Custom option */
727 ppd_cparam_t
*cparam
; /* Custom parameter */
728 char *units
; /* Custom points units */
731 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
733 if ((cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
)) == NULL
)
736 switch (cparam
->type
)
738 case PPD_CUSTOM_CURVE
:
739 case PPD_CUSTOM_INVCURVE
:
740 case PPD_CUSTOM_REAL
:
741 cparam
->current
.custom_real
= (float)_cupsStrScand(choice
+ 7,
745 case PPD_CUSTOM_POINTS
:
746 cparam
->current
.custom_points
= (float)_cupsStrScand(choice
+ 7,
752 if (!strcasecmp(units
, "cm"))
753 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
754 else if (!strcasecmp(units
, "mm"))
755 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
756 else if (!strcasecmp(units
, "m"))
757 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
758 else if (!strcasecmp(units
, "in"))
759 cparam
->current
.custom_points
*= 72.0f
;
760 else if (!strcasecmp(units
, "ft"))
761 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
765 case PPD_CUSTOM_INT
:
766 cparam
->current
.custom_int
= atoi(choice
+ 7);
769 case PPD_CUSTOM_PASSCODE
:
770 case PPD_CUSTOM_PASSWORD
:
771 case PPD_CUSTOM_STRING
:
772 if (cparam
->current
.custom_string
)
773 _cupsStrFree(cparam
->current
.custom_string
);
775 cparam
->current
.custom_string
= _cupsStrAlloc(choice
+ 7);
782 * Make sure that we keep the option marked below...
787 else if (choice
[0] == '{')
790 * Handle multi-value custom options...
793 ppd_coption_t
*coption
; /* Custom option */
794 ppd_cparam_t
*cparam
; /* Custom parameter */
795 char *units
; /* Custom points units */
796 int num_vals
; /* Number of values */
797 cups_option_t
*vals
, /* Values */
801 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
804 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
806 num_vals
= cupsParseOptions(choice
+ 1, 0, &vals
);
808 for (i
= 0, val
= vals
; i
< num_vals
; i
++, val
++)
810 if ((cparam
= ppdFindCustomParam(coption
, val
->name
)) == NULL
)
813 switch (cparam
->type
)
815 case PPD_CUSTOM_CURVE
:
816 case PPD_CUSTOM_INVCURVE
:
817 case PPD_CUSTOM_REAL
:
818 cparam
->current
.custom_real
= (float)_cupsStrScand(val
->value
,
822 case PPD_CUSTOM_POINTS
:
823 cparam
->current
.custom_points
= (float)_cupsStrScand(val
->value
,
829 if (!strcasecmp(units
, "cm"))
830 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
831 else if (!strcasecmp(units
, "mm"))
832 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
833 else if (!strcasecmp(units
, "m"))
834 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
835 else if (!strcasecmp(units
, "in"))
836 cparam
->current
.custom_points
*= 72.0f
;
837 else if (!strcasecmp(units
, "ft"))
838 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
842 case PPD_CUSTOM_INT
:
843 cparam
->current
.custom_int
= atoi(val
->value
);
846 case PPD_CUSTOM_PASSCODE
:
847 case PPD_CUSTOM_PASSWORD
:
848 case PPD_CUSTOM_STRING
:
849 if (cparam
->current
.custom_string
)
850 _cupsStrFree(cparam
->current
.custom_string
);
852 cparam
->current
.custom_string
= _cupsStrAlloc(val
->value
);
857 cupsFreeOptions(num_vals
, vals
);
862 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
863 if (!strcasecmp(c
->choice
, choice
))
871 * Option found; mark it and then handle unmarking any other options.
874 if (o
->ui
!= PPD_UI_PICKMANY
)
877 * Unmark all other choices...
880 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, c
)) != NULL
)
883 cupsArrayRemove(ppd
->marked
, oldc
);
886 if (!strcasecmp(option
, "PageSize") || !strcasecmp(option
, "PageRegion"))
889 * Mark current page size...
892 for (j
= 0; j
< ppd
->num_sizes
; j
++)
893 ppd
->sizes
[j
].marked
= !strcasecmp(ppd
->sizes
[j
].name
,
897 * Unmark the current PageSize or PageRegion setting, as
901 if (!strcasecmp(option
, "PageSize"))
903 if ((o
= ppdFindOption(ppd
, "PageRegion")) != NULL
)
906 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
909 cupsArrayRemove(ppd
->marked
, oldc
);
915 if ((o
= ppdFindOption(ppd
, "PageSize")) != NULL
)
918 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
921 cupsArrayRemove(ppd
->marked
, oldc
);
926 else if (!strcasecmp(option
, "InputSlot"))
929 * Unmark ManualFeed option...
932 if ((o
= ppdFindOption(ppd
, "ManualFeed")) != NULL
)
935 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
938 cupsArrayRemove(ppd
->marked
, oldc
);
942 else if (!strcasecmp(option
, "ManualFeed") &&
943 !strcasecmp(choice
, "True"))
946 * Unmark InputSlot option...
949 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
952 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
955 cupsArrayRemove(ppd
->marked
, oldc
);
963 cupsArrayAdd(ppd
->marked
, c
);
966 * Return the number of conflicts...
969 return (ppdConflicts(ppd
));
974 * 'ppdFirstOption()' - Return the first option in the PPD file.
976 * Options are returned from all groups in ascending alphanumeric order.
981 ppd_option_t
* /* O - First option or @code NULL@ */
982 ppdFirstOption(ppd_file_t
*ppd
) /* I - PPD file */
987 return ((ppd_option_t
*)cupsArrayFirst(ppd
->options
));
992 * 'ppdNextOption()' - Return the next option in the PPD file.
994 * Options are returned from all groups in ascending alphanumeric order.
999 ppd_option_t
* /* O - Next option or @code NULL@ */
1000 ppdNextOption(ppd_file_t
*ppd
) /* I - PPD file */
1005 return ((ppd_option_t
*)cupsArrayNext(ppd
->options
));
1011 * 'debug_marked()' - Output the marked array to stdout...
1015 debug_marked(ppd_file_t
*ppd
, /* I - PPD file data */
1016 const char *title
) /* I - Title for list */
1018 ppd_choice_t
*c
; /* Current choice */
1021 printf("cupsMarkOptions: %s\n", title
);
1023 for (c
= (ppd_choice_t
*)cupsArrayFirst(ppd
->marked
);
1025 c
= (ppd_choice_t
*)cupsArrayNext(ppd
->marked
))
1026 printf("cupsMarkOptions: %s=%s\n", c
->option
->keyword
, c
->choice
);
1032 * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
1036 ppd_defaults(ppd_file_t
*ppd
, /* I - PPD file */
1037 ppd_group_t
*g
) /* I - Group to default */
1039 int i
; /* Looping var */
1040 ppd_option_t
*o
; /* Current option */
1041 ppd_group_t
*sg
; /* Current sub-group */
1044 for (i
= g
->num_options
, o
= g
->options
; i
> 0; i
--, o
++)
1045 if (strcasecmp(o
->keyword
, "PageRegion") != 0)
1046 ppdMarkOption(ppd
, o
->keyword
, o
->defchoice
);
1048 for (i
= g
->num_subgroups
, sg
= g
->subgroups
; i
> 0; i
--, sg
++)
1049 ppd_defaults(ppd
, sg
);
1054 * 'ppd_mark_choices()' - Mark one or more option choices from a string.
1057 static int /* O - 1 if there are conflicts, 0 otherwise */
1058 ppd_mark_choices(ppd_file_t
*ppd
, /* I - PPD file */
1059 const char *options
) /* I - "*Option Choice ..." string */
1061 char option
[PPD_MAX_NAME
], /* Current option */
1062 choice
[PPD_MAX_NAME
], /* Current choice */
1063 *ptr
; /* Pointer into option or choice */
1064 int conflict
= 0; /* Do we have a conflict? */
1071 * Read all of the "*Option Choice" pairs from the string, marking PPD
1072 * options as we go...
1078 * Skip leading whitespace...
1081 while (isspace(*options
& 255))
1084 if (*options
!= '*')
1088 * Get the option name...
1093 while (*options
&& !isspace(*options
& 255) &&
1094 ptr
< (option
+ sizeof(option
) - 1))
1095 *ptr
++ = *options
++;
1106 while (isspace(*options
& 255))
1113 while (*options
&& !isspace(*options
& 255) &&
1114 ptr
< (choice
+ sizeof(choice
) - 1))
1115 *ptr
++ = *options
++;
1120 * Mark the option...
1123 if (ppdMarkOption(ppd
, option
, choice
))
1128 * Return whether we had any conflicts...
1136 * End of "$Id: mark.c 7278 2008-01-31 01:23:09Z mike $".