/* PSPP - computes sample statistics.
- Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
Written by Ben Pfaff <blp@gnu.org>.
This program is free software; you can redistribute it and/or
#include <ctype.h>
#include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
#include <libpspp/message.h>
#include "helpers.h"
#include "evaluate.h"
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 (;;)
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;
return;
case OP_return_string:
- *(struct fixed_string *) result = ss[-1];
+ *(struct substring *) result = ss[-1];
return;
#include "evaluate.inc"
default:
- abort ();
+ NOT_REACHED ();
}
}
}
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);
}
\f
#include <language/lexer/lexer.h>
#include <language/command.h>
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 ();
+ d = dataset_dict (ds);
+ }
old_value_cnt = dict_get_next_value_idx (d);
v = dict_create_var (d, name, width);
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, old_value_cnt, 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->fv)->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->fv)->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);
case OP_string:
{
- struct fixed_string s;
+ struct substring s;
expr_evaluate (expr, c, 0, &s);
fputc ('"', stderr);
}
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;
}
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, "i<%d>", op->integer);
break;
default:
- abort ();
+ NOT_REACHED ();
}
}
fprintf (stderr, "\n");