From: Ben Pfaff Date: Sun, 24 May 2009 18:26:41 +0000 (-0700) Subject: New function parse_value() for parsing a value of specified width. X-Git-Tag: v0.7.3~79 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp-builds.git;a=commitdiff_plain;h=e588208caf725f595d63a07ddd2116331173e81d New function parse_value() for parsing a value of specified width. Occasionally a value of a given width needs to be parsed from syntax. This commit adds a helper function for doing so and modifies a few pieces of code to use it. Probably there are other places where it would be useful that could not easily be found with "grep". This commit also renames the range-parser code to value-parser and puts the new function in there, as a natural generalization. Suggested by John Darrington. --- diff --git a/src/language/dictionary/missing-values.c b/src/language/dictionary/missing-values.c index 950abc15..66e642eb 100644 --- a/src/language/dictionary/missing-values.c +++ b/src/language/dictionary/missing-values.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009 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 published by @@ -26,8 +26,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/src/language/expressions/evaluate.c b/src/language/expressions/evaluate.c index d5f5f387..ad108f5a 100644 --- a/src/language/expressions/evaluate.c +++ b/src/language/expressions/evaluate.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "xalloc.h" @@ -174,11 +175,8 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) else c = case_unshare_and_resize (c, dict_get_proto (d)); - if (lex_is_number (lexer)) - case_data_rw (c, v)->f = lex_tokval (lexer); - else - memcpy (case_str_rw (c, v), ds_data (lex_tokstr (lexer)), - var_get_width (v)); + if (!parse_value (lexer, case_data_rw (c, v), var_get_width (v))) + NOT_REACHED (); lex_get (lexer); if (!lex_force_match (lexer, ')')) diff --git a/src/language/lexer/automake.mk b/src/language/lexer/automake.mk index 0ce371af..aff3f2a2 100644 --- a/src/language/lexer/automake.mk +++ b/src/language/lexer/automake.mk @@ -7,8 +7,8 @@ language_lexer_sources = \ src/language/lexer/subcommand-list.h \ src/language/lexer/format-parser.c \ src/language/lexer/format-parser.h \ - src/language/lexer/range-parser.c \ - src/language/lexer/range-parser.h \ + src/language/lexer/value-parser.c \ + src/language/lexer/value-parser.h \ src/language/lexer/variable-parser.c \ src/language/lexer/variable-parser.h diff --git a/src/language/lexer/range-parser.c b/src/language/lexer/range-parser.c deleted file mode 100644 index 4cf21cf0..00000000 --- a/src/language/lexer/range-parser.c +++ /dev/null @@ -1,121 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2005, 2006 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 published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include -#include "range-parser.h" -#include -#include -#include -#include "lexer.h" -#include -#include -#include - -#include "gettext.h" -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -static bool parse_number (struct lexer *, double *, const enum fmt_type *); - -/* Parses and stores a numeric value, or a range of the form "x - THRU y". Open-ended ranges may be specified as "LO(WEST) THRU - y" or "x THRU HI(GHEST)". Sets *X and *Y to the range or the - value and returns success. - - Numeric values are always accepted. If FORMAT is nonnull, - then string values are also accepted, and converted to numeric - values using *FORMAT. */ -bool -parse_num_range (struct lexer *lexer, - double *x, double *y, const enum fmt_type *format) -{ - if (lex_match_id (lexer, "LO") || lex_match_id (lexer, "LOWEST")) - *x = LOWEST; - else if (!parse_number (lexer, x, format)) - return false; - - if (lex_match_id (lexer, "THRU")) - { - if (lex_match_id (lexer, "HI") || lex_match_id (lexer, "HIGHEST")) - *y = HIGHEST; - else if (!parse_number (lexer, y, format)) - return false; - - if (*y < *x) - { - double t; - msg (SW, _("Low end of range (%g) is below high end (%g). " - "The range will be treated as reversed."), - *x, *y); - t = *x; - *x = *y; - *y = t; - } - else if (*x == *y) - msg (SW, _("Ends of range are equal (%g)."), *x); - - return true; - } - else - { - if (*x == LOWEST) - { - msg (SE, _("LO or LOWEST must be part of a range.")); - return false; - } - *y = *x; - } - - return true; -} - -/* Parses a number and stores it in *X. Returns success. - - Numeric values are always accepted. If FORMAT is nonnull, - then string values are also accepted, and converted to numeric - values using *FORMAT. */ -static bool -parse_number (struct lexer *lexer, double *x, const enum fmt_type *format) -{ - if (lex_is_number (lexer)) - { - *x = lex_number (lexer); - lex_get (lexer); - return true; - } - else if (lex_token (lexer) == T_STRING && format != NULL) - { - union value v; - data_in (ds_ss (lex_tokstr (lexer)), LEGACY_NATIVE, - *format, 0, 0, 0, &v, 0); - lex_get (lexer); - *x = v.f; - if (*x == SYSMIS) - { - msg (SE, _("System-missing value is not valid here.")); - return false; - } - return true; - } - else - { - if (format != NULL) - lex_error (lexer, _("expecting number or data string")); - else - lex_force_num (lexer); - return false; - } -} diff --git a/src/language/lexer/range-parser.h b/src/language/lexer/range-parser.h deleted file mode 100644 index 8cff0e1c..00000000 --- a/src/language/lexer/range-parser.h +++ /dev/null @@ -1,27 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2005 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 published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef RANGE_PRS_H -#define RANGE_PRS_H 1 - -#include - -struct lexer; -enum fmt_type; -bool parse_num_range (struct lexer *, - double *x, double *y, const enum fmt_type *fmt); - -#endif /* range-prs.h */ diff --git a/src/language/lexer/value-parser.c b/src/language/lexer/value-parser.c new file mode 100644 index 00000000..2cf9cf2b --- /dev/null +++ b/src/language/lexer/value-parser.c @@ -0,0 +1,145 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2005, 2006, 2009 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 published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "value-parser.h" +#include +#include +#include +#include "lexer.h" +#include +#include +#include + +#include "gettext.h" +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + +static bool parse_number (struct lexer *, double *, const enum fmt_type *); + +/* Parses and stores a numeric value, or a range of the form "x + THRU y". Open-ended ranges may be specified as "LO(WEST) THRU + y" or "x THRU HI(GHEST)". Sets *X and *Y to the range or the + value and returns success. + + Numeric values are always accepted. If FORMAT is nonnull, + then string values are also accepted, and converted to numeric + values using *FORMAT. */ +bool +parse_num_range (struct lexer *lexer, + double *x, double *y, const enum fmt_type *format) +{ + if (lex_match_id (lexer, "LO") || lex_match_id (lexer, "LOWEST")) + *x = LOWEST; + else if (!parse_number (lexer, x, format)) + return false; + + if (lex_match_id (lexer, "THRU")) + { + if (lex_match_id (lexer, "HI") || lex_match_id (lexer, "HIGHEST")) + *y = HIGHEST; + else if (!parse_number (lexer, y, format)) + return false; + + if (*y < *x) + { + double t; + msg (SW, _("Low end of range (%g) is below high end (%g). " + "The range will be treated as reversed."), + *x, *y); + t = *x; + *x = *y; + *y = t; + } + else if (*x == *y) + msg (SW, _("Ends of range are equal (%g)."), *x); + + return true; + } + else + { + if (*x == LOWEST) + { + msg (SE, _("LO or LOWEST must be part of a range.")); + return false; + } + *y = *x; + } + + return true; +} + +/* Parses a number and stores it in *X. Returns success. + + Numeric values are always accepted. If FORMAT is nonnull, + then string values are also accepted, and converted to numeric + values using *FORMAT. */ +static bool +parse_number (struct lexer *lexer, double *x, const enum fmt_type *format) +{ + if (lex_is_number (lexer)) + { + *x = lex_number (lexer); + lex_get (lexer); + return true; + } + else if (lex_token (lexer) == T_STRING && format != NULL) + { + union value v; + data_in (ds_ss (lex_tokstr (lexer)), LEGACY_NATIVE, + *format, 0, 0, 0, &v, 0); + lex_get (lexer); + *x = v.f; + if (*x == SYSMIS) + { + msg (SE, _("System-missing value is not valid here.")); + return false; + } + return true; + } + else + { + if (format != NULL) + lex_error (lexer, _("expecting number or data string")); + else + lex_force_num (lexer); + return false; + } +} + +/* Parses the current token from LEXER into value V, which must + already have been initialized with the specified WIDTH. + Returns true if successful, false otherwise. */ +bool +parse_value (struct lexer *lexer, union value *v, int width) +{ + if (width == 0) + { + if (!lex_force_num (lexer)) + return false; + v->f = lex_tokval (lexer); + } + else + { + if (!lex_force_string (lexer)) + return false; + value_copy_str_rpad (v, width, ds_cstr (lex_tokstr (lexer)), ' '); + } + + lex_get (lexer); + + return true; +} diff --git a/src/language/lexer/value-parser.h b/src/language/lexer/value-parser.h new file mode 100644 index 00000000..4f9004a3 --- /dev/null +++ b/src/language/lexer/value-parser.h @@ -0,0 +1,29 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2005, 2009 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 published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef VALUE_PARSER_H +#define VALUE_PARSER_H 1 + +#include + +struct lexer; +enum fmt_type; +union value; +bool parse_num_range (struct lexer *, + double *x, double *y, const enum fmt_type *fmt); +bool parse_value (struct lexer *, union value *, int width); + +#endif /* value-parser.h */ diff --git a/src/language/stats/t-test.q b/src/language/stats/t-test.q index a3f4cf8f..c0a6f477 100644 --- a/src/language/stats/t-test.q +++ b/src/language/stats/t-test.q @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -126,8 +127,6 @@ struct t_test_proc union value g_value[2]; /* CMP_EQ only: Per-group indep var values. */ }; -static int parse_value (struct lexer *, union value *, int width); - /* Statistics Summary Box */ struct ssbox { @@ -421,29 +420,6 @@ tts_custom_pairs (struct lexer *lexer, struct dataset *ds, free (vars2); return 1; } - -/* Parses the current token (numeric or string, depending on type) - value v and returns success. */ -static int -parse_value (struct lexer *lexer, union value *v, int width) -{ - if (width == 0) - { - if (!lex_force_num (lexer)) - return 0; - v->f = lex_tokval (lexer); - } - else - { - if (!lex_force_string (lexer)) - return 0; - value_copy_str_rpad (v, width, ds_cstr (lex_tokstr (lexer)), ' '); - } - - lex_get (lexer); - - return 1; -} /* Implementation of the SSBOX object. */ diff --git a/src/language/xforms/count.c b/src/language/xforms/count.c index 6e234c4b..8ce2d125 100644 --- a/src/language/xforms/count.c +++ b/src/language/xforms/count.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/language/xforms/recode.c b/src/language/xforms/recode.c index 57a742c9..60c8f408 100644 --- a/src/language/xforms/recode.c +++ b/src/language/xforms/recode.c @@ -29,8 +29,8 @@ #include #include #include +#include #include -#include #include #include #include