X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Fq2c.c;h=27ff530d318eb9c364ba7db5d59fb8e99c13cc4a;hb=dd415397beff015f3e9dabde00c95db263c99768;hp=be0f29c5216ac392209e3e075a6df469208b54b2;hpb=15d25f33d8af81f11ac05379ae267f85da2b3077;p=pspp diff --git a/src/language/lexer/q2c.c b/src/language/lexer/q2c.c index be0f29c521..27ff530d31 100644 --- a/src/language/lexer/q2c.c +++ b/src/language/lexer/q2c.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2008 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2008, 2010, 2011 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 @@ -83,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) @@ -108,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 @@ -227,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 @@ -587,11 +585,7 @@ struct subcommand int narray; /* Index of next array element. */ const char *prefix; /* Prefix for variable and constant names. */ specifier *spec; /* Array of specifiers. */ - - /* SBC_STRING and SBC_INT only. */ - char *restriction; /* Expression restricting string length. */ - char *message; /* Error message. */ - int translatable; /* Error message is translatable */ + char *pv_options; /* PV_* options for SBC_VARLIST. */ }; /* Name of the command; i.e., DESCRIPTIVES. */ @@ -813,7 +807,6 @@ parse_subcommand (subcommand *sbc) sbc->narray = 0; sbc->type = SBC_PLAIN; sbc->spec = NULL; - sbc->translatable = 0; if (match_token ('[')) { @@ -850,39 +843,18 @@ parse_subcommand (subcommand *sbc) if (match_token ('(')) { force_string (); - sbc->message = xstrdup (tokstr); + sbc->pv_options = xstrdup (tokstr); lex_get(); skip_token (')'); } - else sbc->message = NULL; + else + sbc->pv_options = NULL; sbc->type = SBC_VARLIST; } else if (match_id ("INTEGER")) - { sbc->type = match_id ("LIST") ? SBC_INT_LIST : SBC_INT; - if ( token == T_STRING) - { - sbc->restriction = xstrdup (tokstr); - lex_get (); - if ( match_id("N_") ) - { - skip_token('('); - force_string (); - lex_get(); - skip_token(')'); - sbc->translatable = 1; - } - else { - force_string (); - lex_get (); - } - sbc->message = xstrdup (tokstr); - } - else - sbc->restriction = NULL; - } else if (match_id ("PINT")) sbc->type = SBC_PINT; else if (match_id ("DOUBLE")) @@ -893,19 +865,7 @@ parse_subcommand (subcommand *sbc) sbc->type = SBC_DBL; } else if (match_id ("STRING")) - { - sbc->type = SBC_STRING; - if (token == T_STRING) - { - sbc->restriction = xstrdup (tokstr); - lex_get (); - force_string (); - sbc->message = xstrdup (tokstr); - lex_get (); - } - else - sbc->restriction = NULL; - } + sbc->type = SBC_STRING; else if (match_id ("CUSTOM")) sbc->type = SBC_CUSTOM; else @@ -974,6 +934,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 @@ -1069,7 +1042,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); @@ -1082,13 +1055,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); } } @@ -1122,7 +1095,7 @@ dump_declarations (void) dump (0, "%s%scount", st_upper (prefix), st_upper (sbc->prefix)); dump (-1, "};"); - dump (-1, nullstr); + dump_blank_line (-1); } } } @@ -1139,7 +1112,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)); @@ -1217,7 +1190,7 @@ dump_declarations (void) } dump (-1, "};"); - dump (-1, nullstr); + dump_blank_line (-1); } /* Write out prototypes for custom_*() functions as necessary. */ @@ -1240,7 +1213,7 @@ dump_declarations (void) } if (seen) - dump (0, nullstr); + dump_blank_line (0); } /* Prototypes for parsing and freeing functions. */ @@ -1250,7 +1223,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); } } @@ -1411,12 +1384,14 @@ make_match (const char *t) "|| lex_match_id (lexer, \"FALSE\"))"); else if (isdigit ((unsigned char) t[0])) sprintf (s, "lex_match_int (lexer, %s)", t); - else + else if (strchr (t, hyphen_proxy)) { char *c = unmunge (t); - sprintf (s, "lex_match_hyphenated_word (lexer, \"%s\")", c); + sprintf (s, "lex_match_phrase (lexer, \"%s\")", c); free (c); } + else + sprintf (s, "lex_match_id (lexer, \"%s\")", t); return s; } @@ -1480,17 +1455,16 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) { if (s->optvalue) { - dump (1, "if (lex_match (lexer, '('))"); + dump (1, "if (lex_match (lexer, T_LPAREN))"); dump (1, "{"); } else { - dump (1, "if (!lex_match (lexer, '('))"); + dump (1, "if (!lex_match (lexer, T_LPAREN))"); dump (1, "{"); - dump (0, "msg (SE, _(\"`(' expected after %s " - "specifier of %s subcommand.\"));", - s->specname, sbc->name); - dump (0, "goto lossage;"); + dump (0, "lex_error_expecting (lexer, \"`('\", " + "NULL_SENTINEL);"); + dump (0, "goto lossage;"); dump (-1, "}"); outdent (); } @@ -1498,40 +1472,24 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) if (s->value == VAL_INT) { - dump (1, "if (!lex_is_integer (lexer))"); - dump (1, "{"); - dump (0, "msg (SE, _(\"%s specifier of %s subcommand " - "requires an integer argument.\"));", - s->specname, sbc->name); + dump (1, "if (!lex_force_int (lexer))"); dump (0, "goto lossage;"); - dump (-1, "}"); dump (-1, "p->%s%s = lex_integer (lexer);", sbc->prefix, st_lower (s->valname)); } else if (s->value == VAL_DBL) { - dump (1, "if (!lex_is_number (lexer))"); - dump (1, "{"); - dump (0, "msg (SE, _(\"Number expected after %s " - "specifier of %s subcommand.\"));", - s->specname, sbc->name); + dump (1, "if (!lex_force_num (lexer))"); dump (0, "goto lossage;"); - dump (-1, "}"); dump (-1, "p->%s%s = lex_tokval (lexer);", sbc->prefix, st_lower (s->valname)); } else if (s->value == VAL_STRING) { - dump (1, "if (lex_token (lexer) != T_ID " - "&& lex_token (lexer) != T_STRING)"); - dump (1, "{"); - dump (0, "msg (SE, _(\"%s specifier of %s subcommand " - "requires a string argument.\"));", - s->specname, sbc->name); + dump (1, "if (!lex_force_string_or_id (lexer))"); dump (0, "goto lossage;"); - dump (-1, "}"); dump (-1, "free (p->%s%s);", sbc->prefix, st_lower (s->valname)); - dump (0, "p->%s%s = xstrdup (ds_cstr (lex_tokstr (lexer)));", + dump (0, "p->%s%s = ss_xstrdup (ss_tokss (lexer));", sbc->prefix, st_lower (s->valname)); } else @@ -1552,9 +1510,7 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) } dump (1, "{"); - dump (0, "msg (SE, _(\"Bad argument for %s " - "specifier of %s subcommand.\"));", - s->specname, sbc->name); + dump (0, "lex_error (lexer, NULL);"); dump (0, "goto lossage;"); dump (-1, "}"); outdent (); @@ -1564,13 +1520,8 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) if (s->valtype == VT_PAREN) { - dump (1, "if (!lex_match (lexer, ')'))"); - dump (1, "{"); - dump (0, "msg (SE, _(\"`)' expected after argument for " - "%s specifier of %s.\"));", - s->specname, sbc->name); + dump (1, "if (!lex_force_match (lexer, T_RPAREN))"); dump (0, "goto lossage;"); - dump (-1, "}"); outdent (); if (s->optvalue) { @@ -1600,7 +1551,7 @@ dump_subcommand (const subcommand *sbc) { int count; - dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')"); + dump (1, "while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)"); dump (1, "{"); { @@ -1658,7 +1609,7 @@ dump_subcommand (const subcommand *sbc) } } - dump (0, "lex_match (lexer, ',');"); + dump (0, "lex_match (lexer, T_COMMA);"); dump (-1, "}"); outdent (); } @@ -1668,8 +1619,8 @@ dump_subcommand (const subcommand *sbc) "PV_APPEND%s%s))", st_lower (sbc->prefix), st_lower (sbc->name), st_lower (sbc->prefix), st_lower (sbc->name), - sbc->message ? " |" : "", - sbc->message ? sbc->message : ""); + sbc->pv_options ? " |" : "", + sbc->pv_options ? sbc->pv_options : ""); dump (0, "goto lossage;"); outdent (); } @@ -1684,31 +1635,13 @@ dump_subcommand (const subcommand *sbc) } else if (sbc->type == SBC_STRING) { - if (sbc->restriction) - { - dump (1, "{"); - dump (0, "int x;"); - } dump (1, "if (!lex_force_string (lexer))"); dump (0, "return false;"); outdent (); - if (sbc->restriction) - { - dump (0, "x = ds_length (lex_tokstr (lexer));"); - dump (1, "if (!(%s))", sbc->restriction); - dump (1, "{"); - dump (0, "msg (SE, _(\"String for %s must be %s.\"));", - sbc->name, sbc->message); - dump (0, "goto lossage;"); - dump (-1, "}"); - outdent (); - } dump (0, "free(p->s_%s);", st_lower(sbc->name) ); - dump (0, "p->s_%s = ds_xstrdup (lex_tokstr (lexer));", + dump (0, "p->s_%s = ss_xstrdup (lex_tokss (lexer));", st_lower (sbc->name)); dump (0, "lex_get (lexer);"); - if (sbc->restriction) - dump (-1, "}"); } else if (sbc->type == SBC_DBL) { @@ -1726,41 +1659,29 @@ dump_subcommand (const subcommand *sbc) dump (0, "goto lossage;"); dump (-1, "x = lex_integer (lexer);"); dump (0, "lex_get(lexer);"); - if (sbc->restriction) - { - char buf[1024]; - dump (1, "if (!(%s))", sbc->restriction); - dump (1, "{"); - sprintf(buf,sbc->message,sbc->name); - if ( sbc->translatable ) - dump (0, "msg (SE, gettext(\"%s\"));",buf); - else - dump (0, "msg (SE, \"%s\");",buf); - dump (0, "goto lossage;"); - dump (-1, "}"); - } dump (0, "p->n_%s[p->sbc_%s - 1] = x;", st_lower (sbc->name), st_lower(sbc->name) ); dump (-1,"}"); } else if (sbc->type == SBC_PINT) { - dump (0, "lex_match (lexer, '(');"); + dump (0, "lex_match (lexer, T_LPAREN);"); dump (1, "if (!lex_force_int (lexer))"); dump (0, "goto lossage;"); dump (-1, "p->n_%s = lex_integer (lexer);", st_lower (sbc->name)); - dump (0, "lex_match (lexer, ')');"); + dump (0, "lex_match (lexer, T_RPAREN);"); } else if (sbc->type == SBC_DBL_LIST || sbc->type == SBC_INT_LIST) { dump (0, "if ( p->sbc_%s > MAXLISTS)",st_lower(sbc->name)); dump (1, "{"); - dump (0, "msg (SE, \"No more than %%d %s subcommands allowed\",MAXLISTS);",st_lower(sbc->name)); + dump (0, "subc_list_error (lexer, \"%s\", MAXLISTS);", + st_lower(sbc->name)); dump (0, "goto lossage;"); dump (-1,"}"); - dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')"); + dump (1, "while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)"); dump (1, "{"); - dump (0, "lex_match (lexer, ',');"); + dump (0, "lex_match (lexer, T_COMMA);"); dump (0, "if (!lex_force_num (lexer))"); dump (1, "{"); dump (0, "goto lossage;"); @@ -1808,7 +1729,7 @@ dump_parser (int persistent) dump (0, "static int"); dump (0, "parse_%s (struct lexer *lexer, struct dataset *ds%s, struct cmd_%s *p, void *aux UNUSED)", make_identifier (cmdname), - (def && ( def->type == SBC_VARLIST && def->type == SBC_CUSTOM))?"":" UNUSED", + (def && ( def->type == SBC_VARLIST || def->type == SBC_CUSTOM))?"":" UNUSED", make_identifier (cmdname)); dump (1, "{"); @@ -1822,13 +1743,13 @@ dump_parser (int persistent) { if (def->type == SBC_VARLIST) dump (1, "if (lex_token (lexer) == T_ID " - "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != NULL " - "&& lex_look_ahead (lexer) != '=')"); + "&& dict_lookup_var (dataset_dict (ds), lex_tokcstr (lexer)) != NULL " + "&& lex_next_token (lexer, 1) != T_EQUALS)"); else { dump (0, "if ((lex_token (lexer) == T_ID " - "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) " - "&& lex_look_ahead () != '=')"); + "&& dict_lookup_var (dataset_dict (ds), lex_tokcstr (lexer)) " + "&& lex_next_token (lexer, 1) != T_EQUALS)"); dump (1, " || token == T_ALL)"); } dump (1, "{"); @@ -1872,14 +1793,13 @@ dump_parser (int persistent) f = 1; dump (1, "{"); - dump (0, "lex_match (lexer, '=');"); + dump (0, "lex_match (lexer, T_EQUALS);"); dump (0, "p->sbc_%s++;", st_lower (sbc->name)); if (sbc->arity != ARITY_MANY) { dump (1, "if (p->sbc_%s > 1)", st_lower (sbc->name)); dump (1, "{"); - dump (0, "msg (SE, _(\"%s subcommand may be given only once.\"));", - sbc->name); + dump (0, "lex_sbc_only_once (\"%s\");", sbc->name); dump (0, "goto lossage;"); dump (-1, "}"); outdent (); @@ -1895,7 +1815,7 @@ dump_parser (int persistent) dump(1,"else if ( settings_get_syntax () != COMPATIBLE && lex_match_id(lexer, \"ALGORITHM\"))"); dump(1,"{"); - dump (0, "lex_match (lexer, '=');"); + dump (0, "lex_match (lexer, T_EQUALS);"); dump(1,"if (lex_match_id(lexer, \"COMPATIBLE\"))"); dump(0,"settings_set_cmd_algorithm (COMPATIBLE);"); @@ -1908,17 +1828,17 @@ dump_parser (int persistent) - dump (1, "if (!lex_match (lexer, '/'))"); + dump (1, "if (!lex_match (lexer, T_SLASH))"); dump (0, "break;"); dump (-2, "}"); outdent (); - dump (0, nullstr); - dump (1, "if (lex_token (lexer) != '.')"); + dump_blank_line (0); + dump (1, "if (lex_token (lexer) != T_ENDCMD)"); 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 (); @@ -1933,23 +1853,22 @@ dump_parser (int persistent) { dump (0, "if ( 0 == p->sbc_%s)", st_lower (sbc->name)); dump (1, "{"); - dump (0, "msg (SE, _(\"%s subcommand must be given.\"));", - sbc->name); + dump (0, "lex_sbc_missing (\"%s\");", 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); } @@ -1959,7 +1878,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, " */"); @@ -2115,22 +2034,21 @@ 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, nullstr); - - dump (0, "#include \"xalloc.h\""); - dump (0, nullstr); - - dump (0, "#include \"gettext.h\""); - dump (0, "#define _(msgid) gettext (msgid)"); - dump (0, nullstr); + dump_blank_line (0); + + dump (0, "#include \"data/settings.h\""); + dump (0, "#include \"data/variable.h\""); + dump (0, "#include \"language/lexer/lexer.h\""); + dump (0, "#include \"language/lexer/subcommand-list.h\""); + dump (0, "#include \"language/lexer/variable-parser.h\""); + dump (0, "#include \"libpspp/assertion.h\""); + dump (0, "#include \"libpspp/cast.h\""); + dump (0, "#include \"libpspp/message.h\""); + dump (0, "#include \"libpspp/str.h\""); + dump_blank_line (0); + + dump (0, "#include \"gl/xalloc.h\""); + dump_blank_line (0); } else if (!strcmp (directive, "declarations")) dump_declarations ();