X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fcompute.c;h=37592c885862c4b4d64064e251411ea5b3a06f9b;hb=d5fd364b203a2a84e5034b6ff5ac5d6c4412edb7;hp=2152b6db1a71e5addcd30cad2a56b2c1860656f4;hpb=05e356b2a3087e819ef3b5388e29c822f41502e1;p=pspp-builds.git diff --git a/src/compute.c b/src/compute.c index 2152b6db..37592c88 100644 --- a/src/compute.c +++ b/src/compute.c @@ -14,8 +14,8 @@ 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 "error.h" @@ -31,6 +31,9 @@ #include "str.h" #include "var.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + struct compute_trns; struct lvalue; @@ -38,7 +41,7 @@ struct lvalue; vector element. */ static struct lvalue *lvalue_parse (void); static int lvalue_get_type (const struct lvalue *); -static int lvalue_is_vector (const struct lvalue *); +static bool lvalue_is_vector (const struct lvalue *); static void lvalue_finalize (struct lvalue *, struct compute_trns *); static void lvalue_destroy (struct lvalue *); @@ -46,8 +49,6 @@ static void lvalue_destroy (struct lvalue *); /* COMPUTE and IF transformation. */ struct compute_trns { - struct trns_header h; - /* Test expression (IF only). */ struct expression *test; /* Test expression. */ @@ -64,10 +65,10 @@ struct compute_trns struct expression *rvalue; /* Rvalue expression. */ }; -static int parse_rvalue_expression (struct compute_trns *, - const struct lvalue *); +static struct expression *parse_rvalue (const struct lvalue *); static struct compute_trns *compute_trns_create (void); -static void compute_trns_free (struct trns_header *); +static trns_proc_func *get_proc_func (const struct lvalue *); +static trns_free_func compute_trns_free; /* COMPUTE. */ @@ -77,28 +78,27 @@ cmd_compute (void) struct lvalue *lvalue = NULL; struct compute_trns *compute = NULL; + compute = compute_trns_create (); + lvalue = lvalue_parse (); if (lvalue == NULL) goto fail; - compute = compute_trns_create (); - - if (!lex_force_match ('=') || !parse_rvalue_expression (compute, lvalue)) + if (!lex_force_match ('=')) + goto fail; + compute->rvalue = parse_rvalue (lvalue); + if (compute->rvalue == NULL) goto fail; - lvalue_finalize (lvalue, compute); + add_transformation (get_proc_func (lvalue), compute_trns_free, compute); - add_transformation (&compute->h); + lvalue_finalize (lvalue, compute); - return CMD_SUCCESS; + return lex_end_of_command (); fail: lvalue_destroy (lvalue); - if (compute != NULL) - { - compute_trns_free (&compute->h); - free (compute); - } + compute_trns_free (compute); return CMD_FAILURE; } @@ -106,10 +106,9 @@ cmd_compute (void) /* Handle COMPUTE or IF with numeric target variable. */ static int -compute_num (struct trns_header *compute_, struct ccase *c, - int case_num) +compute_num (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -122,10 +121,9 @@ compute_num (struct trns_header *compute_, struct ccase *c, /* Handle COMPUTE or IF with numeric vector element target variable. */ static int -compute_num_vec (struct trns_header *compute_, struct ccase *c, - int case_num) +compute_num_vec (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -155,10 +153,9 @@ compute_num_vec (struct trns_header *compute_, struct ccase *c, /* Handle COMPUTE or IF with string target variable. */ static int -compute_str (struct trns_header *compute_, struct ccase *c, - int case_num) +compute_str (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -171,10 +168,9 @@ compute_str (struct trns_header *compute_, struct ccase *c, /* Handle COMPUTE or IF with string vector element target variable. */ static int -compute_str_vec (struct trns_header *compute_, struct ccase *c, - int case_num) +compute_str_vec (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -229,56 +225,45 @@ cmd_if (void) goto fail; /* Rvalue expression. */ - if (!lex_force_match ('=') || !parse_rvalue_expression (compute, lvalue)) + if (!lex_force_match ('=')) + goto fail; + compute->rvalue = parse_rvalue (lvalue); + if (compute->rvalue == NULL) goto fail; - lvalue_finalize (lvalue, compute); + add_transformation (get_proc_func (lvalue), compute_trns_free, compute); - add_transformation (&compute->h); + lvalue_finalize (lvalue, compute); - return CMD_SUCCESS; + return lex_end_of_command (); fail: lvalue_destroy (lvalue); - if (compute != NULL) - { - compute_trns_free (&compute->h); - free (compute); - } + compute_trns_free (compute); return CMD_FAILURE; } /* Code common to COMPUTE and IF. */ -/* Checks for type mismatches on transformation C. Also checks for - command terminator, sets the case-handling proc from the array - passed. */ -static int -parse_rvalue_expression (struct compute_trns *compute, - const struct lvalue *lvalue) +static trns_proc_func * +get_proc_func (const struct lvalue *lvalue) { - int type = lvalue_get_type (lvalue); - int vector = lvalue_is_vector (lvalue); + bool is_numeric = lvalue_get_type (lvalue) == NUMERIC; + bool is_vector = lvalue_is_vector (lvalue); - assert (type == NUMERIC || type == ALPHA); - - compute->rvalue = expr_parse (default_dict, - type == ALPHA ? EXPR_STRING : EXPR_NUMBER); - if (compute->rvalue == NULL) - return 0; + return (is_numeric + ? (is_vector ? compute_num_vec : compute_num) + : (is_vector ? compute_str_vec : compute_str)); +} - if (type == NUMERIC) - compute->h.proc = vector ? compute_num_vec : compute_num; - else - compute->h.proc = vector ? compute_str_vec : compute_str; +/* Parses and returns an rvalue expression of the same type as + LVALUE, or a null pointer on failure. */ +static struct expression * +parse_rvalue (const struct lvalue *lvalue) +{ + bool is_numeric = lvalue_get_type (lvalue) == NUMERIC; - if (token != '.') - { - lex_error (_("expecting end of command")); - return 0; - } - - return 1; + return expr_parse (default_dict, is_numeric ? EXPR_NUMBER : EXPR_STRING); } /* Returns a new struct compute_trns after initializing its fields. */ @@ -286,8 +271,6 @@ static struct compute_trns * compute_trns_create (void) { struct compute_trns *compute = xmalloc (sizeof *compute); - compute->h.proc = NULL; - compute->h.free = compute_trns_free; compute->test = NULL; compute->variable = NULL; compute->vector = NULL; @@ -298,13 +281,17 @@ compute_trns_create (void) /* Deletes all the fields in COMPUTE. */ static void -compute_trns_free (struct trns_header *compute_) +compute_trns_free (void *compute_) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; - expr_free (compute->test); - expr_free (compute->element); - expr_free (compute->rvalue); + if (compute != NULL) + { + expr_free (compute->test); + expr_free (compute->element); + expr_free (compute->rvalue); + free (compute); + } } /* COMPUTE or IF target variable or vector element. */ @@ -315,7 +302,7 @@ struct lvalue struct expression *element; /* Destination vector element, or NULL. */ }; -/* Parses the target variable or vector elector into a new +/* Parses the target variable or vector element into a new `struct lvalue', which is returned. */ static struct lvalue * lvalue_parse (void) @@ -353,8 +340,7 @@ lvalue_parse (void) else { /* Variable name. */ - strncpy (lvalue->var_name, tokid, LONG_NAME_LEN); - lvalue->var_name[LONG_NAME_LEN] = '\0'; + str_copy_trunc (lvalue->var_name, sizeof lvalue->var_name, tokid); lex_get (); } return lvalue; @@ -371,8 +357,7 @@ lvalue_get_type (const struct lvalue *lvalue) { if (lvalue->vector == NULL) { - struct variable *var - = dict_lookup_var (default_dict, lvalue->var_name); + struct variable *var = dict_lookup_var (default_dict, lvalue->var_name); if (var == NULL) return NUMERIC; else @@ -383,7 +368,7 @@ lvalue_get_type (const struct lvalue *lvalue) } /* Returns nonzero if LVALUE has a vector as its target. */ -static int +static bool lvalue_is_vector (const struct lvalue *lvalue) { return lvalue->vector != NULL; @@ -392,8 +377,7 @@ lvalue_is_vector (const struct lvalue *lvalue) /* Finalizes making LVALUE the target of COMPUTE, by creating the target variable if necessary and setting fields in COMPUTE. */ static void -lvalue_finalize (struct lvalue *lvalue, - struct compute_trns *compute) +lvalue_finalize (struct lvalue *lvalue, struct compute_trns *compute) { if (lvalue->vector == NULL) { @@ -423,8 +407,8 @@ lvalue_finalize (struct lvalue *lvalue, static void lvalue_destroy (struct lvalue *lvalue) { - if ( ! lvalue ) - return ; + if (lvalue == NULL) + return; expr_free (lvalue->element); free (lvalue);