X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Fvariable-parser.c;h=2de98829bbc06f828eabc12299469e098612a65a;hb=02c64395051af942e9aeff20de6685c706ef1023;hp=904ebe755f43104b92c9267fd49a13ac7c6395a6;hpb=255b128bd64df42632d2a509bd9436f0163539d6;p=pspp-builds.git diff --git a/src/language/lexer/variable-parser.c b/src/language/lexer/variable-parser.c index 904ebe75..2de98829 100644 --- a/src/language/lexer/variable-parser.c +++ b/src/language/lexer/variable-parser.c @@ -79,7 +79,7 @@ parse_vs_variable (const struct var_set *vs) variable if successful. On failure emits an error message and returns a null pointer. */ struct variable * -parse_dict_variable (const struct dictionary *d) +parse_variable (const struct dictionary *d) { struct var_set *vs = var_set_create_from_dict (d); struct variable *var = parse_vs_variable (vs); @@ -87,21 +87,11 @@ parse_dict_variable (const struct dictionary *d) return var; } -/* Parses a variable name in default_dict and returns the - variable if successful. On failure emits an error message and - returns a null pointer. */ -struct variable * -parse_variable (void) -{ - return parse_dict_variable (default_dict); -} - - /* Parses a set of variables from dictionary D given options OPTS. Resulting list of variables stored in *VAR and the - number of variables into *CNT. Returns nonzero only if + number of variables into *CNT. Returns true only if successful. */ -int +bool parse_variables (const struct dictionary *d, struct variable ***var, size_t *cnt, int opts) { @@ -120,19 +110,42 @@ parse_variables (const struct dictionary *d, struct variable ***var, return success; } +/* Parses a set of variables from dictionary D given options + OPTS. Resulting list of variables stored in *VARS and the + number of variables into *VAR_CNT. Returns true only if + successful. Same behavior as parse_variables, except that all + allocations are taken from the given POOL. */ +bool +parse_variables_pool (struct pool *pool, const struct dictionary *dict, + struct variable ***vars, size_t *var_cnt, int opts) +{ + int retval; + + /* PV_APPEND is unsafe because parse_variables would free the + existing names on failure, but those names are presumably + already in the pool, which would attempt to re-free it + later. */ + assert (!(opts & PV_APPEND)); + + retval = parse_variables (dict, vars, var_cnt, opts); + if (retval) + pool_register (pool, free, *vars); + return retval; +} + /* Parses a variable name from VS. If successful, sets *IDX to the variable's index in VS, *CLASS to the variable's - dictionary class, and returns nonzero. Returns zero on + dictionary class, and returns true. Returns false on failure. */ -static int +static bool parse_var_idx_class (const struct var_set *vs, size_t *idx, enum dict_class *class) { if (!parse_vs_variable_idx (vs, idx)) - return 0; + return false; *class = dict_class_from_id (var_set_get_var (vs, *idx)->name); - return 1; + return true; } /* Add the variable from VS with index IDX to the list of @@ -195,10 +208,10 @@ add_variables (struct variable ***v, size_t *nv, size_t *mv, char *included, add_variable (v, nv, mv, included, pv_opts, vs, i); } -/* Note that if parse_variables() returns 0, *v is free()'d. - Conversely, if parse_variables() returns non-zero, then *nv is +/* Note that if parse_variables() returns false, *v is free()'d. + Conversely, if parse_variables() returns true, then *nv is nonzero and *v is non-NULL. */ -int +bool parse_var_set_vars (const struct var_set *vs, struct variable ***v, size_t *nv, int pv_opts) @@ -358,7 +371,7 @@ 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 +bool parse_DATA_LIST_vars (char ***names, size_t *nnames, int pv_opts) { int n1, n2; @@ -472,11 +485,46 @@ fail: return success; } +/* Registers each of the NAMES[0...NNAMES - 1] in POOL, as well + as NAMES itself. */ +static void +register_vars_pool (struct pool *pool, char **names, size_t nnames) +{ + size_t i; + + for (i = 0; i < nnames; i++) + pool_register (pool, free, names[i]); + pool_register (pool, free, names); +} + +/* Parses a list of variable names according to the DATA LIST + version of the TO convention. Same args as + parse_DATA_LIST_vars(), except that all allocations are taken + from the given POOL. */ +bool +parse_DATA_LIST_vars_pool (struct pool *pool, + char ***names, size_t *nnames, int pv_opts) +{ + int retval; + + /* PV_APPEND is unsafe because parse_DATA_LIST_vars would free + the existing names on failure, but those names are + presumably already in the pool, which would attempt to + re-free it later. */ + assert (!(pv_opts & PV_APPEND)); + + retval = parse_DATA_LIST_vars (names, nnames, pv_opts); + if (retval) + register_vars_pool (pool, *names, *nnames); + return retval; +} + /* Parses a list of variables where some of the variables may be existing and the rest are to be created. Same args as parse_DATA_LIST_vars(). */ -int -parse_mixed_vars (char ***names, size_t *nnames, int pv_opts) +bool +parse_mixed_vars (const struct dictionary *dict, + char ***names, size_t *nnames, int pv_opts) { size_t i; @@ -491,12 +539,12 @@ parse_mixed_vars (char ***names, size_t *nnames, int pv_opts) } while (token == T_ID || token == T_ALL) { - if (token == T_ALL || dict_lookup_var (default_dict, tokid) != NULL) + if (token == T_ALL || dict_lookup_var (dict, tokid) != NULL) { struct variable **v; size_t nv; - if (!parse_variables (default_dict, &v, &nv, PV_NONE)) + if (!parse_variables (dict, &v, &nv, PV_NONE)) goto fail; *names = xnrealloc (*names, *nnames + nv, sizeof **names); for (i = 0; i < nv; i++) @@ -520,24 +568,25 @@ fail: /* Parses a list of variables where some of the variables may be existing and the rest are to be created. Same args as - parse_DATA_LIST_vars(), except that all allocations are taken + parse_mixed_vars(), except that all allocations are taken from the given POOL. */ -int -parse_mixed_vars_pool (struct pool *pool, +bool +parse_mixed_vars_pool (const struct dictionary *dict, struct pool *pool, char ***names, size_t *nnames, int pv_opts) { - int retval = parse_mixed_vars (names, nnames, pv_opts); - if (retval) - { - size_t i; + int retval; - for (i = 0; i < *nnames; i++) - pool_register (pool, free, (*names)[i]); - pool_register (pool, free, *names); - } + /* PV_APPEND is unsafe because parse_mixed_vars_pool would free + the existing names on failure, but those names are + presumably already in the pool, which would attempt to + re-free it later. */ + assert (!(pv_opts & PV_APPEND)); + + retval = parse_mixed_vars (dict, names, nnames, pv_opts); + if (retval) + register_vars_pool (pool, *names, *nnames); return retval; } - /* A set of variables. */ struct var_set