X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fq2c.c;h=c1b7e8d77cc3c9b82a0ab770903a1137f1fed903;hb=e210b20bf6f405637c8c03dd280b5a4a627191b8;hp=5d188bbcedd1a04ca10b89d272aa45a5f8fbe693;hpb=eeb3352d718b0cd85afab3f7a7466fcac7791c1c;p=pspp diff --git a/src/q2c.c b/src/q2c.c index 5d188bbced..c1b7e8d77c 100644 --- a/src/q2c.c +++ b/src/q2c.c @@ -14,8 +14,8 @@ 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 #include @@ -53,7 +53,7 @@ #define MAX_TOK_LEN 1024 /* argv[0]. */ -char *pgmname; +char *program_name; /* Have the input and output files been opened yet? */ int is_open; @@ -97,7 +97,7 @@ finish_up (void) fclose (in); fclose (out); if (remove (ofn) == -1) - fprintf (stderr, "%s: %s: remove: %s\n", pgmname, ofn, strerror (errno)); + fprintf (stderr, "%s: %s: remove: %s\n", program_name, ofn, strerror (errno)); } void hcf (void) NO_RETURN; @@ -120,7 +120,7 @@ fail (const char *format, ...) va_list args; va_start (args, format); - fprintf (stderr, "%s: ", pgmname); + fprintf (stderr, "%s: ", program_name); vfprintf (stderr, format, args); fprintf (stderr, "\n"); va_end (args); @@ -284,7 +284,7 @@ add_symbol (const char *name, int unique, int value) symbol *iter, *sym; int x; - sym = xmalloc (sizeof (symbol)); + sym = xmalloc (sizeof *sym); sym->name = xstrdup (name); sym->unique = unique; sym->value = value; @@ -342,14 +342,11 @@ find_symbol (int x) #if DEBUGGING /* Writes a printable representation of the current token to stdout. */ -void +static void dump_token (void) { switch (token) { - case T_TSTRING: - printf ("TR_STRING\t\"%s\"\n", tokstr); - break; case T_STRING: printf ("STRING\t\"%s\"\n", tokstr); break; @@ -535,6 +532,13 @@ typedef enum } subcommand_type; +typedef enum + { + ARITY_ONCE_EXACTLY, /* must occur exactly once */ + ARITY_ONCE_ONLY, /* zero or once */ + ARITY_MANY /* 0, 1, ... , inf */ + }subcommand_arity; + /* A single subcommand. */ typedef struct subcommand subcommand; struct subcommand @@ -542,7 +546,7 @@ struct subcommand subcommand *next; /* Next in the chain. */ char *name; /* Subcommand name. */ subcommand_type type; /* One of SBC_*. */ - int once; /* 1=Subcommand may appear only once. */ + subcommand_arity arity; /* How many times should the subcommand occur*/ int narray; /* Index of next array element. */ const char *prefix; /* Prefix for variable and constant names. */ specifier *spec; /* Array of specifiers. */ @@ -553,16 +557,6 @@ struct subcommand int translatable; /* Error message is translatable */ }; -typedef struct aux_subcommand aux_subcommand; -struct aux_subcommand - { - aux_subcommand *next; /* Next in the chain. */ - char *name; /* Subcommand name. */ - char *value; /* Subcommand value */ - }; - -static aux_subcommand *aux_subcommands ; - /* Name of the command; i.e., DESCRIPTIVES. */ char *cmdname; @@ -720,7 +714,7 @@ parse_specifier (specifier *spec, subcommand *sbc) for (;;) { - *s = xmalloc (sizeof (setting)); + *s = xmalloc (sizeof **s); parse_setting (*s, spec); if (token == ',' || token == ';' || token == '.') break; @@ -745,7 +739,7 @@ parse_specifiers (subcommand *sbc) for (;;) { - *spec = xmalloc (sizeof (specifier)); + *spec = xmalloc (sizeof **spec); parse_specifier (*spec, sbc); if (token == ';' || token == '.') break; @@ -759,6 +753,8 @@ parse_specifiers (subcommand *sbc) static void parse_subcommand (subcommand *sbc) { + sbc->arity = ARITY_MANY; + if (match_token ('*')) { if (def) @@ -766,7 +762,11 @@ parse_subcommand (subcommand *sbc) def = sbc; } - sbc->once = match_token ('+'); + if ( match_token('+')) + sbc->arity = ARITY_ONCE_ONLY ; + else if (match_token('^')) + sbc->arity = ARITY_ONCE_EXACTLY ; + force_id (); sbc->name = xstrdup (tokstr); @@ -883,7 +883,7 @@ parse_subcommands (void) for (;;) { - *sbc = xmalloc (sizeof (subcommand)); + *sbc = xmalloc (sizeof **sbc); (*sbc)->next = NULL; parse_subcommand (*sbc); @@ -1133,7 +1133,7 @@ dump_declarations (void) break; case SBC_VARLIST: - dump (0, "int %sn_%s;", st_lower (sbc->prefix), + dump (0, "size_t %sn_%s;", st_lower (sbc->prefix), st_lower (sbc->name)); dump (0, "struct variable **%sv_%s;", st_lower (sbc->prefix), st_lower (sbc->name)); @@ -1448,7 +1448,7 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) if (s->value == VAL_INT) { - dump (1, "if (!lex_integer_p ())"); + dump (1, "if (!lex_is_integer ())"); dump (1, "{"); dump (0, "msg (SE, _(\"%s specifier of %s subcommand " "requires an integer argument.\"));", @@ -1460,7 +1460,7 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) } else { - dump (1, "if (token != T_NUM)"); + dump (1, "if (!lex_is_number ())"); dump (1, "{"); dump (0, "msg (SE, _(\"Number expected after %s " "specifier of %s subcommand.\"));", @@ -1611,7 +1611,7 @@ dump_subcommand (const subcommand *sbc) { dump (0, "p->%sv_%s = parse_variable ();", st_lower (sbc->prefix), st_lower (sbc->name)); - dump (1, "if (p->%sv_%s)", + dump (1, "if (!p->%sv_%s)", st_lower (sbc->prefix), st_lower (sbc->name)); dump (0, "goto lossage;"); outdent (); @@ -1648,7 +1648,7 @@ dump_subcommand (const subcommand *sbc) { dump (1, "if (!lex_force_num ())"); dump (0, "goto lossage;"); - dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_double ();", + dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_number ();", st_lower (sbc->name), st_lower (sbc->name) ); dump (0, "lex_get();"); } @@ -1700,7 +1700,7 @@ dump_subcommand (const subcommand *sbc) dump (0, "goto lossage;"); dump (-1,"}"); - dump (0, "subc_list_double_push(&p->dl_%s[p->sbc_%s-1],lex_double ());", + dump (0, "subc_list_double_push(&p->dl_%s[p->sbc_%s-1],lex_number ());", st_lower (sbc->name),st_lower (sbc->name) ); @@ -1805,7 +1805,7 @@ dump_parser (int persistent) dump (0, "lex_match ('=');"); dump (0, "p->sbc_%s++;", st_lower (sbc->name)); - if (sbc->once) + if (sbc->arity != ARITY_MANY) { dump (1, "if (p->sbc_%s > 1)", st_lower (sbc->name)); dump (1, "{"); @@ -1820,6 +1820,8 @@ dump_parser (int persistent) outdent (); } } + + /* Now deal with the /ALGORITHM subcommand implicit to all commands */ dump(1,"else if ( get_syntax() != COMPATIBLE && lex_match_id(\"ALGORITHM\"))"); dump(1,"{"); @@ -1835,6 +1837,7 @@ dump_parser (int persistent) dump (-1, "}"); outdent (); + dump (1, "if (!lex_match ('/'))"); dump (0, "break;"); @@ -1847,159 +1850,36 @@ dump_parser (int persistent) dump (0, "goto lossage;"); dump (-1, "}"); dump (0, nullstr); - dump (-1, "return 1;"); - dump (0, nullstr); - dump (-1, "lossage:"); - indent (); - dump (0, "free_%s (p);", make_identifier (cmdname)); - dump (0, "return 0;"); - dump (-1, "}"); - dump (0, nullstr); -} - - -/* Write out the code to parse aux subcommand SBC. */ -static void -dump_aux_subcommand (const subcommand *sbc) -{ - if (sbc->type == SBC_PLAIN ) - { - specifier *spec; - - for (spec = sbc->spec; spec; spec = spec->next) - { - char buf[80]; - sprintf(buf,"p->%s%s",st_lower(sbc->prefix),spec->varname); - - dump (0, "msg(MM,\"%s is %%s\",",sbc->name); - dump (0, "(%s < 1000)?\"not set\":settings[%s - 1000]", buf, buf); - - dump (0, ");"); - } - } - else if (sbc->type == SBC_STRING) - { - dump (0, "msg(MM,\"%s is \\\"%%s\\\"\",p->s_%s);", sbc->name,st_lower(sbc->name) ); - } - else if (sbc->type == SBC_INT) - { - dump (1, "{"); - dump (0, "int i;"); - dump (1, "for (i = 0; i < MAXLISTS; ++i)"); - dump (0, "msg(MM,\"%s is %%ld\",p->n_%s[i]);", sbc->name,st_lower(sbc->name) ); - outdent(); - dump (-1, "}"); - } - else if (sbc->type == SBC_CUSTOM) - { - dump (0, "aux_%scustom_%s(p);",st_lower(prefix),make_identifier(sbc->name)); - } - else - assert(0); -} - + outdent (); -/* Write out auxilliary parser. */ -static void -dump_aux_parser (void) -{ - int f=0; - subcommand *sbc; - aux_subcommand *asbc; - - /* Write out English strings for all the identifiers in the symbol table. */ { - int f, k; - symbol *sym; - char *buf = NULL; - - /* Note the squirmings necessary to make sure that the last string - is not followed by a comma (is it necessary to do that ?? ) */ - for (sym = symtab, f = k = 0; sym; sym = sym->next) - if (!sym->unique && !is_keyword (sym->name)) - { - if (!f) - { - dump (0, "/* Strings for subcommand specifiers. */"); - dump (1, "static const char *settings[]="); - dump (1, "{"); - f = 1; - } - - if (buf == NULL) - buf = xmalloc (1024); - else - dump (0, buf); + /* Check that mandatory subcommands have been specified */ + subcommand *sbc; - sprintf (buf, "\"%s\",",sym->name); - } - if (buf) - { - buf[strlen (buf) - 1] = 0; - dump (0, buf); - free (buf); - } - if (f) + for (sbc = subcommands; sbc; sbc = sbc->next) { - dump (-1, "};"); - dump (-1, nullstr); + + if ( sbc->arity == ARITY_ONCE_EXACTLY ) + { + 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, "goto lossage;"); + dump (-1, "}"); + dump (0, nullstr); + } } } - - indent = 0; - - dump (0, "static int"); - dump (0, "aux_parse_%s (struct cmd_%s *p)", make_identifier (cmdname), - make_identifier (cmdname)); - dump (1, "{"); - - dump (1, "for (;;)"); - dump (1, "{"); - - - for (sbc = subcommands; sbc; sbc = sbc->next) - { - dump (1, "%sif (%s)", f ? "else " : "", make_match (sbc->name)); - f = 1; - dump (1, "{"); - - dump_aux_subcommand (sbc); - - dump (-1, "}"); - outdent (); - } - - for (asbc = aux_subcommands ; asbc ; asbc = asbc->next) - { - dump (1, "%sif (%s)", f ? "else " : "", make_match (asbc->name)); - f = 1; - dump (1, "{"); - dump(0,"aux_%s();",make_identifier(asbc->value)); - dump (-1, "}"); - outdent (); - } - - dump (1, "if (!lex_match ('/'))"); - dump (0, "break;"); - dump (-2, "}"); - outdent (); - dump (0, nullstr); - dump (1, "if (token != '.')"); - dump (1, "{"); - dump (0, "lex_error (_(\"expecting end of command\"));"); - dump (0, "goto lossage;"); - dump (-1, "}"); - dump (0, nullstr); dump (-1, "return 1;"); dump (0, nullstr); dump (-1, "lossage:"); indent (); dump (0, "free_%s (p);", make_identifier (cmdname)); dump (0, "return 0;"); - dump (-1, "} /* aux_parse_%s (struct cmd_%s *p) */", - make_identifier (cmdname), make_identifier (cmdname)); + dump (-1, "}"); dump (0, nullstr); } @@ -2058,6 +1938,9 @@ dump_free (int persistent) { switch (sbc->type) { + case SBC_VARLIST: + dump (0, "free (p->v_variables);"); + break; case SBC_STRING: dump (0, "free (p->s_%s);", st_lower (sbc->name)); break; @@ -2106,12 +1989,10 @@ recognize_directive (void) return directive; } -static void aux_parse (void); - int main (int argc, char *argv[]) { - pgmname = argv[0]; + program_name = argv[0]; if (argc != 3) fail ("Syntax: q2c input.q output.c"); @@ -2167,7 +2048,10 @@ main (int argc, char *argv[]) dump (0, "#include \"str.h\""); dump (0, "#include \"subclist.h\""); dump (0, "#include \"var.h\""); + dump (0, nullstr); + dump (0, "#include \"gettext.h\""); + dump (0, "#define _(msgid) gettext (msgid)"); dump (0, nullstr); } else if (!strcmp (directive, "declarations")) @@ -2182,11 +2066,6 @@ main (int argc, char *argv[]) dump_parser (1); dump_free (1); } - else if (!strcmp (directive, "aux_functions")) - { - aux_parse(); - dump_aux_parser (); - } else error ("unknown directive `%s'", directive); indent = 0; @@ -2197,34 +2076,3 @@ main (int argc, char *argv[]) return EXIT_SUCCESS; } - -/* Parse an entire auxilliary specification. */ -static void -aux_parse (void) -{ - aux_subcommand *sbc; - aux_subcommand *prevsbc = 0 ; - get_line(); - lex_get(); - - for (;;) - { - sbc = xmalloc(sizeof(aux_subcommand)); - sbc->next = prevsbc; - sbc->name = xstrdup (tokstr); - lex_get(); - skip_token('='); - sbc->value = xstrdup (tokstr); - lex_get(); - if (token == '.') - break; - skip_token(';'); - prevsbc = sbc; - - } - /* Skip trailing star-slash line. */ - get_line (); - aux_subcommands = sbc; -} - -