-\f
-/* Finds a DO REPEAT macro with name MACRO_NAME and returns the
- appropriate subsitution if found, or NULL if not. */
-static char *
-find_substitution (struct repeat_block *block, const char *name, size_t length)
-{
- struct repeat_entry *e;
-
- for (e = block->macros; e; e = e->next)
- if (!memcasecmp (e->id, name, length) && strlen (e->id) == length)
- return e->replacement[block->loop_idx];
-
- return NULL;
-}
-
-/* Makes appropriate DO REPEAT macro substitutions within the
- repeated lines. */
-static void
-do_repeat_filter (struct getl_interface *block_, struct string *line)
-{
- struct repeat_block *block = (struct repeat_block *) block_;
- bool in_apos, in_quote;
- char *cp;
- struct string output;
- bool dot;
-
- ds_init_empty (&output);
-
- /* Strip trailing whitespace, check for & remove terminal dot. */
- while (isspace (ds_last (line)))
- ds_truncate (line, ds_length (line) - 1);
- dot = ds_chomp (line, get_endcmd ());
-
- in_apos = in_quote = false;
- for (cp = ds_cstr (line); cp < ds_end (line); )
- {
- if (*cp == '\'' && !in_quote)
- in_apos = !in_apos;
- else if (*cp == '"' && !in_apos)
- in_quote = !in_quote;
-
- if (in_quote || in_apos || !lex_is_id1 (*cp))
- ds_put_char (&output, *cp++);
- else
- {
- const char *start = cp;
- char *end = lex_skip_identifier (start);
- const char *substitution = find_substitution (block,
- start, end - start);
- if (substitution != NULL)
- ds_put_cstr (&output, substitution);
- else
- ds_put_substring (&output, ss_buffer (start, end - start));
- cp = end;
- }
- }
- if (dot)
- ds_put_char (&output, get_endcmd ());
-
- ds_swap (line, &output);
- ds_destroy (&output);
-}
-
-/* Function called by getl to read a line.
- Puts the line in OUTPUT, sets the file name in *FILE_NAME and
- line number in *LINE_NUMBER. Returns true if a line was
- obtained, false if the source is exhausted. */
-static bool
-do_repeat_read (struct getl_interface *b, struct string *output)
-{
- struct repeat_block *block = (struct repeat_block *) b;
- struct line_list *line;
-
- if (block->cur_line == NULL)
- {
- block->loop_idx++;
- if (block->loop_idx >= block->loop_cnt)
- return false;
- block->cur_line = block->first_line;
- if (block->cur_line == NULL)
- return false;
- }
- line = block->cur_line;
-
- ds_assign_cstr (output, line->line);
- block->cur_line = line->next;
- return true;
-}
-
-/* Frees a DO REPEAT block.
- Called by getl to close out the DO REPEAT block. */
-static void
-do_repeat_close (struct getl_interface *block_)
-{
- struct repeat_block *block = (struct repeat_block *) block_;
- pool_destroy (block->pool);
-}
-
-
-static bool
-always_false (const struct getl_interface *i UNUSED)
-{
- return false;
-}