devind.c devind.h dfm-read.c dfm-read.h dfm-write.c dfm-write.h \
dictionary.c dictionary.h do-if.c do-ifP.h echo.c error.c error.h \
factor_stats.c factor_stats.h file-handle.h file-type.c filename.c \
-filename.h flip.c font.h format.c format.def format.h formats.c get.c \
+filename.h flip.c font.h format.c format-prs.c format.def format.h formats.c get.c \
getl.c getl.h glob.c glob.h groff-font.c group.c group.h group_proc.h \
hash.c hash.h histogram.c histogram.h html.c htmlP.h include.c \
-inpt-pgm.c lexer.c lexer.h levene.c levene.h linked-list.c \
+inpt-pgm.c lexer.c lexer.h lex-def.h lex-def.c levene.c levene.h linked-list.c \
linked-list.h log.h loop.c magic.c magic.h main.c main.h matrix-data.c \
mis-val.c misc.c misc.h missing-values.c missing-values.h \
modify-vars.c moments.c moments.h numeric.c output.c output.h \
return 1;
}
\f
-/* A algo_random_func that uses random.h. */
-unsigned
-algo_default_random (unsigned max, void *aux UNUSED)
-{
- unsigned long r_min = gsl_rng_min (get_rng ());
- return (gsl_rng_get (get_rng ()) - r_min) % max;
-}
-
-/* Randomly reorders ARRAY, which contains COUNT elements of SIZE
- bytes each. Uses RANDOM as a source of random data, passing
- AUX as the auxiliary data. RANDOM may be null to use a
- default random source. */
-void
-random_shuffle (void *array_, size_t count, size_t size,
- algo_random_func *random, void *aux)
-{
- unsigned char *array = array_;
- int i;
-
- if (random == NULL)
- random = algo_default_random;
-
- for (i = 1; i < count; i++)
- SWAP (array + i * size, array + random (i + 1, aux) * size, size);
-}
-\f
/* Copies the COUNT elements of SIZE bytes each from ARRAY to
RESULT, except that elements for which PREDICATE is false are
not copied. Returns the number of elements copied. AUX is
assert (d != NULL);
assert (name != NULL);
- assert (strlen (name) >= 1);
- assert (strlen (name) <= LONG_NAME_LEN);
-
assert (width >= 0 && width < 256);
+
+ assert (var_is_valid_name(name,0));
/* Make sure there's not already a variable by that name. */
if (dict_lookup_var (d, name) != NULL)
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <config.h>
+#include "format.h"
+#include <ctype.h>
+#include "error.h"
+#include <stdlib.h>
+#include "error.h"
+#include "lexer.h"
+#include "misc.h"
+#include "str.h"
+#include "var.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+
+/* Parses the alphabetic prefix of the current token as a format
+ specifier name. Returns the corresponding format specifier
+ type if successful, or -1 on failure. If ALLOW_XT is zero,
+ then X and T format specifiers are not allowed. If CP is
+ nonzero, then *CP is set to the first non-alphabetic character
+ in the current token on success or to a null pointer on
+ failure. */
+int
+parse_format_specifier_name (const char **cp, enum fmt_parse_flags flags)
+{
+ char *sp, *ep;
+ int idx;
+
+ sp = ep = ds_c_str (&tokstr);
+ while (isalpha ((unsigned char) *ep))
+ ep++;
+
+ if (sp != ep)
+ {
+ /* Find format. */
+ for (idx = 0; idx < FMT_NUMBER_OF_FORMATS; idx++)
+ if (strlen (formats[idx].name) == ep - sp
+ && !buf_compare_case (formats[idx].name, sp, ep - sp))
+ break;
+
+ /* Check format. */
+ if (idx < FMT_NUMBER_OF_FORMATS)
+ {
+ if (!(flags & FMTP_ALLOW_XT) && (idx == FMT_T || idx == FMT_X))
+ {
+ if (!(flags & FMTP_SUPPRESS_ERRORS))
+ msg (SE, _("X and T format specifiers not allowed here."));
+ idx = -1;
+ }
+ }
+ else
+ {
+ /* No match. */
+ if (!(flags & FMTP_SUPPRESS_ERRORS))
+ msg (SE, _("%.*s is not a valid data format."),
+ (int) (ep - sp), ds_c_str (&tokstr));
+ idx = -1;
+ }
+ }
+ else
+ {
+ lex_error ("expecting data format");
+ idx = -1;
+ }
+
+ if (cp != NULL)
+ {
+ if (idx != -1)
+ *cp = ep;
+ else
+ *cp = NULL;
+ }
+
+ return idx;
+}
+
+
+/* Parses a format specifier from the token stream and returns
+ nonzero only if successful. Emits an error message on
+ failure. Allows X and T format specifiers only if ALLOW_XT is
+ nonzero. The caller should call check_input_specifier() or
+ check_output_specifier() on the parsed format as
+ necessary. */
+int
+parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags flags)
+{
+ struct fmt_spec spec;
+ struct fmt_desc *f;
+ const char *cp;
+ char *cp2;
+ int type, w, d;
+
+ if (token != T_ID)
+ {
+ if (!(flags & FMTP_SUPPRESS_ERRORS))
+ msg (SE, _("Format specifier expected."));
+ return 0;
+ }
+ type = parse_format_specifier_name (&cp, flags);
+ if (type == -1)
+ return 0;
+ f = &formats[type];
+
+ w = strtol (cp, &cp2, 10);
+ if (cp2 == cp && type != FMT_X)
+ {
+ if (!(flags & FMTP_SUPPRESS_ERRORS))
+ msg (SE, _("Data format %s does not specify a width."),
+ ds_c_str (&tokstr));
+ return 0;
+ }
+
+ cp = cp2;
+ if (f->n_args > 1 && *cp == '.')
+ {
+ cp++;
+ d = strtol (cp, &cp2, 10);
+ cp = cp2;
+ }
+ else
+ d = 0;
+
+ if (*cp)
+ {
+ if (!(flags & FMTP_SUPPRESS_ERRORS))
+ msg (SE, _("Data format %s is not valid."), ds_c_str (&tokstr));
+ return 0;
+ }
+ lex_get ();
+
+ spec.type = type;
+ spec.w = w;
+ spec.d = d;
+ *input = spec;
+
+ return 1;
+}
+
/* Common formats. */
const struct fmt_spec f8_2 = {FMT_F, 8, 2};
-/* Parses the alphabetic prefix of the current token as a format
- specifier name. Returns the corresponding format specifier
- type if successful, or -1 on failure. If ALLOW_XT is zero,
- then X and T format specifiers are not allowed. If CP is
- nonzero, then *CP is set to the first non-alphabetic character
- in the current token on success or to a null pointer on
- failure. */
-int
-parse_format_specifier_name (const char **cp, enum fmt_parse_flags flags)
-{
- char *sp, *ep;
- int idx;
-
- sp = ep = ds_c_str (&tokstr);
- while (isalpha ((unsigned char) *ep))
- ep++;
-
- if (sp != ep)
- {
- /* Find format. */
- for (idx = 0; idx < FMT_NUMBER_OF_FORMATS; idx++)
- if (strlen (formats[idx].name) == ep - sp
- && !buf_compare_case (formats[idx].name, sp, ep - sp))
- break;
-
- /* Check format. */
- if (idx < FMT_NUMBER_OF_FORMATS)
- {
- if (!(flags & FMTP_ALLOW_XT) && (idx == FMT_T || idx == FMT_X))
- {
- if (!(flags & FMTP_SUPPRESS_ERRORS))
- msg (SE, _("X and T format specifiers not allowed here."));
- idx = -1;
- }
- }
- else
- {
- /* No match. */
- if (!(flags & FMTP_SUPPRESS_ERRORS))
- msg (SE, _("%.*s is not a valid data format."),
- (int) (ep - sp), ds_c_str (&tokstr));
- idx = -1;
- }
- }
- else
- {
- lex_error ("expecting data format");
- idx = -1;
- }
-
- if (cp != NULL)
- {
- if (idx != -1)
- *cp = ep;
- else
- *cp = NULL;
- }
-
- return idx;
-}
-
/* Converts F to its string representation (for instance, "F8.2") and
returns a pointer to a static buffer containing that string. */
char *
assert (check_output_specifier (output, 0));
}
-/* Parses a format specifier from the token stream and returns
- nonzero only if successful. Emits an error message on
- failure. Allows X and T format specifiers only if ALLOW_XT is
- nonzero. The caller should call check_input_specifier() or
- check_output_specifier() on the parsed format as
- necessary. */
-int
-parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags flags)
-{
- struct fmt_spec spec;
- struct fmt_desc *f;
- const char *cp;
- char *cp2;
- int type, w, d;
-
- if (token != T_ID)
- {
- if (!(flags & FMTP_SUPPRESS_ERRORS))
- msg (SE, _("Format specifier expected."));
- return 0;
- }
- type = parse_format_specifier_name (&cp, flags);
- if (type == -1)
- return 0;
- f = &formats[type];
-
- w = strtol (cp, &cp2, 10);
- if (cp2 == cp && type != FMT_X)
- {
- if (!(flags & FMTP_SUPPRESS_ERRORS))
- msg (SE, _("Data format %s does not specify a width."),
- ds_c_str (&tokstr));
- return 0;
- }
-
- cp = cp2;
- if (f->n_args > 1 && *cp == '.')
- {
- cp++;
- d = strtol (cp, &cp2, 10);
- cp = cp2;
- }
- else
- d = 0;
-
- if (*cp)
- {
- if (!(flags & FMTP_SUPPRESS_ERRORS))
- msg (SE, _("Data format %s is not valid."), ds_c_str (&tokstr));
- return 0;
- }
- lex_get ();
-
- spec.type = type;
- spec.w = w;
- spec.d = d;
- *input = spec;
-
- return 1;
-}
-
/* Returns the width corresponding to the format specifier. The
return value is the value of the `width' member of a `struct
variable' for such an input format. */
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-9, 2000, 2005 Free Software Foundation, Inc.
+ Written by John Darrington <john@darrington.wattle.id.au>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/*
+ This file is concerned with the definition of the PSPP syntax, NOT the
+ action of scanning/parsing code .
+*/
+
+#include <config.h>
+#include "lex-def.h"
+
+
+#include <assert.h>
+#include <string.h>
+
+
+/* Table of keywords. */
+const char *keywords[T_N_KEYWORDS + 1] =
+ {
+ "AND", "OR", "NOT",
+ "EQ", "GE", "GT", "LE", "LT", "NE",
+ "ALL", "BY", "TO", "WITH",
+ NULL,
+ };
+
+
+
+/* Comparing identifiers. */
+
+/* Keywords match if one of the following is true: KW and TOK are
+ identical (except for differences in case), or TOK is at least 3
+ characters long and those characters are identical to KW. KW_LEN
+ is the length of KW, TOK_LEN is the length of TOK. */
+int
+lex_id_match_len (const char *kw, size_t kw_len,
+ const char *tok, size_t tok_len)
+{
+ size_t i = 0;
+
+ assert (kw && tok);
+ for (;;)
+ {
+ if (i == kw_len && i == tok_len)
+ return 1;
+ else if (i == tok_len)
+ return i >= 3;
+ else if (i == kw_len)
+ return 0;
+ else if (toupper ((unsigned char) kw[i])
+ != toupper ((unsigned char) tok[i]))
+ return 0;
+
+ i++;
+ }
+}
+
+/* Same as lex_id_match_len() minus the need to pass in the lengths. */
+int
+lex_id_match (const char *kw, const char *tok)
+{
+ return lex_id_match_len (kw, strlen (kw), tok, strlen (tok));
+}
+
+
+
+/* Returns the proper token type, either T_ID or a reserved keyword
+ enum, for ID[], which must contain LEN characters. */
+int
+lex_id_to_token (const char *id, size_t len)
+{
+ const char **kwp;
+
+ if (len < 2 || len > 4)
+ return T_ID;
+
+ for (kwp = keywords; *kwp; kwp++)
+ if (!strcasecmp (*kwp, id))
+ return T_FIRST_KEYWORD + (kwp - keywords);
+
+ return T_ID;
+}
+\f
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#if !lex_def_h
+#define lex_def_h 1
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+/* Returns nonzero if character CH may be the first character in an
+ identifier. */
+#define CHAR_IS_ID1(CH) \
+ (isalpha ((unsigned char) (CH)) \
+ || (CH) == '@' \
+ || (CH) == '#' \
+ || (CH) == '$')
+
+/* Returns nonzero if character CH may be a character in an
+ identifier other than the first. */
+#define CHAR_IS_IDN(CH) \
+ (CHAR_IS_ID1 (CH) \
+ || isdigit ((unsigned char) (CH)) \
+ || (CH) == '.' \
+ || (CH) == '_')
+
+/* Token types. */
+/* The order of the enumerals below is important. Do not change it. */
+enum
+ {
+ T_ID = 256, /* Identifier. */
+ T_POS_NUM, /* Positive number. */
+ T_NEG_NUM, /* Negative number. */
+ T_STRING, /* Quoted string. */
+ T_STOP, /* End of input. */
+
+ T_AND, /* AND */
+ T_OR, /* OR */
+ T_NOT, /* NOT */
+
+ T_EQ, /* EQ */
+ T_GE, /* GE or >= */
+ T_GT, /* GT or > */
+ T_LE, /* LE or <= */
+ T_LT, /* LT or < */
+ T_NE, /* NE or ~= */
+
+ T_ALL, /* ALL */
+ T_BY, /* BY */
+ T_TO, /* TO */
+ T_WITH, /* WITH */
+
+ T_EXP, /* ** */
+
+ T_FIRST_KEYWORD = T_AND,
+ T_LAST_KEYWORD = T_WITH,
+ T_N_KEYWORDS = T_LAST_KEYWORD - T_FIRST_KEYWORD + 1
+ };
+
+
+/* Comparing identifiers. */
+int lex_id_match_len (const char *keyword_string, size_t keyword_len,
+ const char *token_string, size_t token_len);
+int lex_id_match (const char *keyword_string, const char *token_string);
+int lex_id_to_token (const char *id, size_t len);
+
+#endif /* !lex_def_h */
\f
/* Global variables. */
+extern const char *keywords[T_N_KEYWORDS + 1];
+
+
/* Current token. */
int token;
\f
/* Static variables. */
-/* Table of keywords. */
-static const char *keywords[T_N_KEYWORDS + 1] =
- {
- "AND", "OR", "NOT",
- "EQ", "GE", "GT", "LE", "LT", "NE",
- "ALL", "BY", "TO", "WITH",
- NULL,
- };
-
/* Pointer to next token in getl_buf. */
static char *prog;
return 0;
}
}
-\f
-/* Comparing identifiers. */
-
-/* Keywords match if one of the following is true: KW and TOK are
- identical (except for differences in case), or TOK is at least 3
- characters long and those characters are identical to KW. KW_LEN
- is the length of KW, TOK_LEN is the length of TOK. */
-int
-lex_id_match_len (const char *kw, size_t kw_len,
- const char *tok, size_t tok_len)
-{
- size_t i = 0;
-
- assert (kw && tok);
- for (;;)
- {
- if (i == kw_len && i == tok_len)
- return 1;
- else if (i == tok_len)
- return i >= 3;
- else if (i == kw_len)
- return 0;
- else if (toupper ((unsigned char) kw[i])
- != toupper ((unsigned char) tok[i]))
- return 0;
-
- i++;
- }
-}
-
-/* Same as lex_id_match_len() minus the need to pass in the lengths. */
-int
-lex_id_match (const char *kw, const char *tok)
-{
- return lex_id_match_len (kw, strlen (kw), tok, strlen (tok));
-}
-
-/* Returns the proper token type, either T_ID or a reserved keyword
- enum, for ID[], which must contain LEN characters. */
-int
-lex_id_to_token (const char *id, size_t len)
-{
- const char **kwp;
-
- if (len < 2 || len > 4)
- return T_ID;
-
- for (kwp = keywords; *kwp; kwp++)
- if (!strcasecmp (*kwp, id))
- return T_FIRST_KEYWORD + (kwp - keywords);
-
- return T_ID;
-}
-\f
/* Weird token functions. */
/* Returns the first character of the next token, except that if the
#include <ctype.h>
#include <stdbool.h>
-/* Returns nonzero if character CH may be the first character in an
- identifier. */
-#define CHAR_IS_ID1(CH) \
- (isalpha ((unsigned char) (CH)) \
- || (CH) == '@' \
- || (CH) == '#' \
- || (CH) == '$')
-
-/* Returns nonzero if character CH may be a character in an
- identifier other than the first. */
-#define CHAR_IS_IDN(CH) \
- (CHAR_IS_ID1 (CH) \
- || isdigit ((unsigned char) (CH)) \
- || (CH) == '.' \
- || (CH) == '_')
-
-/* Token types. */
-/* The order of the enumerals below is important. Do not change it. */
-enum
- {
- T_ID = 256, /* Identifier. */
- T_POS_NUM, /* Positive number. */
- T_NEG_NUM, /* Negative number. */
- T_STRING, /* Quoted string. */
- T_STOP, /* End of input. */
-
- T_AND, /* AND */
- T_OR, /* OR */
- T_NOT, /* NOT */
-
- T_EQ, /* EQ */
- T_GE, /* GE or >= */
- T_GT, /* GT or > */
- T_LE, /* LE or <= */
- T_LT, /* LT or < */
- T_NE, /* NE or ~= */
-
- T_ALL, /* ALL */
- T_BY, /* BY */
- T_TO, /* TO */
- T_WITH, /* WITH */
-
- T_EXP, /* ** */
-
- T_FIRST_KEYWORD = T_AND,
- T_LAST_KEYWORD = T_WITH,
- T_N_KEYWORDS = T_LAST_KEYWORD - T_FIRST_KEYWORD + 1
- };
+#include "lex-def.h"
+
extern int token;
extern double tokval;
int lex_force_id (void);
int lex_force_string (void);
-/* Comparing identifiers. */
-int lex_id_match_len (const char *keyword_string, size_t keyword_len,
- const char *token_string, size_t token_len);
-int lex_id_match (const char *keyword_string, const char *token_string);
-int lex_id_to_token (const char *id, size_t len);
/* Weird token functions. */
int lex_look_ahead (void);
-/* Discards all the current state in preparation for a data-input
- command like DATA LIST or GET. */
-void
-discard_variables (void)
-{
- dict_clear (default_dict);
- default_handle = NULL;
-
- n_lag = 0;
-
- if (vfm_source != NULL)
- {
- free_case_source (vfm_source);
- vfm_source = NULL;
- }
-
- cancel_transformations ();
-
- ctl_stack = NULL;
-
- expr_free (process_if_expr);
- process_if_expr = NULL;
-
- cancel_temporary ();
-
- pgm_state = STATE_INIT;
-}
\f
/* Returns true if NAME is an acceptable name for a variable,
false otherwise. If ISSUE_ERROR is true, issues an
ofs = strlen (v->short_name);
strcpy (v->short_name + ofs, start);
}
+
+
+/* Returns the dictionary class corresponding to a variable named
+ NAME. */
+enum dict_class
+dict_class_from_id (const char *name)
+{
+ assert (name != NULL);
+
+ switch (name[0])
+ {
+ default:
+ return DC_ORDINARY;
+ case '$':
+ return DC_SYSTEM;
+ case '#':
+ return DC_SCRATCH;
+ }
+}
+
+/* Returns the name of dictionary class DICT_CLASS. */
+const char *
+dict_class_to_name (enum dict_class dict_class)
+{
+ switch (dict_class)
+ {
+ case DC_ORDINARY:
+ return _("ordinary");
+ case DC_SYSTEM:
+ return _("system");
+ case DC_SCRATCH:
+ return _("scratch");
+ default:
+ assert (0);
+ abort ();
+ }
+}
return parse_dict_variable (default_dict);
}
-/* Returns the dictionary class corresponding to a variable named
- NAME. */
-enum dict_class
-dict_class_from_id (const char *name)
-{
- assert (name != NULL);
-
- switch (name[0])
- {
- default:
- return DC_ORDINARY;
- case '$':
- return DC_SYSTEM;
- case '#':
- return DC_SCRATCH;
- }
-}
-
-/* Returns the name of dictionary class DICT_CLASS. */
-const char *
-dict_class_to_name (enum dict_class dict_class)
-{
- switch (dict_class)
- {
- case DC_ORDINARY:
- return _("ordinary");
- case DC_SYSTEM:
- return _("system");
- case DC_SCRATCH:
- return _("scratch");
- default:
- assert (0);
- abort ();
- }
-}
/* Parses a set of variables from dictionary D given options
OPTS. Resulting list of variables stored in *VAR and the
#include "alloc.h"
#include "case.h"
#include "casefile.h"
+#include "command.h"
#include "dictionary.h"
#include "do-ifP.h"
#include "error.h"
casefile_destroy (aux->casefile);
aux->casefile = NULL;
}
+
+
+/* Discards all the current state in preparation for a data-input
+ command like DATA LIST or GET. */
+void
+discard_variables (void)
+{
+ dict_clear (default_dict);
+ default_handle = NULL;
+
+ n_lag = 0;
+
+ if (vfm_source != NULL)
+ {
+ free_case_source (vfm_source);
+ vfm_source = NULL;
+ }
+
+ cancel_transformations ();
+
+ ctl_stack = NULL;
+
+ expr_free (process_if_expr);
+ process_if_expr = NULL;
+
+ cancel_temporary ();
+
+ pgm_state = STATE_INIT;
+}