From 95612cfa608188fc323ed3f8560cc6aea953ff32 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 12 Nov 2002 08:05:59 +0000 Subject: [PATCH] * src/struniq.h, src/struniq.c (struniq_t): Is const. (STRUNIQ_EQ, struniq_assert, struniq_assert_p): New. Use struniq for symbols. * src/symtab.h (symbol_t): The tag member is a struniq. (symbol_type_set): Adjust. * src/symtab.c (symbol_new): Takes a struniq. (symbol_free): Don't free the tag member. (hash_compare_symbol_t, hash_symbol_t): Rename as... (hash_compare_symbol, hash_symbol): these. Use the fact that tags as struniqs. (symbol_get): Use struniq_new. * src/symlist.h, src/symlist.c (symbol_list_n_type_name_get): Returns a strniq. * src/reader.h (merger_list, grammar_currentmerge_set): The name and type members are struniqs. * src/reader.c (get_merge_function) (grammar_current_rule_merge_set): Adjust. (TYPE, current_type): Are struniq. Use struniq for file names. * src/files.h, src/files.c (infile): Split into... (grammar_file, current_file): these. * src/scan-gram.c (YY_USER_INIT, handle_syncline): Adjust. * src/reduce.c (reduce_print): Likewise. * src/getargs.c (getargs): Likewise. * src/complain.h, src/complain.c: Likewise. * src/main.c (main): Call struniqs_new early enough to use it for file names. Don't free the input file name. --- ChangeLog | 35 ++++++++++++ src/complain.c | 6 +-- src/complain.h | 2 +- src/files.c | 7 +-- src/files.h | 10 +++- src/getargs.c | 3 +- src/main.c | 5 +- src/muscle_tab.c | 2 +- src/output.c | 6 +-- src/parse-gram.c | 158 +++++++++++++++++++++++++++---------------------------- src/parse-gram.y | 5 +- src/reader.c | 21 ++++---- src/reader.h | 6 +-- src/reduce.c | 4 +- src/scan-gram.l | 8 ++- src/struniq.c | 27 ++++++++-- src/struniq.h | 9 +++- src/symlist.c | 2 +- src/symlist.h | 2 +- src/symtab.c | 25 +++++---- src/symtab.h | 4 +- 21 files changed, 208 insertions(+), 139 deletions(-) diff --git a/ChangeLog b/ChangeLog index 20d8cd1..2e7843a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,40 @@ 2002-11-12 Akim Demaille + * src/struniq.h, src/struniq.c (struniq_t): Is const. + (STRUNIQ_EQ, struniq_assert, struniq_assert_p): New. + + Use struniq for symbols. + + * src/symtab.h (symbol_t): The tag member is a struniq. + (symbol_type_set): Adjust. + * src/symtab.c (symbol_new): Takes a struniq. + (symbol_free): Don't free the tag member. + (hash_compare_symbol_t, hash_symbol_t): Rename as... + (hash_compare_symbol, hash_symbol): these. + Use the fact that tags as struniqs. + (symbol_get): Use struniq_new. + * src/symlist.h, src/symlist.c (symbol_list_n_type_name_get): + Returns a strniq. + * src/reader.h (merger_list, grammar_currentmerge_set): The name + and type members are struniqs. + * src/reader.c (get_merge_function) + (grammar_current_rule_merge_set): Adjust. + (TYPE, current_type): Are struniq. + + Use struniq for file names. + + * src/files.h, src/files.c (infile): Split into... + (grammar_file, current_file): these. + * src/scan-gram.c (YY_USER_INIT, handle_syncline): Adjust. + * src/reduce.c (reduce_print): Likewise. + * src/getargs.c (getargs): Likewise. + * src/complain.h, src/complain.c: Likewise. + * src/main.c (main): Call struniqs_new early enough to use it for + file names. + Don't free the input file name. + +2002-11-12 Akim Demaille + * src/symtab.c (symbol_free): Remove dead deactivated code: type_name are properly removed. Don't use XFREE to free items that cannot be NULL. diff --git a/src/complain.c b/src/complain.c index 7adff36..7d2f0c5 100644 --- a/src/complain.c +++ b/src/complain.c @@ -117,7 +117,7 @@ warn (const char *message, ...) va_list args; fflush (stdout); - fprintf (stderr, "%s: %s", infile ? infile : program_name, _("warning: ")); + fprintf (stderr, "%s: %s", current_file ? current_file : program_name, _("warning: ")); va_start (args, message); vfprintf (stderr, message, args); @@ -156,7 +156,7 @@ complain (const char *message, ...) va_list args; fflush (stdout); - fprintf (stderr, "%s: ", infile ? infile : program_name); + fprintf (stderr, "%s: ", current_file ? current_file : program_name); va_start (args, message); vfprintf (stderr, message, args); @@ -195,7 +195,7 @@ fatal (const char *message, ...) va_list args; fflush (stdout); - fprintf (stderr, "%s: ", infile ? infile : program_name); + fprintf (stderr, "%s: ", current_file ? current_file : program_name); fputs (_("fatal error: "), stderr); diff --git a/src/complain.h b/src/complain.h index 0e527c4..5c15b3f 100644 --- a/src/complain.h +++ b/src/complain.h @@ -50,7 +50,7 @@ void fatal_at (location_t location, const char *format, ...) __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))); /* Position in the current input file. */ -extern char *infile; +extern const char *current_file; /* This variable is set each time `warn' is called. */ extern bool warning_issued; diff --git a/src/files.c b/src/files.c index 7815e37..02cf0dd 100644 --- a/src/files.c +++ b/src/files.c @@ -50,7 +50,8 @@ char *spec_graph_file = NULL; /* for -g. */ char *spec_defines_file = NULL; /* for --defines. */ char *parser_file_name = NULL; -char *infile = NULL; +struniq_t grammar_file = NULL; +struniq_t current_file = NULL; static char *full_base_name = NULL; @@ -279,7 +280,7 @@ compute_base_names (void) { /* Otherwise, the short base name is computed from the input grammar: `foo/bar.yy' => `bar'. */ - filename_split (infile, &base, &tab, &ext); + filename_split (grammar_file, &base, &tab, &ext); short_base_name = xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0))); @@ -291,7 +292,7 @@ compute_base_names (void) stpcpy (stpcpy (full_base_name, short_base_name), EXT_TAB); /* Computes the extensions from the grammar file name. */ - filename_split (infile, &base, &tab, &ext); + filename_split (grammar_file, &base, &tab, &ext); if (ext && !yacc_flag) compute_exts_from_gf (ext); } diff --git a/src/files.h b/src/files.h index a6cbfa2..26d1590 100644 --- a/src/files.h +++ b/src/files.h @@ -21,6 +21,8 @@ #ifndef FILES_H_ # define FILES_H_ +# include "struniq.h" + /* File name specified with -o for the output file, or 0 if no -o. */ extern char *spec_outfile; @@ -50,7 +52,13 @@ extern FILE *finput; extern struct obstack pre_prologue_obstack; extern struct obstack post_prologue_obstack; -extern char *infile; +/* The file name as given on the command line. + Not named "input_file" because Flex uses this name for an argument, + and therefore GCC warns about a name clash. */ +extern struniq_t grammar_file; + +/* The current file name. Might change with %include, or with #line. */ +extern struniq_t current_file; void compute_output_file_names (void); diff --git a/src/getargs.c b/src/getargs.c index 061ec7f..4411656 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -24,6 +24,7 @@ #include "argmatch.h" #include "error.h" #include "complain.h" +#include "struniq.h" #include "getargs.h" #include "files.h" @@ -419,5 +420,5 @@ getargs (int argc, char *argv[]) usage (EXIT_FAILURE); } - infile = xstrdup (argv[optind]); + current_file = grammar_file = struniq_new (argv[optind]); } diff --git a/src/main.c b/src/main.c index f86bfda..ce470f3 100644 --- a/src/main.c +++ b/src/main.c @@ -55,6 +55,8 @@ main (int argc, char *argv[]) (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); + struniqs_new (); + getargs (argc, argv); time_report = trace_flag & trace_time; @@ -64,7 +66,6 @@ main (int argc, char *argv[]) if (trace_flag & trace_bitsets) bitset_stats_enable (); - struniqs_new (); muscle_init (); /* Read the input. Copy some parts of it to FGUARD, FACTION, FTABLE @@ -160,8 +161,6 @@ main (int argc, char *argv[]) reduce_free (); conflicts_free (); grammar_free (); - /* FIXME: We are leaking all the other file names. */ - free (infile); /* The scanner memory cannot be released right after parsing, as it contains things such as user actions, prologue, epilogue etc. */ diff --git a/src/muscle_tab.c b/src/muscle_tab.c index 92af0df..979604f 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -65,7 +65,7 @@ muscle_init (void) /* Version and input file. */ MUSCLE_INSERT_STRING ("version", VERSION); - MUSCLE_INSERT_C_STRING ("filename", infile); + MUSCLE_INSERT_C_STRING ("filename", grammar_file); } diff --git a/src/output.c b/src/output.c index 63d0202..177e6c0 100644 --- a/src/output.c +++ b/src/output.c @@ -198,7 +198,7 @@ prepare_symbols (void) /*-------------------------------------------------------------. | Prepare the muscles related to the rules: rhs, prhs, r1, r2, | -| rline, dprec, merger | +| rline, dprec, merger. | `-------------------------------------------------------------*/ static void @@ -230,9 +230,9 @@ prepare_rules (void) rhs[i++] = -1; /* Line where rule was defined. */ rline[r] = rules[r].location.first_line; - /* Dynamic precedence (GLR) */ + /* Dynamic precedence (GLR). */ dprec[r] = rules[r].dprec; - /* Merger-function index (GLR) */ + /* Merger-function index (GLR). */ merger[r] = rules[r].merger; } assert (i == nritems); diff --git a/src/parse-gram.c b/src/parse-gram.c index 69ef7eb..5d2706c 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -207,7 +207,7 @@ do { \ static void yyprint (FILE *file, int type, const yystype *value); symbol_class current_class = unknown_sym; -char *current_type = 0; +struniq_t current_type = 0; symbol_t *current_lhs; location_t current_lhs_location; assoc_t current_assoc; @@ -458,14 +458,14 @@ static const yysigned_char yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const unsigned short yyrline[] = { - 0, 168, 168, 181, 183, 186, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, - 204, 205, 206, 207, 208, 211, 213, 214, 218, 225, - 224, 235, 234, 247, 246, 252, 252, 257, 266, 281, - 283, 284, 287, 289, 294, 296, 300, 305, 310, 316, - 322, 332, 335, 344, 346, 352, 354, 359, 366, 365, - 370, 372, 375, 378, 380, 382, 384, 386, 390, 392, - 395, 401, 410, 418, 423, 429, 431 + 0, 169, 169, 182, 184, 187, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 199, 200, 201, 202, 203, + 205, 206, 207, 208, 209, 212, 214, 215, 219, 226, + 225, 236, 235, 248, 247, 253, 253, 258, 267, 282, + 284, 285, 288, 290, 295, 297, 301, 306, 311, 317, + 323, 333, 336, 345, 347, 353, 355, 360, 367, 366, + 371, 373, 376, 379, 381, 383, 385, 387, 391, 393, + 396, 402, 411, 419, 424, 430, 432 }; #endif @@ -1216,7 +1216,7 @@ yyreduce: switch (yyn) { case 2: -#line 170 "parse-gram.y" +#line 171 "parse-gram.y" { yycontrol->errcode = 0; epilogue_set (yyvsp[0].string, yylsp[0]); @@ -1224,109 +1224,109 @@ yyreduce: break; case 6: -#line 188 "parse-gram.y" +#line 189 "parse-gram.y" { prologue_augment (yyvsp[0].string, yylsp[0]); } break; case 7: -#line 189 "parse-gram.y" +#line 190 "parse-gram.y" { debug_flag = 1; } break; case 8: -#line 190 "parse-gram.y" +#line 191 "parse-gram.y" { muscle_insert (yyvsp[-1].string, yyvsp[0].string); } break; case 9: -#line 191 "parse-gram.y" +#line 192 "parse-gram.y" { defines_flag = 1; } break; case 10: -#line 192 "parse-gram.y" +#line 193 "parse-gram.y" { error_verbose = 1; } break; case 11: -#line 193 "parse-gram.y" +#line 194 "parse-gram.y" { expected_conflicts = yyvsp[0].integer; } break; case 12: -#line 194 "parse-gram.y" +#line 195 "parse-gram.y" { spec_file_prefix = yyvsp[0].string; } break; case 13: -#line 195 "parse-gram.y" +#line 196 "parse-gram.y" { glr_parser = 1; } break; case 14: -#line 197 "parse-gram.y" +#line 198 "parse-gram.y" { muscle_pair_list_grow ("lex_param", yyvsp[-2].string, yyvsp[0].string); } break; case 15: -#line 198 "parse-gram.y" +#line 199 "parse-gram.y" { locations_flag = 1; } break; case 16: -#line 199 "parse-gram.y" +#line 200 "parse-gram.y" { spec_name_prefix = yyvsp[0].string; } break; case 17: -#line 200 "parse-gram.y" +#line 201 "parse-gram.y" { no_lines_flag = 1; } break; case 18: -#line 201 "parse-gram.y" +#line 202 "parse-gram.y" { spec_outfile = yyvsp[0].string; } break; case 19: -#line 203 "parse-gram.y" +#line 204 "parse-gram.y" { muscle_pair_list_grow ("parse_param", yyvsp[-2].string, yyvsp[0].string); } break; case 20: -#line 204 "parse-gram.y" +#line 205 "parse-gram.y" { pure_parser = 1; } break; case 21: -#line 205 "parse-gram.y" +#line 206 "parse-gram.y" { skeleton = yyvsp[0].string; } break; case 22: -#line 206 "parse-gram.y" +#line 207 "parse-gram.y" { token_table_flag = 1; } break; case 23: -#line 207 "parse-gram.y" +#line 208 "parse-gram.y" { report_flag = 1; } break; case 24: -#line 208 "parse-gram.y" +#line 209 "parse-gram.y" { yacc_flag = 1; } break; case 27: -#line 215 "parse-gram.y" +#line 216 "parse-gram.y" { grammar_start_symbol_set (yyvsp[0].symbol, yylsp[0]); } break; case 28: -#line 219 "parse-gram.y" +#line 220 "parse-gram.y" { typed = 1; MUSCLE_INSERT_INT ("stype_line", yylsp[0].first_line); @@ -1335,12 +1335,12 @@ yyreduce: break; case 29: -#line 225 "parse-gram.y" +#line 226 "parse-gram.y" { current_braced_code = destructor_braced_code; } break; case 30: -#line 227 "parse-gram.y" +#line 228 "parse-gram.y" { symbol_list_t *list; for (list = yyvsp[0].list; list; list = list->next) @@ -1351,12 +1351,12 @@ yyreduce: break; case 31: -#line 235 "parse-gram.y" +#line 236 "parse-gram.y" { current_braced_code = printer_braced_code; } break; case 32: -#line 237 "parse-gram.y" +#line 238 "parse-gram.y" { symbol_list_t *list; for (list = yyvsp[0].list; list; list = list->next) @@ -1367,12 +1367,12 @@ yyreduce: break; case 33: -#line 247 "parse-gram.y" +#line 248 "parse-gram.y" { current_class = nterm_sym; } break; case 34: -#line 248 "parse-gram.y" +#line 249 "parse-gram.y" { current_class = unknown_sym; current_type = NULL; @@ -1380,12 +1380,12 @@ yyreduce: break; case 35: -#line 252 "parse-gram.y" +#line 253 "parse-gram.y" { current_class = token_sym; } break; case 36: -#line 253 "parse-gram.y" +#line 254 "parse-gram.y" { current_class = unknown_sym; current_type = NULL; @@ -1393,17 +1393,17 @@ yyreduce: break; case 37: -#line 258 "parse-gram.y" +#line 259 "parse-gram.y" { symbol_list_t *list; for (list = yyvsp[0].list; list; list = list->next) - symbol_type_set (list->sym, yyvsp[-1].string, yylsp[-1]); + symbol_type_set (list->sym, yyvsp[-1].struniq, yylsp[-1]); symbol_list_free (yyvsp[0].list); } break; case 38: -#line 268 "parse-gram.y" +#line 269 "parse-gram.y" { symbol_list_t *list; ++current_prec; @@ -1418,49 +1418,49 @@ yyreduce: break; case 39: -#line 282 "parse-gram.y" +#line 283 "parse-gram.y" { yyval.assoc = left_assoc; } break; case 40: -#line 283 "parse-gram.y" +#line 284 "parse-gram.y" { yyval.assoc = right_assoc; } break; case 41: -#line 284 "parse-gram.y" +#line 285 "parse-gram.y" { yyval.assoc = non_assoc; } break; case 42: -#line 288 "parse-gram.y" +#line 289 "parse-gram.y" { current_type = NULL; } break; case 43: -#line 289 "parse-gram.y" - { current_type = yyvsp[0].string; } +#line 290 "parse-gram.y" + { current_type = yyvsp[0].struniq; } break; case 44: -#line 295 "parse-gram.y" +#line 296 "parse-gram.y" { yyval.list = symbol_list_new (yyvsp[0].symbol, yylsp[0]); } break; case 45: -#line 296 "parse-gram.y" +#line 297 "parse-gram.y" { yyval.list = symbol_list_prepend (yyvsp[-1].list, yyvsp[0].symbol, yylsp[0]); } break; case 46: -#line 302 "parse-gram.y" +#line 303 "parse-gram.y" { - current_type = yyvsp[0].string; + current_type = yyvsp[0].struniq; } break; case 47: -#line 306 "parse-gram.y" +#line 307 "parse-gram.y" { symbol_class_set (yyvsp[0].symbol, current_class, yylsp[0]); symbol_type_set (yyvsp[0].symbol, current_type, yylsp[0]); @@ -1468,7 +1468,7 @@ yyreduce: break; case 48: -#line 311 "parse-gram.y" +#line 312 "parse-gram.y" { symbol_class_set (yyvsp[-1].symbol, current_class, yylsp[-1]); symbol_type_set (yyvsp[-1].symbol, current_type, yylsp[-1]); @@ -1477,7 +1477,7 @@ yyreduce: break; case 49: -#line 317 "parse-gram.y" +#line 318 "parse-gram.y" { symbol_class_set (yyvsp[-1].symbol, current_class, yylsp[-1]); symbol_type_set (yyvsp[-1].symbol, current_type, yylsp[-1]); @@ -1486,7 +1486,7 @@ yyreduce: break; case 50: -#line 323 "parse-gram.y" +#line 324 "parse-gram.y" { symbol_class_set (yyvsp[-2].symbol, current_class, yylsp[-2]); symbol_type_set (yyvsp[-2].symbol, current_type, yylsp[-2]); @@ -1496,17 +1496,17 @@ yyreduce: break; case 51: -#line 334 "parse-gram.y" +#line 335 "parse-gram.y" {;} break; case 52: -#line 336 "parse-gram.y" +#line 337 "parse-gram.y" {;} break; case 56: -#line 355 "parse-gram.y" +#line 356 "parse-gram.y" { if (yacc_flag) complain_at (yyloc, _("POSIX forbids declarations in the grammar")); @@ -1514,79 +1514,79 @@ yyreduce: break; case 57: -#line 360 "parse-gram.y" +#line 361 "parse-gram.y" { yyerrok; } break; case 58: -#line 366 "parse-gram.y" +#line 367 "parse-gram.y" { current_lhs = yyvsp[-1].symbol; current_lhs_location = yylsp[-1]; } break; case 59: -#line 367 "parse-gram.y" +#line 368 "parse-gram.y" {;} break; case 60: -#line 371 "parse-gram.y" +#line 372 "parse-gram.y" { grammar_rule_end (yylsp[0]); } break; case 61: -#line 372 "parse-gram.y" +#line 373 "parse-gram.y" { grammar_rule_end (yylsp[0]); } break; case 62: -#line 377 "parse-gram.y" +#line 378 "parse-gram.y" { grammar_rule_begin (current_lhs, current_lhs_location); } break; case 63: -#line 379 "parse-gram.y" +#line 380 "parse-gram.y" { grammar_current_rule_symbol_append (yyvsp[0].symbol, yylsp[0]); } break; case 64: -#line 381 "parse-gram.y" +#line 382 "parse-gram.y" { grammar_current_rule_action_append (yyvsp[0].string, yylsp[0]); } break; case 65: -#line 383 "parse-gram.y" +#line 384 "parse-gram.y" { grammar_current_rule_prec_set (yyvsp[0].symbol, yylsp[0]); } break; case 66: -#line 385 "parse-gram.y" +#line 386 "parse-gram.y" { grammar_current_rule_dprec_set (yyvsp[0].integer, yylsp[0]); } break; case 67: -#line 387 "parse-gram.y" - { grammar_current_rule_merge_set (yyvsp[0].string, yylsp[0]); } +#line 388 "parse-gram.y" + { grammar_current_rule_merge_set (yyvsp[0].struniq, yylsp[0]); } break; case 68: -#line 391 "parse-gram.y" +#line 392 "parse-gram.y" { yyval.symbol = yyvsp[0].symbol; } break; case 69: -#line 392 "parse-gram.y" +#line 393 "parse-gram.y" { yyval.symbol = yyvsp[0].symbol; } break; case 70: -#line 397 "parse-gram.y" +#line 398 "parse-gram.y" { yyval.string = yyvsp[0].string; } break; case 71: -#line 403 "parse-gram.y" +#line 404 "parse-gram.y" { yyval.symbol = symbol_get (yyvsp[0].string, yylsp[0]); symbol_class_set (yyval.symbol, token_sym, yylsp[0]); @@ -1594,7 +1594,7 @@ yyreduce: break; case 72: -#line 412 "parse-gram.y" +#line 413 "parse-gram.y" { yyval.string = yyvsp[0].string + 1; yyval.string[strlen (yyval.string) - 1] = '\0'; @@ -1602,14 +1602,14 @@ yyreduce: break; case 73: -#line 420 "parse-gram.y" +#line 421 "parse-gram.y" { yyval.string = xstrdup (""); } break; case 74: -#line 424 "parse-gram.y" +#line 425 "parse-gram.y" { yyval.string = yyvsp[0].string; } @@ -1838,7 +1838,7 @@ yyreturn: } -#line 433 "parse-gram.y" +#line 434 "parse-gram.y" /*------------------------------------------------------------------. | When debugging the parser, display tokens' locations and values. | diff --git a/src/parse-gram.y b/src/parse-gram.y index 7035694..74a6574 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -75,7 +75,7 @@ do { \ static void yyprint (FILE *file, int type, const yystype *value); symbol_class current_class = unknown_sym; -char *current_type = 0; +struniq_t current_type = 0; symbol_t *current_lhs; location_t current_lhs_location; assoc_t current_assoc; @@ -157,8 +157,9 @@ braced_code_t current_braced_code = action_braced_code; %token BRACED_CODE "{...}" -%type TYPE STRING string_content +%type STRING string_content BRACED_CODE PROLOGUE EPILOGUE epilogue.opt action +%type TYPE %type INT %type ID symbol string_as_id %type precedence_declarator diff --git a/src/reader.c b/src/reader.c index 64601e3..fa34809 100644 --- a/src/reader.c +++ b/src/reader.c @@ -102,12 +102,11 @@ epilogue_set (const char *epilogue, location_t location) /*-------------------------------------------------------------------. | Return the merger index for a merging function named NAME, whose | | arguments have type TYPE. Records the function, if new, in | -| merger_list. | +| MERGER_LIST. | `-------------------------------------------------------------------*/ static int -get_merge_function (const char* name, const char* type, - location_t loc) +get_merge_function (struniq_t name, struniq_t type, location_t loc) { merger_list *syms; merger_list head; @@ -117,21 +116,21 @@ get_merge_function (const char* name, const char* type, return 0; if (type == NULL) - type = ""; + type = struniq_new (""); head.next = merge_functions; for (syms = &head, n = 1; syms->next != NULL; syms = syms->next, n += 1) - if (strcmp (name, syms->next->name) == 0) + if (STRUNIQ_EQ (name, syms->next->name)) break; if (syms->next == NULL) { syms->next = XMALLOC (merger_list, 1); - syms->next->name = xstrdup (name); - syms->next->type = xstrdup (type); + syms->next->name = struniq_new (name); + syms->next->type = struniq_new (type); syms->next->next = NULL; merge_functions = head.next; } - else if (strcmp (type, syms->next->type) != 0) + else if (!STRUNIQ_EQ (type, syms->next->type)) warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"), name, type, syms->next->type); return n; @@ -257,7 +256,7 @@ grammar_current_rule_check (void) if (first_rhs) { const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : ""; - if (strcmp (lhs_type, rhs_type)) + if (!STRUNIQ_EQ (lhs_type, rhs_type)) complain_at (current_rule->location, _("type clash on default action: <%s> != <%s>"), lhs_type, rhs_type); @@ -358,7 +357,7 @@ grammar_current_rule_dprec_set (int dprec, location_t location) rule. */ void -grammar_current_rule_merge_set (const char* name, location_t location) +grammar_current_rule_merge_set (struniq_t name, location_t location) { if (! glr_parser) warn_at (location, _("%s affects only GLR parsers"), "%merge"); @@ -491,7 +490,7 @@ reader (void) obstack_init (&pre_prologue_obstack); obstack_init (&post_prologue_obstack); - finput = xfopen (infile, "r"); + finput = xfopen (grammar_file, "r"); gram_in = finput; gram__flex_debug = trace_flag & trace_scan; diff --git a/src/reader.h b/src/reader.h index c241344..cca624a 100644 --- a/src/reader.h +++ b/src/reader.h @@ -27,8 +27,8 @@ typedef struct merger_list { struct merger_list* next; - const char* name; - const char* type; + struniq_t name; + struniq_t type; } merger_list; @@ -76,7 +76,7 @@ void grammar_rule_end (location_t l); void grammar_midrule_action (void); void grammar_current_rule_prec_set (symbol_t *precsym, location_t l); void grammar_current_rule_dprec_set (int dprec, location_t l); -void grammar_current_rule_merge_set (const char* name, location_t l); +void grammar_current_rule_merge_set (struniq_t name, location_t l); void grammar_current_rule_symbol_append (symbol_t *symbol, location_t l); void grammar_current_rule_action_append (const char *action, location_t l); diff --git a/src/reduce.c b/src/reduce.c index 3b19cc1..699f45a 100644 --- a/src/reduce.c +++ b/src/reduce.c @@ -389,7 +389,7 @@ reduce_print (void) nuseless_productions), nuseless_productions); - fprintf (stderr, "%s: %s: ", infile, _("warning")); + fprintf (stderr, "%s: %s: ", grammar_file, _("warning")); if (nuseless_nonterminals > 0) fprintf (stderr, ngettext ("%d useless nonterminal", @@ -449,7 +449,7 @@ reduce_grammar (void) fprintf (stderr, "reduced %s defines %d terminals, %d nonterminals\ , and %d productions.\n", - infile, ntokens, nvars, nrules); + grammar_file, ntokens, nvars, nrules); } } diff --git a/src/scan-gram.l b/src/scan-gram.l index da92baa..02f5e85 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -36,7 +36,7 @@ #define YY_USER_INIT \ do { \ LOCATION_RESET (*yylloc); \ - yylloc->file = infile; \ + yylloc->file = current_file; \ /* This is only to avoid GCC warnings. */ \ if (yycontrol) {;}; \ } while (0) @@ -829,10 +829,8 @@ handle_syncline (char *args, location_t *location) const char *file = NULL; file = strchr (args, '"') + 1; *strchr (file, '"') = 0; - /* FIXME: Leaking... Can't free, as some locations are still - pointing to the old file name. */ - infile = xstrdup (file); - location->file = infile; + current_file = xstrdup (file); + location->file = current_file; location->last_line = lineno; } diff --git a/src/struniq.c b/src/struniq.c index 4260a70..e3d32bb 100644 --- a/src/struniq.c +++ b/src/struniq.c @@ -20,6 +20,7 @@ #include "system.h" #include "quotearg.h" +#include "error.h" #include "hash.h" #include "struniq.h" @@ -39,20 +40,36 @@ static struct hash_table *struniqs_table = NULL; const struniq_t struniq_new (const char *s) { - /* Keep the struniqs in a printable form. */ - struniq_t res = hash_lookup (struniqs_table, - quotearg_style (escape_quoting_style, s)); - + struniq_t res = hash_lookup (struniqs_table, s); if (!res) { /* First insertion in the hash. */ - res = xstrdup (quotearg_style (escape_quoting_style, s)); + res = xstrdup (s); hash_insert (struniqs_table, res); } return res; } +/*---------------------------------. +| Return TRUE iff S is a struniq. | +`---------------------------------*/ + +bool +struniq_assert_p (const char *s) +{ + if (!hash_lookup (struniqs_table, s)) + { + error (0, 0, "not a struniq: %s", quotearg (s)); + return false; + } + else + { + return true; + } +} + + /*--------------------. | Print the struniq. | `--------------------*/ diff --git a/src/struniq.h b/src/struniq.h index e83a083..bd33c8c 100644 --- a/src/struniq.h +++ b/src/struniq.h @@ -25,11 +25,14 @@ | struniq_t -- pointers to unique copies of C strings. | `------------------------------------------------------*/ -typedef char *struniq_t; +typedef const char *struniq_t; /* Return the struniq for S. */ const struniq_t struniq_new (const char *s); +/* Two struniq have the same value iff they are the same. */ +#define STRUNIQ_EQ(S1, S2) ((S1) == (S2)) + /*--------------------------------------. | Initializing, destroying, debugging. | `--------------------------------------*/ @@ -37,6 +40,10 @@ const struniq_t struniq_new (const char *s); /* Create the string table. */ void struniqs_new (void); +/* Die if S is not a struniq. */ +#define struniq_assert(S) assert (struniq_assert_p (S)); +bool struniq_assert_p (const char *s); + /* Free all the memory allocated for symbols. */ void struniqs_free (void); diff --git a/src/symlist.c b/src/symlist.c index 8b61c8d..92d8513 100644 --- a/src/symlist.c +++ b/src/symlist.c @@ -86,7 +86,7 @@ symbol_list_length (symbol_list_t *list) | symbol N in rule RULE. | `--------------------------------------------------------------*/ -char * +struniq_t symbol_list_n_type_name_get (symbol_list_t *rule, location_t location, int n) { int i; diff --git a/src/symlist.h b/src/symlist.h index 4f75570..33aae34 100644 --- a/src/symlist.h +++ b/src/symlist.h @@ -56,7 +56,7 @@ unsigned int symbol_list_length (symbol_list_t *list); /* Get the data type (alternative in the union) of the value for symbol N in rule RULE. */ -char *symbol_list_n_type_name_get (symbol_list_t *rule, +struniq_t symbol_list_n_type_name_get (symbol_list_t *rule, location_t location, int n); #endif /* !SYMLIST_H_ */ diff --git a/src/symtab.c b/src/symtab.c index c293de2..66f697a 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -42,11 +42,12 @@ location_t startsymbol_location; `---------------------------------*/ static symbol_t * -symbol_new (const char *tag, location_t location) +symbol_new (struniq_t tag, location_t location) { symbol_t *res = XMALLOC (symbol_t, 1); - res->tag = xstrdup (tag); + struniq_assert (tag); + res->tag = tag; res->location = location; res->type_name = NULL; @@ -72,13 +73,14 @@ symbol_new (const char *tag, location_t location) `------------------------------------------------------------------*/ void -symbol_type_set (symbol_t *symbol, char *type_name, location_t location) +symbol_type_set (symbol_t *symbol, struniq_t type_name, location_t location) { if (type_name) { if (symbol->type_name) complain_at (location, _("type redeclaration for %s"), symbol->tag); + struniq_assert (type_name); symbol->type_name = type_name; } } @@ -200,7 +202,6 @@ symbol_user_token_number_set (symbol_t *symbol, static void symbol_free (symbol_t *this) { - free (this->tag); free (this); } @@ -376,15 +377,17 @@ symbol_translation (symbol_t *this) static struct hash_table *symbol_table = NULL; static bool -hash_compare_symbol_t (const symbol_t *m1, const symbol_t *m2) +hash_compare_symbol (const symbol_t *m1, const symbol_t *m2) { - return strcmp (m1->tag, m2->tag) == 0; + /* Since tags are unique, we can compare the pointers themselves. */ + return STRUNIQ_EQ (m1->tag, m2->tag); } static unsigned int -hash_symbol_t (const symbol_t *m, unsigned int tablesize) +hash_symbol (const symbol_t *m, unsigned int tablesize) { - return hash_string (m->tag, tablesize); + /* Since tags are unique, we can hash the pointer itself. */ + return ((size_t) m->tag) % tablesize; } @@ -397,8 +400,8 @@ symbols_new (void) { symbol_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, - (Hash_hasher) hash_symbol_t, - (Hash_comparator) hash_compare_symbol_t, + (Hash_hasher) hash_symbol, + (Hash_comparator) hash_compare_symbol, (Hash_data_freer) symbol_free); } @@ -415,7 +418,7 @@ symbol_get (const char *key, location_t location) symbol_t *entry; /* Keep the symbol in a printable form. */ - key = quotearg_style (escape_quoting_style, key); + key = struniq_new (quotearg_style (escape_quoting_style, key)); *(char const **) &probe.tag = key; entry = hash_lookup (symbol_table, &probe); diff --git a/src/symtab.h b/src/symtab.h index ecf28cd..23a7335 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -48,7 +48,7 @@ typedef struct symbol_s symbol_t; struct symbol_s { /* The key, name of the symbol. */ - char *tag; + struniq_t tag; /* The location of its first occurence. */ location_t location; @@ -98,7 +98,7 @@ void symbol_make_alias (symbol_t *symbol, symbol_t *symval, /* Set the TYPE_NAME associated to SYMBOL. Does nothing if passed 0 as TYPE_NAME. */ void symbol_type_set (symbol_t *symbol, - char *type_name, location_t location); + struniq_t type_name, location_t location); /* Set the DESTRUCTOR associated to SYMBOL. */ void symbol_destructor_set (symbol_t *symbol, -- 2.7.4