1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Option conflict management routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker *
10*5e7646d2SAndroid Build Coastguard Worker * PostScript is a trademark of Adobe Systems, Inc.
11*5e7646d2SAndroid Build Coastguard Worker */
12*5e7646d2SAndroid Build Coastguard Worker
13*5e7646d2SAndroid Build Coastguard Worker /*
14*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
15*5e7646d2SAndroid Build Coastguard Worker */
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
18*5e7646d2SAndroid Build Coastguard Worker #include "ppd-private.h"
19*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
20*5e7646d2SAndroid Build Coastguard Worker
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker /*
23*5e7646d2SAndroid Build Coastguard Worker * Local constants...
24*5e7646d2SAndroid Build Coastguard Worker */
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker enum
27*5e7646d2SAndroid Build Coastguard Worker {
28*5e7646d2SAndroid Build Coastguard Worker _PPD_OPTION_CONSTRAINTS,
29*5e7646d2SAndroid Build Coastguard Worker _PPD_INSTALLABLE_CONSTRAINTS,
30*5e7646d2SAndroid Build Coastguard Worker _PPD_ALL_CONSTRAINTS
31*5e7646d2SAndroid Build Coastguard Worker };
32*5e7646d2SAndroid Build Coastguard Worker
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker /*
35*5e7646d2SAndroid Build Coastguard Worker * Local functions...
36*5e7646d2SAndroid Build Coastguard Worker */
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker static int ppd_is_installable(ppd_group_t *installable,
39*5e7646d2SAndroid Build Coastguard Worker const char *option);
40*5e7646d2SAndroid Build Coastguard Worker static void ppd_load_constraints(ppd_file_t *ppd);
41*5e7646d2SAndroid Build Coastguard Worker static cups_array_t *ppd_test_constraints(ppd_file_t *ppd,
42*5e7646d2SAndroid Build Coastguard Worker const char *option,
43*5e7646d2SAndroid Build Coastguard Worker const char *choice,
44*5e7646d2SAndroid Build Coastguard Worker int num_options,
45*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options,
46*5e7646d2SAndroid Build Coastguard Worker int which);
47*5e7646d2SAndroid Build Coastguard Worker
48*5e7646d2SAndroid Build Coastguard Worker
49*5e7646d2SAndroid Build Coastguard Worker /*
50*5e7646d2SAndroid Build Coastguard Worker * 'cupsGetConflicts()' - Get a list of conflicting options in a marked PPD.
51*5e7646d2SAndroid Build Coastguard Worker *
52*5e7646d2SAndroid Build Coastguard Worker * This function gets a list of options that would conflict if "option" and
53*5e7646d2SAndroid Build Coastguard Worker * "choice" were marked in the PPD. You would typically call this function
54*5e7646d2SAndroid Build Coastguard Worker * after marking the currently selected options in the PPD in order to
55*5e7646d2SAndroid Build Coastguard Worker * determine whether a new option selection would cause a conflict.
56*5e7646d2SAndroid Build Coastguard Worker *
57*5e7646d2SAndroid Build Coastguard Worker * The number of conflicting options are returned with "options" pointing to
58*5e7646d2SAndroid Build Coastguard Worker * the conflicting options. The returned option array must be freed using
59*5e7646d2SAndroid Build Coastguard Worker * @link cupsFreeOptions@.
60*5e7646d2SAndroid Build Coastguard Worker *
61*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.4/macOS 10.6@
62*5e7646d2SAndroid Build Coastguard Worker */
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of conflicting options */
cupsGetConflicts(ppd_file_t * ppd,const char * option,const char * choice,cups_option_t ** options)65*5e7646d2SAndroid Build Coastguard Worker cupsGetConflicts(
66*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file */
67*5e7646d2SAndroid Build Coastguard Worker const char *option, /* I - Option to test */
68*5e7646d2SAndroid Build Coastguard Worker const char *choice, /* I - Choice to test */
69*5e7646d2SAndroid Build Coastguard Worker cups_option_t **options) /* O - Conflicting options */
70*5e7646d2SAndroid Build Coastguard Worker {
71*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
72*5e7646d2SAndroid Build Coastguard Worker num_options; /* Number of conflicting options */
73*5e7646d2SAndroid Build Coastguard Worker cups_array_t *active; /* Active conflicts */
74*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconsts_t *c; /* Current constraints */
75*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconst_t *cptr; /* Current constraint */
76*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *marked; /* Marked choice */
77*5e7646d2SAndroid Build Coastguard Worker
78*5e7646d2SAndroid Build Coastguard Worker
79*5e7646d2SAndroid Build Coastguard Worker /*
80*5e7646d2SAndroid Build Coastguard Worker * Range check input...
81*5e7646d2SAndroid Build Coastguard Worker */
82*5e7646d2SAndroid Build Coastguard Worker
83*5e7646d2SAndroid Build Coastguard Worker if (options)
84*5e7646d2SAndroid Build Coastguard Worker *options = NULL;
85*5e7646d2SAndroid Build Coastguard Worker
86*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !option || !choice || !options)
87*5e7646d2SAndroid Build Coastguard Worker return (0);
88*5e7646d2SAndroid Build Coastguard Worker
89*5e7646d2SAndroid Build Coastguard Worker /*
90*5e7646d2SAndroid Build Coastguard Worker * Test for conflicts...
91*5e7646d2SAndroid Build Coastguard Worker */
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker active = ppd_test_constraints(ppd, option, choice, 0, NULL,
94*5e7646d2SAndroid Build Coastguard Worker _PPD_ALL_CONSTRAINTS);
95*5e7646d2SAndroid Build Coastguard Worker
96*5e7646d2SAndroid Build Coastguard Worker /*
97*5e7646d2SAndroid Build Coastguard Worker * Loop through all of the UI constraints and add any options that conflict...
98*5e7646d2SAndroid Build Coastguard Worker */
99*5e7646d2SAndroid Build Coastguard Worker
100*5e7646d2SAndroid Build Coastguard Worker for (num_options = 0, c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active);
101*5e7646d2SAndroid Build Coastguard Worker c;
102*5e7646d2SAndroid Build Coastguard Worker c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active))
103*5e7646d2SAndroid Build Coastguard Worker {
104*5e7646d2SAndroid Build Coastguard Worker for (i = c->num_constraints, cptr = c->constraints;
105*5e7646d2SAndroid Build Coastguard Worker i > 0;
106*5e7646d2SAndroid Build Coastguard Worker i --, cptr ++)
107*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(cptr->option->keyword, option))
108*5e7646d2SAndroid Build Coastguard Worker {
109*5e7646d2SAndroid Build Coastguard Worker if (cptr->choice)
110*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(cptr->option->keyword,
111*5e7646d2SAndroid Build Coastguard Worker cptr->choice->choice, num_options,
112*5e7646d2SAndroid Build Coastguard Worker options);
113*5e7646d2SAndroid Build Coastguard Worker else if ((marked = ppdFindMarkedChoice(ppd,
114*5e7646d2SAndroid Build Coastguard Worker cptr->option->keyword)) != NULL)
115*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(cptr->option->keyword, marked->choice,
116*5e7646d2SAndroid Build Coastguard Worker num_options, options);
117*5e7646d2SAndroid Build Coastguard Worker }
118*5e7646d2SAndroid Build Coastguard Worker }
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(active);
121*5e7646d2SAndroid Build Coastguard Worker
122*5e7646d2SAndroid Build Coastguard Worker return (num_options);
123*5e7646d2SAndroid Build Coastguard Worker }
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker /*
127*5e7646d2SAndroid Build Coastguard Worker * 'cupsResolveConflicts()' - Resolve conflicts in a marked PPD.
128*5e7646d2SAndroid Build Coastguard Worker *
129*5e7646d2SAndroid Build Coastguard Worker * This function attempts to resolve any conflicts in a marked PPD, returning
130*5e7646d2SAndroid Build Coastguard Worker * a list of option changes that are required to resolve them. On input,
131*5e7646d2SAndroid Build Coastguard Worker * "num_options" and "options" contain any pending option changes that have
132*5e7646d2SAndroid Build Coastguard Worker * not yet been marked, while "option" and "choice" contain the most recent
133*5e7646d2SAndroid Build Coastguard Worker * selection which may or may not be in "num_options" or "options".
134*5e7646d2SAndroid Build Coastguard Worker *
135*5e7646d2SAndroid Build Coastguard Worker * On successful return, "num_options" and "options" are updated to contain
136*5e7646d2SAndroid Build Coastguard Worker * "option" and "choice" along with any changes required to resolve conflicts
137*5e7646d2SAndroid Build Coastguard Worker * specified in the PPD file and 1 is returned.
138*5e7646d2SAndroid Build Coastguard Worker *
139*5e7646d2SAndroid Build Coastguard Worker * If option conflicts cannot be resolved, "num_options" and "options" are not
140*5e7646d2SAndroid Build Coastguard Worker * changed and 0 is returned.
141*5e7646d2SAndroid Build Coastguard Worker *
142*5e7646d2SAndroid Build Coastguard Worker * When resolving conflicts, @code cupsResolveConflicts@ does not consider
143*5e7646d2SAndroid Build Coastguard Worker * changes to the current page size (@code media@, @code PageSize@, and
144*5e7646d2SAndroid Build Coastguard Worker * @code PageRegion@) or to the most recent option specified in "option".
145*5e7646d2SAndroid Build Coastguard Worker * Thus, if the only way to resolve a conflict is to change the page size
146*5e7646d2SAndroid Build Coastguard Worker * or the option the user most recently changed, @code cupsResolveConflicts@
147*5e7646d2SAndroid Build Coastguard Worker * will return 0 to indicate it was unable to resolve the conflicts.
148*5e7646d2SAndroid Build Coastguard Worker *
149*5e7646d2SAndroid Build Coastguard Worker * The @code cupsResolveConflicts@ function uses one of two sources of option
150*5e7646d2SAndroid Build Coastguard Worker * constraint information. The preferred constraint information is defined by
151*5e7646d2SAndroid Build Coastguard Worker * @code cupsUIConstraints@ and @code cupsUIResolver@ attributes - in this
152*5e7646d2SAndroid Build Coastguard Worker * case, the PPD file provides constraint resolution actions.
153*5e7646d2SAndroid Build Coastguard Worker *
154*5e7646d2SAndroid Build Coastguard Worker * The backup constraint information is defined by the
155*5e7646d2SAndroid Build Coastguard Worker * @code UIConstraints@ and @code NonUIConstraints@ attributes. These
156*5e7646d2SAndroid Build Coastguard Worker * constraints are resolved algorithmically by first selecting the default
157*5e7646d2SAndroid Build Coastguard Worker * choice for the conflicting option, then iterating over all possible choices
158*5e7646d2SAndroid Build Coastguard Worker * until a non-conflicting option choice is found.
159*5e7646d2SAndroid Build Coastguard Worker *
160*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.4/macOS 10.6@
161*5e7646d2SAndroid Build Coastguard Worker */
162*5e7646d2SAndroid Build Coastguard Worker
163*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
cupsResolveConflicts(ppd_file_t * ppd,const char * option,const char * choice,int * num_options,cups_option_t ** options)164*5e7646d2SAndroid Build Coastguard Worker cupsResolveConflicts(
165*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file */
166*5e7646d2SAndroid Build Coastguard Worker const char *option, /* I - Newly selected option or @code NULL@ for none */
167*5e7646d2SAndroid Build Coastguard Worker const char *choice, /* I - Newly selected choice or @code NULL@ for none */
168*5e7646d2SAndroid Build Coastguard Worker int *num_options, /* IO - Number of additional selected options */
169*5e7646d2SAndroid Build Coastguard Worker cups_option_t **options) /* IO - Additional selected options */
170*5e7646d2SAndroid Build Coastguard Worker {
171*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
172*5e7646d2SAndroid Build Coastguard Worker tries, /* Number of tries */
173*5e7646d2SAndroid Build Coastguard Worker num_newopts; /* Number of new options */
174*5e7646d2SAndroid Build Coastguard Worker cups_option_t *newopts; /* New options */
175*5e7646d2SAndroid Build Coastguard Worker cups_array_t *active = NULL, /* Active constraints */
176*5e7646d2SAndroid Build Coastguard Worker *pass, /* Resolvers for this pass */
177*5e7646d2SAndroid Build Coastguard Worker *resolvers, /* Resolvers we have used */
178*5e7646d2SAndroid Build Coastguard Worker *test; /* Test array for conflicts */
179*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconsts_t *consts; /* Current constraints */
180*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconst_t *constptr; /* Current constraint */
181*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *resolver; /* Current resolver */
182*5e7646d2SAndroid Build Coastguard Worker const char *resval; /* Pointer into resolver value */
183*5e7646d2SAndroid Build Coastguard Worker char resoption[PPD_MAX_NAME],
184*5e7646d2SAndroid Build Coastguard Worker /* Current resolver option */
185*5e7646d2SAndroid Build Coastguard Worker reschoice[PPD_MAX_NAME],
186*5e7646d2SAndroid Build Coastguard Worker /* Current resolver choice */
187*5e7646d2SAndroid Build Coastguard Worker *resptr, /* Pointer into option/choice */
188*5e7646d2SAndroid Build Coastguard Worker firstpage[255]; /* AP_FIRSTPAGE_Keyword string */
189*5e7646d2SAndroid Build Coastguard Worker const char *value; /* Selected option value */
190*5e7646d2SAndroid Build Coastguard Worker int changed; /* Did we change anything? */
191*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *marked; /* Marked choice */
192*5e7646d2SAndroid Build Coastguard Worker
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker /*
195*5e7646d2SAndroid Build Coastguard Worker * Range check input...
196*5e7646d2SAndroid Build Coastguard Worker */
197*5e7646d2SAndroid Build Coastguard Worker
198*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !num_options || !options || (option == NULL) != (choice == NULL))
199*5e7646d2SAndroid Build Coastguard Worker return (0);
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker /*
202*5e7646d2SAndroid Build Coastguard Worker * Build a shadow option array...
203*5e7646d2SAndroid Build Coastguard Worker */
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker num_newopts = 0;
206*5e7646d2SAndroid Build Coastguard Worker newopts = NULL;
207*5e7646d2SAndroid Build Coastguard Worker
208*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < *num_options; i ++)
209*5e7646d2SAndroid Build Coastguard Worker num_newopts = cupsAddOption((*options)[i].name, (*options)[i].value,
210*5e7646d2SAndroid Build Coastguard Worker num_newopts, &newopts);
211*5e7646d2SAndroid Build Coastguard Worker if (option && _cups_strcasecmp(option, "Collate"))
212*5e7646d2SAndroid Build Coastguard Worker num_newopts = cupsAddOption(option, choice, num_newopts, &newopts);
213*5e7646d2SAndroid Build Coastguard Worker
214*5e7646d2SAndroid Build Coastguard Worker /*
215*5e7646d2SAndroid Build Coastguard Worker * Loop until we have no conflicts...
216*5e7646d2SAndroid Build Coastguard Worker */
217*5e7646d2SAndroid Build Coastguard Worker
218*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->sorted_attrs);
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker resolvers = NULL;
221*5e7646d2SAndroid Build Coastguard Worker pass = cupsArrayNew((cups_array_func_t)_cups_strcasecmp, NULL);
222*5e7646d2SAndroid Build Coastguard Worker tries = 0;
223*5e7646d2SAndroid Build Coastguard Worker
224*5e7646d2SAndroid Build Coastguard Worker while (tries < 100 &&
225*5e7646d2SAndroid Build Coastguard Worker (active = ppd_test_constraints(ppd, NULL, NULL, num_newopts, newopts,
226*5e7646d2SAndroid Build Coastguard Worker _PPD_ALL_CONSTRAINTS)) != NULL)
227*5e7646d2SAndroid Build Coastguard Worker {
228*5e7646d2SAndroid Build Coastguard Worker tries ++;
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker if (!resolvers)
231*5e7646d2SAndroid Build Coastguard Worker resolvers = cupsArrayNew((cups_array_func_t)_cups_strcasecmp, NULL);
232*5e7646d2SAndroid Build Coastguard Worker
233*5e7646d2SAndroid Build Coastguard Worker for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active), changed = 0;
234*5e7646d2SAndroid Build Coastguard Worker consts;
235*5e7646d2SAndroid Build Coastguard Worker consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(active))
236*5e7646d2SAndroid Build Coastguard Worker {
237*5e7646d2SAndroid Build Coastguard Worker if (consts->resolver[0])
238*5e7646d2SAndroid Build Coastguard Worker {
239*5e7646d2SAndroid Build Coastguard Worker /*
240*5e7646d2SAndroid Build Coastguard Worker * Look up the resolver...
241*5e7646d2SAndroid Build Coastguard Worker */
242*5e7646d2SAndroid Build Coastguard Worker
243*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(pass, consts->resolver))
244*5e7646d2SAndroid Build Coastguard Worker continue; /* Already applied this resolver... */
245*5e7646d2SAndroid Build Coastguard Worker
246*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(resolvers, consts->resolver))
247*5e7646d2SAndroid Build Coastguard Worker {
248*5e7646d2SAndroid Build Coastguard Worker /*
249*5e7646d2SAndroid Build Coastguard Worker * Resolver loop!
250*5e7646d2SAndroid Build Coastguard Worker */
251*5e7646d2SAndroid Build Coastguard Worker
252*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsResolveConflicts: Resolver loop with %s!",
253*5e7646d2SAndroid Build Coastguard Worker consts->resolver));
254*5e7646d2SAndroid Build Coastguard Worker goto error;
255*5e7646d2SAndroid Build Coastguard Worker }
256*5e7646d2SAndroid Build Coastguard Worker
257*5e7646d2SAndroid Build Coastguard Worker if ((resolver = ppdFindAttr(ppd, "cupsUIResolver",
258*5e7646d2SAndroid Build Coastguard Worker consts->resolver)) == NULL)
259*5e7646d2SAndroid Build Coastguard Worker {
260*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsResolveConflicts: Resolver %s not found!",
261*5e7646d2SAndroid Build Coastguard Worker consts->resolver));
262*5e7646d2SAndroid Build Coastguard Worker goto error;
263*5e7646d2SAndroid Build Coastguard Worker }
264*5e7646d2SAndroid Build Coastguard Worker
265*5e7646d2SAndroid Build Coastguard Worker if (!resolver->value)
266*5e7646d2SAndroid Build Coastguard Worker {
267*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsResolveConflicts: Resolver %s has no value!",
268*5e7646d2SAndroid Build Coastguard Worker consts->resolver));
269*5e7646d2SAndroid Build Coastguard Worker goto error;
270*5e7646d2SAndroid Build Coastguard Worker }
271*5e7646d2SAndroid Build Coastguard Worker
272*5e7646d2SAndroid Build Coastguard Worker /*
273*5e7646d2SAndroid Build Coastguard Worker * Add the options from the resolver...
274*5e7646d2SAndroid Build Coastguard Worker */
275*5e7646d2SAndroid Build Coastguard Worker
276*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pass, consts->resolver);
277*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(resolvers, consts->resolver);
278*5e7646d2SAndroid Build Coastguard Worker
279*5e7646d2SAndroid Build Coastguard Worker for (resval = resolver->value; *resval && !changed;)
280*5e7646d2SAndroid Build Coastguard Worker {
281*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*resval))
282*5e7646d2SAndroid Build Coastguard Worker resval ++;
283*5e7646d2SAndroid Build Coastguard Worker
284*5e7646d2SAndroid Build Coastguard Worker if (*resval != '*')
285*5e7646d2SAndroid Build Coastguard Worker break;
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker for (resval ++, resptr = resoption;
288*5e7646d2SAndroid Build Coastguard Worker *resval && !_cups_isspace(*resval);
289*5e7646d2SAndroid Build Coastguard Worker resval ++)
290*5e7646d2SAndroid Build Coastguard Worker if (resptr < (resoption + sizeof(resoption) - 1))
291*5e7646d2SAndroid Build Coastguard Worker *resptr++ = *resval;
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker *resptr = '\0';
294*5e7646d2SAndroid Build Coastguard Worker
295*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*resval))
296*5e7646d2SAndroid Build Coastguard Worker resval ++;
297*5e7646d2SAndroid Build Coastguard Worker
298*5e7646d2SAndroid Build Coastguard Worker for (resptr = reschoice;
299*5e7646d2SAndroid Build Coastguard Worker *resval && !_cups_isspace(*resval);
300*5e7646d2SAndroid Build Coastguard Worker resval ++)
301*5e7646d2SAndroid Build Coastguard Worker if (resptr < (reschoice + sizeof(reschoice) - 1))
302*5e7646d2SAndroid Build Coastguard Worker *resptr++ = *resval;
303*5e7646d2SAndroid Build Coastguard Worker
304*5e7646d2SAndroid Build Coastguard Worker *resptr = '\0';
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker if (!resoption[0] || !reschoice[0])
307*5e7646d2SAndroid Build Coastguard Worker break;
308*5e7646d2SAndroid Build Coastguard Worker
309*5e7646d2SAndroid Build Coastguard Worker /*
310*5e7646d2SAndroid Build Coastguard Worker * Is this the option we are changing?
311*5e7646d2SAndroid Build Coastguard Worker */
312*5e7646d2SAndroid Build Coastguard Worker
313*5e7646d2SAndroid Build Coastguard Worker snprintf(firstpage, sizeof(firstpage), "AP_FIRSTPAGE_%s", resoption);
314*5e7646d2SAndroid Build Coastguard Worker
315*5e7646d2SAndroid Build Coastguard Worker if (option &&
316*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(resoption, option) ||
317*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(firstpage, option) ||
318*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "PageSize") &&
319*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(resoption, "PageRegion")) ||
320*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") &&
321*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(resoption, "PageSize")) ||
322*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") &&
323*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(resoption, "PageRegion")) ||
324*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "PageRegion") &&
325*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(resoption, "PageSize")) ||
326*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion") &&
327*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(resoption, "PageSize")) ||
328*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion") &&
329*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(resoption, "PageRegion"))))
330*5e7646d2SAndroid Build Coastguard Worker continue;
331*5e7646d2SAndroid Build Coastguard Worker
332*5e7646d2SAndroid Build Coastguard Worker /*
333*5e7646d2SAndroid Build Coastguard Worker * Try this choice...
334*5e7646d2SAndroid Build Coastguard Worker */
335*5e7646d2SAndroid Build Coastguard Worker
336*5e7646d2SAndroid Build Coastguard Worker if ((test = ppd_test_constraints(ppd, resoption, reschoice,
337*5e7646d2SAndroid Build Coastguard Worker num_newopts, newopts,
338*5e7646d2SAndroid Build Coastguard Worker _PPD_ALL_CONSTRAINTS)) == NULL)
339*5e7646d2SAndroid Build Coastguard Worker {
340*5e7646d2SAndroid Build Coastguard Worker /*
341*5e7646d2SAndroid Build Coastguard Worker * That worked...
342*5e7646d2SAndroid Build Coastguard Worker */
343*5e7646d2SAndroid Build Coastguard Worker
344*5e7646d2SAndroid Build Coastguard Worker changed = 1;
345*5e7646d2SAndroid Build Coastguard Worker }
346*5e7646d2SAndroid Build Coastguard Worker else
347*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(test);
348*5e7646d2SAndroid Build Coastguard Worker
349*5e7646d2SAndroid Build Coastguard Worker /*
350*5e7646d2SAndroid Build Coastguard Worker * Add the option/choice from the resolver regardless of whether it
351*5e7646d2SAndroid Build Coastguard Worker * worked; this makes sure that we can cascade several changes to
352*5e7646d2SAndroid Build Coastguard Worker * make things resolve...
353*5e7646d2SAndroid Build Coastguard Worker */
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker num_newopts = cupsAddOption(resoption, reschoice, num_newopts,
356*5e7646d2SAndroid Build Coastguard Worker &newopts);
357*5e7646d2SAndroid Build Coastguard Worker }
358*5e7646d2SAndroid Build Coastguard Worker }
359*5e7646d2SAndroid Build Coastguard Worker else
360*5e7646d2SAndroid Build Coastguard Worker {
361*5e7646d2SAndroid Build Coastguard Worker /*
362*5e7646d2SAndroid Build Coastguard Worker * Try resolving by choosing the default values for non-installable
363*5e7646d2SAndroid Build Coastguard Worker * options, then by iterating through the possible choices...
364*5e7646d2SAndroid Build Coastguard Worker */
365*5e7646d2SAndroid Build Coastguard Worker
366*5e7646d2SAndroid Build Coastguard Worker int j; /* Looping var */
367*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *cptr; /* Current choice */
368*5e7646d2SAndroid Build Coastguard Worker ppd_size_t *size; /* Current page size */
369*5e7646d2SAndroid Build Coastguard Worker
370*5e7646d2SAndroid Build Coastguard Worker
371*5e7646d2SAndroid Build Coastguard Worker for (i = consts->num_constraints, constptr = consts->constraints;
372*5e7646d2SAndroid Build Coastguard Worker i > 0 && !changed;
373*5e7646d2SAndroid Build Coastguard Worker i --, constptr ++)
374*5e7646d2SAndroid Build Coastguard Worker {
375*5e7646d2SAndroid Build Coastguard Worker /*
376*5e7646d2SAndroid Build Coastguard Worker * Can't resolve by changing an installable option...
377*5e7646d2SAndroid Build Coastguard Worker */
378*5e7646d2SAndroid Build Coastguard Worker
379*5e7646d2SAndroid Build Coastguard Worker if (constptr->installable)
380*5e7646d2SAndroid Build Coastguard Worker continue;
381*5e7646d2SAndroid Build Coastguard Worker
382*5e7646d2SAndroid Build Coastguard Worker /*
383*5e7646d2SAndroid Build Coastguard Worker * Is this the option we are changing?
384*5e7646d2SAndroid Build Coastguard Worker */
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker if (option &&
387*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(constptr->option->keyword, option) ||
388*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "PageSize") &&
389*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(constptr->option->keyword, "PageRegion")) ||
390*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "PageRegion") &&
391*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(constptr->option->keyword, "PageSize"))))
392*5e7646d2SAndroid Build Coastguard Worker continue;
393*5e7646d2SAndroid Build Coastguard Worker
394*5e7646d2SAndroid Build Coastguard Worker /*
395*5e7646d2SAndroid Build Coastguard Worker * Get the current option choice...
396*5e7646d2SAndroid Build Coastguard Worker */
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker if ((value = cupsGetOption(constptr->option->keyword, num_newopts,
399*5e7646d2SAndroid Build Coastguard Worker newopts)) == NULL)
400*5e7646d2SAndroid Build Coastguard Worker {
401*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(constptr->option->keyword, "PageSize") ||
402*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(constptr->option->keyword, "PageRegion"))
403*5e7646d2SAndroid Build Coastguard Worker {
404*5e7646d2SAndroid Build Coastguard Worker if ((value = cupsGetOption("PageSize", num_newopts,
405*5e7646d2SAndroid Build Coastguard Worker newopts)) == NULL)
406*5e7646d2SAndroid Build Coastguard Worker value = cupsGetOption("PageRegion", num_newopts, newopts);
407*5e7646d2SAndroid Build Coastguard Worker
408*5e7646d2SAndroid Build Coastguard Worker if (!value)
409*5e7646d2SAndroid Build Coastguard Worker {
410*5e7646d2SAndroid Build Coastguard Worker if ((size = ppdPageSize(ppd, NULL)) != NULL)
411*5e7646d2SAndroid Build Coastguard Worker value = size->name;
412*5e7646d2SAndroid Build Coastguard Worker else
413*5e7646d2SAndroid Build Coastguard Worker value = "";
414*5e7646d2SAndroid Build Coastguard Worker }
415*5e7646d2SAndroid Build Coastguard Worker }
416*5e7646d2SAndroid Build Coastguard Worker else
417*5e7646d2SAndroid Build Coastguard Worker {
418*5e7646d2SAndroid Build Coastguard Worker marked = ppdFindMarkedChoice(ppd, constptr->option->keyword);
419*5e7646d2SAndroid Build Coastguard Worker value = marked ? marked->choice : "";
420*5e7646d2SAndroid Build Coastguard Worker }
421*5e7646d2SAndroid Build Coastguard Worker }
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(value, "Custom.", 7))
424*5e7646d2SAndroid Build Coastguard Worker value = "Custom";
425*5e7646d2SAndroid Build Coastguard Worker
426*5e7646d2SAndroid Build Coastguard Worker /*
427*5e7646d2SAndroid Build Coastguard Worker * Try the default choice...
428*5e7646d2SAndroid Build Coastguard Worker */
429*5e7646d2SAndroid Build Coastguard Worker
430*5e7646d2SAndroid Build Coastguard Worker test = NULL;
431*5e7646d2SAndroid Build Coastguard Worker
432*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(value, constptr->option->defchoice) &&
433*5e7646d2SAndroid Build Coastguard Worker (test = ppd_test_constraints(ppd, constptr->option->keyword,
434*5e7646d2SAndroid Build Coastguard Worker constptr->option->defchoice,
435*5e7646d2SAndroid Build Coastguard Worker num_newopts, newopts,
436*5e7646d2SAndroid Build Coastguard Worker _PPD_OPTION_CONSTRAINTS)) == NULL)
437*5e7646d2SAndroid Build Coastguard Worker {
438*5e7646d2SAndroid Build Coastguard Worker /*
439*5e7646d2SAndroid Build Coastguard Worker * That worked...
440*5e7646d2SAndroid Build Coastguard Worker */
441*5e7646d2SAndroid Build Coastguard Worker
442*5e7646d2SAndroid Build Coastguard Worker num_newopts = cupsAddOption(constptr->option->keyword,
443*5e7646d2SAndroid Build Coastguard Worker constptr->option->defchoice,
444*5e7646d2SAndroid Build Coastguard Worker num_newopts, &newopts);
445*5e7646d2SAndroid Build Coastguard Worker changed = 1;
446*5e7646d2SAndroid Build Coastguard Worker }
447*5e7646d2SAndroid Build Coastguard Worker else
448*5e7646d2SAndroid Build Coastguard Worker {
449*5e7646d2SAndroid Build Coastguard Worker /*
450*5e7646d2SAndroid Build Coastguard Worker * Try each choice instead...
451*5e7646d2SAndroid Build Coastguard Worker */
452*5e7646d2SAndroid Build Coastguard Worker
453*5e7646d2SAndroid Build Coastguard Worker for (j = constptr->option->num_choices,
454*5e7646d2SAndroid Build Coastguard Worker cptr = constptr->option->choices;
455*5e7646d2SAndroid Build Coastguard Worker j > 0;
456*5e7646d2SAndroid Build Coastguard Worker j --, cptr ++)
457*5e7646d2SAndroid Build Coastguard Worker {
458*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(test);
459*5e7646d2SAndroid Build Coastguard Worker test = NULL;
460*5e7646d2SAndroid Build Coastguard Worker
461*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(value, cptr->choice) &&
462*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(constptr->option->defchoice, cptr->choice) &&
463*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp("Custom", cptr->choice) &&
464*5e7646d2SAndroid Build Coastguard Worker (test = ppd_test_constraints(ppd, constptr->option->keyword,
465*5e7646d2SAndroid Build Coastguard Worker cptr->choice, num_newopts,
466*5e7646d2SAndroid Build Coastguard Worker newopts,
467*5e7646d2SAndroid Build Coastguard Worker _PPD_OPTION_CONSTRAINTS)) == NULL)
468*5e7646d2SAndroid Build Coastguard Worker {
469*5e7646d2SAndroid Build Coastguard Worker /*
470*5e7646d2SAndroid Build Coastguard Worker * This choice works...
471*5e7646d2SAndroid Build Coastguard Worker */
472*5e7646d2SAndroid Build Coastguard Worker
473*5e7646d2SAndroid Build Coastguard Worker num_newopts = cupsAddOption(constptr->option->keyword,
474*5e7646d2SAndroid Build Coastguard Worker cptr->choice, num_newopts,
475*5e7646d2SAndroid Build Coastguard Worker &newopts);
476*5e7646d2SAndroid Build Coastguard Worker changed = 1;
477*5e7646d2SAndroid Build Coastguard Worker break;
478*5e7646d2SAndroid Build Coastguard Worker }
479*5e7646d2SAndroid Build Coastguard Worker }
480*5e7646d2SAndroid Build Coastguard Worker
481*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(test);
482*5e7646d2SAndroid Build Coastguard Worker }
483*5e7646d2SAndroid Build Coastguard Worker }
484*5e7646d2SAndroid Build Coastguard Worker }
485*5e7646d2SAndroid Build Coastguard Worker }
486*5e7646d2SAndroid Build Coastguard Worker
487*5e7646d2SAndroid Build Coastguard Worker if (!changed)
488*5e7646d2SAndroid Build Coastguard Worker {
489*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1cupsResolveConflicts: Unable to automatically resolve "
490*5e7646d2SAndroid Build Coastguard Worker "constraint!");
491*5e7646d2SAndroid Build Coastguard Worker goto error;
492*5e7646d2SAndroid Build Coastguard Worker }
493*5e7646d2SAndroid Build Coastguard Worker
494*5e7646d2SAndroid Build Coastguard Worker cupsArrayClear(pass);
495*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(active);
496*5e7646d2SAndroid Build Coastguard Worker active = NULL;
497*5e7646d2SAndroid Build Coastguard Worker }
498*5e7646d2SAndroid Build Coastguard Worker
499*5e7646d2SAndroid Build Coastguard Worker if (tries >= 100)
500*5e7646d2SAndroid Build Coastguard Worker goto error;
501*5e7646d2SAndroid Build Coastguard Worker
502*5e7646d2SAndroid Build Coastguard Worker /*
503*5e7646d2SAndroid Build Coastguard Worker * Free the caller's option array...
504*5e7646d2SAndroid Build Coastguard Worker */
505*5e7646d2SAndroid Build Coastguard Worker
506*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(*num_options, *options);
507*5e7646d2SAndroid Build Coastguard Worker
508*5e7646d2SAndroid Build Coastguard Worker /*
509*5e7646d2SAndroid Build Coastguard Worker * If Collate is the option we are testing, add it here. Otherwise, remove
510*5e7646d2SAndroid Build Coastguard Worker * any Collate option from the resolve list since the filters automatically
511*5e7646d2SAndroid Build Coastguard Worker * handle manual collation...
512*5e7646d2SAndroid Build Coastguard Worker */
513*5e7646d2SAndroid Build Coastguard Worker
514*5e7646d2SAndroid Build Coastguard Worker if (option && !_cups_strcasecmp(option, "Collate"))
515*5e7646d2SAndroid Build Coastguard Worker num_newopts = cupsAddOption(option, choice, num_newopts, &newopts);
516*5e7646d2SAndroid Build Coastguard Worker else
517*5e7646d2SAndroid Build Coastguard Worker num_newopts = cupsRemoveOption("Collate", num_newopts, &newopts);
518*5e7646d2SAndroid Build Coastguard Worker
519*5e7646d2SAndroid Build Coastguard Worker /*
520*5e7646d2SAndroid Build Coastguard Worker * Return the new list of options to the caller...
521*5e7646d2SAndroid Build Coastguard Worker */
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker *num_options = num_newopts;
524*5e7646d2SAndroid Build Coastguard Worker *options = newopts;
525*5e7646d2SAndroid Build Coastguard Worker
526*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pass);
527*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(resolvers);
528*5e7646d2SAndroid Build Coastguard Worker
529*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->sorted_attrs);
530*5e7646d2SAndroid Build Coastguard Worker
531*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsResolveConflicts: Returning %d options:", num_newopts));
532*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
533*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_newopts; i ++)
534*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsResolveConflicts: options[%d]: %s=%s", i,
535*5e7646d2SAndroid Build Coastguard Worker newopts[i].name, newopts[i].value));
536*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
537*5e7646d2SAndroid Build Coastguard Worker
538*5e7646d2SAndroid Build Coastguard Worker return (1);
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker /*
541*5e7646d2SAndroid Build Coastguard Worker * If we get here, we failed to resolve...
542*5e7646d2SAndroid Build Coastguard Worker */
543*5e7646d2SAndroid Build Coastguard Worker
544*5e7646d2SAndroid Build Coastguard Worker error:
545*5e7646d2SAndroid Build Coastguard Worker
546*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_newopts, newopts);
547*5e7646d2SAndroid Build Coastguard Worker
548*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(active);
549*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pass);
550*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(resolvers);
551*5e7646d2SAndroid Build Coastguard Worker
552*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->sorted_attrs);
553*5e7646d2SAndroid Build Coastguard Worker
554*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1cupsResolveConflicts: Unable to resolve conflicts!");
555*5e7646d2SAndroid Build Coastguard Worker
556*5e7646d2SAndroid Build Coastguard Worker return (0);
557*5e7646d2SAndroid Build Coastguard Worker }
558*5e7646d2SAndroid Build Coastguard Worker
559*5e7646d2SAndroid Build Coastguard Worker
560*5e7646d2SAndroid Build Coastguard Worker /*
561*5e7646d2SAndroid Build Coastguard Worker * 'ppdConflicts()' - Check to see if there are any conflicts among the
562*5e7646d2SAndroid Build Coastguard Worker * marked option choices.
563*5e7646d2SAndroid Build Coastguard Worker *
564*5e7646d2SAndroid Build Coastguard Worker * The returned value is the same as returned by @link ppdMarkOption@.
565*5e7646d2SAndroid Build Coastguard Worker */
566*5e7646d2SAndroid Build Coastguard Worker
567*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of conflicts found */
ppdConflicts(ppd_file_t * ppd)568*5e7646d2SAndroid Build Coastguard Worker ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */
569*5e7646d2SAndroid Build Coastguard Worker {
570*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping variable */
571*5e7646d2SAndroid Build Coastguard Worker conflicts; /* Number of conflicts */
572*5e7646d2SAndroid Build Coastguard Worker cups_array_t *active; /* Active conflicts */
573*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconsts_t *c; /* Current constraints */
574*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconst_t *cptr; /* Current constraint */
575*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *o; /* Current option */
576*5e7646d2SAndroid Build Coastguard Worker
577*5e7646d2SAndroid Build Coastguard Worker
578*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
579*5e7646d2SAndroid Build Coastguard Worker return (0);
580*5e7646d2SAndroid Build Coastguard Worker
581*5e7646d2SAndroid Build Coastguard Worker /*
582*5e7646d2SAndroid Build Coastguard Worker * Clear all conflicts...
583*5e7646d2SAndroid Build Coastguard Worker */
584*5e7646d2SAndroid Build Coastguard Worker
585*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->options);
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker for (o = ppdFirstOption(ppd); o; o = ppdNextOption(ppd))
588*5e7646d2SAndroid Build Coastguard Worker o->conflicted = 0;
589*5e7646d2SAndroid Build Coastguard Worker
590*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->options);
591*5e7646d2SAndroid Build Coastguard Worker
592*5e7646d2SAndroid Build Coastguard Worker /*
593*5e7646d2SAndroid Build Coastguard Worker * Test for conflicts...
594*5e7646d2SAndroid Build Coastguard Worker */
595*5e7646d2SAndroid Build Coastguard Worker
596*5e7646d2SAndroid Build Coastguard Worker active = ppd_test_constraints(ppd, NULL, NULL, 0, NULL,
597*5e7646d2SAndroid Build Coastguard Worker _PPD_ALL_CONSTRAINTS);
598*5e7646d2SAndroid Build Coastguard Worker conflicts = cupsArrayCount(active);
599*5e7646d2SAndroid Build Coastguard Worker
600*5e7646d2SAndroid Build Coastguard Worker /*
601*5e7646d2SAndroid Build Coastguard Worker * Loop through all of the UI constraints and flag any options
602*5e7646d2SAndroid Build Coastguard Worker * that conflict...
603*5e7646d2SAndroid Build Coastguard Worker */
604*5e7646d2SAndroid Build Coastguard Worker
605*5e7646d2SAndroid Build Coastguard Worker for (c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active);
606*5e7646d2SAndroid Build Coastguard Worker c;
607*5e7646d2SAndroid Build Coastguard Worker c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active))
608*5e7646d2SAndroid Build Coastguard Worker {
609*5e7646d2SAndroid Build Coastguard Worker for (i = c->num_constraints, cptr = c->constraints;
610*5e7646d2SAndroid Build Coastguard Worker i > 0;
611*5e7646d2SAndroid Build Coastguard Worker i --, cptr ++)
612*5e7646d2SAndroid Build Coastguard Worker cptr->option->conflicted = 1;
613*5e7646d2SAndroid Build Coastguard Worker }
614*5e7646d2SAndroid Build Coastguard Worker
615*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(active);
616*5e7646d2SAndroid Build Coastguard Worker
617*5e7646d2SAndroid Build Coastguard Worker /*
618*5e7646d2SAndroid Build Coastguard Worker * Return the number of conflicts found...
619*5e7646d2SAndroid Build Coastguard Worker */
620*5e7646d2SAndroid Build Coastguard Worker
621*5e7646d2SAndroid Build Coastguard Worker return (conflicts);
622*5e7646d2SAndroid Build Coastguard Worker }
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker
625*5e7646d2SAndroid Build Coastguard Worker /*
626*5e7646d2SAndroid Build Coastguard Worker * 'ppdInstallableConflict()' - Test whether an option choice conflicts with
627*5e7646d2SAndroid Build Coastguard Worker * an installable option.
628*5e7646d2SAndroid Build Coastguard Worker *
629*5e7646d2SAndroid Build Coastguard Worker * This function tests whether a particular option choice is available based
630*5e7646d2SAndroid Build Coastguard Worker * on constraints against options in the "InstallableOptions" group.
631*5e7646d2SAndroid Build Coastguard Worker *
632*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.4/macOS 10.6@
633*5e7646d2SAndroid Build Coastguard Worker */
634*5e7646d2SAndroid Build Coastguard Worker
635*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 if conflicting, 0 if not conflicting */
ppdInstallableConflict(ppd_file_t * ppd,const char * option,const char * choice)636*5e7646d2SAndroid Build Coastguard Worker ppdInstallableConflict(
637*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file */
638*5e7646d2SAndroid Build Coastguard Worker const char *option, /* I - Option */
639*5e7646d2SAndroid Build Coastguard Worker const char *choice) /* I - Choice */
640*5e7646d2SAndroid Build Coastguard Worker {
641*5e7646d2SAndroid Build Coastguard Worker cups_array_t *active; /* Active conflicts */
642*5e7646d2SAndroid Build Coastguard Worker
643*5e7646d2SAndroid Build Coastguard Worker
644*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ppdInstallableConflict(ppd=%p, option=\"%s\", choice=\"%s\")",
645*5e7646d2SAndroid Build Coastguard Worker ppd, option, choice));
646*5e7646d2SAndroid Build Coastguard Worker
647*5e7646d2SAndroid Build Coastguard Worker /*
648*5e7646d2SAndroid Build Coastguard Worker * Range check input...
649*5e7646d2SAndroid Build Coastguard Worker */
650*5e7646d2SAndroid Build Coastguard Worker
651*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !option || !choice)
652*5e7646d2SAndroid Build Coastguard Worker return (0);
653*5e7646d2SAndroid Build Coastguard Worker
654*5e7646d2SAndroid Build Coastguard Worker /*
655*5e7646d2SAndroid Build Coastguard Worker * Test constraints using the new option...
656*5e7646d2SAndroid Build Coastguard Worker */
657*5e7646d2SAndroid Build Coastguard Worker
658*5e7646d2SAndroid Build Coastguard Worker active = ppd_test_constraints(ppd, option, choice, 0, NULL,
659*5e7646d2SAndroid Build Coastguard Worker _PPD_INSTALLABLE_CONSTRAINTS);
660*5e7646d2SAndroid Build Coastguard Worker
661*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(active);
662*5e7646d2SAndroid Build Coastguard Worker
663*5e7646d2SAndroid Build Coastguard Worker return (active != NULL);
664*5e7646d2SAndroid Build Coastguard Worker }
665*5e7646d2SAndroid Build Coastguard Worker
666*5e7646d2SAndroid Build Coastguard Worker
667*5e7646d2SAndroid Build Coastguard Worker /*
668*5e7646d2SAndroid Build Coastguard Worker * 'ppd_is_installable()' - Determine whether an option is in the
669*5e7646d2SAndroid Build Coastguard Worker * InstallableOptions group.
670*5e7646d2SAndroid Build Coastguard Worker */
671*5e7646d2SAndroid Build Coastguard Worker
672*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 if installable, 0 if normal */
ppd_is_installable(ppd_group_t * installable,const char * name)673*5e7646d2SAndroid Build Coastguard Worker ppd_is_installable(
674*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *installable, /* I - InstallableOptions group */
675*5e7646d2SAndroid Build Coastguard Worker const char *name) /* I - Option name */
676*5e7646d2SAndroid Build Coastguard Worker {
677*5e7646d2SAndroid Build Coastguard Worker if (installable)
678*5e7646d2SAndroid Build Coastguard Worker {
679*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
680*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *option; /* Current option */
681*5e7646d2SAndroid Build Coastguard Worker
682*5e7646d2SAndroid Build Coastguard Worker
683*5e7646d2SAndroid Build Coastguard Worker for (i = installable->num_options, option = installable->options;
684*5e7646d2SAndroid Build Coastguard Worker i > 0;
685*5e7646d2SAndroid Build Coastguard Worker i --, option ++)
686*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(option->keyword, name))
687*5e7646d2SAndroid Build Coastguard Worker return (1);
688*5e7646d2SAndroid Build Coastguard Worker }
689*5e7646d2SAndroid Build Coastguard Worker
690*5e7646d2SAndroid Build Coastguard Worker return (0);
691*5e7646d2SAndroid Build Coastguard Worker }
692*5e7646d2SAndroid Build Coastguard Worker
693*5e7646d2SAndroid Build Coastguard Worker
694*5e7646d2SAndroid Build Coastguard Worker /*
695*5e7646d2SAndroid Build Coastguard Worker * 'ppd_load_constraints()' - Load constraints from a PPD file.
696*5e7646d2SAndroid Build Coastguard Worker */
697*5e7646d2SAndroid Build Coastguard Worker
698*5e7646d2SAndroid Build Coastguard Worker static void
ppd_load_constraints(ppd_file_t * ppd)699*5e7646d2SAndroid Build Coastguard Worker ppd_load_constraints(ppd_file_t *ppd) /* I - PPD file */
700*5e7646d2SAndroid Build Coastguard Worker {
701*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
702*5e7646d2SAndroid Build Coastguard Worker ppd_const_t *oldconst; /* Current UIConstraints data */
703*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *constattr; /* Current cupsUIConstraints attribute */
704*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconsts_t *consts; /* Current cupsUIConstraints data */
705*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconst_t *constptr; /* Current constraint */
706*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *installable; /* Installable options group */
707*5e7646d2SAndroid Build Coastguard Worker const char *vptr; /* Pointer into constraint value */
708*5e7646d2SAndroid Build Coastguard Worker char option[PPD_MAX_NAME], /* Option name/MainKeyword */
709*5e7646d2SAndroid Build Coastguard Worker choice[PPD_MAX_NAME], /* Choice/OptionKeyword */
710*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into option or choice */
711*5e7646d2SAndroid Build Coastguard Worker
712*5e7646d2SAndroid Build Coastguard Worker
713*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7ppd_load_constraints(ppd=%p)", ppd));
714*5e7646d2SAndroid Build Coastguard Worker
715*5e7646d2SAndroid Build Coastguard Worker /*
716*5e7646d2SAndroid Build Coastguard Worker * Create an array to hold the constraint data...
717*5e7646d2SAndroid Build Coastguard Worker */
718*5e7646d2SAndroid Build Coastguard Worker
719*5e7646d2SAndroid Build Coastguard Worker ppd->cups_uiconstraints = cupsArrayNew(NULL, NULL);
720*5e7646d2SAndroid Build Coastguard Worker
721*5e7646d2SAndroid Build Coastguard Worker /*
722*5e7646d2SAndroid Build Coastguard Worker * Find the installable options group if it exists...
723*5e7646d2SAndroid Build Coastguard Worker */
724*5e7646d2SAndroid Build Coastguard Worker
725*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_groups, installable = ppd->groups;
726*5e7646d2SAndroid Build Coastguard Worker i > 0;
727*5e7646d2SAndroid Build Coastguard Worker i --, installable ++)
728*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(installable->name, "InstallableOptions"))
729*5e7646d2SAndroid Build Coastguard Worker break;
730*5e7646d2SAndroid Build Coastguard Worker
731*5e7646d2SAndroid Build Coastguard Worker if (i <= 0)
732*5e7646d2SAndroid Build Coastguard Worker installable = NULL;
733*5e7646d2SAndroid Build Coastguard Worker
734*5e7646d2SAndroid Build Coastguard Worker /*
735*5e7646d2SAndroid Build Coastguard Worker * Load old-style [Non]UIConstraints data...
736*5e7646d2SAndroid Build Coastguard Worker */
737*5e7646d2SAndroid Build Coastguard Worker
738*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_consts, oldconst = ppd->consts; i > 0; i --, oldconst ++)
739*5e7646d2SAndroid Build Coastguard Worker {
740*5e7646d2SAndroid Build Coastguard Worker /*
741*5e7646d2SAndroid Build Coastguard Worker * Weed out nearby duplicates, since the PPD spec requires that you
742*5e7646d2SAndroid Build Coastguard Worker * define both "*Foo foo *Bar bar" and "*Bar bar *Foo foo"...
743*5e7646d2SAndroid Build Coastguard Worker */
744*5e7646d2SAndroid Build Coastguard Worker
745*5e7646d2SAndroid Build Coastguard Worker if (i > 1 &&
746*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(oldconst[0].option1, oldconst[1].option2) &&
747*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(oldconst[0].choice1, oldconst[1].choice2) &&
748*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(oldconst[0].option2, oldconst[1].option1) &&
749*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(oldconst[0].choice2, oldconst[1].choice1))
750*5e7646d2SAndroid Build Coastguard Worker continue;
751*5e7646d2SAndroid Build Coastguard Worker
752*5e7646d2SAndroid Build Coastguard Worker /*
753*5e7646d2SAndroid Build Coastguard Worker * Allocate memory...
754*5e7646d2SAndroid Build Coastguard Worker */
755*5e7646d2SAndroid Build Coastguard Worker
756*5e7646d2SAndroid Build Coastguard Worker if ((consts = calloc(1, sizeof(_ppd_cups_uiconsts_t))) == NULL)
757*5e7646d2SAndroid Build Coastguard Worker {
758*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for "
759*5e7646d2SAndroid Build Coastguard Worker "UIConstraints!");
760*5e7646d2SAndroid Build Coastguard Worker return;
761*5e7646d2SAndroid Build Coastguard Worker }
762*5e7646d2SAndroid Build Coastguard Worker
763*5e7646d2SAndroid Build Coastguard Worker if ((constptr = calloc(2, sizeof(_ppd_cups_uiconst_t))) == NULL)
764*5e7646d2SAndroid Build Coastguard Worker {
765*5e7646d2SAndroid Build Coastguard Worker free(consts);
766*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for "
767*5e7646d2SAndroid Build Coastguard Worker "UIConstraints!");
768*5e7646d2SAndroid Build Coastguard Worker return;
769*5e7646d2SAndroid Build Coastguard Worker }
770*5e7646d2SAndroid Build Coastguard Worker
771*5e7646d2SAndroid Build Coastguard Worker /*
772*5e7646d2SAndroid Build Coastguard Worker * Fill in the information...
773*5e7646d2SAndroid Build Coastguard Worker */
774*5e7646d2SAndroid Build Coastguard Worker
775*5e7646d2SAndroid Build Coastguard Worker consts->num_constraints = 2;
776*5e7646d2SAndroid Build Coastguard Worker consts->constraints = constptr;
777*5e7646d2SAndroid Build Coastguard Worker
778*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(oldconst->option1, "Custom", 6) &&
779*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(oldconst->choice1, "True"))
780*5e7646d2SAndroid Build Coastguard Worker {
781*5e7646d2SAndroid Build Coastguard Worker constptr[0].option = ppdFindOption(ppd, oldconst->option1 + 6);
782*5e7646d2SAndroid Build Coastguard Worker constptr[0].choice = ppdFindChoice(constptr[0].option, "Custom");
783*5e7646d2SAndroid Build Coastguard Worker constptr[0].installable = 0;
784*5e7646d2SAndroid Build Coastguard Worker }
785*5e7646d2SAndroid Build Coastguard Worker else
786*5e7646d2SAndroid Build Coastguard Worker {
787*5e7646d2SAndroid Build Coastguard Worker constptr[0].option = ppdFindOption(ppd, oldconst->option1);
788*5e7646d2SAndroid Build Coastguard Worker constptr[0].choice = ppdFindChoice(constptr[0].option,
789*5e7646d2SAndroid Build Coastguard Worker oldconst->choice1);
790*5e7646d2SAndroid Build Coastguard Worker constptr[0].installable = ppd_is_installable(installable,
791*5e7646d2SAndroid Build Coastguard Worker oldconst->option1);
792*5e7646d2SAndroid Build Coastguard Worker }
793*5e7646d2SAndroid Build Coastguard Worker
794*5e7646d2SAndroid Build Coastguard Worker if (!constptr[0].option || (!constptr[0].choice && oldconst->choice1[0]))
795*5e7646d2SAndroid Build Coastguard Worker {
796*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!",
797*5e7646d2SAndroid Build Coastguard Worker oldconst->option1, oldconst->choice1));
798*5e7646d2SAndroid Build Coastguard Worker free(consts->constraints);
799*5e7646d2SAndroid Build Coastguard Worker free(consts);
800*5e7646d2SAndroid Build Coastguard Worker continue;
801*5e7646d2SAndroid Build Coastguard Worker }
802*5e7646d2SAndroid Build Coastguard Worker
803*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(oldconst->option2, "Custom", 6) &&
804*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(oldconst->choice2, "True"))
805*5e7646d2SAndroid Build Coastguard Worker {
806*5e7646d2SAndroid Build Coastguard Worker constptr[1].option = ppdFindOption(ppd, oldconst->option2 + 6);
807*5e7646d2SAndroid Build Coastguard Worker constptr[1].choice = ppdFindChoice(constptr[1].option, "Custom");
808*5e7646d2SAndroid Build Coastguard Worker constptr[1].installable = 0;
809*5e7646d2SAndroid Build Coastguard Worker }
810*5e7646d2SAndroid Build Coastguard Worker else
811*5e7646d2SAndroid Build Coastguard Worker {
812*5e7646d2SAndroid Build Coastguard Worker constptr[1].option = ppdFindOption(ppd, oldconst->option2);
813*5e7646d2SAndroid Build Coastguard Worker constptr[1].choice = ppdFindChoice(constptr[1].option,
814*5e7646d2SAndroid Build Coastguard Worker oldconst->choice2);
815*5e7646d2SAndroid Build Coastguard Worker constptr[1].installable = ppd_is_installable(installable,
816*5e7646d2SAndroid Build Coastguard Worker oldconst->option2);
817*5e7646d2SAndroid Build Coastguard Worker }
818*5e7646d2SAndroid Build Coastguard Worker
819*5e7646d2SAndroid Build Coastguard Worker if (!constptr[1].option || (!constptr[1].choice && oldconst->choice2[0]))
820*5e7646d2SAndroid Build Coastguard Worker {
821*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!",
822*5e7646d2SAndroid Build Coastguard Worker oldconst->option2, oldconst->choice2));
823*5e7646d2SAndroid Build Coastguard Worker free(consts->constraints);
824*5e7646d2SAndroid Build Coastguard Worker free(consts);
825*5e7646d2SAndroid Build Coastguard Worker continue;
826*5e7646d2SAndroid Build Coastguard Worker }
827*5e7646d2SAndroid Build Coastguard Worker
828*5e7646d2SAndroid Build Coastguard Worker consts->installable = constptr[0].installable || constptr[1].installable;
829*5e7646d2SAndroid Build Coastguard Worker
830*5e7646d2SAndroid Build Coastguard Worker /*
831*5e7646d2SAndroid Build Coastguard Worker * Add it to the constraints array...
832*5e7646d2SAndroid Build Coastguard Worker */
833*5e7646d2SAndroid Build Coastguard Worker
834*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ppd->cups_uiconstraints, consts);
835*5e7646d2SAndroid Build Coastguard Worker }
836*5e7646d2SAndroid Build Coastguard Worker
837*5e7646d2SAndroid Build Coastguard Worker /*
838*5e7646d2SAndroid Build Coastguard Worker * Then load new-style constraints...
839*5e7646d2SAndroid Build Coastguard Worker */
840*5e7646d2SAndroid Build Coastguard Worker
841*5e7646d2SAndroid Build Coastguard Worker for (constattr = ppdFindAttr(ppd, "cupsUIConstraints", NULL);
842*5e7646d2SAndroid Build Coastguard Worker constattr;
843*5e7646d2SAndroid Build Coastguard Worker constattr = ppdFindNextAttr(ppd, "cupsUIConstraints", NULL))
844*5e7646d2SAndroid Build Coastguard Worker {
845*5e7646d2SAndroid Build Coastguard Worker if (!constattr->value)
846*5e7646d2SAndroid Build Coastguard Worker {
847*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("8ppd_load_constraints: Bad cupsUIConstraints value!");
848*5e7646d2SAndroid Build Coastguard Worker continue;
849*5e7646d2SAndroid Build Coastguard Worker }
850*5e7646d2SAndroid Build Coastguard Worker
851*5e7646d2SAndroid Build Coastguard Worker for (i = 0, vptr = strchr(constattr->value, '*');
852*5e7646d2SAndroid Build Coastguard Worker vptr;
853*5e7646d2SAndroid Build Coastguard Worker i ++, vptr = strchr(vptr + 1, '*'));
854*5e7646d2SAndroid Build Coastguard Worker
855*5e7646d2SAndroid Build Coastguard Worker if (i == 0)
856*5e7646d2SAndroid Build Coastguard Worker {
857*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("8ppd_load_constraints: Bad cupsUIConstraints value!");
858*5e7646d2SAndroid Build Coastguard Worker continue;
859*5e7646d2SAndroid Build Coastguard Worker }
860*5e7646d2SAndroid Build Coastguard Worker
861*5e7646d2SAndroid Build Coastguard Worker if ((consts = calloc(1, sizeof(_ppd_cups_uiconsts_t))) == NULL)
862*5e7646d2SAndroid Build Coastguard Worker {
863*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for "
864*5e7646d2SAndroid Build Coastguard Worker "cupsUIConstraints!");
865*5e7646d2SAndroid Build Coastguard Worker return;
866*5e7646d2SAndroid Build Coastguard Worker }
867*5e7646d2SAndroid Build Coastguard Worker
868*5e7646d2SAndroid Build Coastguard Worker if ((constptr = calloc((size_t)i, sizeof(_ppd_cups_uiconst_t))) == NULL)
869*5e7646d2SAndroid Build Coastguard Worker {
870*5e7646d2SAndroid Build Coastguard Worker free(consts);
871*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for "
872*5e7646d2SAndroid Build Coastguard Worker "cupsUIConstraints!");
873*5e7646d2SAndroid Build Coastguard Worker return;
874*5e7646d2SAndroid Build Coastguard Worker }
875*5e7646d2SAndroid Build Coastguard Worker
876*5e7646d2SAndroid Build Coastguard Worker consts->num_constraints = i;
877*5e7646d2SAndroid Build Coastguard Worker consts->constraints = constptr;
878*5e7646d2SAndroid Build Coastguard Worker
879*5e7646d2SAndroid Build Coastguard Worker strlcpy(consts->resolver, constattr->spec, sizeof(consts->resolver));
880*5e7646d2SAndroid Build Coastguard Worker
881*5e7646d2SAndroid Build Coastguard Worker for (i = 0, vptr = strchr(constattr->value, '*');
882*5e7646d2SAndroid Build Coastguard Worker vptr;
883*5e7646d2SAndroid Build Coastguard Worker i ++, vptr = strchr(vptr, '*'), constptr ++)
884*5e7646d2SAndroid Build Coastguard Worker {
885*5e7646d2SAndroid Build Coastguard Worker /*
886*5e7646d2SAndroid Build Coastguard Worker * Extract "*Option Choice" or just "*Option"...
887*5e7646d2SAndroid Build Coastguard Worker */
888*5e7646d2SAndroid Build Coastguard Worker
889*5e7646d2SAndroid Build Coastguard Worker for (vptr ++, ptr = option; *vptr && !_cups_isspace(*vptr); vptr ++)
890*5e7646d2SAndroid Build Coastguard Worker if (ptr < (option + sizeof(option) - 1))
891*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *vptr;
892*5e7646d2SAndroid Build Coastguard Worker
893*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
894*5e7646d2SAndroid Build Coastguard Worker
895*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*vptr))
896*5e7646d2SAndroid Build Coastguard Worker vptr ++;
897*5e7646d2SAndroid Build Coastguard Worker
898*5e7646d2SAndroid Build Coastguard Worker if (*vptr == '*')
899*5e7646d2SAndroid Build Coastguard Worker choice[0] = '\0';
900*5e7646d2SAndroid Build Coastguard Worker else
901*5e7646d2SAndroid Build Coastguard Worker {
902*5e7646d2SAndroid Build Coastguard Worker for (ptr = choice; *vptr && !_cups_isspace(*vptr); vptr ++)
903*5e7646d2SAndroid Build Coastguard Worker if (ptr < (choice + sizeof(choice) - 1))
904*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *vptr;
905*5e7646d2SAndroid Build Coastguard Worker
906*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
907*5e7646d2SAndroid Build Coastguard Worker }
908*5e7646d2SAndroid Build Coastguard Worker
909*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(option, "Custom", 6) && !_cups_strcasecmp(choice, "True"))
910*5e7646d2SAndroid Build Coastguard Worker {
911*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(option, option + 6);
912*5e7646d2SAndroid Build Coastguard Worker strlcpy(choice, "Custom", sizeof(choice));
913*5e7646d2SAndroid Build Coastguard Worker }
914*5e7646d2SAndroid Build Coastguard Worker
915*5e7646d2SAndroid Build Coastguard Worker constptr->option = ppdFindOption(ppd, option);
916*5e7646d2SAndroid Build Coastguard Worker constptr->choice = ppdFindChoice(constptr->option, choice);
917*5e7646d2SAndroid Build Coastguard Worker constptr->installable = ppd_is_installable(installable, option);
918*5e7646d2SAndroid Build Coastguard Worker consts->installable |= constptr->installable;
919*5e7646d2SAndroid Build Coastguard Worker
920*5e7646d2SAndroid Build Coastguard Worker if (!constptr->option || (!constptr->choice && choice[0]))
921*5e7646d2SAndroid Build Coastguard Worker {
922*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!",
923*5e7646d2SAndroid Build Coastguard Worker option, choice));
924*5e7646d2SAndroid Build Coastguard Worker break;
925*5e7646d2SAndroid Build Coastguard Worker }
926*5e7646d2SAndroid Build Coastguard Worker }
927*5e7646d2SAndroid Build Coastguard Worker
928*5e7646d2SAndroid Build Coastguard Worker if (!vptr)
929*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ppd->cups_uiconstraints, consts);
930*5e7646d2SAndroid Build Coastguard Worker else
931*5e7646d2SAndroid Build Coastguard Worker {
932*5e7646d2SAndroid Build Coastguard Worker free(consts->constraints);
933*5e7646d2SAndroid Build Coastguard Worker free(consts);
934*5e7646d2SAndroid Build Coastguard Worker }
935*5e7646d2SAndroid Build Coastguard Worker }
936*5e7646d2SAndroid Build Coastguard Worker }
937*5e7646d2SAndroid Build Coastguard Worker
938*5e7646d2SAndroid Build Coastguard Worker
939*5e7646d2SAndroid Build Coastguard Worker /*
940*5e7646d2SAndroid Build Coastguard Worker * 'ppd_test_constraints()' - See if any constraints are active.
941*5e7646d2SAndroid Build Coastguard Worker */
942*5e7646d2SAndroid Build Coastguard Worker
943*5e7646d2SAndroid Build Coastguard Worker static cups_array_t * /* O - Array of active constraints */
ppd_test_constraints(ppd_file_t * ppd,const char * option,const char * choice,int num_options,cups_option_t * options,int which)944*5e7646d2SAndroid Build Coastguard Worker ppd_test_constraints(
945*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file */
946*5e7646d2SAndroid Build Coastguard Worker const char *option, /* I - Current option */
947*5e7646d2SAndroid Build Coastguard Worker const char *choice, /* I - Current choice */
948*5e7646d2SAndroid Build Coastguard Worker int num_options, /* I - Number of additional options */
949*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options, /* I - Additional options */
950*5e7646d2SAndroid Build Coastguard Worker int which) /* I - Which constraints to test */
951*5e7646d2SAndroid Build Coastguard Worker {
952*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
953*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconsts_t *consts; /* Current constraints */
954*5e7646d2SAndroid Build Coastguard Worker _ppd_cups_uiconst_t *constptr; /* Current constraint */
955*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t key, /* Search key */
956*5e7646d2SAndroid Build Coastguard Worker *marked; /* Marked choice */
957*5e7646d2SAndroid Build Coastguard Worker cups_array_t *active = NULL; /* Active constraints */
958*5e7646d2SAndroid Build Coastguard Worker const char *value, /* Current value */
959*5e7646d2SAndroid Build Coastguard Worker *firstvalue; /* AP_FIRSTPAGE_Keyword value */
960*5e7646d2SAndroid Build Coastguard Worker char firstpage[255]; /* AP_FIRSTPAGE_Keyword string */
961*5e7646d2SAndroid Build Coastguard Worker
962*5e7646d2SAndroid Build Coastguard Worker
963*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7ppd_test_constraints(ppd=%p, option=\"%s\", choice=\"%s\", "
964*5e7646d2SAndroid Build Coastguard Worker "num_options=%d, options=%p, which=%d)", ppd, option, choice,
965*5e7646d2SAndroid Build Coastguard Worker num_options, options, which));
966*5e7646d2SAndroid Build Coastguard Worker
967*5e7646d2SAndroid Build Coastguard Worker if (!ppd->cups_uiconstraints)
968*5e7646d2SAndroid Build Coastguard Worker ppd_load_constraints(ppd);
969*5e7646d2SAndroid Build Coastguard Worker
970*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9ppd_test_constraints: %d constraints!",
971*5e7646d2SAndroid Build Coastguard Worker cupsArrayCount(ppd->cups_uiconstraints)));
972*5e7646d2SAndroid Build Coastguard Worker
973*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->marked);
974*5e7646d2SAndroid Build Coastguard Worker
975*5e7646d2SAndroid Build Coastguard Worker for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(ppd->cups_uiconstraints);
976*5e7646d2SAndroid Build Coastguard Worker consts;
977*5e7646d2SAndroid Build Coastguard Worker consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(ppd->cups_uiconstraints))
978*5e7646d2SAndroid Build Coastguard Worker {
979*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9ppd_test_constraints: installable=%d, resolver=\"%s\", "
980*5e7646d2SAndroid Build Coastguard Worker "num_constraints=%d option1=\"%s\", choice1=\"%s\", "
981*5e7646d2SAndroid Build Coastguard Worker "option2=\"%s\", choice2=\"%s\", ...",
982*5e7646d2SAndroid Build Coastguard Worker consts->installable, consts->resolver, consts->num_constraints,
983*5e7646d2SAndroid Build Coastguard Worker consts->constraints[0].option->keyword,
984*5e7646d2SAndroid Build Coastguard Worker consts->constraints[0].choice ?
985*5e7646d2SAndroid Build Coastguard Worker consts->constraints[0].choice->choice : "",
986*5e7646d2SAndroid Build Coastguard Worker consts->constraints[1].option->keyword,
987*5e7646d2SAndroid Build Coastguard Worker consts->constraints[1].choice ?
988*5e7646d2SAndroid Build Coastguard Worker consts->constraints[1].choice->choice : ""));
989*5e7646d2SAndroid Build Coastguard Worker
990*5e7646d2SAndroid Build Coastguard Worker if (consts->installable && which < _PPD_INSTALLABLE_CONSTRAINTS)
991*5e7646d2SAndroid Build Coastguard Worker continue; /* Skip installable option constraint */
992*5e7646d2SAndroid Build Coastguard Worker
993*5e7646d2SAndroid Build Coastguard Worker if (!consts->installable && which == _PPD_INSTALLABLE_CONSTRAINTS)
994*5e7646d2SAndroid Build Coastguard Worker continue; /* Skip non-installable option constraint */
995*5e7646d2SAndroid Build Coastguard Worker
996*5e7646d2SAndroid Build Coastguard Worker if ((which == _PPD_OPTION_CONSTRAINTS || which == _PPD_INSTALLABLE_CONSTRAINTS) && option)
997*5e7646d2SAndroid Build Coastguard Worker {
998*5e7646d2SAndroid Build Coastguard Worker /*
999*5e7646d2SAndroid Build Coastguard Worker * Skip constraints that do not involve the current option...
1000*5e7646d2SAndroid Build Coastguard Worker */
1001*5e7646d2SAndroid Build Coastguard Worker
1002*5e7646d2SAndroid Build Coastguard Worker for (i = consts->num_constraints, constptr = consts->constraints;
1003*5e7646d2SAndroid Build Coastguard Worker i > 0;
1004*5e7646d2SAndroid Build Coastguard Worker i --, constptr ++)
1005*5e7646d2SAndroid Build Coastguard Worker {
1006*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(constptr->option->keyword, option))
1007*5e7646d2SAndroid Build Coastguard Worker break;
1008*5e7646d2SAndroid Build Coastguard Worker
1009*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(option, "AP_FIRSTPAGE_", 13) &&
1010*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(constptr->option->keyword, option + 13))
1011*5e7646d2SAndroid Build Coastguard Worker break;
1012*5e7646d2SAndroid Build Coastguard Worker }
1013*5e7646d2SAndroid Build Coastguard Worker
1014*5e7646d2SAndroid Build Coastguard Worker if (!i)
1015*5e7646d2SAndroid Build Coastguard Worker continue;
1016*5e7646d2SAndroid Build Coastguard Worker }
1017*5e7646d2SAndroid Build Coastguard Worker
1018*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9ppd_test_constraints: Testing...");
1019*5e7646d2SAndroid Build Coastguard Worker
1020*5e7646d2SAndroid Build Coastguard Worker for (i = consts->num_constraints, constptr = consts->constraints;
1021*5e7646d2SAndroid Build Coastguard Worker i > 0;
1022*5e7646d2SAndroid Build Coastguard Worker i --, constptr ++)
1023*5e7646d2SAndroid Build Coastguard Worker {
1024*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9ppd_test_constraints: %s=%s?", constptr->option->keyword,
1025*5e7646d2SAndroid Build Coastguard Worker constptr->choice ? constptr->choice->choice : ""));
1026*5e7646d2SAndroid Build Coastguard Worker
1027*5e7646d2SAndroid Build Coastguard Worker if (constptr->choice &&
1028*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(constptr->option->keyword, "PageSize") ||
1029*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(constptr->option->keyword, "PageRegion")))
1030*5e7646d2SAndroid Build Coastguard Worker {
1031*5e7646d2SAndroid Build Coastguard Worker /*
1032*5e7646d2SAndroid Build Coastguard Worker * PageSize and PageRegion are used depending on the selected input slot
1033*5e7646d2SAndroid Build Coastguard Worker * and manual feed mode. Validate against the selected page size instead
1034*5e7646d2SAndroid Build Coastguard Worker * of an individual option...
1035*5e7646d2SAndroid Build Coastguard Worker */
1036*5e7646d2SAndroid Build Coastguard Worker
1037*5e7646d2SAndroid Build Coastguard Worker if (option && choice &&
1038*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "PageSize") ||
1039*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(option, "PageRegion")))
1040*5e7646d2SAndroid Build Coastguard Worker {
1041*5e7646d2SAndroid Build Coastguard Worker value = choice;
1042*5e7646d2SAndroid Build Coastguard Worker }
1043*5e7646d2SAndroid Build Coastguard Worker else if ((value = cupsGetOption("PageSize", num_options,
1044*5e7646d2SAndroid Build Coastguard Worker options)) == NULL)
1045*5e7646d2SAndroid Build Coastguard Worker if ((value = cupsGetOption("PageRegion", num_options,
1046*5e7646d2SAndroid Build Coastguard Worker options)) == NULL)
1047*5e7646d2SAndroid Build Coastguard Worker if ((value = cupsGetOption("media", num_options, options)) == NULL)
1048*5e7646d2SAndroid Build Coastguard Worker {
1049*5e7646d2SAndroid Build Coastguard Worker ppd_size_t *size = ppdPageSize(ppd, NULL);
1050*5e7646d2SAndroid Build Coastguard Worker
1051*5e7646d2SAndroid Build Coastguard Worker if (size)
1052*5e7646d2SAndroid Build Coastguard Worker value = size->name;
1053*5e7646d2SAndroid Build Coastguard Worker }
1054*5e7646d2SAndroid Build Coastguard Worker
1055*5e7646d2SAndroid Build Coastguard Worker if (value && !_cups_strncasecmp(value, "Custom.", 7))
1056*5e7646d2SAndroid Build Coastguard Worker value = "Custom";
1057*5e7646d2SAndroid Build Coastguard Worker
1058*5e7646d2SAndroid Build Coastguard Worker if (option && choice &&
1059*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") ||
1060*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion")))
1061*5e7646d2SAndroid Build Coastguard Worker {
1062*5e7646d2SAndroid Build Coastguard Worker firstvalue = choice;
1063*5e7646d2SAndroid Build Coastguard Worker }
1064*5e7646d2SAndroid Build Coastguard Worker else if ((firstvalue = cupsGetOption("AP_FIRSTPAGE_PageSize",
1065*5e7646d2SAndroid Build Coastguard Worker num_options, options)) == NULL)
1066*5e7646d2SAndroid Build Coastguard Worker firstvalue = cupsGetOption("AP_FIRSTPAGE_PageRegion", num_options,
1067*5e7646d2SAndroid Build Coastguard Worker options);
1068*5e7646d2SAndroid Build Coastguard Worker
1069*5e7646d2SAndroid Build Coastguard Worker if (firstvalue && !_cups_strncasecmp(firstvalue, "Custom.", 7))
1070*5e7646d2SAndroid Build Coastguard Worker firstvalue = "Custom";
1071*5e7646d2SAndroid Build Coastguard Worker
1072*5e7646d2SAndroid Build Coastguard Worker if ((!value || _cups_strcasecmp(value, constptr->choice->choice)) &&
1073*5e7646d2SAndroid Build Coastguard Worker (!firstvalue || _cups_strcasecmp(firstvalue, constptr->choice->choice)))
1074*5e7646d2SAndroid Build Coastguard Worker {
1075*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9ppd_test_constraints: NO");
1076*5e7646d2SAndroid Build Coastguard Worker break;
1077*5e7646d2SAndroid Build Coastguard Worker }
1078*5e7646d2SAndroid Build Coastguard Worker }
1079*5e7646d2SAndroid Build Coastguard Worker else if (constptr->choice)
1080*5e7646d2SAndroid Build Coastguard Worker {
1081*5e7646d2SAndroid Build Coastguard Worker /*
1082*5e7646d2SAndroid Build Coastguard Worker * Compare against the constrained choice...
1083*5e7646d2SAndroid Build Coastguard Worker */
1084*5e7646d2SAndroid Build Coastguard Worker
1085*5e7646d2SAndroid Build Coastguard Worker if (option && choice && !_cups_strcasecmp(option, constptr->option->keyword))
1086*5e7646d2SAndroid Build Coastguard Worker {
1087*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(choice, "Custom.", 7))
1088*5e7646d2SAndroid Build Coastguard Worker value = "Custom";
1089*5e7646d2SAndroid Build Coastguard Worker else
1090*5e7646d2SAndroid Build Coastguard Worker value = choice;
1091*5e7646d2SAndroid Build Coastguard Worker }
1092*5e7646d2SAndroid Build Coastguard Worker else if ((value = cupsGetOption(constptr->option->keyword, num_options,
1093*5e7646d2SAndroid Build Coastguard Worker options)) != NULL)
1094*5e7646d2SAndroid Build Coastguard Worker {
1095*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(value, "Custom.", 7))
1096*5e7646d2SAndroid Build Coastguard Worker value = "Custom";
1097*5e7646d2SAndroid Build Coastguard Worker }
1098*5e7646d2SAndroid Build Coastguard Worker else if (constptr->choice->marked)
1099*5e7646d2SAndroid Build Coastguard Worker value = constptr->choice->choice;
1100*5e7646d2SAndroid Build Coastguard Worker else
1101*5e7646d2SAndroid Build Coastguard Worker value = NULL;
1102*5e7646d2SAndroid Build Coastguard Worker
1103*5e7646d2SAndroid Build Coastguard Worker /*
1104*5e7646d2SAndroid Build Coastguard Worker * Now check AP_FIRSTPAGE_option...
1105*5e7646d2SAndroid Build Coastguard Worker */
1106*5e7646d2SAndroid Build Coastguard Worker
1107*5e7646d2SAndroid Build Coastguard Worker snprintf(firstpage, sizeof(firstpage), "AP_FIRSTPAGE_%s",
1108*5e7646d2SAndroid Build Coastguard Worker constptr->option->keyword);
1109*5e7646d2SAndroid Build Coastguard Worker
1110*5e7646d2SAndroid Build Coastguard Worker if (option && choice && !_cups_strcasecmp(option, firstpage))
1111*5e7646d2SAndroid Build Coastguard Worker {
1112*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(choice, "Custom.", 7))
1113*5e7646d2SAndroid Build Coastguard Worker firstvalue = "Custom";
1114*5e7646d2SAndroid Build Coastguard Worker else
1115*5e7646d2SAndroid Build Coastguard Worker firstvalue = choice;
1116*5e7646d2SAndroid Build Coastguard Worker }
1117*5e7646d2SAndroid Build Coastguard Worker else if ((firstvalue = cupsGetOption(firstpage, num_options,
1118*5e7646d2SAndroid Build Coastguard Worker options)) != NULL)
1119*5e7646d2SAndroid Build Coastguard Worker {
1120*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(firstvalue, "Custom.", 7))
1121*5e7646d2SAndroid Build Coastguard Worker firstvalue = "Custom";
1122*5e7646d2SAndroid Build Coastguard Worker }
1123*5e7646d2SAndroid Build Coastguard Worker else
1124*5e7646d2SAndroid Build Coastguard Worker firstvalue = NULL;
1125*5e7646d2SAndroid Build Coastguard Worker
1126*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9ppd_test_constraints: value=%s, firstvalue=%s", value,
1127*5e7646d2SAndroid Build Coastguard Worker firstvalue));
1128*5e7646d2SAndroid Build Coastguard Worker
1129*5e7646d2SAndroid Build Coastguard Worker if ((!value || _cups_strcasecmp(value, constptr->choice->choice)) &&
1130*5e7646d2SAndroid Build Coastguard Worker (!firstvalue || _cups_strcasecmp(firstvalue, constptr->choice->choice)))
1131*5e7646d2SAndroid Build Coastguard Worker {
1132*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9ppd_test_constraints: NO");
1133*5e7646d2SAndroid Build Coastguard Worker break;
1134*5e7646d2SAndroid Build Coastguard Worker }
1135*5e7646d2SAndroid Build Coastguard Worker }
1136*5e7646d2SAndroid Build Coastguard Worker else if (option && choice &&
1137*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(option, constptr->option->keyword))
1138*5e7646d2SAndroid Build Coastguard Worker {
1139*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(choice, "None") || !_cups_strcasecmp(choice, "Off") ||
1140*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice, "False"))
1141*5e7646d2SAndroid Build Coastguard Worker {
1142*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9ppd_test_constraints: NO");
1143*5e7646d2SAndroid Build Coastguard Worker break;
1144*5e7646d2SAndroid Build Coastguard Worker }
1145*5e7646d2SAndroid Build Coastguard Worker }
1146*5e7646d2SAndroid Build Coastguard Worker else if ((value = cupsGetOption(constptr->option->keyword, num_options,
1147*5e7646d2SAndroid Build Coastguard Worker options)) != NULL)
1148*5e7646d2SAndroid Build Coastguard Worker {
1149*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(value, "None") || !_cups_strcasecmp(value, "Off") ||
1150*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "False"))
1151*5e7646d2SAndroid Build Coastguard Worker {
1152*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9ppd_test_constraints: NO");
1153*5e7646d2SAndroid Build Coastguard Worker break;
1154*5e7646d2SAndroid Build Coastguard Worker }
1155*5e7646d2SAndroid Build Coastguard Worker }
1156*5e7646d2SAndroid Build Coastguard Worker else
1157*5e7646d2SAndroid Build Coastguard Worker {
1158*5e7646d2SAndroid Build Coastguard Worker key.option = constptr->option;
1159*5e7646d2SAndroid Build Coastguard Worker
1160*5e7646d2SAndroid Build Coastguard Worker if ((marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key))
1161*5e7646d2SAndroid Build Coastguard Worker == NULL ||
1162*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(marked->choice, "None") ||
1163*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(marked->choice, "Off") ||
1164*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(marked->choice, "False")))
1165*5e7646d2SAndroid Build Coastguard Worker {
1166*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9ppd_test_constraints: NO");
1167*5e7646d2SAndroid Build Coastguard Worker break;
1168*5e7646d2SAndroid Build Coastguard Worker }
1169*5e7646d2SAndroid Build Coastguard Worker }
1170*5e7646d2SAndroid Build Coastguard Worker }
1171*5e7646d2SAndroid Build Coastguard Worker
1172*5e7646d2SAndroid Build Coastguard Worker if (i <= 0)
1173*5e7646d2SAndroid Build Coastguard Worker {
1174*5e7646d2SAndroid Build Coastguard Worker if (!active)
1175*5e7646d2SAndroid Build Coastguard Worker active = cupsArrayNew(NULL, NULL);
1176*5e7646d2SAndroid Build Coastguard Worker
1177*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(active, consts);
1178*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9ppd_test_constraints: Added...");
1179*5e7646d2SAndroid Build Coastguard Worker }
1180*5e7646d2SAndroid Build Coastguard Worker }
1181*5e7646d2SAndroid Build Coastguard Worker
1182*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->marked);
1183*5e7646d2SAndroid Build Coastguard Worker
1184*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("8ppd_test_constraints: Found %d active constraints!",
1185*5e7646d2SAndroid Build Coastguard Worker cupsArrayCount(active)));
1186*5e7646d2SAndroid Build Coastguard Worker
1187*5e7646d2SAndroid Build Coastguard Worker return (active);
1188*5e7646d2SAndroid Build Coastguard Worker }
1189