Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d2f41b4

Browse files
committed
ecpg: add cross-checks to parse.pl for usage of internal tables.
parse.pl contains several constant tables that describe tweaks to be made to the backend grammar. In the same spirit as 00b0e72, add cross-checks that each table entry is used at least once (or exactly once if that's appropriate). This should help catch cases where adjustments to the backend grammar cause a table entry not to match as expected. Per suggestion from Michael Paquier. Discussion: https://postgr.es/m/ZsLVbjsc5x5Saesg@paquier.xyz
1 parent 66ac94c commit d2f41b4

File tree

1 file changed

+39
-2
lines changed

1 file changed

+39
-2
lines changed

src/interfaces/ecpg/preproc/parse.pl

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
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.
3941
my %replace_token = (
@@ -44,6 +46,8 @@
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
@@ -68,6 +72,8 @@
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.
@@ -111,6 +117,8 @@
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

@@ -198,6 +206,30 @@
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.
203235
sub 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

Comments
 (0)