X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fvars-prs.c;h=920f8c9147ad2dee992b69588e929b90af399052;hb=d7b5d9144738a5a8989d45a01f4e458a78b68c0b;hp=2cc0236418c19c57f63031c3ed6ec458c518b045;hpb=4a4c003e2b2c01274b305e907fc63ba33d8481ae;p=pspp diff --git a/src/vars-prs.c b/src/vars-prs.c index 2cc0236418..920f8c9147 100644 --- a/src/vars-prs.c +++ b/src/vars-prs.c @@ -14,12 +14,13 @@ 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 "var.h" #include +#include #include #include "alloc.h" #include "bitvector.h" @@ -28,28 +29,35 @@ #include "hash.h" #include "lexer.h" #include "misc.h" +#include "size_max.h" #include "str.h" -/* Parses a name as a variable within VS and returns the - variable's index if successful. On failure emits an error - message and returns a null pointer. */ -static int -parse_vs_variable_idx (const struct var_set *vs) -{ - int idx; +#include "gettext.h" +#define _(msgid) gettext (msgid) +/* Parses a name as a variable within VS. Sets *IDX to the + variable's index and returns true if successful. On failure + emits an error message and returns false. */ +static bool +parse_vs_variable_idx (const struct var_set *vs, size_t *idx) +{ + assert (idx != NULL); + if (token != T_ID) { lex_error (_("expecting variable name")); - return -1; + return false; + } + else if (var_set_lookup_var_idx (vs, tokid, idx)) + { + lex_get (); + return true; + } + else + { + msg (SE, _("%s is not a variable name."), tokid); + return false; } - - idx = var_set_lookup_var_idx (vs, tokid); - if (idx < 0) - msg (SE, _("%s is not a variable name."), tokid); - lex_get (); - - return idx; } /* Parses a name as a variable within VS and returns the variable @@ -58,8 +66,8 @@ parse_vs_variable_idx (const struct var_set *vs) static struct variable * parse_vs_variable (const struct var_set *vs) { - int idx = parse_vs_variable_idx (vs); - return idx >= 0 ? var_set_get_var (vs, idx) : NULL; + size_t idx; + return parse_vs_variable_idx (vs, &idx) ? var_set_get_var (vs, idx) : NULL; } /* Parses a variable name in dictionary D and returns the @@ -83,41 +91,6 @@ parse_variable (void) return parse_dict_variable (default_dict); } -/* Returns the dictionary class corresponding to a variable named - NAME. */ -enum dict_class -dict_class_from_id (const char *name) -{ - assert (name != NULL); - - switch (name[0]) - { - default: - return DC_ORDINARY; - case '$': - return DC_SYSTEM; - case '#': - return DC_SCRATCH; - } -} - -/* Returns the name of dictionary class DICT_CLASS. */ -const char * -dict_class_to_name (enum dict_class dict_class) -{ - switch (dict_class) - { - case DC_ORDINARY: - return _("ordinary"); - case DC_SYSTEM: - return _("system"); - case DC_SCRATCH: - return _("scratch"); - default: - assert (0); - abort (); - } -} /* Parses a set of variables from dictionary D given options OPTS. Resulting list of variables stored in *VAR and the @@ -125,7 +98,7 @@ dict_class_to_name (enum dict_class dict_class) successful. */ int parse_variables (const struct dictionary *d, struct variable ***var, - int *cnt, int opts) + size_t *cnt, int opts) { struct var_set *vs; int success; @@ -134,7 +107,6 @@ parse_variables (const struct dictionary *d, struct variable ***var, assert (var != NULL); assert (cnt != NULL); - vs = var_set_create_from_dict (d); success = parse_var_set_vars (vs, var, cnt, opts); if ( success == 0 ) @@ -148,11 +120,10 @@ parse_variables (const struct dictionary *d, struct variable ***var, dictionary class, and returns nonzero. Returns zero on failure. */ static int -parse_var_idx_class (const struct var_set *vs, int *idx, +parse_var_idx_class (const struct var_set *vs, size_t *idx, enum dict_class *class) { - *idx = parse_vs_variable_idx (vs); - if (*idx < 0) + if (!parse_vs_variable_idx (vs, idx)) return 0; *class = dict_class_from_id (var_set_get_var (vs, *idx)->name); @@ -165,9 +136,9 @@ parse_var_idx_class (const struct var_set *vs, int *idx, PV_OPTS, which also affects what variables are allowed in appropriate ways. */ static void -add_variable (struct variable ***v, int *nv, int *mv, +add_variable (struct variable ***v, size_t *nv, size_t *mv, char *included, int pv_opts, - const struct var_set *vs, int idx) + const struct var_set *vs, size_t idx) { struct variable *add = var_set_get_var (vs, idx); @@ -193,7 +164,7 @@ add_variable (struct variable ***v, int *nv, int *mv, if (*nv >= *mv) { *mv = 2 * (*nv + 1); - *v = xrealloc (*v, *mv * sizeof **v); + *v = xnrealloc (*v, *mv, sizeof **v); } if ((pv_opts & PV_DUPLICATE) || !included[idx]) @@ -211,12 +182,12 @@ add_variable (struct variable ***v, int *nv, int *mv, duplicates if indicated by PV_OPTS, which also affects what variables are allowed in appropriate ways. */ static void -add_variables (struct variable ***v, int *nv, int *mv, char *included, +add_variables (struct variable ***v, size_t *nv, size_t *mv, char *included, int pv_opts, const struct var_set *vs, int first_idx, int last_idx, enum dict_class class) { - int i; + size_t i; for (i = first_idx; i <= last_idx; i++) if (dict_class_from_id (var_set_get_var (vs, i)->name) == class) @@ -228,10 +199,10 @@ add_variables (struct variable ***v, int *nv, int *mv, char *included, nonzero and *v is non-NULL. */ int parse_var_set_vars (const struct var_set *vs, - struct variable ***v, int *nv, + struct variable ***v, size_t *nv, int pv_opts) { - int mv; + size_t mv; char *included; assert (vs != NULL); @@ -258,16 +229,16 @@ parse_var_set_vars (const struct var_set *vs, if (!(pv_opts & PV_DUPLICATE)) { - int i; + size_t i; - included = xcalloc (var_set_get_cnt (vs)); + included = xcalloc (var_set_get_cnt (vs), sizeof *included); for (i = 0; i < *nv; i++) included[(*v)[i]->index] = 1; } else included = NULL; -if (lex_match (T_ALL)) + if (lex_match (T_ALL)) add_variables (v, nv, &mv, included, pv_opts, vs, 0, var_set_get_cnt (vs) - 1, DC_ORDINARY); else @@ -275,17 +246,16 @@ if (lex_match (T_ALL)) do { enum dict_class class; - int first_idx; + size_t first_idx; if (!parse_var_idx_class (vs, &first_idx, &class)) goto fail; if (!lex_match (T_TO)) - add_variable (v, nv, &mv, included, pv_opts, - vs, first_idx); + add_variable (v, nv, &mv, included, pv_opts, vs, first_idx); else { - int last_idx; + size_t last_idx; enum dict_class last_class; struct variable *first_var, *last_var; @@ -303,6 +273,7 @@ if (lex_match (T_ALL)) first_var->name, last_var->name); goto fail; } + if (class != last_class) { msg (SE, _("When using the TO keyword to specify several " @@ -385,14 +356,14 @@ extract_num (char *s, char *r, int *n, int *d) /* Parses a list of variable names according to the DATA LIST version of the TO convention. */ int -parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts) +parse_DATA_LIST_vars (char ***names, size_t *nnames, int pv_opts) { int n1, n2; int d1, d2; int n; - int nvar, mvar; - char *name1, *name2; - char *root1, *root2; + size_t nvar, mvar; + char name1[LONG_NAME_LEN + 1], name2[LONG_NAME_LEN + 1]; + char root1[LONG_NAME_LEN + 1], root2[LONG_NAME_LEN + 1]; int success = 0; assert (names != NULL); @@ -409,10 +380,6 @@ parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts) *names = NULL; } - name1 = xmalloc (4 * (SHORT_NAME_LEN + 1)); - name2 = &name1[1 * SHORT_NAME_LEN + 1]; - root1 = &name1[2 * SHORT_NAME_LEN + 1]; - root2 = &name1[3 * SHORT_NAME_LEN + 1]; do { if (token != T_ID) @@ -443,7 +410,7 @@ parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts) || !extract_num (name2, root2, &n2, &d2)) goto fail; - if (strcmp (root1, root2)) + if (strcasecmp (root1, root2)) { msg (SE, _("Prefixes don't match in use of TO convention.")); goto fail; @@ -459,13 +426,14 @@ parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts) if (mvar < nvar + (n2 - n1 + 1)) { mvar += ROUND_UP (n2 - n1 + 1, 16); - *names = xrealloc (*names, mvar * sizeof **names); + *names = xnrealloc (*names, mvar, sizeof **names); } for (n = n1; n <= n2; n++) { - (*names)[nvar] = xmalloc (SHORT_NAME_LEN + 1); - sprintf ((*names)[nvar], "%s%0*d", root1, d1, n); + char name[LONG_NAME_LEN + 1]; + sprintf (name, "%s%0*d", root1, d1, n); + (*names)[nvar] = xstrdup (name); nvar++; } } @@ -474,7 +442,7 @@ parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts) if (nvar >= mvar) { mvar += 16; - *names = xrealloc (*names, mvar * sizeof **names); + *names = xnrealloc (*names, mvar, sizeof **names); } (*names)[nvar++] = xstrdup (name1); } @@ -489,7 +457,6 @@ parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts) fail: *nnames = nvar; - free (name1); if (!success) { int i; @@ -506,9 +473,9 @@ fail: existing and the rest are to be created. Same args as parse_DATA_LIST_vars(). */ int -parse_mixed_vars (char ***names, int *nnames, int pv_opts) +parse_mixed_vars (char ***names, size_t *nnames, int pv_opts) { - int i; + size_t i; assert (names != NULL); assert (nnames != NULL); @@ -524,11 +491,11 @@ parse_mixed_vars (char ***names, int *nnames, int pv_opts) if (token == T_ALL || dict_lookup_var (default_dict, tokid) != NULL) { struct variable **v; - int nv; + size_t nv; if (!parse_variables (default_dict, &v, &nv, PV_NONE)) goto fail; - *names = xrealloc (*names, (*nnames + nv) * sizeof **names); + *names = xnrealloc (*names, *nnames + nv, sizeof **names); for (i = 0; i < nv; i++) (*names)[*nnames + i] = xstrdup (v[i]->name); free (v); @@ -553,7 +520,7 @@ struct var_set { size_t (*get_cnt) (const struct var_set *); struct variable *(*get_var) (const struct var_set *, size_t idx); - int (*lookup_var_idx) (const struct var_set *, const char *); + bool (*lookup_var_idx) (const struct var_set *, const char *, size_t *); void (*destroy) (struct var_set *); void *aux; }; @@ -583,20 +550,23 @@ var_set_get_var (const struct var_set *vs, size_t idx) struct variable * var_set_lookup_var (const struct var_set *vs, const char *name) { - int idx = var_set_lookup_var_idx (vs, name); - return idx >= 0 ? var_set_get_var (vs, idx) : NULL; + size_t idx; + return (var_set_lookup_var_idx (vs, name, &idx) + ? var_set_get_var (vs, idx) + : NULL); } -/* Returns the index in VS of the variable named NAME, or -1 if - VS contains no variable with that name. */ -int -var_set_lookup_var_idx (const struct var_set *vs, const char *name) +/* If VS contains a variable named NAME, sets *IDX to its index + and returns true. Otherwise, returns false. */ +bool +var_set_lookup_var_idx (const struct var_set *vs, const char *name, + size_t *idx) { assert (vs != NULL); assert (name != NULL); - assert (strlen (name) <= LONG_NAME_LEN ); + assert (strlen (name) <= LONG_NAME_LEN); - return vs->lookup_var_idx (vs, name); + return vs->lookup_var_idx (vs, name, idx); } /* Destroys VS. */ @@ -626,14 +596,21 @@ dict_var_set_get_var (const struct var_set *vs, size_t idx) return dict_get_var (d, idx); } -/* Returns the index of the variable in VS named NAME, or -1 if - VS contains no variable with that name. */ -static int -dict_var_set_lookup_var_idx (const struct var_set *vs, const char *name) +/* If VS contains a variable named NAME, sets *IDX to its index + and returns true. Otherwise, returns false. */ +static bool +dict_var_set_lookup_var_idx (const struct var_set *vs, const char *name, + size_t *idx) { struct dictionary *d = vs->aux; struct variable *v = dict_lookup_var (d, name); - return v != NULL ? v->index : -1; + if (v != NULL) + { + *idx = v->index; + return true; + } + else + return false; } /* Destroys VS. */ @@ -662,7 +639,6 @@ struct array_var_set struct variable *const *var;/* Array of variables. */ size_t var_cnt; /* Number of elements in var. */ struct hsh_table *name_tab; /* Hash from variable names to variables. */ - struct hsh_table *longname_tab; /* Hash of short names indexed by long names */ }; /* Returns the number of variables in VS. */ @@ -684,34 +660,25 @@ array_var_set_get_var (const struct var_set *vs, size_t idx) return (struct variable *) avs->var[idx]; } -/* Returns the index of the variable in VS named NAME, or -1 if - VS contains no variable with that name. */ -static int -array_var_set_lookup_var_idx (const struct var_set *vs, const char *name) +/* If VS contains a variable named NAME, sets *IDX to its index + and returns true. Otherwise, returns false. */ +static bool +array_var_set_lookup_var_idx (const struct var_set *vs, const char *name, + size_t *idx) { - char *short_name ; struct array_var_set *avs = vs->aux; struct variable v, *vp, *const *vpp; - struct name_table_entry key; - key.longname = name; - - struct name_table_entry *nte; - - assert (avs->longname_tab); - - - nte = hsh_find (avs->longname_tab, &key); - - if (!nte) - return -1; - - short_name = nte->name; - - strcpy (v.name, short_name); + strcpy (v.name, name); vp = &v; vpp = hsh_find (avs->name_tab, &vp); - return vpp != NULL ? vpp - avs->var : -1; + if (vpp != NULL) + { + *idx = vpp - avs->var; + return true; + } + else + return false; } /* Destroys VS. */ @@ -721,7 +688,6 @@ array_var_set_destroy (struct var_set *vs) struct array_var_set *avs = vs->aux; hsh_destroy (avs->name_tab); - hsh_destroy (avs->longname_tab); free (avs); free (vs); } @@ -744,36 +710,14 @@ var_set_create_from_array (struct variable *const *var, size_t var_cnt) avs->var = var; avs->var_cnt = var_cnt; avs->name_tab = hsh_create (2 * var_cnt, - compare_var_ptr_names, hash_var_ptr_name, - NULL, NULL); - - avs->longname_tab = hsh_create (2 * var_cnt, - compare_long_names, hash_long_name, - (hsh_free_func *) free_nte, - NULL); - + compare_var_ptr_names, hash_var_ptr_name, NULL, + NULL); for (i = 0; i < var_cnt; i++) - { - struct name_table_entry *nte ; - - if (hsh_insert (avs->name_tab, &var[i]) != NULL) - { - var_set_destroy (vs); - return NULL; - } - - nte = xmalloc (sizeof (*nte)); - nte->name = strdup(var[i]->name); - nte->longname = strdup(var[i]->longname); - - if (hsh_insert (avs->longname_tab, nte) != NULL) - { - var_set_destroy (vs); - free (nte); - return NULL; - } - - } - + if (hsh_insert (avs->name_tab, (void *) &var[i]) != NULL) + { + var_set_destroy (vs); + return NULL; + } + return vs; }