]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/options.c
cbaa5919064c0bc1277b7759ae489bdf505b62a1
2 * "$Id: options.c 4980 2006-01-25 19:57:45Z 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 const char *page_size
; /* PageSize option */
371 cups_option_t
*optptr
; /* Current option */
372 ppd_option_t
*option
; /* PPD option */
373 static const char * const duplex_options
[] =
374 { /* Duplex option names */
375 "Duplex", /* Adobe */
376 "EFDuplex", /* EFI */
377 "EFDuplexing", /* EFI */
378 "KD03Duplex", /* Kodak */
379 "JCLDuplex" /* Samsung */
381 static const char * const duplex_one
[] =
382 { /* one-sided names */
386 static const char * const duplex_two_long
[] =
387 { /* two-sided-long-edge names */
388 "DuplexNoTumble", /* Adobe */
389 "LongEdge", /* EFI */
392 static const char * const duplex_two_short
[] =
393 { /* two-sided-long-edge names */
394 "DuplexTumble", /* Adobe */
395 "ShortEdge", /* EFI */
404 if (ppd
== NULL
|| num_options
<= 0 || options
== NULL
)
413 for (i
= num_options
, optptr
= options
; i
> 0; i
--, optptr
++)
414 if (!strcasecmp(optptr
->name
, "media"))
417 * Loop through the option string, separating it at commas and
418 * marking each individual option as long as the corresponding
419 * PPD option (PageSize, InputSlot, etc.) is not also set.
421 * For PageSize, we also check for an empty option value since
422 * some versions of MacOS X use it to specify auto-selection
423 * of the media based solely on the size.
426 page_size
= cupsGetOption("PageSize", num_options
, options
);
428 for (val
= optptr
->value
; *val
;)
431 * Extract the sub-option from the string...
434 for (ptr
= s
; *val
&& *val
!= ',' && (ptr
- s
) < (sizeof(s
) - 1);)
445 if (!page_size
|| !page_size
[0])
446 if (ppdMarkOption(ppd
, "PageSize", s
))
449 if (cupsGetOption("InputSlot", num_options
, options
) == NULL
)
450 if (ppdMarkOption(ppd
, "InputSlot", s
))
453 if (cupsGetOption("MediaType", num_options
, options
) == NULL
)
454 if (ppdMarkOption(ppd
, "MediaType", s
))
457 if (cupsGetOption("EFMediaType", num_options
, options
) == NULL
)
458 if (ppdMarkOption(ppd
, "EFMediaType", s
))
461 if (cupsGetOption("EFMediaQualityMode", num_options
, options
) == NULL
)
462 if (ppdMarkOption(ppd
, "EFMediaQualityMode", s
)) /* EFI */
465 if (strcasecmp(s
, "manual") == 0 &&
466 cupsGetOption("ManualFeed", num_options
, options
) == NULL
)
467 if (ppdMarkOption(ppd
, "ManualFeed", "True"))
471 else if (!strcasecmp(optptr
->name
, "sides"))
473 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
474 if (cupsGetOption(duplex_options
[j
], num_options
, options
) != NULL
)
477 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
480 * Don't override the PPD option with the IPP attribute...
486 if (!strcasecmp(optptr
->value
, "one-sided"))
489 * Mark the appropriate duplex option for one-sided output...
492 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
493 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
496 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
498 for (k
= 0; k
< (int)(sizeof(duplex_one
) / sizeof(duplex_one
[0])); k
++)
499 if (ppdFindChoice(option
, duplex_one
[k
]))
501 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_one
[k
]))
508 else if (!strcasecmp(optptr
->value
, "two-sided-long-edge"))
511 * Mark the appropriate duplex option for two-sided-long-edge output...
514 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
515 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
518 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
520 for (k
= 0; k
< (int)(sizeof(duplex_two_long
) / sizeof(duplex_two_long
[0])); k
++)
521 if (ppdFindChoice(option
, duplex_two_long
[k
]))
523 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_two_long
[k
]))
530 else if (!strcasecmp(optptr
->value
, "two-sided-short-edge"))
533 * Mark the appropriate duplex option for two-sided-short-edge output...
536 for (j
= 0; j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])); j
++)
537 if ((option
= ppdFindOption(ppd
, duplex_options
[j
])) != NULL
)
540 if (j
< (int)(sizeof(duplex_options
) / sizeof(duplex_options
[0])))
542 for (k
= 0; k
< (int)(sizeof(duplex_two_short
) / sizeof(duplex_two_short
[0])); k
++)
543 if (ppdFindChoice(option
, duplex_two_short
[k
]))
545 if (ppdMarkOption(ppd
, duplex_options
[j
], duplex_two_short
[k
]))
553 else if (!strcasecmp(optptr
->name
, "resolution") ||
554 !strcasecmp(optptr
->name
, "printer-resolution"))
556 if (ppdMarkOption(ppd
, "Resolution", optptr
->value
))
558 if (ppdMarkOption(ppd
, "SetResolution", optptr
->value
))
559 /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
561 if (ppdMarkOption(ppd
, "JCLResolution", optptr
->value
)) /* HP */
563 if (ppdMarkOption(ppd
, "CNRes_PGP", optptr
->value
)) /* Canon */
566 else if (!strcasecmp(optptr
->name
, "output-bin"))
568 if (cupsGetOption("OutputBin", num_options
, options
) == NULL
)
569 if (ppdMarkOption(ppd
, "OutputBin", optptr
->value
))
572 else if (ppdMarkOption(ppd
, optptr
->name
, optptr
->value
))
580 * End of "$Id: options.c 4980 2006-01-25 19:57:45Z mike $".