3333
3434
3535# These hash tables define additional transformations to apply to
36- # grammar rules.
36+ # grammar rules. For bug-detection purposes, we count usages of
37+ # each hash table entry in a second hash table, and verify that
38+ # all the entries get used.
3739
3840# Substitutions to apply to tokens whenever they are seen in a rule.
3941my %replace_token = (
4446 ' IDENT' => ' ecpg_ident' ,
4547 ' PARAM' => ' ecpg_param' ,);
4648
49+ my %replace_token_used ;
50+
4751# This hash can provide a result type to override "void" for nonterminals
4852# that need that, or it can specify 'ignore' to cause us to skip the rule
4953# for that nonterminal. (In either case, ecpg.trailer had better provide
6872 ' plassign_target' => ' ignore' ,
6973 ' plassign_equals' => ' ignore' ,);
7074
75+ my %replace_types_used ;
76+
7177# This hash provides an "ignore" option or substitute expansion for any
7278# rule or rule alternative. The hash key is the same "concattokens" tag
7379# used for lookup in ecpg.addons.
111117 ' PREPARE prepared_name prep_type_clause AS PreparableStmt' ,
112118 ' var_nameColId' => ' ECPGColId' );
113119
120+ my %replace_line_used ;
121+
114122
115123# Declare assorted state variables.
116124
198206 die " addon rule $_ was matched multiple times\n " if $addons {$_ }{used } > 1;
199207}
200208
209+ # Likewise cross-check that entries in our internal hash tables match something.
210+ foreach (keys %replace_token )
211+ {
212+ die " replace_token entry $_ was never used\n "
213+ if !defined ($replace_token_used {$_ });
214+ # multiple use of a replace_token entry is fine
215+ }
216+
217+ foreach (keys %replace_types )
218+ {
219+ die " replace_types entry $_ was never used\n "
220+ if !defined ($replace_types_used {$_ });
221+ die " replace_types entry $_ was matched multiple times\n "
222+ if $replace_types_used {$_ } > 1;
223+ }
224+
225+ foreach (keys %replace_line )
226+ {
227+ die " replace_line entry $_ was never used\n "
228+ if !defined ($replace_line_used {$_ });
229+ die " replace_line entry $_ was matched multiple times\n "
230+ if $replace_line_used {$_ } > 1;
231+ }
232+
201233
202234# Read the backend grammar.
203235sub main
@@ -399,6 +431,7 @@ sub main
399431 # Apply replace_token substitution if we have one.
400432 if (exists $replace_token { $arr [$fieldIndexer ] })
401433 {
434+ $replace_token_used { $arr [$fieldIndexer ] }++;
402435 $arr [$fieldIndexer ] = $replace_token { $arr [$fieldIndexer ] };
403436 }
404437
@@ -424,6 +457,7 @@ sub main
424457 && $replace_types {$non_term_id } eq ' ignore' )
425458 {
426459 # We'll ignore this nonterminal and rule altogether.
460+ $replace_types_used {$non_term_id }++;
427461 $copymode = 0;
428462 next line;
429463 }
@@ -450,6 +484,7 @@ sub main
450484 . $replace_types {$non_term_id } . ' '
451485 . $non_term_id ;
452486 add_to_buffer(' types' , $tstr );
487+ $replace_types_used {$non_term_id }++;
453488 }
454489
455490 # Emit the target part of the rule.
@@ -615,8 +650,10 @@ sub emit_rule
615650
616651 # apply replace_line substitution if any
617652 my $rep = $replace_line {$tag };
618- if ($rep )
653+ if (defined $rep )
619654 {
655+ $replace_line_used {$tag }++;
656+
620657 if ($rep eq ' ignore' )
621658 {
622659 return 0;
0 commit comments