#include <data/settings.h>
#include <language/command.h>
#include <language/lexer/lexer.h>
+#include <language/lexer/variable-parser.h>
#include <language/line-buffer.h>
#include <libpspp/alloc.h>
#include <libpspp/message.h>
struct repeat_block
{
struct pool *pool; /* Pool used for storage. */
+ struct dataset *ds; /* The dataset for this block */
struct line_list *first_line; /* First line in line buffer. */
struct line_list *cur_line; /* Current line in line buffer. */
int loop_cnt; /* Number of loops. */
static bool parse_lines (struct repeat_block *);
static void create_vars (struct repeat_block *);
-static int parse_ids (struct repeat_entry *, struct pool *);
+static int parse_ids (const struct dictionary *dict, struct repeat_entry *, struct pool *);
static int parse_numbers (struct repeat_entry *, struct pool *);
static int parse_strings (struct repeat_entry *, struct pool *);
static void do_repeat_close (void *block);
int
-cmd_do_repeat (void)
+cmd_do_repeat (struct dataset *ds)
{
struct repeat_block *block;
block = pool_create_container (struct repeat_block, pool);
+ block->ds = ds;
if (!parse_specification (block) || !parse_lines (block))
goto error;
{
struct repeat_entry *e;
struct repeat_entry *iter;
+ struct dictionary *dict = dataset_dict (block->ds);
int count;
/* Get a stand-in variable name and make sure it's unique. */
if (!lex_force_id ())
return false;
- if (dict_lookup_var (default_dict, tokid))
+ if (dict_lookup_var (dict, tokid))
msg (SW, _("Dummy variable name \"%s\" hides dictionary "
"variable \"%s\"."),
tokid, tokid);
/* Get the details of the variable's possible values. */
if (token == T_ID)
- count = parse_ids (e, block->pool);
+ count = parse_ids (dict, e, block->pool);
else if (lex_is_number ())
count = parse_numbers (e, block->pool);
else if (token == T_STRING)
const char *cur_file_name;
int cur_line_number;
struct line_list *line;
+ struct string cur_line_copy;
bool dot;
- if (!getl_read_line (NULL))
+ if (! lex_get_line_raw ())
return false;
/* If the current file has changed then record the fact. */
|| !strcmp (cur_file_name, previous_file_name))
previous_file_name = pool_strdup (block->pool, cur_file_name);
- ds_rtrim (&getl_buf, ss_cstr (CC_SPACES));
- dot = ds_chomp (&getl_buf, get_endcmd ());
- if (recognize_do_repeat (ds_cstr (&getl_buf)))
+ ds_init_string (&cur_line_copy, lex_entire_line_ds () );
+ ds_rtrim (&cur_line_copy, ss_cstr (CC_SPACES));
+ dot = ds_chomp (&cur_line_copy, get_endcmd ());
+
+ if (recognize_do_repeat (ds_cstr (&cur_line_copy)))
nesting_level++;
- else if (recognize_end_repeat (ds_cstr (&getl_buf), &block->print))
+ else if (recognize_end_repeat (ds_cstr (&cur_line_copy), &block->print))
{
if (nesting_level-- == 0)
{
lex_discard_line ();
+ ds_destroy (&cur_line_copy);
return true;
}
}
if (dot)
- ds_put_char (&getl_buf, get_endcmd ());
+ ds_put_char (&cur_line_copy, get_endcmd ());
line = *last_line = pool_alloc (block->pool, sizeof *line);
line->next = NULL;
line->file_name = previous_file_name;
line->line_number = cur_line_number;
- line->line = pool_strdup (block->pool, ds_cstr (&getl_buf));
+ line->line = pool_strdup (block->pool, ds_cstr (&cur_line_copy) );
last_line = &line->next;
+
+ ds_destroy (&cur_line_copy);
}
lex_discard_line ();
{
/* Ignore return value: if the variable already
exists there is no harm done. */
- dict_create_var (default_dict, iter->replacement[i], 0);
+ dict_create_var (dataset_dict (block->ds), iter->replacement[i], 0);
}
}
}
/* Parses a set of ids for DO REPEAT. */
static int
-parse_ids (struct repeat_entry *e, struct pool *pool)
+parse_ids (const struct dictionary *dict, struct repeat_entry *e, struct pool *pool)
{
size_t n = 0;
e->type = VAR_NAMES;
- return parse_mixed_vars_pool (pool, &e->replacement, &n, PV_NONE) ? n : 0;
+ return parse_mixed_vars_pool (dict, pool, &e->replacement, &n, PV_NONE) ? n : 0;
}
/* Adds STRING to E's list of replacements, which has *USED
}
\f
int
-cmd_end_repeat (void)
+cmd_end_repeat (struct dataset *ds UNUSED)
{
msg (SE, _("No matching DO REPEAT."));
return CMD_CASCADING_FAILURE;
return NULL;
}
-/* Makes appropriate DO REPEAT macro substitutions within getl_buf. */
+/* Makes appropriate DO REPEAT macro substitutions within the
+ repeated lines. */
static void
do_repeat_filter (struct string *line, void *block_)
{