1 /* PSPP - computes sample statistics.
2 Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "range-parser.h"
23 #include <data/data-in.h>
24 #include <libpspp/message.h>
26 #include <libpspp/magic.h>
27 #include <libpspp/str.h>
28 #include <data/value.h>
31 #define _(msgid) gettext (msgid)
32 #define N_(msgid) msgid
34 static bool parse_number (struct lexer *, double *, const struct fmt_spec *);
36 /* Parses and stores a numeric value, or a range of the form "x
37 THRU y". Open-ended ranges may be specified as "LO(WEST) THRU
38 y" or "x THRU HI(GHEST)". Sets *X and *Y to the range or the
39 value and returns success.
41 Numeric values are always accepted. If F is nonnull, then
42 string values are also accepted, and converted to numeric
43 values using the specified format. */
45 parse_num_range (struct lexer *lexer, double *x, double *y, const struct fmt_spec *f)
47 if (lex_match_id (lexer, "LO") || lex_match_id (lexer, "LOWEST"))
49 else if (!parse_number (lexer, x, f))
52 if (lex_match_id (lexer, "THRU"))
54 if (lex_match_id (lexer, "HI") || lex_match_id (lexer, "HIGHEST"))
56 else if (!parse_number (lexer, y, f))
62 msg (SW, _("Low end of range (%g) is below high end (%g). "
63 "The range will be treated as reversed."),
70 msg (SW, _("Ends of range are equal (%g)."), *x);
78 msg (SE, _("LO or LOWEST must be part of a range."));
87 /* Parses a number and stores it in *X. Returns success.
89 Numeric values are always accepted. If F is nonnull, then
90 string values are also accepted, and converted to numeric
91 values using the specified format. */
93 parse_number (struct lexer *lexer, double *x, const struct fmt_spec *f)
95 if (lex_is_number (lexer))
97 *x = lex_number (lexer);
101 else if (lex_token (lexer) == T_STRING && f != NULL)
105 di.s = ds_data (lex_tokstr (lexer));
106 di.e = ds_end (lex_tokstr (lexer));
110 di.f2 = ds_length (lex_tokstr (lexer));
117 msg (SE, _("System-missing value is not valid here."));
125 lex_error (lexer, _("expecting number or data string"));
127 lex_force_num (lexer);