X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Foutput%2Foptions.c;h=52bfa81aad0661446277516c65140ca226179415;hb=9d4b6c71c0cd089bb94296fab50a703735b89ccd;hp=c3dcf915a87ba0ed0d192ae95b18097ad12374f7;hpb=a06dd54ab3d37656a1edfb8ee7de859cc0baac0e;p=pspp diff --git a/src/output/options.c b/src/output/options.c index c3dcf915a8..52bfa81aad 100644 --- a/src/output/options.c +++ b/src/output/options.c @@ -38,67 +38,32 @@ #include "gettext.h" #define _(msgid) gettext (msgid) -/* Creates and returns a new struct driver_option that contains copies of - all of the supplied arguments. All of the arguments must be nonnull, - except that VALUE may be NULL (if the user did not supply a value for this - option). - - Refer to struct driver_option for the meaning of each argument. */ -struct driver_option * -driver_option_create (const char *driver_name, const char *name, - const char *value, const char *default_value) -{ - struct driver_option *o = xmalloc (sizeof *o); - o->driver_name = xstrdup (driver_name); - o->name = xstrdup (name); - o->value = value != NULL ? xstrdup (value) : NULL; - o->default_value = default_value ? xstrdup (default_value) : NULL; - return o; -} - -/* Creates and returns a new struct driver_option for output driver DRIVER - (which is needed only to the extent that its name will be used in error - messages). The option named NAME is extracted from OPTIONS. DEFAULT_VALUE - is the default value of the option, used if the given option was not - supplied or was invalid. */ -struct driver_option * -driver_option_get (struct output_driver *driver, struct string_map *options, +/* Creates and returns a new struct driver_option for driver DRIVER_NAME (which + is used only in error messages). The option named NAME is extracted from + OPTIONS. DEFAULT_VALUE is the default value of the option, used if the + given option was not supplied or was invalid. */ +struct driver_option +driver_option_get (struct driver_options *options, const char *name, const char *default_value) { - struct driver_option *option; - char *value; - - value = string_map_find_and_delete (options, name); - option = driver_option_create (output_driver_get_name (driver), name, value, - default_value); - free (value); - return option; -} - -/* Frees driver option O. */ -void -driver_option_destroy (struct driver_option *o) -{ - if (o != NULL) - { - free (o->driver_name); - free (o->name); - free (o->value); - free (o->default_value); - free (o); - } + char *value = string_map_find_and_delete (&options->map, name); + if (value) + string_array_append_nocopy (&options->garbage, value); + return (struct driver_option) { + .driver_name = options->driver_name, + .name = name, + .value = value, + .default_value = default_value, + }; } -/* Stores the paper size of the value of option O into *H and *V, in 1/72000" - units. Any syntax accepted by measure_paper() may be used. - - Destroys O. */ +/* Stores the paper size of the value of option O into *H and *V, in inches. + Any syntax accepted by measure_paper() may be used. */ void -parse_paper_size (struct driver_option *o, int *h, int *v) +parse_paper_size (struct driver_option o, double *h, double *v) { - if (o->value == NULL || !measure_paper (o->value, h, v)) - measure_paper (o->default_value, h, v); - driver_option_destroy (o); + if (!o.value || !measure_paper (o.value, h, v)) + measure_paper (o.default_value, h, v); } static int @@ -120,24 +85,18 @@ do_parse_boolean (const char *driver_name, const char *key, } /* Parses and return O's value as a Boolean value. "true" and "false", "yes" - and "no", "on" and "off", and "1" and "0" are acceptable boolean strings. - - Destroys O. */ + and "no", "on" and "off", and "1" and "0" are acceptable boolean strings. */ bool -parse_boolean (struct driver_option *o) +parse_boolean (struct driver_option o) { - bool retval; - - retval = do_parse_boolean (o->driver_name, o->name, o->default_value) > 0; - if (o->value != NULL) + bool retval = do_parse_boolean (o.driver_name, o.name, o.default_value) > 0; + if (o.value) { - int value = do_parse_boolean (o->driver_name, o->name, o->value); + int value = do_parse_boolean (o.driver_name, o.name, o.value); if (value >= 0) retval = value; } - driver_option_destroy (o); - return retval; } @@ -148,40 +107,31 @@ parse_boolean (struct driver_option *o) O has no user-specified value, then O's default value is treated the same way. If the default value still does not match, parse_enum() returns 0. - Example: parse_enum (o, "a", 1, "b", 2, NULL_SENTINEL) returns 1 if O's - value if "a", 2 if O's value is "b". - - Destroys O. */ + Example: parse_enum (o, "a", 1, "b", 2) returns 1 if O's value if "a", 2 if + O's value is "b". */ int -parse_enum (struct driver_option *o, ...) +(parse_enum) (struct driver_option o, ...) { va_list args; - int retval; - - retval = 0; va_start (args, o); + + int retval = 0; for (;;) { - const char *s; - int value; - - s = va_arg (args, const char *); - if (s == NULL) + const char *s = va_arg (args, const char *); + if (!s) { - if (o->value != NULL) + if (o.value) { - struct string choices; - int i; - - ds_init_empty (&choices); + struct string choices = DS_EMPTY_INITIALIZER; va_end (args); va_start (args, o); - for (i = 0; ; i++) + for (int i = 0; ; i++) { s = va_arg (args, const char *); - if (s == NULL) + if (!s) break; - value = va_arg (args, int); + va_arg (args, int); if (i > 0) ds_put_cstr (&choices, ", "); @@ -190,43 +140,39 @@ parse_enum (struct driver_option *o, ...) msg (MW, _("%s: `%s' is `%s' but one of the following " "is required: %s"), - o->driver_name, o->name, o->value, ds_cstr (&choices)); + o.driver_name, o.name, o.value, ds_cstr (&choices)); ds_destroy (&choices); } break; } - value = va_arg (args, int); - if (o->value != NULL && !strcmp (s, o->value)) + int value = va_arg (args, int); + if (o.value && !strcmp (s, o.value)) { retval = value; break; } - else if (!strcmp (s, o->default_value)) + else if (!strcmp (s, o.default_value)) retval = value; } va_end (args); - driver_option_destroy (o); return retval; } /* Parses O's value as an integer in the range MIN_VALUE to MAX_VALUE - (inclusive) and returns the integer. - - Destroys O. */ + (inclusive) and returns the integer. */ int -parse_int (struct driver_option *o, int min_value, int max_value) +parse_int (struct driver_option o, int min_value, int max_value) { - int retval = strtol (o->default_value, NULL, 0); + int retval = strtol (o.default_value, NULL, 0); - if (o->value != NULL) + if (o.value) { - int value; - char *tail; - errno = 0; - value = strtol (o->value, &tail, 0); - if (tail != o->value && *tail == '\0' && errno != ERANGE + + char *tail; + int value = strtol (o.value, &tail, 0); + if (tail != o.value && *tail == '\0' && errno != ERANGE && value >= min_value && value <= max_value) retval = value; else if (max_value == INT_MAX) @@ -234,68 +180,53 @@ parse_int (struct driver_option *o, int min_value, int max_value) if (min_value == 0) msg (MW, _("%s: `%s' is `%s' but a non-negative integer " "is required"), - o->driver_name, o->name, o->value); + o.driver_name, o.name, o.value); else if (min_value == 1) msg (MW, _("%s: `%s' is `%s' but a positive integer is " - "required"), o->driver_name, o->name, o->value); + "required"), o.driver_name, o.name, o.value); else if (min_value == INT_MIN) msg (MW, _("%s: `%s' is `%s' but an integer is required"), - o->driver_name, o->name, o->value); + o.driver_name, o.name, o.value); else msg (MW, _("%s: `%s' is `%s' but an integer greater " "than %d is required"), - o->driver_name, o->name, o->value, min_value - 1); + o.driver_name, o.name, o.value, min_value - 1); } else msg (MW, _("%s: `%s' is `%s' but an integer between %d and " "%d is required"), - o->driver_name, o->name, o->value, min_value, max_value); + o.driver_name, o.name, o.value, min_value, max_value); } - - driver_option_destroy (o); return retval; } /* Parses O's value as a dimension, as understood by measure_dimension(), and - returns its length in units of 1/72000". - - Destroys O. */ -int -parse_dimension (struct driver_option *o) + returns its length in inches. */ +double +parse_dimension (struct driver_option o) { - int retval; - - retval = (o->value != NULL ? measure_dimension (o->value) - : o->default_value != NULL ? measure_dimension (o->default_value) - : -1); - - driver_option_destroy (o); - return retval; + return (o.value ? measure_dimension (o.value) + : o.default_value ? measure_dimension (o.default_value) + : -1); } /* Parses O's value as a string and returns it as a malloc'd string that the - caller is responsible for freeing. - - Destroys O. */ + caller is responsible for freeing. */ char * -parse_string (struct driver_option *o) +parse_string (struct driver_option o) { - char *retval = xstrdup (o->value != NULL ? o->value : o->default_value); - driver_option_destroy (o); - return retval; + return xstrdup (o.value ? o.value : o.default_value); } static char * default_chart_file_name (const char *file_name) { - if (strcmp (file_name, "-")) - { - const char *extension = strrchr (file_name, '.'); - int stem_length = extension ? extension - file_name : strlen (file_name); - return xasprintf ("%.*s-#", stem_length, file_name); - } - else + if (!strcmp (file_name, "-")) return NULL; + + const char *extension = strrchr (file_name, '.'); + int stem_length = extension ? extension - file_name : strlen (file_name); + return xasprintf ("%.*s-#", stem_length, file_name); } /* Parses and returns a chart file name, or NULL if no charts should be output. @@ -303,41 +234,31 @@ default_chart_file_name (const char *file_name) which the client will presumably replace by a number as part of writing charts to separate files. - If O->value is "none", then this function returns NULL. + If o.value is "none", then this function returns NULL. - If O->value is non-NULL but not "none", returns a copy of that string (if it + If o.value is non-NULL but not "none", returns a copy of that string (if it contains '#'). - If O->value is NULL, then O's default_value should be the name of the main + If o.value is NULL, then O's default_value should be the name of the main output file. Returns NULL if default_value is "-", and otherwise returns a - copy of string string with its extension stripped off and "-#.png" appended. - - Destroys O. */ + copy of string string with its extension stripped off and "-#.png" + appended. */ char * -parse_chart_file_name (struct driver_option *o) +parse_chart_file_name (struct driver_option o) { - char *chart_file_name; - - if (o->value != NULL) + if (!o.value) + return default_chart_file_name (o.default_value); + else if (!strcmp (o.value, "none")) + return NULL; + else if (strchr (o.value, '#') != NULL) + return xstrdup (o.value); + else { - if (!strcmp (o->value, "none")) - chart_file_name = NULL; - else if (strchr (o->value, '#') != NULL) - chart_file_name = xstrdup (o->value); - else - { - msg (MW, _("%s: `%s' is `%s' but a file name that contains " - "`#' is required."), - o->driver_name, o->name, o->value); - chart_file_name = default_chart_file_name (o->default_value); - } + msg (MW, _("%s: `%s' is `%s' but a file name that contains " + "`#' is required."), + o.driver_name, o.name, o.value); + return default_chart_file_name (o.default_value); } - else - chart_file_name = default_chart_file_name (o->default_value); - - driver_option_destroy (o); - - return chart_file_name; } static int @@ -516,7 +437,7 @@ lookup_color_name (const char *s) return -1; } -static bool +bool parse_color__ (const char *s, struct cell_color *color) { /* #rrrrggggbbbb */ @@ -530,6 +451,7 @@ parse_color__ (const char *s, struct cell_color *color) color->r = r16 >> 8; color->g = g16 >> 8; color->b = b16 >> 8; + color->alpha = 255; return true; } @@ -542,6 +464,7 @@ parse_color__ (const char *s, struct cell_color *color) color->r = r; color->g = g; color->b = b; + color->alpha = 255; return true; } @@ -553,6 +476,7 @@ parse_color__ (const char *s, struct cell_color *color) color->r = r; color->g = g; color->b = b; + color->alpha = 255; return true; } @@ -564,17 +488,20 @@ parse_color__ (const char *s, struct cell_color *color) color->r = r; color->g = g; color->b = b; + color->alpha = 255; return true; } /* rgba(r,g,b,a), ignoring a. */ - if (sscanf (s, "rgba (%"SCNi8" , %"SCNi8" , %"SCNi8", %*f) %n", - &r, &g, &b, &len) == 3 + double alpha; + if (sscanf (s, "rgba (%"SCNi8" , %"SCNi8" , %"SCNi8", %lf) %n", + &r, &g, &b, &alpha, &len) == 4 && !s[len]) { color->r = r; color->g = g; color->b = b; + color->alpha = alpha <= 0 ? 0 : alpha >= 1 ? 255 : alpha * 255.0; return true; } @@ -584,6 +511,13 @@ parse_color__ (const char *s, struct cell_color *color) color->r = code >> 16; color->g = code >> 8; color->b = code; + color->alpha = 255; + return true; + } + + if (!strcmp (s, "transparent")) + { + *color = (struct cell_color) { .alpha = 0 }; return true; } @@ -592,22 +526,13 @@ parse_color__ (const char *s, struct cell_color *color) /* Parses and returns color information from O. */ struct cell_color -parse_color (struct driver_option *o) +parse_color (struct driver_option o) { - if (o->value) - { - struct cell_color color; - if (parse_color__ (o->value, &color)) - return color; - - msg (MW, _("%s: `%s' is `%s', which could not be parsed as a color"), - o->driver_name, o->name, o->value); - } - - struct cell_color color; - if (parse_color__ (o->default_value, &color)) - return color; - - return (struct cell_color) CELL_COLOR_BLACK; + struct cell_color color = CELL_COLOR_BLACK; + parse_color__ (o.default_value, &color); + if (o.value && !parse_color__ (o.value, &color)) + msg (MW, _("%s: `%s' is `%s', which could not be parsed as a color"), + o.driver_name, o.name, o.value); + return color; }