X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fvariable.c;h=fe4645ee41e1b7d7fad9042e5dc5014076ace03c;hb=refs%2Fbuilds%2F20130102032118%2Fpspp;hp=2ceeecd2717c86212378bc783b0fea293d80d6bc;hpb=46bb129a4fd2ee138775f622e21424e53a6002af;p=pspp diff --git a/src/data/variable.c b/src/data/variable.c index 2ceeecd271..fe4645ee41 100644 --- a/src/data/variable.c +++ b/src/data/variable.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012 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 @@ -54,6 +54,7 @@ struct variable struct fmt_spec write; /* Default format for WRITE. */ struct val_labs *val_labs; /* Value labels. */ char *label; /* Variable label. */ + struct string name_and_label; /* The name and label in the same string */ /* GUI information. */ enum measure measure; /* Nominal, ordinal, or continuous. */ @@ -91,9 +92,7 @@ var_create (const char *name, int width) assert (width >= 0 && width <= MAX_STRING); - v = xmalloc (sizeof *v); - v->vardict = NULL; - v->name = NULL; + v = xzalloc (sizeof *v); var_set_name (v, name); v->width = width; mv_init (&v->miss, width); @@ -103,13 +102,8 @@ var_create (const char *name, int width) v->measure = var_default_measure (type); v->display_width = var_default_display_width (width); v->print = v->write = var_default_formats (width); - v->val_labs = NULL; - v->label = NULL; - v->short_names = NULL; - v->short_name_cnt = 0; - v->aux = NULL; - v->aux_dtor = NULL; attrset_init (&v->attributes); + ds_init_empty (&v->name_and_label); return v; } @@ -160,6 +154,7 @@ var_destroy (struct variable *v) var_clear_label (v); attrset_destroy (var_get_attributes (v)); free (v->name); + ds_destroy (&v->name_and_label); free (v); } } @@ -173,6 +168,8 @@ var_get_name (const struct variable *v) return v->name; } + + /* Sets V's name to NAME, a UTF-8 encoded string. Do not use this function for a variable in a dictionary. Use dict_rename_var instead. */ @@ -184,6 +181,8 @@ var_set_name (struct variable *v, const char *name) free (v->name); v->name = xstrdup (name); + ds_destroy (&v->name_and_label); + ds_init_empty (&v->name_and_label); dict_var_changed (v); } @@ -202,7 +201,7 @@ compare_vars_by_name (const void *a_, const void *b_, const void *aux UNUSED) const struct variable *a = a_; const struct variable *b = b_; - return strcasecmp (a->name, b->name); + return utf8_strcasecmp (a->name, b->name); } /* A hsh_hash_func that hashes variable V based on its name. */ @@ -211,7 +210,7 @@ hash_var_by_name (const void *v_, const void *aux UNUSED) { const struct variable *v = v_; - return hash_case_string (v->name, 0); + return utf8_hash_case_string (v->name, 0); } /* A hsh_compare_func that orders pointers to variables A and B @@ -223,7 +222,7 @@ compare_var_ptrs_by_name (const void *a_, const void *b_, struct variable *const *a = a_; struct variable *const *b = b_; - return strcasecmp (var_get_name (*a), var_get_name (*b)); + return utf8_strcasecmp (var_get_name (*a), var_get_name (*b)); } /* A hsh_compare_func that orders pointers to variables A and B @@ -247,7 +246,7 @@ hash_var_ptr_by_name (const void *v_, const void *aux UNUSED) { struct variable *const *v = v_; - return hash_case_string (var_get_name (*v), 0); + return utf8_hash_case_string (var_get_name (*v), 0); } /* Returns the type of variable V. */ @@ -536,9 +535,12 @@ var_get_print_format (const struct variable *v) void var_set_print_format (struct variable *v, const struct fmt_spec *print) { - assert (fmt_check_width_compat (print, v->width)); - v->print = *print; - dict_var_changed (v); + if (!fmt_equal (&v->print, print)) + { + assert (fmt_check_width_compat (print, v->width)); + v->print = *print; + dict_var_changed (v); + } } /* Returns V's write format specification. */ @@ -555,9 +557,12 @@ var_get_write_format (const struct variable *v) void var_set_write_format (struct variable *v, const struct fmt_spec *write) { - assert (fmt_check_width_compat (write, v->width)); - v->write = *write; - dict_var_changed (v); + if (!fmt_equal (&v->write, write)) + { + assert (fmt_check_width_compat (write, v->width)); + v->write = *write; + dict_var_changed (v); + } } /* Sets V's print and write format specifications to FORMAT, @@ -582,14 +587,51 @@ var_default_formats (int width) ? fmt_for_output (FMT_F, 8, 2) : fmt_for_output (FMT_A, width, 0)); } + + + +/* Update the combined name and label string if necessary */ +static void +update_vl_string (const struct variable *v) +{ + /* Cast away const! */ + struct string *str = (struct string *) &v->name_and_label; + + if (ds_is_empty (str)) + { + if (v->label) + ds_put_format (str, _("%s (%s)"), v->label, v->name); + else + ds_put_cstr (str, v->name); + } +} + + /* Return a string representing this variable, in the form most appropriate from a human factors perspective, that is, its variable label if it has one, otherwise its name. */ const char * var_to_string (const struct variable *v) { - return v->label != NULL ? v->label : v->name; + enum settings_var_style style = settings_get_var_style (); + + switch (style) + { + case SETTINGS_VAR_STYLE_NAMES: + return v->name; + break; + case SETTINGS_VAR_STYLE_LABELS: + return v->label != NULL ? v->label : v->name; + break; + case SETTINGS_VAR_STYLE_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. */ @@ -641,6 +683,9 @@ var_set_label (struct variable *v, const char *label, bool issue_warning) v->label = ss_xstrdup (s); } + ds_destroy (&v->name_and_label); + ds_init_empty (&v->name_and_label); + dict_var_changed (v); return truncated; @@ -881,8 +926,7 @@ var_set_short_name (struct variable *var, size_t idx, const char *short_name) for (i = old_cnt; i < var->short_name_cnt; i++) var->short_names[i] = NULL; } - var->short_names[idx] = xstrdup (short_name); - str_uppercase (var->short_names[idx]); + var->short_names[idx] = utf8_to_upper (short_name); } dict_var_changed (var);