X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fvariable.c;h=2b0dd2579dc49c39a228755faff72fb57b060a9b;hb=42d90dac4bc5ee06ef0dd3cd62b84378f16e7ea9;hp=3e3c72a6bb7299eb7fb434f4feaed620ad0230f2;hpb=3dd0f6ae0d5eb73a2270a243e443c4ae03c2c16e;p=pspp diff --git a/src/data/variable.c b/src/data/variable.c index 3e3c72a6bb..2b0dd2579d 100644 --- a/src/data/variable.c +++ b/src/data/variable.c @@ -1,5 +1,6 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, + 2014, 2016, 2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,10 +43,47 @@ #include "gettext.h" #define _(msgid) gettext (msgid) +#define N_(msgid) (msgid) + +/* This should follow the definition in Gtk */ +typedef struct +{ + int value; + const char *name; + const char *label; +} GEnumValue; + +const GEnumValue align[] = + { + {ALIGN_LEFT, "left", N_("Left")}, + {ALIGN_RIGHT, "right", N_("Right")}, + {ALIGN_CENTRE, "center", N_("Center")}, + {0,0,0} + }; + +const GEnumValue measure[] = + { + {MEASURE_NOMINAL, "nominal", N_("Nominal")}, + {MEASURE_ORDINAL, "ordinal", N_("Ordinal")}, + {MEASURE_SCALE, "scale", N_("Scale")}, + {0,0,0} + }; + +const GEnumValue role[] = + { + {ROLE_INPUT, "input", N_("Input")}, + {ROLE_TARGET, "output", N_("Output")}, + {ROLE_BOTH, "both", N_("Both")}, + {ROLE_NONE, "none", N_("None")}, + {ROLE_PARTITION, "partition", N_("Partition")}, + {ROLE_SPLIT, "split", N_("Split")}, + {0,0,0} + }; /* A variable. */ struct variable { + int ref_cnt; /* Dictionary information. */ char *name; /* Variable name. Mixed case. */ int width; /* 0 for numeric, otherwise string width. */ @@ -109,28 +147,43 @@ var_create (const char *name, int width) attrset_init (&v->attributes); ds_init_empty (&v->name_and_label); + v->ref_cnt = 1; + return v; } /* Destroys variable V. V must not belong to a dictionary. If it does, use dict_delete_var instead. */ +static void +var_destroy__ (struct variable *v) +{ + assert (!var_has_vardict (v)); + mv_destroy (&v->miss); + var_clear_short_names (v); + val_labs_destroy (v->val_labs); + var_set_label_quiet (v, NULL); + attrset_destroy (var_get_attributes (v)); + free (v->name); + ds_destroy (&v->name_and_label); + free (v); +} + +struct variable * +var_ref (struct variable *v) +{ + v->ref_cnt++; + return v; +} + void -var_destroy (struct variable *v) +var_unref (struct variable *v) { - if (v != NULL) - { - assert (!var_has_vardict (v)); - mv_destroy (&v->miss); - var_clear_short_names (v); - val_labs_destroy (v->val_labs); - var_set_label_quiet (v, NULL); - attrset_destroy (var_get_attributes (v)); - free (v->name); - ds_destroy (&v->name_and_label); - free (v); - } + if (--v->ref_cnt == 0) + var_destroy__ (v); } + + /* Variable names. */ @@ -150,7 +203,6 @@ static void var_set_name_quiet (struct variable *v, const char *name) { assert (!var_has_vardict (v)); - assert (id_is_plausible (name, false)); free (v->name); v->name = xstrdup (name); @@ -523,46 +575,50 @@ append_value (const struct variable *v, const union value *value, struct string *str) { char *s = data_out (value, var_get_encoding (v), &v->print); - ds_put_cstr (str, s); + struct substring ss = ss_cstr (s); + ss_rtrim (&ss, ss_cstr (" ")); + ds_put_substring (str, ss); free (s); } -/* Append STR with a string representing VALUE for variable V. - That is, if VALUE has a label, append that label, - otherwise format VALUE and append the formatted string. - STR must be a pointer to an initialised struct string. -*/ void -var_append_value_name (const struct variable *v, const union value *value, - struct string *str) +var_append_value_name__ (const struct variable *v, const union value *value, + enum settings_value_show show, struct string *str) { - enum settings_value_style style = settings_get_value_style (); - const char *name = var_lookup_value_label (v, value); + const char *label = var_lookup_value_label (v, value); - switch (style) + switch (show) { - case SETTINGS_VAL_STYLE_VALUES: + case SETTINGS_VALUE_SHOW_VALUE: append_value (v, value, str); break; - case SETTINGS_VAL_STYLE_LABELS: - if (name == NULL) - append_value (v, value, str); + default: + case SETTINGS_VALUE_SHOW_LABEL: + if (label) + ds_put_cstr (str, label); else - ds_put_cstr (str, name); + append_value (v, value, str); break; - case SETTINGS_VAL_STYLE_BOTH: - default: + case SETTINGS_VALUE_SHOW_BOTH: append_value (v, value, str); - if (name != NULL) - { - ds_put_cstr (str, " ("); - ds_put_cstr (str, name); - ds_put_cstr (str, ")"); - } + if (label != NULL) + ds_put_format (str, " %s", label); break; - }; + } +} + +/* Append STR with a string representing VALUE for variable V. + That is, if VALUE has a label, append that label, + otherwise format VALUE and append the formatted string. + STR must be a pointer to an initialised struct string. +*/ +void +var_append_value_name (const struct variable *v, const union value *value, + struct string *str) +{ + var_append_value_name__ (v, value, settings_get_show_values (), str); } /* Print and write formats. */ @@ -685,24 +741,19 @@ update_vl_string (const struct variable *v) const char * var_to_string (const struct variable *v) { - enum settings_var_style style = settings_get_var_style (); - - switch (style) - { - case SETTINGS_VAR_STYLE_NAMES: + switch (settings_get_show_variables ()) + { + case SETTINGS_VALUE_SHOW_VALUE: return v->name; - break; - case SETTINGS_VAR_STYLE_LABELS: + + case SETTINGS_VALUE_SHOW_LABEL: + default: return v->label != NULL ? v->label : v->name; - break; - case SETTINGS_VAR_STYLE_BOTH: + + case SETTINGS_VALUE_SHOW_BOTH: update_vl_string (v); return ds_cstr (&v->name_and_label); - break; - default: - NOT_REACHED (); - break; - }; + } } /* Returns V's variable label, or a null pointer if it has none. */ @@ -767,24 +818,13 @@ measure_is_valid (enum measure m) return m == MEASURE_NOMINAL || m == MEASURE_ORDINAL || m == MEASURE_SCALE; } -/* Returns a string version of measurement level M, for display to a user. */ +/* Returns a string version of measurement level M, for display to a user. + The caller may translate the string by passing it to gettext(). */ const char * measure_to_string (enum measure m) { - switch (m) - { - case MEASURE_NOMINAL: - return _("Nominal"); - - case MEASURE_ORDINAL: - return _("Ordinal"); - - case MEASURE_SCALE: - return _("Scale"); - - default: - return "Invalid"; - } + assert (m == measure[m].value); + return measure[m].label; } /* Returns a string version of measurement level M, for use in PSPP command @@ -864,33 +904,13 @@ var_role_is_valid (enum var_role role) } } -/* Returns a string version of ROLE, for display to a user. */ +/* Returns a string version of ROLE, for display to a user. + The caller may translate the string by passing it to gettext(). */ const char * -var_role_to_string (enum var_role role) +var_role_to_string (enum var_role r) { - switch (role) - { - case ROLE_INPUT: - return _("Input"); - - case ROLE_TARGET: - return _("Output"); - - case ROLE_BOTH: - return _("Both"); - - case ROLE_NONE: - return _("None"); - - case ROLE_PARTITION: - return _("Partition"); - - case ROLE_SPLIT: - return _("Split"); - - default: - return "Invalid"; - } + assert (r == role[r].value); + return role[r].label; } /* Returns a string version of ROLE, for use in PSPP comamnd syntax. */ @@ -992,24 +1012,13 @@ alignment_is_valid (enum alignment a) return a == ALIGN_LEFT || a == ALIGN_RIGHT || a == ALIGN_CENTRE; } -/* Returns a string version of alignment A, for display to a user. */ +/* Returns a string version of alignment A, for display to a user. + The caller may translate the string by passing it to gettext(). */ const char * alignment_to_string (enum alignment a) { - switch (a) - { - case ALIGN_LEFT: - return _("Left"); - - case ALIGN_RIGHT: - return _("Right"); - - case ALIGN_CENTRE: - return _("Center"); - - default: - return "Invalid"; - } + assert (a == align[a].value); + return align[a].label; } /* Returns a string version of alignment A, for use in PSPP command syntax. */ @@ -1141,8 +1150,6 @@ var_set_short_name (struct variable *var, size_t idx, const char *short_name) { struct variable *ov = var_clone (var); - assert (short_name == NULL || id_is_plausible (short_name, false)); - /* Clear old short name numbered IDX, if any. */ if (idx < var->short_name_cnt) {