X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fq2c.c;h=3bba239035f7120ed1ac264ce42f3f156c1db809;hb=48dd2c7e82ecd7629109484ed873bcb67ec8c655;hp=5d188bbcedd1a04ca10b89d272aa45a5f8fbe693;hpb=eeb3352d718b0cd85afab3f7a7466fcac7791c1c;p=pspp diff --git a/src/q2c.c b/src/q2c.c index 5d188bbced..3bba239035 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 @@ -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. */ @@ -720,7 +724,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 +749,7 @@ parse_specifiers (subcommand *sbc) for (;;) { - *spec = xmalloc (sizeof (specifier)); + *spec = xmalloc (sizeof **spec); parse_specifier (*spec, sbc); if (token == ';' || token == '.') break; @@ -759,6 +763,8 @@ parse_specifiers (subcommand *sbc) static void parse_subcommand (subcommand *sbc) { + sbc->arity = ARITY_MANY; + if (match_token ('*')) { if (def) @@ -766,7 +772,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 +893,7 @@ parse_subcommands (void) for (;;) { - *sbc = xmalloc (sizeof (subcommand)); + *sbc = xmalloc (sizeof **sbc); (*sbc)->next = NULL; parse_subcommand (*sbc); @@ -1133,7 +1143,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 +1458,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 +1470,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 +1621,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 +1658,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 +1710,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 +1815,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 +1830,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 +1847,7 @@ dump_parser (int persistent) dump (-1, "}"); outdent (); + dump (1, "if (!lex_match ('/'))"); dump (0, "break;"); @@ -1847,6 +1860,29 @@ dump_parser (int persistent) dump (0, "goto lossage;"); dump (-1, "}"); dump (0, nullstr); + + outdent (); + + { + /* Check that mandatory subcommands have been specified */ + subcommand *sbc; + + for (sbc = subcommands; sbc; sbc = sbc->next) + { + + 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); + } + } + } + dump (-1, "return 1;"); dump (0, nullstr); dump (-1, "lossage:"); @@ -2058,6 +2094,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; @@ -2167,7 +2206,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")) @@ -2209,7 +2251,7 @@ aux_parse (void) for (;;) { - sbc = xmalloc(sizeof(aux_subcommand)); + sbc = xmalloc (sizeof *sbc); sbc->next = prevsbc; sbc->name = xstrdup (tokstr); lex_get();