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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
-#include <assert.h>
+#include "repeat.h"
+#include "error.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include "alloc.h"
-#include "cases.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "getline.h"
#include "lexer.h"
#include "str.h"
#include "var.h"
-#undef DEBUGGING
-/*#define DEBUGGING 1*/
#include "debug-print.h"
/* Describes one DO REPEAT macro. */
struct repeat_entry
{
int type; /* 1=variable names, 0=any other. */
- char id[9]; /* Macro identifier. */
+ char id[LONG_NAME_LEN + 1]; /* Macro identifier. */
char **replacement; /* Macro replacement. */
struct repeat_entry *next;
};
static void clean_up (void);
static int internal_cmd_do_repeat (void);
-#if DEBUGGING
-static void debug_print (void);
-static void debug_print_lines (void);
-#endif
-
int
cmd_do_repeat (void)
{
internal_cmd_do_repeat (void)
{
/* Name of first DO REPEAT macro. */
- char first_name[9];
+ char first_name[LONG_NAME_LEN + 1];
/* Current filename. */
const char *current_filename = NULL;
int print;
/* The first step is parsing the DO REPEAT command itself. */
- lex_match_id ("DO");
- lex_match_id ("REPEAT");
-
count = 0;
line_buf_head = NULL;
do
if (!lex_force_id ())
return 0;
for (iter = repeat_tab; iter; iter = iter->next)
- if (!strcmp (iter->id, tokid))
+ if (!strcasecmp (iter->id, tokid))
{
msg (SE, _("Identifier %s is given twice."), tokid);
return 0;
if (token == T_ID)
result = parse_ids (e);
- else if (token == T_NUM)
+ else if (lex_is_number ())
result = parse_numbers (e);
else if (token == T_STRING)
result = parse_strings (e);
}
while (token != '.');
-#if DEBUGGING
- debug_print ();
-#endif
-
/* Read all the lines inside the DO REPEAT ... END REPEAT. */
{
int nest = 1;
command names must appear on a single line--they can't be
spread out. */
{
- char *cp = ds_value (&getl_buf);
+ char *cp = ds_c_str (&getl_buf);
/* Skip leading indentors and any whitespace. */
if (*cp == '+' || *cp == '-' || *cp == '.')
line_buf_tail->len = ds_length (&getl_buf);
line_buf_tail->line = xmalloc (ds_length (&getl_buf) + 1);
memcpy (line_buf_tail->line,
- ds_value (&getl_buf), ds_length (&getl_buf) + 1);
+ ds_c_str (&getl_buf), ds_length (&getl_buf) + 1);
}
}
REPEAT line. We should actually check for the PRINT specifier.
This can be done easier when we buffer entire commands instead of
doing it token by token; see TODO. */
- lex_entire_line ();
+ lex_discard_line ();
/* Tie up the loose end of the chain. */
if (line_buf_head == NULL)
}
line_buf_tail->next = NULL;
- /* Show the line list. */
-#if DEBUGGING
- debug_print_lines ();
-#endif
-
/* Make new variables. */
{
struct repeat_entry *iter;
{
/* Note that if the variable already exists there is no
harm done. */
- struct variable *v = create_variable (&default_dict,
- iter->replacement[i],
- NUMERIC, 0);
-
- /* If we created the variable then we need to initialize
- its observations to SYSMIS. */
- if (v)
- envector (v);
+ dict_create_var (default_dict, iter->replacement[i], 0);
}
}
}
\f
/* Finds a DO REPEAT macro with name MACRO_NAME and returns the
appropriate subsitution if found, or NULL if not. */
-char *
+static char *
find_DO_REPEAT_substitution (char *macro_name)
{
struct getl_script *s;
/* Terminal dot. */
int dot = 0;
- ds_init (NULL, &output, ds_size (&getl_buf));
+ ds_init (&output, ds_capacity (&getl_buf));
/* Strip trailing whitespace, check for & remove terminal dot. */
while (ds_length (&getl_buf) > 0
&& isspace ((unsigned char) ds_end (&getl_buf)[-1]))
ds_truncate (&getl_buf, ds_length (&getl_buf) - 1);
- if (ds_length (&getl_buf) > 0 && ds_end (&getl_buf)[-1] == set_endcmd)
+ if (ds_length (&getl_buf) > 0 && ds_end (&getl_buf)[-1] == get_endcmd() )
{
dot = 1;
ds_truncate (&getl_buf, ds_length (&getl_buf) - 1);
}
- for (cp = ds_value (&getl_buf); cp < ds_end (&getl_buf); )
+ for (cp = ds_c_str (&getl_buf); cp < ds_end (&getl_buf); )
{
if (*cp == '\'' && !in_quote)
in_apos ^= 1;
if (in_quote || in_apos || !CHAR_IS_ID1 (*cp))
{
- ds_putchar (&output, *cp++);
+ ds_putc (&output, *cp++);
continue;
}
/* Collect an identifier. */
{
- char name[9];
+ char name[LONG_NAME_LEN + 1];
char *start = cp;
char *np = name;
char *substitution;
- while (CHAR_IS_IDN (*cp) && np < &name[8])
+ while (CHAR_IS_IDN (*cp) && np < &name[LONG_NAME_LEN])
*np++ = *cp++;
while (CHAR_IS_IDN (*cp))
cp++;
substitution = find_DO_REPEAT_substitution (name);
if (!substitution)
{
- ds_concat_buffer (&output, start, cp - start);
+ ds_concat (&output, start, cp - start);
continue;
}
/* Force output buffer size, copy substitution. */
- ds_concat (&output, substitution);
+ ds_puts (&output, substitution);
}
}
if (dot)
- ds_putchar (&output, (unsigned char) set_endcmd);
+ ds_putc (&output, get_endcmd() );
ds_destroy (&getl_buf);
getl_buf = output;
}
-\f
-/* Debugging code. */
-
-#if DEBUGGING
-static void
-debug_print (void)
-{
- struct repeat_entry *iter;
- int j;
-
- printf ("DO REPEAT\n");
- for (iter = repeat_tab; iter; iter = iter->next)
- {
- printf (" %s%s=", iter->id, iter->type ? "(ids)" : "");
- for (j = 0; j < count; j++)
- printf ("%s ", iter->replacement[j]);
- putc (iter->next ? '/' : '.', stdout);
- printf ("\n");
- }
-}
-
-static void
-debug_print_lines (void)
-{
- struct getl_line_list *iter;
- const char *fn = "(none)";
- int ln = 65536;
-
- printf ("---begin DO REPEAT lines---\n");
- for (iter = line_buf_head; iter; iter = iter->next)
- {
- if (iter->len < 0)
- {
- ln = -iter->len;
- fn = iter->line;
- } else {
- printf ("%s:%d: %s", fn, ln++, iter->line);
- }
- }
- printf ("---end DO REPEAT lines---\n");
-}
-#endif /* DEBUGGING */