]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/options.c
2 * "$Id: options.c 4918 2006-01-12 05:14:40Z mike $"
4 * Option routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2005 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * cupsAddOption() - Add an option to an option array.
29 * cupsFreeOptions() - Free all memory used by options.
30 * cupsGetOption() - Get an option value.
31 * cupsParseOptions() - Parse options from a command-line argument.
32 * cupsMarkOptions() - Mark command-line options in a PPD file.
36 * Include necessary headers...
47 * 'cupsAddOption()' - Add an option to an option array.
50 int /* O - Number of options */
51 cupsAddOption(const char *name
, /* I - Name of option */
52 const char *value
, /* I - Value of option */
53 int num_options
,/* I - Number of options */
54 cups_option_t
**options
) /* IO - Pointer to options */
56 int i
; /* Looping var */
57 cups_option_t
*temp
; /* Pointer to new option */
60 if (name
== NULL
|| !name
[0] || value
== NULL
||
61 options
== NULL
|| num_options
< 0)
65 * Look for an existing option with the same name...
68 for (i
= 0, temp
= *options
; i
< num_options
; i
++, temp
++)
69 if (strcasecmp(temp
->name
, name
) == 0)
75 * No matching option name...
79 temp
= (cups_option_t
*)malloc(sizeof(cups_option_t
));
81 temp
= (cups_option_t
*)realloc(*options
, sizeof(cups_option_t
) *
89 temp
->name
= strdup(name
);
95 * Match found; free the old value...
101 temp
->value
= strdup(value
);
103 return (num_options
);
108 * 'cupsFreeOptions()' - Free all memory used by options.
113 int num_options
, /* I - Number of options */
114 cups_option_t
*options
) /* I - Pointer to options */
116 int i
; /* Looping var */
119 if (num_options
<= 0 || options
== NULL
)
122 for (i
= 0; i
< num_options
; i
++)
124 free(options
[i
].name
);
125 free(options
[i
].value
);
133 * 'cupsGetOption()' - Get an option value.
136 const char * /* O - Option value or NULL */
137 cupsGetOption(const char *name
, /* I - Name of option */
138 int num_options
,/* I - Number of options */
139 cups_option_t
*options
) /* I - Options */
141 int i
; /* Looping var */
144 if (name
== NULL
|| num_options
<= 0 || options
== NULL
)
147 for (i
= 0; i
< num_options
; i
++)
148 if (strcasecmp(options
[i
].name
, name
) == 0)
149 return (options
[i
].value
);
156 * 'cupsParseOptions()' - Parse options from a command-line argument.
158 * This function converts space-delimited name/value pairs according
159 * to the PAPI text option ABNF specification. Collection values
160 * ("name={a=... b=... c=...}") are stored with the curley brackets
161 * intact - use cupsParseOptions() on the value to extract the collection
165 int /* O - Number of options found */
167 const char *arg
, /* I - Argument to parse */
168 int num_options
, /* I - Number of options */
169 cups_option_t
**options
) /* O - Options found */
171 char *copyarg
, /* Copy of input string */
172 *ptr
, /* Pointer into string */
173 *name
, /* Pointer to name */
174 *value
; /* Pointer to value */
177 if (arg
== NULL
|| options
== NULL
|| num_options
< 0)
181 * Make a copy of the argument string and then divide it up...
184 copyarg
= strdup(arg
);
188 * Skip leading spaces...
191 while (isspace(*ptr
& 255))
195 * Loop through the string...
201 * Get the name up to a SPACE, =, or end-of-string...
205 while (!isspace(*ptr
& 255) && *ptr
!= '=' && *ptr
!= '\0')
209 * Avoid an empty name...
216 * Skip trailing spaces...
219 while (isspace(*ptr
& 255))
225 * Start of another option...
228 if (strncasecmp(name
, "no", 2) == 0)
229 num_options
= cupsAddOption(name
+ 2, "false", num_options
,
232 num_options
= cupsAddOption(name
, "true", num_options
, options
);
238 * Remove = and parse the value...
246 * Quoted string constant...
252 while (*ptr
!= '\'' && *ptr
!= '\0')
255 _cups_strcpy(ptr
, ptr
+ 1);
263 else if (*ptr
== '\"')
266 * Double-quoted string constant...
272 while (*ptr
!= '\"' && *ptr
!= '\0')
275 _cups_strcpy(ptr
, ptr
+ 1);
283 else if (*ptr
== '{')
286 * Collection value...
293 for (depth
= 1; *ptr
; ptr
++)
296 else if (*ptr
== '}')
307 else if (*ptr
== '\\')
308 _cups_strcpy(ptr
, ptr
+ 1);
316 * Normal space-delimited string...
321 while (!isspace(*ptr
& 255) && *ptr
!= '\0')
324 _cups_strcpy(ptr
, ptr
+ 1);
331 * Skip trailing whitespace...
334 while (isspace(*ptr
& 255))
338 * Add the string value...
341 num_options
= cupsAddOption(name
, value
, num_options
, options
);
345 * Free the copy of the argument we made and return the number of options
351 return (num_options
);
356 * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
359 int /* O - 1 if conflicting */
361 ppd_file_t
*ppd
, /* I - PPD file */
362 int num_options
, /* I - Number of options */
363 cups_option_t
*options
) /* I - Options */
365 int i
, j
, k
; /* Looping vars */
366 int conflict
; /* Option conflicts */
367 char *val
, /* Pointer into value */
368 *ptr
, /* Pointer into string */
369 s
[255]; /* Temporary string */
370 cups_option_t
*optptr
; /* Current option */
371 ppd_option_t
*option
; /* PPD option */
372 static const char * const duplex_options
[] =
373 { /* Duplex option names */
374 "Duplex", /* Adobe */
375 "EFDuplex", /* EFI */
376 "EFDuplexing", /* EFI */
377 "KD03Duplex", /* Kodak */
378 "JCLDuplex" /* Samsung */
380 static const char * const duplex_one
[] =
381 { /* one-sided names */
385 static const char * const duplex_two_long
[] =
386 { /* two-sided-long-edge names */
387 "DuplexNoTumble", /* Adobe */
388 "LongEdge", /* EFI */
391 static const char * const duplex_two_short
[] =
392 { /* two-sided-long-edge names */
393 "DuplexTumble", /* Adobe */
394 "ShortEdge", /* EFI */
403 if (ppd
== NULL
|| num_options
<= 0 || options
== NULL
)
412 for (i
= num_options
, optptr
= options
; i
> 0; i
--, optptr
++)
413 if (!strcasecmp(optptr
->name
, "media"))
416 * Loop through the option string, separating it at commas and
417 * marking each individual option.
420 for (val
= optptr
->value
; *val
;)
423 * Extract the sub-option from the string...
426 for (ptr
= s
; *val
&& *val
!= ',' && (ptr
- s
) < (sizeof(s
) - 1);)
437 if (cupsGetOption("PageSize", num_options
, options
) == NULL
)
438 if (ppdMarkOption(ppd
, "PageSize", s
))
441 if (cupsGetOption("InputSlot", num_options
, options
) == NULL
)
442 if (ppdMarkOption(ppd
, "InputSlot", s
))
445 if (cupsGetOption("MediaType", num_options
, options
) == NULL
)
446 if (ppdMarkOption(ppd
, "MediaType", s
))
449 if (cupsGetOption("EFMediaType", num_options
, options
) == NULL
)
450 if (ppdMarkOption(ppd
, "EFMediaType", s
))
453 if (cupsGetOption("EFMediaQualityMode", num_options
, options
) == NULL
)
454 if (ppdMarkOption(ppd
, "EFMediaQualityMode", s
)) /* EFI */
457 if (strcasecmp(s
, "manual") == 0 &&
458 cupsGetOption("ManualFeed", num_options
, options
) == NULL
)
459 if (ppdMarkOption(ppd
, "ManualFeed", "True"))
463 else if (!strcasecmp(optptr
->name
, "sides"))
465 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
466 if (cupsGetOption(duplex_options
[j
], num_options
, options
) != NULL
)
469 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
472 * Don't override the PPD option with the IPP attribute...
478 if (!strcasecmp(optptr
->value
, "one-sided"))
481 * Mark the appropriate duplex option for one-sided output...
484 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
485 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
488 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
490 for (k
= 0; k
< (int)(sizeof(duplex_one
) / sizeof(duplex_one
[0])); k
++)
491 if (ppdFindChoice(option
, duplex_one
[k
]))
493 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_one
[k
]))
500 else if (!strcasecmp(optptr
->value
, "two-sided-long-edge"))
503 * Mark the appropriate duplex option for two-sided-long-edge output...
506 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
507 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
510 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
512 for (k
= 0; k
< (int)(sizeof(duplex_two_long
) / sizeof(duplex_two_long
[0])); k
++)
513 if (ppdFindChoice(option
, duplex_two_long
[k
]))
515 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_two_long
[k
]))
522 else if (!strcasecmp(optptr
->value
, "two-sided-short-edge"))
525 * Mark the appropriate duplex option for two-sided-short-edge output...
528 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
529 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
532 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
534 for (k
= 0; k
< (int)(sizeof(duplex_two_short
) / sizeof(duplex_two_short
[0])); k
++)
535 if (ppdFindChoice(option
, duplex_two_short
[k
]))
537 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_two_short
[k
]))
545 else if (!strcasecmp(optptr
->name
, "resolution") ||
546 !strcasecmp(optptr
->name
, "printer-resolution"))
548 if (ppdMarkOption(ppd
, "Resolution", optptr
->value
))
550 if (ppdMarkOption(ppd
, "SetResolution", optptr
->value
))
551 /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
553 if (ppdMarkOption(ppd
, "JCLResolution", optptr
->value
)) /* HP */
555 if (ppdMarkOption(ppd
, "CNRes_PGP", optptr
->value
)) /* Canon */
558 else if (!strcasecmp(optptr
->name
, "output-bin"))
560 if (cupsGetOption("OutputBin", num_options
, options
) == NULL
)
561 if (ppdMarkOption(ppd
, "OutputBin", optptr
->value
))
564 else if (ppdMarkOption(ppd
, optptr
->name
, optptr
->value
))
572 * End of "$Id: options.c 4918 2006-01-12 05:14:40Z mike $".