X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Flanguage%2Fcontrol%2Floop.c;h=cece7f68f647cf91e1fd925759c9b7c7a0c80f06;hb=ae1e48a9727327898aaf9662f53a9a1ec115ab11;hp=5a2417131e49dd3b7ff1a24d2dd90da7b5a9071e;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp
diff --git a/src/language/control/loop.c b/src/language/control/loop.c
index 5a2417131e..cece7f68f6 100644
--- a/src/language/control/loop.c
+++ b/src/language/control/loop.c
@@ -1,39 +1,39 @@
-/* PSPP - computes sample statistics.
- Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+/* PSPP - a program for statistical analysis.
+ Copyright (C) 1997-9, 2000, 2009-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 the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ 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.
+ 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. */
+ along with this program. If not, see . */
#include
-#include "control-stack.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+#include "language/control/control-stack.h"
+
+#include "data/case.h"
+#include "data/dataset.h"
+#include "data/dictionary.h"
+#include "data/settings.h"
+#include "data/transformations.h"
+#include "data/variable.h"
+#include "language/command.h"
+#include "language/expressions/public.h"
+#include "language/lexer/lexer.h"
+#include "libpspp/compiler.h"
+#include "libpspp/message.h"
+#include "libpspp/misc.h"
+#include "libpspp/pool.h"
+#include "libpspp/str.h"
+
+#include "gl/xalloc.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
@@ -103,7 +103,7 @@ cmd_loop (struct lexer *lexer, struct dataset *ds)
bool ok = true;
loop = create_loop_trns (ds);
- while (lex_token (lexer) != '.' && ok)
+ while (lex_token (lexer) != T_ENDCMD && ok)
{
if (lex_match_id (lexer, "IF"))
ok = parse_if_clause (lexer, loop, &loop->loop_condition);
@@ -154,7 +154,7 @@ cmd_end_loop (struct lexer *lexer, struct dataset *ds)
/* Parses BREAK. */
int
-cmd_break (struct lexer *lexer, struct dataset *ds)
+cmd_break (struct lexer *lexer UNUSED, struct dataset *ds)
{
struct ctl_stmt *loop = ctl_stack_search (&loop_class);
if (loop == NULL)
@@ -162,7 +162,7 @@ cmd_break (struct lexer *lexer, struct dataset *ds)
add_transformation (ds, break_trns_proc, NULL, loop);
- return lex_end_of_command (lexer);
+ return CMD_SUCCESS;
}
/* Closes a LOOP construct by emitting the END LOOP
@@ -181,7 +181,7 @@ close_loop (void *loop_)
&& loop->index_var == NULL
&& loop->loop_condition == NULL
&& loop->end_loop_condition == NULL)
- loop->max_pass_count = get_mxloops ();
+ loop->max_pass_count = settings_get_mxloops ();
}
/* Parses an IF clause for LOOP or END LOOP and stores the
@@ -221,18 +221,18 @@ parse_index_clause (struct dataset *ds, struct lexer *lexer,
return false;
}
- loop->index_var = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer));
+ loop->index_var = dict_lookup_var (dataset_dict (ds), lex_tokcstr (lexer));
if (loop->index_var != NULL)
*created_index_var = false;
else
{
loop->index_var = dict_create_var_assert (dataset_dict (ds),
- lex_tokid (lexer), 0);
+ lex_tokcstr (lexer), 0);
*created_index_var = true;
}
lex_get (lexer);
- if (!lex_force_match (lexer, '='))
+ if (!lex_force_match (lexer, T_EQUALS))
return false;
loop->first_expr = expr_parse_pool (lexer, loop->pool,
@@ -261,7 +261,7 @@ parse_index_clause (struct dataset *ds, struct lexer *lexer,
}
if (loop->last_expr == NULL)
{
- lex_sbc_missing (lexer, "TO");
+ lex_sbc_missing ("TO");
return false;
}
if (loop->by_expr == NULL)
@@ -304,24 +304,26 @@ loop_trns_finalize (void *do_if_ UNUSED)
/* Sets up LOOP for the first pass. */
static int
-loop_trns_proc (void *loop_, struct ccase *c, casenumber case_num)
+loop_trns_proc (void *loop_, struct ccase **c, casenumber case_num)
{
struct loop_trns *loop = loop_;
if (loop->index_var != NULL)
{
/* Evaluate loop index expressions. */
- loop->cur = expr_evaluate_num (loop->first_expr, c, case_num);
+ loop->cur = expr_evaluate_num (loop->first_expr, *c, case_num);
if (loop->by_expr != NULL)
- loop->by = expr_evaluate_num (loop->by_expr, c, case_num);
- loop->last = expr_evaluate_num (loop->last_expr, c, case_num);
+ loop->by = expr_evaluate_num (loop->by_expr, *c, case_num);
+ loop->last = expr_evaluate_num (loop->last_expr, *c, case_num);
/* Even if the loop is never entered, set the index
variable to the initial value. */
- case_data_rw (c, loop->index_var)->f = loop->cur;
+ *c = case_unshare (*c);
+ case_data_rw (*c, loop->index_var)->f = loop->cur;
/* Throw out pathological cases. */
- if (!finite (loop->cur) || !finite (loop->by) || !finite (loop->last)
+ if (!isfinite (loop->cur) || !isfinite (loop->by)
+ || !isfinite (loop->last)
|| loop->by == 0.0
|| (loop->by > 0.0 && loop->cur > loop->last)
|| (loop->by < 0.0 && loop->cur < loop->last))
@@ -335,7 +337,7 @@ loop_trns_proc (void *loop_, struct ccase *c, casenumber case_num)
/* Check condition. */
if (loop->loop_condition != NULL
- && expr_evaluate_num (loop->loop_condition, c, case_num) != 1.0)
+ && expr_evaluate_num (loop->loop_condition, *c, case_num) != 1.0)
goto zero_pass;
return loop->past_LOOP_index;
@@ -356,21 +358,17 @@ loop_trns_free (void *loop_)
/* Finishes a pass through the loop and starts the next. */
static int
-end_loop_trns_proc (void *loop_, struct ccase *c, casenumber case_num UNUSED)
+end_loop_trns_proc (void *loop_, struct ccase **c, casenumber case_num UNUSED)
{
struct loop_trns *loop = loop_;
if (loop->end_loop_condition != NULL
- && expr_evaluate_num (loop->end_loop_condition, c, case_num) != 0.0)
+ && expr_evaluate_num (loop->end_loop_condition, *c, case_num) != 0.0)
goto break_out;
/* MXLOOPS limiter. */
- if (loop->max_pass_count >= 0)
- {
- if (loop->pass >= loop->max_pass_count)
- goto break_out;
- loop->pass++;
- }
+ if (loop->max_pass_count >= 0 && ++loop->pass >= loop->max_pass_count)
+ goto break_out;
/* Indexing clause limiter: counting downward. */
if (loop->index_var != NULL)
@@ -379,11 +377,12 @@ end_loop_trns_proc (void *loop_, struct ccase *c, casenumber case_num UNUSED)
if ((loop->by > 0.0 && loop->cur > loop->last)
|| (loop->by < 0.0 && loop->cur < loop->last))
goto break_out;
- case_data_rw (c, loop->index_var)->f = loop->cur;
+ *c = case_unshare (*c);
+ case_data_rw (*c, loop->index_var)->f = loop->cur;
}
if (loop->loop_condition != NULL
- && expr_evaluate_num (loop->loop_condition, c, case_num) != 1.0)
+ && expr_evaluate_num (loop->loop_condition, *c, case_num) != 1.0)
goto break_out;
return loop->past_LOOP_index;
@@ -394,7 +393,8 @@ end_loop_trns_proc (void *loop_, struct ccase *c, casenumber case_num UNUSED)
/* Executes BREAK. */
static int
-break_trns_proc (void *loop_, struct ccase *c UNUSED, casenumber case_num UNUSED)
+break_trns_proc (void *loop_, struct ccase **c UNUSED,
+ casenumber case_num UNUSED)
{
struct loop_trns *loop = loop_;