X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fcontrol%2Frepeat.c;h=ecff0577bf3ca64624e139cbd31b633ffe4e8ab1;hb=086322fd8c85a303ba6f552950d6f057f2867add;hp=32847bb4a9298bd100f0cb80e8489097adc7d8ca;hpb=9b94efd7513afdb12a6023024e00e50801532fee;p=pspp-builds.git diff --git a/src/language/control/repeat.c b/src/language/control/repeat.c index 32847bb4..ecff0577 100644 --- a/src/language/control/repeat.c +++ b/src/language/control/repeat.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2007 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 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 @@ -16,28 +16,29 @@ #include -#include "repeat.h" +#include "language/control/repeat.h" #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "intprops.h" -#include "xalloc.h" +#include "data/dictionary.h" +#include "data/procedure.h" +#include "data/settings.h" +#include "libpspp/getl.h" +#include "language/command.h" +#include "language/lexer/lexer.h" +#include "language/lexer/variable-parser.h" +#include "libpspp/cast.h" +#include "libpspp/ll.h" +#include "libpspp/message.h" +#include "libpspp/misc.h" +#include "libpspp/pool.h" +#include "libpspp/str.h" +#include "data/variable.h" + +#include "gl/intprops.h" +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -167,26 +168,24 @@ parse_specification (struct lexer *lexer, struct repeat_block *block) /* Get a stand-in variable name and make sure it's unique. */ if (!lex_force_id (lexer)) return false; - if (dict_lookup_var (dict, lex_tokid (lexer))) - msg (SW, _("Dummy variable name \"%s\" hides dictionary " - "variable \"%s\"."), - lex_tokid (lexer), lex_tokid (lexer)); - if (find_macro (block, ss_cstr (lex_tokid (lexer)))) + if (dict_lookup_var (dict, lex_tokcstr (lexer))) + msg (SW, _("Dummy variable name `%s' hides dictionary variable `%s'."), + lex_tokcstr (lexer), lex_tokcstr (lexer)); + if (find_macro (block, lex_tokss (lexer))) { - msg (SE, _("Dummy variable name \"%s\" is given twice."), - lex_tokid (lexer)); + msg (SE, _("Dummy variable name `%s' is given twice."), + lex_tokcstr (lexer)); return false; } /* Make a new macro. */ macro = pool_alloc (block->pool, sizeof *macro); - ss_alloc_substring_pool (¯o->name, ss_cstr (lex_tokid (lexer)), - block->pool); + ss_alloc_substring_pool (¯o->name, lex_tokss (lexer), block->pool); ll_push_tail (&block->macros, ¯o->ll); /* Skip equals sign. */ lex_get (lexer); - if (!lex_force_match (lexer, '=')) + if (!lex_force_match (lexer, T_EQUALS)) return false; /* Get the details of the variable's possible values. */ @@ -194,7 +193,7 @@ parse_specification (struct lexer *lexer, struct repeat_block *block) count = parse_ids (lexer, dict, macro, block->pool); else if (lex_is_number (lexer)) count = parse_numbers (lexer, macro, block->pool); - else if (lex_token (lexer) == T_STRING) + else if (lex_is_string (lexer)) count = parse_strings (lexer, macro, block->pool); else { @@ -203,7 +202,7 @@ parse_specification (struct lexer *lexer, struct repeat_block *block) } if (count == 0) return false; - if (lex_token (lexer) != '/' && lex_token (lexer) != '.') + if (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD) { lex_error (lexer, NULL); return false; @@ -219,8 +218,8 @@ parse_specification (struct lexer *lexer, struct repeat_block *block) } else if (block->loop_cnt != count) { - msg (SE, _("Dummy variable \"%.*s\" had %d " - "substitutions, so \"%.*s\" must also, but %d " + msg (SE, _("Dummy variable `%.*s' had %d " + "substitutions, so `%.*s' must also, but %d " "were specified."), (int) ss_length (first_name), ss_data (first_name), block->loop_cnt, @@ -229,9 +228,9 @@ parse_specification (struct lexer *lexer, struct repeat_block *block) return false; } - lex_match (lexer, '/'); + lex_match (lexer, T_SLASH); } - while (lex_token (lexer) != '.'); + while (lex_token (lexer) != T_ENDCMD); return true; } @@ -258,7 +257,7 @@ recognize_keyword (struct substring *line, const char *keyword) { struct substring id; ss_ltrim (line, ss_cstr (CC_SPACES)); - ss_get_chars (line, lex_id_get_length (*line), &id); + ss_get_bytes (line, lex_id_get_length (*line), &id); return lex_id_match (ss_cstr (keyword), id); } @@ -305,7 +304,10 @@ parse_lines (struct lexer *lexer, struct repeat_block *block) /* Retrieve an input line and make a copy of it. */ if (!lex_get_line_raw (lexer)) - return false; + { + msg (SE, _("DO REPEAT without END REPEAT.")); + return false; + } ds_init_string (&text, lex_entire_line_ds (lexer)); /* Record file name. */ @@ -454,9 +456,9 @@ parse_numbers (struct lexer *lexer, struct repeat_macro *macro, add_replacement (ss_cstr (pool_asprintf (pool, "%g", i)), macro, pool, &used, &allocated); - lex_match (lexer, ','); + lex_match (lexer, T_COMMA); } - while (lex_token (lexer) != '/' && lex_token (lexer) != '.'); + while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD); return used; } @@ -475,7 +477,7 @@ parse_strings (struct lexer *lexer, struct repeat_macro *macro, struct pool *poo { char *string; - if (lex_token (lexer) != T_STRING) + if (!lex_force_string (lexer)) { msg (SE, _("String expected.")); return 0; @@ -486,9 +488,9 @@ parse_strings (struct lexer *lexer, struct repeat_macro *macro, struct pool *poo add_replacement (ss_cstr (string), macro, pool, &used, &allocated); lex_get (lexer); - lex_match (lexer, ','); + lex_match (lexer, T_COMMA); } - while (lex_token (lexer) != '/' && lex_token (lexer) != '.'); + while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD); return used; } @@ -512,10 +514,10 @@ find_substitution (struct repeat_block *block, struct substring name) /* Makes appropriate DO REPEAT macro substitutions within the repeated lines. */ static void -do_repeat_filter (struct getl_interface *block_, - struct string *line) +do_repeat_filter (struct getl_interface *interface, struct string *line) { - struct repeat_block *block = (struct repeat_block *) block_; + struct repeat_block *block + = UP_CAST (interface, struct repeat_block, parent); bool in_apos, in_quote, dot; struct substring input; struct string output; @@ -525,7 +527,7 @@ do_repeat_filter (struct getl_interface *block_, /* Strip trailing whitespace, check for & remove terminal dot. */ ds_rtrim (line, ss_cstr (CC_SPACES)); - dot = ds_chomp (line, settings_get_endcmd ()); + dot = ds_chomp_byte (line, '.'); input = ds_ss (line); in_apos = in_quote = false; while ((c = ss_first (input)) != EOF) @@ -537,18 +539,18 @@ do_repeat_filter (struct getl_interface *block_, if (in_quote || in_apos || !lex_is_id1 (c)) { - ds_put_char (&output, c); + ds_put_byte (&output, c); ss_advance (&input, 1); } else { struct substring id; - ss_get_chars (&input, lex_id_get_length (input), &id); + ss_get_bytes (&input, lex_id_get_length (input), &id); ds_put_substring (&output, find_substitution (block, id)); } } if (dot) - ds_put_char (&output, settings_get_endcmd ()); + ds_put_byte (&output, '.'); ds_swap (line, &output); ds_destroy (&output); @@ -557,7 +559,8 @@ do_repeat_filter (struct getl_interface *block_, static struct repeat_line * current_line (const struct getl_interface *interface) { - struct repeat_block *block = (struct repeat_block *) interface; + struct repeat_block *block + = UP_CAST (interface, struct repeat_block, parent); return (block->cur_line != ll_null (&block->lines) ? ll_data (block->cur_line, struct repeat_line, ll) : NULL); @@ -570,7 +573,8 @@ static bool do_repeat_read (struct getl_interface *interface, struct string *output) { - struct repeat_block *block = (struct repeat_block *) interface; + struct repeat_block *block + = UP_CAST (interface, struct repeat_block, parent); struct repeat_line *line; block->cur_line = ll_next (block->cur_line); @@ -591,9 +595,10 @@ do_repeat_read (struct getl_interface *interface, /* Frees a DO REPEAT block. Called by getl to close out the DO REPEAT block. */ static void -do_repeat_close (struct getl_interface *block_) +do_repeat_close (struct getl_interface *interface) { - struct repeat_block *block = (struct repeat_block *) block_; + struct repeat_block *block + = UP_CAST (interface, struct repeat_block, parent); pool_destroy (block->pool); } @@ -614,10 +619,10 @@ do_repeat_name (const struct getl_interface *interface) } /* Returns the line number in the source file from which the - previous line was originally obtained, or -1 if none. */ + previous line was originally obtained, or 0 if none. */ static int do_repeat_location (const struct getl_interface *interface) { struct repeat_line *line = current_line (interface); - return line ? line->line_number : -1; + return line ? line->line_number : 0; }