X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Fq2c.c;h=1a95d08091936461b083a35b3d27531d3795151e;hb=c75794cffb05769b71a346af8513a3e8dde55f94;hp=4adea9e2dd752cd153e8f54d1c842c0306b7d82f;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp diff --git a/src/language/lexer/q2c.c b/src/language/lexer/q2c.c index 4adea9e2dd..1a95d08091 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; } @@ -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 ();