X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Flanguage%2Flexer%2Fq2c.c;h=cf8e53ee5cb881529ead693e0328f66e520a300b;hb=a46ed36dcbab01d36c08cf560ff96a7effd9779a;hp=4adea9e2dd752cd153e8f54d1c842c0306b7d82f;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp-builds.git
diff --git a/src/language/lexer/q2c.c b/src/language/lexer/q2c.c
index 4adea9e2..cf8e53ee 100644
--- a/src/language/lexer/q2c.c
+++ b/src/language/lexer/q2c.c
@@ -1,20 +1,18 @@
-/* q2c - parser generator for PSPP procedures.
- Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+/* PSPP - a program for statistical analysis.
+ 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 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
@@ -85,8 +83,6 @@ static char *tokstr;
/* Utility functions. */
-static char nullstr[] = "";
-
/* Close all open files and delete the output file, on failure. */
static void
finish_up (void)
@@ -110,8 +106,8 @@ hcf (void)
exit (EXIT_FAILURE);
}
-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;
/* Output an error message and terminate unsuccessfully. */
int
@@ -229,11 +225,11 @@ st_upper (const char *s)
/* Returns the address of the first non-whitespace character in S, or
the address of the null terminator if none. */
static char *
-skip_ws (const char *s)
+skip_ws (char *s)
{
while (isspace ((unsigned char) *s))
s++;
- return (char *) s;
+ return s;
}
/* Read one line from the input file into buf. Lines having special
@@ -359,6 +355,45 @@ dump_token (void)
}
#endif /* DUMP_TOKENS */
+
+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;
+}
+
/* Reads a token from the input file. */
static int
lex_get (void)
@@ -400,9 +435,8 @@ lex_get (void)
{
char *dest = tokstr;
token = T_ID;
- while (*cp == '_' || isalnum ((unsigned char) *cp))
- *dest++ = toupper ((unsigned char) (*cp++));
- *dest++ = '\0';
+
+ id_cpy (&cp);
}
else
token = *cp++;
@@ -938,6 +972,19 @@ dump (int indention, const char *format, ...)
indent += BASE_INDENT * indention;
}
+/* 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
@@ -1033,7 +1080,7 @@ dump_declarations (void)
if (buf == NULL)
buf = xmalloc (1024);
else
- dump (0, buf);
+ dump (0, "%s", buf);
if (k)
sprintf (buf, "%s%s,", st_upper (prefix), sym->name);
@@ -1046,13 +1093,13 @@ dump_declarations (void)
if (buf)
{
buf[strlen (buf) - 1] = 0;
- dump (0, buf);
+ dump (0, "%s", buf);
free (buf);
}
if (f)
{
dump (-1, "};");
- dump (-1, nullstr);
+ dump_blank_line (-1);
}
}
@@ -1086,7 +1133,7 @@ dump_declarations (void)
dump (0, "%s%scount", st_upper (prefix), st_upper (sbc->prefix));
dump (-1, "};");
- dump (-1, nullstr);
+ dump_blank_line (-1);
}
}
}
@@ -1103,7 +1150,7 @@ dump_declarations (void)
int f = 0;
if (sbc != subcommands)
- dump (0, nullstr);
+ dump_blank_line (0);
dump (0, "/* %s subcommand. */", sbc->name);
dump (0, "int sbc_%s;", st_lower (sbc->name));
@@ -1181,7 +1228,7 @@ dump_declarations (void)
}
dump (-1, "};");
- dump (-1, nullstr);
+ dump_blank_line (-1);
}
/* Write out prototypes for custom_*() functions as necessary. */
@@ -1204,7 +1251,7 @@ dump_declarations (void)
}
if (seen)
- dump (0, nullstr);
+ dump_blank_line (0);
}
/* Prototypes for parsing and freeing functions. */
@@ -1214,7 +1261,7 @@ dump_declarations (void)
make_identifier (cmdname), make_identifier (cmdname));
dump (0, "static void free_%s (struct cmd_%s *);",
make_identifier (cmdname), make_identifier (cmdname));
- dump (0, nullstr);
+ dump_blank_line (0);
}
}
@@ -1246,7 +1293,7 @@ dump_specifier_init (const specifier *spec, const subcommand *sbc)
assert (s->value == VAL_INT || s->value == VAL_DBL
|| s->value == VAL_STRING);
- init = (s->value == VAL_INT ? "NOT_LONG"
+ init = (s->value == VAL_INT ? "LONG_MIN"
: s->value == VAL_DBL ? "SYSMIS"
: "NULL");
@@ -1341,7 +1388,7 @@ dump_vars_init (int persistent)
dump (1, "{");
dump (0, "int i;");
dump (1, "for (i = 0; i < MAXLISTS; ++i)");
- dump (0, "p->n_%s[i] = NOT_LONG;", st_lower (sbc->name));
+ dump (0, "p->n_%s[i] = LONG_MIN;", st_lower (sbc->name));
dump (-2, "}");
break;
@@ -1376,7 +1423,11 @@ make_match (const char *t)
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);
+ }
return s;
}
@@ -1483,7 +1534,7 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc)
else if (s->value == VAL_STRING)
{
dump (1, "if (lex_token (lexer) != T_ID "
- "&& lex_token (lexer) != T_STRING)");
+ "&& !lex_is_string (lexer))");
dump (1, "{");
dump (0, "msg (SE, _(\"%s specifier of %s subcommand "
"requires a string argument.\"));",
@@ -1852,16 +1903,16 @@ dump_parser (int persistent)
/* Now deal with the /ALGORITHM subcommand implicit to all commands */
- dump(1,"else if ( get_syntax() != COMPATIBLE && lex_match_id(lexer, \"ALGORITHM\"))");
+ dump(1,"else if ( settings_get_syntax () != COMPATIBLE && lex_match_id(lexer, \"ALGORITHM\"))");
dump(1,"{");
dump (0, "lex_match (lexer, '=');");
dump(1,"if (lex_match_id(lexer, \"COMPATIBLE\"))");
- dump(0,"set_cmd_algorithm(COMPATIBLE);");
+ dump(0,"settings_set_cmd_algorithm (COMPATIBLE);");
outdent();
dump(1,"else if (lex_match_id(lexer, \"ENHANCED\"))");
- dump(0,"set_cmd_algorithm(ENHANCED);");
+ dump(0,"settings_set_cmd_algorithm (ENHANCED);");
dump (-1, "}");
outdent ();
@@ -1872,13 +1923,13 @@ dump_parser (int persistent)
dump (0, "break;");
dump (-2, "}");
outdent ();
- dump (0, nullstr);
+ dump_blank_line (0);
dump (1, "if (lex_token (lexer) != '.')");
dump (1, "{");
dump (0, "lex_error (lexer, _(\"expecting end of command\"));");
dump (0, "goto lossage;");
dump (-1, "}");
- dump (0, nullstr);
+ dump_blank_line (0);
outdent ();
@@ -1897,19 +1948,19 @@ dump_parser (int persistent)
sbc->name);
dump (0, "goto lossage;");
dump (-1, "}");
- dump (0, nullstr);
+ dump_blank_line (0);
}
}
}
dump (-1, "return true;");
- dump (0, nullstr);
+ dump_blank_line (0);
dump (-1, "lossage:");
indent ();
dump (0, "free_%s (p);", make_identifier (cmdname));
dump (0, "return false;");
dump (-1, "}");
- dump (0, nullstr);
+ dump_blank_line (0);
}
@@ -1919,7 +1970,7 @@ dump_header (void)
{
indent = 0;
dump (0, "/* %s\t\t-*- mode: c; buffer-read-only: t -*-", ofn);
- dump (0, nullstr);
+ dump_blank_line (0);
dump (0, " Generated by q2c from %s.", ifn);
dump (0, " Do not modify!");
dump (0, " */");
@@ -2075,21 +2126,22 @@ main (int argc, char *argv[])
indent = 0;
dump (0, "#include ");
- dump (0, "#include ");
dump (0, "#include ");
dump (0, "#include ");
dump (0, "#include ");
dump (0, "#include ");
dump (0, "#include ");
- dump (0, "#include ");
dump (0, "#include ");
dump (0, "#include ");
dump (0, "#include ");
- dump (0, nullstr);
+ dump_blank_line (0);
+
+ dump (0, "#include \"xalloc.h\"");
+ dump_blank_line (0);
dump (0, "#include \"gettext.h\"");
dump (0, "#define _(msgid) gettext (msgid)");
- dump (0, nullstr);
+ dump_blank_line (0);
}
else if (!strcmp (directive, "declarations"))
dump_declarations ();