X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fval-labs.c;h=657bf5c735e8b2d59fc48ed7fb1868b394878da3;hb=0ef6ac022673935ef842a1059aad45b89d59f025;hp=c36ff28b414dc074e1095aed78859b58280fd1b8;hpb=cb4033020c8a24d573814e6ac9192046bffdccac;p=pspp-builds.git diff --git a/src/val-labs.c b/src/val-labs.c index c36ff28b..657bf5c7 100644 --- a/src/val-labs.c +++ b/src/val-labs.c @@ -14,76 +14,43 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #include #include #include #include "alloc.h" -#include "avl.h" #include "command.h" #include "error.h" +#include "hash.h" #include "lexer.h" #include "str.h" +#include "value-labels.h" #include "var.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) /* Declarations. */ -#undef DEBUGGING -/*#define DEBUGGING 1 */ -#include "debug-print.h" - -/* Variable list. */ -static struct variable **v; - -/* Number of variables. */ -static int nv; - static int do_value_labels (int); -static int verify_val_labs (int erase); -static int get_label (void); - -#if DEBUGGING -static void debug_print (void); -#endif +static int verify_val_labs (struct variable **vars, size_t var_cnt); +static void erase_labels (struct variable **vars, size_t var_cnt); +static int get_label (struct variable **vars, size_t var_cnt); /* Stubs. */ -static void -init (void) -{ - v = NULL; -} - -static void -done (void) -{ - free (v); -} - int cmd_value_labels (void) { - int code; - init (); - lex_match_id ("VALUE"); - lex_match_id ("LABELS"); - code = do_value_labels (1); - done (); - return code; + return do_value_labels (1); } int cmd_add_value_labels (void) { - int code; - lex_match_id ("ADD"); - lex_match_id ("VALUE"); - lex_match_id ("LABELS"); - code = do_value_labels (0); - done (); - return code; + return do_value_labels (0); } /* Do it. */ @@ -91,23 +58,38 @@ cmd_add_value_labels (void) static int do_value_labels (int erase) { + struct variable **vars; /* Variable list. */ + size_t var_cnt; /* Number of variables. */ + int parse_err=0; /* true if error parsing variables */ + lex_match ('/'); while (token != '.') { - parse_variables (NULL, &v, &nv, PV_SAME_TYPE); - if (!verify_val_labs (erase)) - return CMD_PART_SUCCESS_MAYBE; + parse_err = !parse_variables (default_dict, &vars, &var_cnt, + PV_SAME_TYPE) ; + if (var_cnt < 1) + { + free(vars); + return CMD_FAILURE; + } + if (!verify_val_labs (vars, var_cnt)) + goto lossage; + if (erase) + erase_labels (vars, var_cnt); while (token != '/' && token != '.') - if (!get_label ()) - return CMD_PART_SUCCESS_MAYBE; + if (!get_label (vars, var_cnt)) + goto lossage; if (token != '/') + { + free (vars); break; + } + lex_get (); - free (v); - v = NULL; + free (vars); } if (token != '.') @@ -116,89 +98,81 @@ do_value_labels (int erase) return CMD_TRAILING_GARBAGE; } -#if DEBUGGING - debug_print (); -#endif - return CMD_SUCCESS; + return parse_err ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS; + + lossage: + free (vars); + return CMD_PART_SUCCESS_MAYBE; } +/* Verifies that none of the VAR_CNT variables in VARS are long + string variables. */ static int -verify_val_labs (int erase) +verify_val_labs (struct variable **vars, size_t var_cnt) { - int i; + size_t i; - if (!nv) - return 1; - - for (i = 0; i < nv; i++) + for (i = 0; i < var_cnt; i++) { - struct variable *vp = v[i]; + struct variable *vp = vars[i]; - if (vp->type == ALPHA && vp->width > 8) + if (vp->type == ALPHA && vp->width > MAX_SHORT_STRING) { msg (SE, _("It is not possible to assign value labels to long " "string variables such as %s."), vp->name); return 0; } - - if (erase && v[i]->val_lab) - { - avl_destroy (vp->val_lab, free_val_lab); - vp->val_lab = NULL; - } } return 1; } -/* Parse all the labels for a particular set of variables and add the - specified labels to those variables. */ -static int -get_label (void) +/* Erases all the labels for the VAR_CNT variables in VARS. */ +static void +erase_labels (struct variable **vars, size_t var_cnt) { - int i; + size_t i; - /* Make sure there's some variables. */ - if (!nv) - { - if (token != T_STRING && token != T_NUM) - return 0; - lex_get (); - return 1; - } + /* Erase old value labels if desired. */ + for (i = 0; i < var_cnt; i++) + val_labs_clear (vars[i]->val_labs); +} +/* Parse all the labels for the VAR_CNT variables in VARS and add + the specified labels to those variables. */ +static int +get_label (struct variable **vars, size_t var_cnt) +{ /* Parse all the labels and add them to the variables. */ do { - struct value_label *label; - - /* Allocate label. */ - label = xmalloc (sizeof *label); - label->ref_count = nv; + union value value; + char *label; + size_t i; - /* Set label->v. */ - if (v[0]->type == ALPHA) + /* Set value. */ + if (vars[0]->type == ALPHA) { if (token != T_STRING) { - msg (SE, _("String expected for value.")); + lex_error (_("expecting string")); return 0; } - st_bare_pad_copy (label->v.s, ds_value (&tokstr), MAX_SHORT_STRING); + buf_copy_str_rpad (value.s, MAX_SHORT_STRING, ds_c_str (&tokstr)); } else { - if (token != T_NUM) + if (!lex_is_number ()) { - msg (SE, _("Number expected for value.")); + lex_error (_("expecting integer")); return 0; } - if (!lex_integer_p ()) + if (!lex_is_integer ()) msg (SW, _("Value label `%g' is not integer."), tokval); - label->v.f = tokval; + value.f = tokval; } - - /* Set label->s. */ lex_get (); + + /* Set label. */ if (!lex_force_string ()) return 0; if (ds_length (&tokstr) > 60) @@ -206,22 +180,10 @@ get_label (void) msg (SW, _("Truncating value label to 60 characters.")); ds_truncate (&tokstr, 60); } - label->s = xstrdup (ds_value (&tokstr)); + label = ds_c_str (&tokstr); - for (i = 0; i < nv; i++) - { - if (!v[i]->val_lab) - v[i]->val_lab = avl_create (NULL, val_lab_cmp, - (void *) (v[i]->width)); - - { - struct value_label *old; - - old = avl_replace (v[i]->val_lab, label); - if (old) - free_value_label (old); - } - } + for (i = 0; i < var_cnt; i++) + val_labs_replace (vars[i]->val_labs, value, label); lex_get (); } @@ -229,75 +191,3 @@ get_label (void) return 1; } - -#if DEBUGGING -static void -debug_print () -{ - int i; - - puts (_("Value labels:")); - for (i = 0; i < nvar; i++) - { - AVLtraverser *t = NULL; - struct value_label *val; - - printf (" %s\n", var[i]->name); - if (var[i]->val_lab) - if (var[i]->type == NUMERIC) - for (val = avltrav (var[i]->val_lab, &t); - val; val = avltrav (var[i]->val_lab, &t)) - printf (" %g: `%s'\n", val->v.f, val->s); - else - for (val = avltrav (var[i]->val_lab, &t); - val; val = avltrav (var[i]->val_lab, &t)) - printf (" `%.8s': `%s'\n", val->v.s, val->s); - else - printf (_(" (no value labels)\n")); - } -} -#endif /* DEBUGGING */ - -/* Compares two value labels and returns a strcmp()-type result. */ -int -val_lab_cmp (const void *a, const void *b, void *param) -{ - if ((int) param) - return strncmp (((struct value_label *) a)->v.s, - ((struct value_label *) b)->v.s, - (int) param); - else - { - int temp = (((struct value_label *) a)->v.f - - ((struct value_label *) b)->v.f); - if (temp > 0) - return 1; - else if (temp < 0) - return -1; - else - return 0; - } -} - -/* Callback function to increment the reference count for a value - label. */ -void * -inc_ref_count (void *pv, void *param unused) -{ - ((struct value_label *) pv)->ref_count++; - return pv; -} - -/* Copy the avl tree of value labels and return a pointer to the - copy. */ -avl_tree * -copy_value_labels (avl_tree *src) -{ - avl_tree *dest; - - if (src == NULL) - return NULL; - dest = avl_copy (NULL, src, inc_ref_count); - - return dest; -}