- Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2008, 2010 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
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
-int fail (const char *, ...) PRINTF_FORMAT (1, 2);
-int error (const char *, ...) PRINTF_FORMAT (1, 2);
+int fail (const char *, ...) PRINTF_FORMAT (1, 2) NO_RETURN;
+int error (const char *, ...) PRINTF_FORMAT (1, 2) NO_RETURN;
/* Returns the address of the first non-whitespace character in S, or
the address of the null terminator if none. */
static char *
/* Returns the address of the first non-whitespace character in S, or
the address of the null terminator if none. */
static char *
+
+const char hyphen_proxy = '_';
+
+static void
+id_cpy (char **cp)
+{
+ char *dest = tokstr;
+ char *src = *cp;
+
+ while (*src == '_' || *src == '-' || isalnum ((unsigned char) *src))
+ {
+ *dest++ = *src == '-' ? hyphen_proxy :toupper ((unsigned char) (*src));
+ src++;
+ }
+
+ *cp = src;
+ *dest++ = '\0';
+}
+
+static char *
+unmunge (const char *s)
+{
+ char *dest = xmalloc (strlen (s) + 1);
+ char *d = dest;
+
+ while (*s)
+ {
+ if (*s == hyphen_proxy)
+ *d = '-';
+ else
+ *d = *s;
+ s++;
+ d++;
+ }
+ *d = '\0';
+
+ return dest;
+}
+
+/* Writes a blank line to the output file and adjusts 'indent' by BASE_INDENT
+ * INDENTION characters.
+
+ (This is only useful because GCC complains about using "" as a format
+ string, for whatever reason.) */
+static void
+dump_blank_line (int indention)
+{
+ oln++;
+ indent += BASE_INDENT * indention;
+ putc ('\n', out);
+}
+
/* Write the structure members for specifier SPEC to the output file.
SBC is the including subcommand. */
static void
/* Write the structure members for specifier SPEC to the output file.
SBC is the including subcommand. */
static void
if (k)
sprintf (buf, "%s%s,", st_upper (prefix), sym->name);
if (k)
sprintf (buf, "%s%s,", st_upper (prefix), sym->name);
dump (0, "%s%scount", st_upper (prefix), st_upper (sbc->prefix));
dump (-1, "};");
dump (0, "%s%scount", st_upper (prefix), st_upper (sbc->prefix));
dump (-1, "};");
dump (0, "/* %s subcommand. */", sbc->name);
dump (0, "int sbc_%s;", st_lower (sbc->name));
dump (0, "/* %s subcommand. */", sbc->name);
dump (0, "int sbc_%s;", st_lower (sbc->name));
make_identifier (cmdname), make_identifier (cmdname));
dump (0, "static void free_%s (struct cmd_%s *);",
make_identifier (cmdname), make_identifier (cmdname));
make_identifier (cmdname), make_identifier (cmdname));
dump (0, "static void free_%s (struct cmd_%s *);",
make_identifier (cmdname), make_identifier (cmdname));
else if (isdigit ((unsigned char) t[0]))
sprintf (s, "lex_match_int (lexer, %s)", t);
else
else if (isdigit ((unsigned char) t[0]))
sprintf (s, "lex_match_int (lexer, %s)", t);
else
- sprintf (s, "lex_match_id (lexer, \"%s\")", t);
+ {
+ char *c = unmunge (t);
+ sprintf (s, "lex_match_hyphenated_word (lexer, \"%s\")", c);
+ free (c);
+ }
dump(1,"{");
dump (0, "lex_match (lexer, '=');");
dump(1,"if (lex_match_id(lexer, \"COMPATIBLE\"))");
dump(1,"{");
dump (0, "lex_match (lexer, '=');");
dump(1,"if (lex_match_id(lexer, \"COMPATIBLE\"))");
dump (1, "if (lex_token (lexer) != '.')");
dump (1, "{");
dump (0, "lex_error (lexer, _(\"expecting end of command\"));");
dump (0, "goto lossage;");
dump (-1, "}");
dump (1, "if (lex_token (lexer) != '.')");
dump (1, "{");
dump (0, "lex_error (lexer, _(\"expecting end of command\"));");
dump (0, "goto lossage;");
dump (-1, "}");
dump (-1, "lossage:");
indent ();
dump (0, "free_%s (p);", make_identifier (cmdname));
dump (0, "return false;");
dump (-1, "}");
dump (-1, "lossage:");
indent ();
dump (0, "free_%s (p);", make_identifier (cmdname));
dump (0, "return false;");
dump (-1, "}");
dump (0, " Generated by q2c from %s.", ifn);
dump (0, " Do not modify!");
dump (0, " */");
dump (0, " Generated by q2c from %s.", ifn);
dump (0, " Do not modify!");
dump (0, " */");
dump (0, "#include <libpspp/assertion.h>");
dump (0, "#include <libpspp/message.h>");
dump (0, "#include <language/lexer/lexer.h>");
dump (0, "#include <language/lexer/variable-parser.h>");
dump (0, "#include <data/settings.h>");
dump (0, "#include <libpspp/assertion.h>");
dump (0, "#include <libpspp/message.h>");
dump (0, "#include <language/lexer/lexer.h>");
dump (0, "#include <language/lexer/variable-parser.h>");
dump (0, "#include <data/settings.h>");
dump (0, "#include <libpspp/str.h>");
dump (0, "#include <language/lexer/subcommand-list.h>");
dump (0, "#include <data/variable.h>");
dump (0, "#include <libpspp/str.h>");
dump (0, "#include <language/lexer/subcommand-list.h>");
dump (0, "#include <data/variable.h>");
dump (0, "#include \"gettext.h\"");
dump (0, "#define _(msgid) gettext (msgid)");
dump (0, "#include \"gettext.h\"");
dump (0, "#define _(msgid) gettext (msgid)");