]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/options.c
2 * "$Id: options.c 7819 2008-08-01 00:27:24Z mike $"
4 * Option routines for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * cupsAddOption() - Add an option to an option array.
20 * cupsFreeOptions() - Free all memory used by options.
21 * cupsGetOption() - Get an option value.
22 * cupsParseOptions() - Parse options from a command-line argument.
23 * cupsRemoveOption() - Remove an option from an option array.
27 * Include necessary headers...
38 * 'cupsAddOption()' - Add an option to an option array.
40 * New option arrays can be initialized simply by passing 0 for the
41 * "num_options" parameter.
44 int /* O - Number of options */
45 cupsAddOption(const char *name
, /* I - Name of option */
46 const char *value
, /* I - Value of option */
47 int num_options
,/* I - Number of options */
48 cups_option_t
**options
) /* IO - Pointer to options */
50 int i
; /* Looping var */
51 cups_option_t
*temp
; /* Pointer to new option */
54 DEBUG_printf(("cupsAddOption(name=\"%s\", value=\"%s\", num_options=%d, "
55 "options=%p)\n", name
, value
, num_options
, options
));
57 if (!name
|| !name
[0] || !value
|| !options
|| num_options
< 0)
59 DEBUG_printf(("cupsAddOption: Returning %d\n", num_options
));
64 * Look for an existing option with the same name...
67 for (i
= 0, temp
= *options
; i
< num_options
; i
++, temp
++)
68 if (!strcasecmp(temp
->name
, name
))
74 * No matching option name...
77 DEBUG_puts("cupsAddOption: New option...");
80 temp
= (cups_option_t
*)malloc(sizeof(cups_option_t
));
82 temp
= (cups_option_t
*)realloc(*options
, sizeof(cups_option_t
) *
87 DEBUG_puts("cupsAddOption: Unable to expand option array, returning 0");
93 temp
->name
= _cupsStrAlloc(name
);
99 * Match found; free the old value...
102 DEBUG_puts("cupsAddOption: Option already exists...");
103 _cupsStrFree(temp
->value
);
106 temp
->value
= _cupsStrAlloc(value
);
108 DEBUG_printf(("cupsAddOption: Returning %d\n", num_options
));
110 return (num_options
);
115 * 'cupsFreeOptions()' - Free all memory used by options.
120 int num_options
, /* I - Number of options */
121 cups_option_t
*options
) /* I - Pointer to options */
123 int i
; /* Looping var */
126 DEBUG_printf(("cupsFreeOptions(num_options=%d, options=%p)\n", num_options
,
129 if (num_options
<= 0 || !options
)
132 for (i
= 0; i
< num_options
; i
++)
134 _cupsStrFree(options
[i
].name
);
135 _cupsStrFree(options
[i
].value
);
143 * 'cupsGetOption()' - Get an option value.
146 const char * /* O - Option value or @code NULL@ */
147 cupsGetOption(const char *name
, /* I - Name of option */
148 int num_options
,/* I - Number of options */
149 cups_option_t
*options
) /* I - Options */
151 int i
; /* Looping var */
154 DEBUG_printf(("cupsGetOption(name=\"%s\", num_options=%d, options=%p)\n",
155 name
, num_options
, options
));
157 if (!name
|| num_options
<= 0 || !options
)
159 DEBUG_puts("cupsGetOption: Returning NULL");
163 for (i
= 0; i
< num_options
; i
++)
164 if (!strcasecmp(options
[i
].name
, name
))
166 DEBUG_printf(("cupsGetOption: Returning \"%s\"\n", options
[i
].value
));
167 return (options
[i
].value
);
170 DEBUG_puts("cupsGetOption: Returning NULL");
176 * 'cupsParseOptions()' - Parse options from a command-line argument.
178 * This function converts space-delimited name/value pairs according
179 * to the PAPI text option ABNF specification. Collection values
180 * ("name={a=... b=... c=...}") are stored with the curley brackets
181 * intact - use @code cupsParseOptions@ on the value to extract the
182 * collection attributes.
185 int /* O - Number of options found */
187 const char *arg
, /* I - Argument to parse */
188 int num_options
, /* I - Number of options */
189 cups_option_t
**options
) /* O - Options found */
191 char *copyarg
, /* Copy of input string */
192 *ptr
, /* Pointer into string */
193 *name
, /* Pointer to name */
194 *value
, /* Pointer to value */
195 quote
; /* Quote character */
198 DEBUG_printf(("cupsParseOptions(arg=\"%s\", num_options=%d, options=%p)\n",
199 arg
, num_options
, options
));
202 * Range check input...
207 DEBUG_printf(("cupsParseOptions: Returning %d\n", num_options
));
208 return (num_options
);
211 if (!options
|| num_options
< 0)
213 DEBUG_puts("cupsParseOptions: Returning 0");
218 * Make a copy of the argument string and then divide it up...
221 if ((copyarg
= strdup(arg
)) == NULL
)
223 DEBUG_puts("cupsParseOptions: Unable to copy arg string");
224 DEBUG_printf(("cupsParseOptions: Returning %d\n", num_options
));
225 return (num_options
);
231 * Remove surrounding {} so we can parse "{name=value ... name=value}"...
234 if ((ptr
= copyarg
+ strlen(copyarg
) - 1) > copyarg
&& *ptr
== '}')
246 * Skip leading spaces...
249 while (isspace(*ptr
& 255))
253 * Loop through the string...
259 * Get the name up to a SPACE, =, or end-of-string...
263 while (!isspace(*ptr
& 255) && *ptr
!= '=' && *ptr
)
267 * Avoid an empty name...
274 * Skip trailing spaces...
277 while (isspace(*ptr
& 255))
280 DEBUG_printf(("cupsParseOptions: name=\"%s\"\n", name
));
288 if (!strncasecmp(name
, "no", 2))
289 num_options
= cupsAddOption(name
+ 2, "false", num_options
,
292 num_options
= cupsAddOption(name
, "true", num_options
, options
);
298 * Remove = and parse the value...
304 while (*ptr
&& !isspace(*ptr
& 255))
308 else if (*ptr
== '\'' || *ptr
== '\"')
311 * Quoted string constant...
315 _cups_strcpy(ptr
, ptr
+ 1);
317 while (*ptr
!= quote
&& *ptr
)
319 if (*ptr
== '\\' && ptr
[1])
320 _cups_strcpy(ptr
, ptr
+ 1);
326 _cups_strcpy(ptr
, ptr
+ 1);
328 else if (*ptr
== '{')
331 * Collection value...
336 for (depth
= 0; *ptr
; ptr
++)
340 else if (*ptr
== '}')
349 else if (*ptr
== '\\' && ptr
[1])
350 _cups_strcpy(ptr
, ptr
+ 1);
356 * Normal space-delimited string...
359 while (!isspace(*ptr
& 255) && *ptr
)
361 if (*ptr
== '\\' && ptr
[1])
362 _cups_strcpy(ptr
, ptr
+ 1);
372 DEBUG_printf(("cupsParseOptions: value=\"%s\"\n", value
));
375 * Skip trailing whitespace...
378 while (isspace(*ptr
& 255))
382 * Add the string value...
385 num_options
= cupsAddOption(name
, value
, num_options
, options
);
389 * Free the copy of the argument we made and return the number of options
395 DEBUG_printf(("cupsParseOptions: Returning %d\n", num_options
));
397 return (num_options
);
402 * 'cupsRemoveOption()' - Remove an option from an option array.
407 int /* O - New number of options */
409 const char *name
, /* I - Option name */
410 int num_options
, /* I - Current number of options */
411 cups_option_t
**options
) /* IO - Options */
413 int i
; /* Looping var */
414 cups_option_t
*option
; /* Current option */
417 DEBUG_printf(("cupsRemoveOption(name=\"%s\", num_options=%d, options=%p)\n",
418 name
, num_options
, options
));
421 * Range check input...
424 if (!name
|| num_options
< 1 || !options
)
426 DEBUG_printf(("cupsRemoveOption: Returning %d\n", num_options
));
427 return (num_options
);
431 * Loop for the option...
434 for (i
= num_options
, option
= *options
; i
> 0; i
--, option
++)
435 if (!strcasecmp(name
, option
->name
))
441 * Remove this option from the array...
444 DEBUG_puts("cupsRemoveOption: Found option, removing it...");
449 _cupsStrFree(option
->name
);
450 _cupsStrFree(option
->value
);
453 memmove(option
, option
+ 1, i
* sizeof(cups_option_t
));
457 * Return the new number of options...
460 DEBUG_printf(("cupsRemoveOption: Returning %d\n", num_options
));
461 return (num_options
);
466 * End of "$Id: options.c 7819 2008-08-01 00:27:24Z mike $".