X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fexpressions%2Fevaluate.c;h=9318f94b56c5b2f12500f5625fe755d6c34b71f3;hb=44326932c8227c64a87f7a92ef16ce83c2fba2d4;hp=4283af25184ea858e42c617c48773a1ca550823b;hpb=393668423c1c9456fd82db6b30f25de078915da5;p=pspp-builds.git diff --git a/src/language/expressions/evaluate.c b/src/language/expressions/evaluate.c index 4283af25..9318f94b 100644 --- a/src/language/expressions/evaluate.c +++ b/src/language/expressions/evaluate.c @@ -1,6 +1,5 @@ /* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. - Written by Ben Pfaff . + Copyright (C) 1997-9, 2000, 2006, 2007 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 @@ -22,6 +21,7 @@ #include #include +#include #include #include "helpers.h" #include "evaluate.h" @@ -31,12 +31,19 @@ static void expr_evaluate (struct expression *e, const struct ccase *c, int case_idx, void *result) { + struct dataset *ds = e->ds; union operation_data *op = e->ops; double *ns = e->number_stack; - struct fixed_string *ss = e->string_stack; + struct substring *ss = e->string_stack; + + /* Without a dictionary/dataset, the expression can't refer to variables, + and you don't need to specify a case when you evaluate the + expression. With a dictionary/dataset, the expression can refer + to variables, so you must specify a case when you evaluate the + expression. */ + assert ((c != NULL) == (e->ds != NULL)); - assert ((c != NULL) == (e->dict != NULL)); pool_clear (e->eval_pool); for (;;) @@ -51,7 +58,7 @@ expr_evaluate (struct expression *e, const struct ccase *c, int case_idx, case OP_string: { - const struct fixed_string *s = &op++->string; + const struct substring *s = &op++->string; *ss++ = copy_string (e, s->string, s->length); } break; @@ -61,13 +68,13 @@ expr_evaluate (struct expression *e, const struct ccase *c, int case_idx, return; case OP_return_string: - *(struct fixed_string *) result = ss[-1]; + *(struct substring *) result = ss[-1]; return; #include "evaluate.inc" default: - abort (); + NOT_REACHED (); } } } @@ -82,75 +89,79 @@ expr_evaluate_num (struct expression *e, const struct ccase *c, int case_idx) return d; } - - void expr_evaluate_str (struct expression *e, const struct ccase *c, int case_idx, char *dst, size_t dst_size) { - struct fixed_string s; + struct substring s; assert (e->type == OP_string); assert ((dst == NULL) == (dst_size == 0)); expr_evaluate (e, c, case_idx, &s); - copy_mangle (dst, dst_size, s.string, s.length); + buf_copy_rpad (dst, dst_size, s.string, s.length); } #include #include int -cmd_debug_evaluate (void) +cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) { bool optimize = true; int retval = CMD_FAILURE; bool dump_postfix = false; - struct dictionary *d = NULL; + struct ccase *c = NULL; + struct dataset *ds = NULL; + struct expression *expr; for (;;) { - if (lex_match_id ("NOOPTIMIZE")) + struct dictionary *d = NULL; + if (lex_match_id (lexer, "NOOPTIMIZE")) optimize = 0; - else if (lex_match_id ("POSTFIX")) + else if (lex_match_id (lexer, "POSTFIX")) dump_postfix = 1; - else if (lex_match ('(')) + else if (lex_match (lexer, '(')) { char name[LONG_NAME_LEN + 1]; struct variable *v; size_t old_value_cnt; int width; - if (!lex_force_id ()) + if (!lex_force_id (lexer)) goto done; - strcpy (name, tokid); + strcpy (name, lex_tokid (lexer)); - lex_get (); - if (!lex_force_match ('=')) + lex_get (lexer); + if (!lex_force_match (lexer, '=')) goto done; - if (lex_is_number ()) + if (lex_is_number (lexer)) { width = 0; - fprintf (stderr, "(%s = %.2f)", name, tokval); + fprintf (stderr, "(%s = %.2f)", name, lex_tokval (lexer)); } - else if (token == T_STRING) + else if (lex_token (lexer) == T_STRING) { - width = ds_length (&tokstr); - fprintf (stderr, "(%s = \"%.2s\")", name, ds_c_str (&tokstr)); + width = ds_length (lex_tokstr (lexer)); + fprintf (stderr, "(%s = \"%.2s\")", name, ds_cstr (lex_tokstr (lexer))); } else { - lex_error (_("expecting number or string")); + lex_error (lexer, _("expecting number or string")); goto done; } - if (d == NULL) - d = dict_create (); - + if ( ds == NULL ) + { + ds = create_dataset (NULL, NULL, NULL); + d = dataset_dict (ds); + } + old_value_cnt = dict_get_next_value_idx (d); v = dict_create_var (d, name, width); if (v == NULL) @@ -162,35 +173,37 @@ cmd_debug_evaluate (void) if (c == NULL) { c = xmalloc (sizeof *c); - case_nullify (c); + case_create (c, dict_get_next_value_idx (d)); } - case_resize (c, old_value_cnt, dict_get_next_value_idx (d)); + else + case_resize (c, dict_get_next_value_idx (d)); - if (lex_is_number ()) - case_data_rw (c, v->fv)->f = tokval; + if (lex_is_number (lexer)) + case_data_rw (c, v)->f = lex_tokval (lexer); else - memcpy (case_data_rw (c, v->fv)->s, ds_data (&tokstr), - v->width); - lex_get (); + memcpy (case_data_rw (c, v)->s, ds_data (lex_tokstr (lexer)), + var_get_width (v)); + lex_get (lexer); - if (!lex_force_match (')')) + if (!lex_force_match (lexer, ')')) goto done; } else break; } - if (token != '/') + if (lex_token (lexer) != '/') { - lex_force_match ('/'); + lex_force_match (lexer, '/'); goto done; } - if (d != NULL) - fprintf (stderr, "; "); - fprintf (stderr, "%s => ", lex_rest_of_line (NULL)); - lex_get (); - expr = expr_parse_any (d, optimize); - if (!expr || lex_end_of_command () != CMD_SUCCESS) + if ( ds != NULL ) + fprintf(stderr, "; "); + fprintf (stderr, "%s => ", lex_rest_of_line (lexer, NULL)); + lex_get (lexer); + + expr = expr_parse_any (lexer, ds, optimize); + if (!expr || lex_end_of_command (lexer) != CMD_SUCCESS) { if (expr != NULL) expr_free (expr); @@ -223,7 +236,7 @@ cmd_debug_evaluate (void) case OP_string: { - struct fixed_string s; + struct substring s; expr_evaluate (expr, c, 0, &s); fputc ('"', stderr); @@ -233,19 +246,22 @@ cmd_debug_evaluate (void) } default: - assert (0); + NOT_REACHED (); } expr_free (expr); retval = CMD_SUCCESS; done: + if (ds) + destroy_dataset (ds); + if (c != NULL) { case_destroy (c); free (c); } - dict_destroy (d); + return retval; } @@ -285,21 +301,23 @@ expr_debug_print_postfix (const struct expression *e) op->string.string != NULL ? op->string.string : ""); break; case OP_format: - fprintf (stderr, "f<%s%d.%d>", - formats[op->format->type].name, - op->format->w, op->format->d); + { + char str[FMT_STRING_LEN_MAX + 1]; + fmt_to_string (op->format, str); + fprintf (stderr, "f<%s>", str); + } break; case OP_variable: - fprintf (stderr, "v<%s>", op->variable->name); + fprintf (stderr, "v<%s>", var_get_name (op->variable)); break; case OP_vector: - fprintf (stderr, "vec<%s>", op->vector->name); + fprintf (stderr, "vec<%s>", vector_get_name (op->vector)); break; case OP_integer: fprintf (stderr, "i<%d>", op->integer); break; default: - abort (); + NOT_REACHED (); } } fprintf (stderr, "\n");