/* * options.c: Option routines for ppdfilt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * * See the AUTHORS file for a list of people who have hacked on * this code. * See the ChangeLog file for a list of changes. * * cupsAddOption() - Add an option to an option array. * cupsFreeOptions() - Free all memory used by options. * cupsGetOption() - Get an option value. * cupsParseOptions() - Parse options from a command-line argument. * cupsMarkOptions() - Mark command-line options in a PPD file. */ /* * Include necessary headers... */ #include "ppdfilt.h" #include "ppd.h" #include #include /* 'cupsAddOption()' - Add an option to an option array. */ int cupsAddOption(const char *name, const char *value, int num_options, cups_option_t ** options) { int i; // Looping var cups_option_t *temp; // Pointer to new option if (name == NULL || value == NULL || options == NULL) return (0); // Look for an existing option with the same name... for (i = 0, temp = *options; i < num_options; i++, temp++) if (g_strcasecmp(temp->name, name) == 0) break; if (i >= num_options) { // No matching option name... if (num_options == 0) temp = (cups_option_t *) malloc(sizeof(cups_option_t)); else temp = (cups_option_t *) realloc(*options, sizeof(cups_option_t) * (num_options + 1)); if (temp == NULL) return (0); *options = temp; temp += num_options; temp->name = g_strdup(name); num_options++; } else { // Match found; free the old value... free(temp->value); } temp->value = g_strdup(value); return (num_options); } /* 'cupsFreeOptions()' - Free all memory used by options. */ void cupsFreeOptions(int num_options, cups_option_t * options) { int i; // Looping var if (num_options == 0 || options == NULL) return; for (i = 0; i < num_options; i++) { free(options[i].name); free(options[i].value); } free(options); } /* 'cupsGetOption()' - Get an option value. */ const char *cupsGetOption(const char *name, int num_options, cups_option_t * options) { int i; // Looping var if (name == NULL || num_options == 0 || options == NULL) return (NULL); for (i = 0; i < num_options; i++) if (g_strcasecmp(options[i].name, name) == 0) return (options[i].value); return (NULL); } /* 'cupsParseOptions()' - Parse options from a command-line argument. */ int cupsParseOptions(const char *arg, int num_options, cups_option_t ** options) { char *copyarg, // Copy of input string *ptr, // Pointer into string *name, // Pointer to name *value; // Pointer to value if (arg == NULL || options == NULL) return (0); // Make a copy of the argument string and then divide it up... copyarg = g_strdup(arg); ptr = copyarg; while (*ptr != '\0') { // Get the name up to a SPACE, =, or end-of-string... name = ptr; while (!isspace(*ptr) && *ptr != '=' && *ptr != '\0') ptr++; while (isspace(*ptr)) // Skip trailing spaces... *ptr++ = '\0'; if (*ptr != '=') { // Start of another option... num_options = cupsAddOption(name, "", num_options, options); continue; } // Remove = and parse the value... *ptr++ = '\0'; if (*ptr == '\'') { // Quoted string constant... ptr++; value = ptr; while (*ptr != '\'' && *ptr != '\0') ptr++; if (*ptr != '\0') *ptr++ = '\0'; } else if (*ptr == '\"') { // Double-quoted string constant... ptr++; value = ptr; while (*ptr != '\"' && *ptr != '\0') ptr++; if (*ptr != '\0') *ptr++ = '\0'; } else { // Normal space-delimited string... value = ptr; while (!isspace(*ptr) && *ptr != '\0') ptr++; while (isspace(*ptr)) *ptr++ = '\0'; } // Add the string value... num_options = cupsAddOption(name, value, num_options, options); } /* Free the copy of the argument we made and return the number of * options found. */ free(copyarg); return (num_options); } // 'cupsMarkOptions()' - Mark command-line options in a PPD file. int cupsMarkOptions(PpdFile * ppd, int num_options, cups_option_t * options) // PPD File Number of options Options { int i; // Looping var int conflict; // Option conflicts char *val, // Pointer into value *ptr, // Pointer into string s[255]; // Temporary string conflict = 0; for (i = num_options; i > 0; i--, options++) if (g_strcasecmp(options->name, "media") == 0) { /* Loop through the option string, separating it at commas and marking each individual option. */ for (val = options->value; *val;) { /* Extract the sub-option from the string... */ for (ptr = s; *val && *val != ',' && (ptr - s) < (signed)(sizeof(s) - 1);) *ptr++ = *val++; *ptr++ = '\0'; if (*val == ',') val++; /* Mark it... */ if (ppd_mark_option(ppd, "PageSize", s)) conflict = 1; if (ppd_mark_option(ppd, "InputSlot", s)) conflict = 1; if (ppd_mark_option(ppd, "MediaType", s)) conflict = 1; if (ppd_mark_option(ppd, "EFMediaQualityMode", s)) // EFI conflict = 1; if (g_strcasecmp(s, "manual") == 0) if (ppd_mark_option(ppd, "ManualFeed", "True")) conflict = 1; } } else if (g_strcasecmp(options->name, "sides") == 0) { if (g_strcasecmp(options->value, "one-sided") == 0) { if (ppd_mark_option(ppd, "Duplex", "None")) conflict = 1; if (ppd_mark_option(ppd, "EFDuplex", "None")) // EFI conflict = 1; if (ppd_mark_option(ppd, "KD03Duplex", "None")) // Kodak conflict = 1; } else if (g_strcasecmp(options->value, "two-sided-long-edge") == 0) { if (ppd_mark_option(ppd, "Duplex", "DuplexNoTumble")) conflict = 1; if (ppd_mark_option(ppd, "EFDuplex", "DuplexNoTumble")) // EFI conflict = 1; if (ppd_mark_option(ppd, "KD03Duplex", "DuplexNoTumble")) // Kodak // // // // conflict = 1; } else if (g_strcasecmp(options->value, "two-sided-short-edge") == 0) { if (ppd_mark_option(ppd, "Duplex", "DuplexTumble")) conflict = 1; if (ppd_mark_option(ppd, "EFDuplex", "DuplexTumble")) // EFI conflict = 1; if (ppd_mark_option(ppd, "KD03Duplex", "DuplexTumble")) // Kodak conflict = 1; } } else if (g_strcasecmp(options->name, "resolution") == 0) { if (ppd_mark_option(ppd, "Resolution", options->value)) conflict = 1; if (ppd_mark_option(ppd, "SetResolution", options->value)) // Calcomp, Linotype, QMS, Summagraphics, Tektronix, // Varityper conflict = 1; if (ppd_mark_option(ppd, "JCLResolution", options->value)) // HP conflict = 1; if (ppd_mark_option(ppd, "CNRes_PGP", options->value)) // Canon conflict = 1; } else if (ppd_mark_option(ppd, options->name, options->value)) conflict = 1; return (conflict); } /* * End of "$Id: options.c,v 1.6 2001/07/19 18:23:02 ben Exp $". */