From 4e5a6cc044c6c82e6c4d842bf056579b6bc47d48 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Thu, 25 Apr 2013 12:10:36 +0200 Subject: [PATCH] convert list.q to list.c Reviewed-by: Ben Pfaff --- src/language/data-io/.gitignore | 1 - src/language/data-io/automake.mk | 4 +- src/language/data-io/{list.q => list.c} | 243 ++++++++++++++++-------- 3 files changed, 162 insertions(+), 86 deletions(-) rename src/language/data-io/{list.q => list.c} (52%) diff --git a/src/language/data-io/.gitignore b/src/language/data-io/.gitignore index f6239472ba..cd4131076c 100644 --- a/src/language/data-io/.gitignore +++ b/src/language/data-io/.gitignore @@ -1,2 +1 @@ file-handle.c -list.c diff --git a/src/language/data-io/automake.mk b/src/language/data-io/automake.mk index 0695bd5d90..edb548c524 100644 --- a/src/language/data-io/automake.mk +++ b/src/language/data-io/automake.mk @@ -1,8 +1,7 @@ ## Process this file with automake to produce Makefile.in -*- makefile -*- src_language_data_io_built_sources = \ - src/language/data-io/file-handle.c \ - src/language/data-io/list.c + src/language/data-io/file-handle.c language_data_io_sources = \ src/language/data-io/combine-files.c \ @@ -19,6 +18,7 @@ language_data_io_sources = \ src/language/data-io/get.c \ src/language/data-io/inpt-pgm.c \ src/language/data-io/inpt-pgm.h \ + src/language/data-io/list.c \ src/language/data-io/placement-parser.c \ src/language/data-io/placement-parser.h \ src/language/data-io/print-space.c \ diff --git a/src/language/data-io/list.q b/src/language/data-io/list.c similarity index 52% rename from src/language/data-io/list.q rename to src/language/data-io/list.c index ddc072a46b..c7f85f3917 100644 --- a/src/language/data-io/list.q +++ b/src/language/data-io/list.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2009-2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009-2011, 2013 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 @@ -31,6 +31,7 @@ #include "language/command.h" #include "language/dictionary/split-file.h" #include "language/lexer/lexer.h" +#include "language/lexer/variable-parser.h" #include "libpspp/compiler.h" #include "libpspp/ll.h" #include "libpspp/message.h" @@ -46,83 +47,39 @@ #include "gettext.h" #define _(msgid) gettext (msgid) -/* (headers) */ +enum numbering + { + format_unnumbered, + format_numbered + }; -/* (specification) - list (lst_): - *variables=varlist("PV_NO_SCRATCH"); - cases=:from n:first,"%s>0"/by n:step,"%s>0"/ *to n:last,"%s>0"; - +format=numbering:numbered/!unnumbered, - wrap:!wrap/single. -*/ -/* (declarations) */ -/* (functions) */ -/* Parsed command. */ -static struct cmd_list cmd; +struct lst_cmd +{ + int first; + int last; + int step; + struct variable **v_variables; + size_t n_variables; + enum numbering numbering; +}; -/* Parses and executes the LIST procedure. */ -int -cmd_list (struct lexer *lexer, struct dataset *ds) + +static int +list_execute (const struct lst_cmd *lcmd, struct dataset *ds) { - struct dictionary *dict = dataset_dict (ds); + const struct dictionary *dict = dataset_dict (ds); + + bool ok; + int i; struct casegrouper *grouper; struct casereader *group; struct subcase sc; - size_t i; - bool ok; - - if (!parse_list (lexer, ds, &cmd, NULL)) - return CMD_FAILURE; - - /* Fill in defaults. */ - if (cmd.step == LONG_MIN) - cmd.step = 1; - if (cmd.first == LONG_MIN) - cmd.first = 1; - if (cmd.last == LONG_MIN) - cmd.last = LONG_MAX; - if (!cmd.sbc_variables) - dict_get_vars (dict, &cmd.v_variables, &cmd.n_variables, - DC_SYSTEM | DC_SCRATCH); - if (cmd.n_variables == 0) - { - msg (SE, _("No variables specified.")); - return CMD_FAILURE; - } - - /* Verify arguments. */ - if (cmd.first > cmd.last) - { - int t; - msg (SW, _("The first case (%ld) specified precedes the last case (%ld) " - "specified. The values will be swapped."), cmd.first, cmd.last); - t = cmd.first; - cmd.first = cmd.last; - cmd.last = t; - } - if (cmd.first < 1) - { - msg (SW, _("The first case (%ld) to list is less than 1. The value is " - "being reset to 1."), cmd.first); - cmd.first = 1; - } - if (cmd.last < 1) - { - msg (SW, _("The last case (%ld) to list is less than 1. The value is " - "being reset to 1."), cmd.last); - cmd.last = 1; - } - if (cmd.step < 1) - { - msg (SW, _("The step value %ld is less than 1. The value is being " - "reset to 1."), cmd.step); - cmd.step = 1; - } subcase_init_empty (&sc); - for (i = 0; i < cmd.n_variables; i++) - subcase_add_var (&sc, cmd.v_variables[i], SC_ASCEND); + for (i = 0; i < lcmd->n_variables; i++) + subcase_add_var (&sc, lcmd->v_variables[i], SC_ASCEND); + grouper = casegrouper_create_splits (proc_open (ds), dict); while (casegrouper_get_next_group (grouper, &group)) @@ -138,19 +95,19 @@ cmd_list (struct lexer *lexer, struct dataset *ds) } group = casereader_project (group, &sc); - if (cmd.numbering == LST_NUMBERED) + if (lcmd->numbering == format_numbered) group = casereader_create_arithmetic_sequence (group, 1, 1); - group = casereader_select (group, cmd.first - 1, - (cmd.last != LONG_MAX ? cmd.last - : CASENUMBER_MAX), cmd.step); + group = casereader_select (group, lcmd->first - 1, + (lcmd->last != LONG_MAX ? lcmd->last + : CASENUMBER_MAX), lcmd->step); - if (cmd.numbering == LST_NUMBERED) + if (lcmd->numbering == format_numbered) { struct fmt_spec fmt; size_t col; int width; - width = cmd.last == LONG_MAX ? 5 : intlog10 (cmd.last); + width = lcmd->last == LONG_MAX ? 5 : intlog10 (lcmd->last); fmt = fmt_for_output (FMT_F, width, 0); col = caseproto_get_n_widths (casereader_get_proto (group)) - 1; @@ -159,9 +116,9 @@ cmd_list (struct lexer *lexer, struct dataset *ds) else t = NULL; - for (i = 0; i < cmd.n_variables; i++) + for (i = 0; i < lcmd->n_variables; i++) { - const struct variable *var = cmd.v_variables[i]; + const struct variable *var = lcmd->v_variables[i]; struct table *c; c = table_from_casereader (group, i, var_get_name (var), @@ -177,13 +134,133 @@ cmd_list (struct lexer *lexer, struct dataset *ds) ok = proc_commit (ds) && ok; subcase_destroy (&sc); - free (cmd.v_variables); + free (lcmd->v_variables); return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE; } -/* - Local Variables: - mode: c - End: -*/ + +/* Parses and executes the LIST procedure. */ +int +cmd_list (struct lexer *lexer, struct dataset *ds) +{ + struct lst_cmd cmd; + const struct dictionary *dict = dataset_dict (ds); + + /* Fill in defaults. */ + cmd.step = 1; + cmd.first = 1; + cmd.last = LONG_MAX; + cmd.n_variables = 0; + cmd.v_variables = NULL; + cmd.numbering = format_unnumbered; + + + while (lex_token (lexer) != T_ENDCMD) + { + lex_match (lexer, T_SLASH); + if (lex_match_id (lexer, "VARIABLES") ) + { + lex_match (lexer, T_EQUALS); + if (! parse_variables (lexer, dict, &cmd.v_variables, &cmd.n_variables, 0 )) + { + msg (SE, _("No variables specified.")); + return CMD_FAILURE; + } + } + else if (lex_match_id (lexer, "FORMAT") ) + { + lex_match (lexer, T_EQUALS); + if (lex_match_id (lexer, "NUMBERED") ) + { + cmd.numbering = format_numbered; + } + else if (lex_match_id (lexer, "UNNUMBERED") ) + { + cmd.numbering = format_unnumbered; + } + else + { + lex_error (lexer, NULL); + goto error; + } + } + /* example: LIST /CASES=FROM 1 TO 25 BY 5. */ + else if (lex_match_id (lexer, "CASES")) + { + lex_match (lexer, T_EQUALS); + lex_force_match_id (lexer, "FROM"); + + if (lex_force_int (lexer)) + { + lex_match_int (lexer, &cmd.first); + lex_get (lexer); + } + + lex_force_match (lexer, T_TO); + + if (lex_force_int (lexer)) + { + cmd.last = lex_integer (lexer); + lex_get (lexer); + } + + lex_force_match (lexer, T_BY); + + if (lex_force_int (lexer)) + { + cmd.step = lex_integer (lexer); + lex_get (lexer); + } + } + else if (! parse_variables (lexer, dict, &cmd.v_variables, &cmd.n_variables, 0 )) + { + return CMD_FAILURE; + } + } + + + /* Verify arguments. */ + if (cmd.first > cmd.last) + { + int t; + msg (SW, _("The first case (%ld) specified precedes the last case (%ld) " + "specified. The values will be swapped."), cmd.first, cmd.last); + t = cmd.first; + cmd.first = cmd.last; + cmd.last = t; + } + + if (cmd.first < 1) + { + msg (SW, _("The first case (%ld) to list is less than 1. The value is " + "being reset to 1."), cmd.first); + cmd.first = 1; + } + + if (cmd.last < 1) + { + msg (SW, _("The last case (%ld) to list is less than 1. The value is " + "being reset to 1."), cmd.last); + cmd.last = 1; + } + + if (cmd.step < 1) + { + msg (SW, _("The step value %ld is less than 1. The value is being " + "reset to 1."), cmd.step); + cmd.step = 1; + } + + /* If no variables were explicitly provided, then default to ALL */ + if (cmd.n_variables == 0) + dict_get_vars (dict, &cmd.v_variables, &cmd.n_variables, + DC_SYSTEM | DC_SCRATCH); + + return list_execute (&cmd, ds); + + error: + free (cmd.v_variables); + return CMD_FAILURE; +} + -- 2.30.2