From: Tom Lane Date: Sat, 9 Jul 2022 19:15:05 +0000 (-0400) Subject: Make assorted quality-of-life improvements in gen_node_support.pl. X-Git-Tag: REL_16_BETA1~2302 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=8eccaf65254225921d6fd1f3bfa23e8a0b1f6bbb;p=postgresql.git Make assorted quality-of-life improvements in gen_node_support.pl. Fix incorrect reporting of the location of errors (such as bogus node attributes). Add header comments to the generated files, containing copyright notices and reminders that they are generated files, as we do in other file-generating scripts. Arrange to not leave a clutter of temporary files when the script detects an error. Discussion: https://postgr.es/m/3843645.1657385930@sss.pgh.pa.us --- diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl index dca5819f951..4a7902e6bfb 100644 --- a/src/backend/nodes/gen_node_support.pl +++ b/src/backend/nodes/gen_node_support.pl @@ -34,6 +34,8 @@ sub elem return grep { $_ eq $x } @_; } +# output file names +my @output_files; # collect node names my @node_types = qw(Node); @@ -124,19 +126,31 @@ foreach my $infile (@ARGV) my $supertype_field; my $node_attrs = ''; + my $node_attrs_lineno; my @my_fields; my %my_field_types; my %my_field_attrs; open my $ifh, '<', $infile or die "could not open \"$infile\": $!"; - my $file_content = do { local $/; <$ifh> }; + my $raw_file_content = do { local $/; <$ifh> }; - # strip C comments - $file_content =~ s{/\*.*?\*/}{}gs; + # strip C comments, preserving newlines so we can count lines correctly + my $file_content = ''; + while ($raw_file_content =~ m{^(.*?)(/\*.*?\*/)(.*)$}s) + { + $file_content .= $1; + my $comment = $2; + $raw_file_content = $3; + $comment =~ tr/\n//cd; + $file_content .= $comment; + } + $file_content .= $raw_file_content; + my $lineno = 0; foreach my $line (split /\n/, $file_content) { + $lineno++; chomp $line; $line =~ s/\s*$//; next if $line eq ''; @@ -153,13 +167,14 @@ foreach my $infile (@ARGV) $is_node_struct = 0; $supertype = undef; next if $line eq '{'; - die "$infile:$.: expected opening brace\n"; + die "$infile:$lineno: expected opening brace\n"; } # second line could be node attributes elsif ($subline == 2 && $line =~ /^\s*pg_node_attr\(([\w(), ]*)\)$/) { - $node_attrs = $1; + $node_attrs = $1; + $node_attrs_lineno = $lineno; # hack: don't count the line $subline--; next; @@ -236,7 +251,7 @@ foreach my $infile (@ARGV) else { die - "$infile:$.: unrecognized attribute \"$attr\"\n"; + "$infile:$node_attrs_lineno: unrecognized attribute \"$attr\"\n"; } } @@ -330,7 +345,9 @@ foreach my $infile (@ARGV) # strip space between type and "*" (pointer) */ $type =~ s/\s+\*$/*/; - die if $type eq ''; + die + "$infile:$lineno: cannot parse data type in \"$line\"\n" + if $type eq ''; my @attrs; if ($attrs) @@ -347,7 +364,7 @@ foreach my $infile (@ARGV) ) { die - "$infile:$.: unrecognized attribute \"$attr\"\n"; + "$infile:$lineno: unrecognized attribute \"$attr\"\n"; } } } @@ -362,7 +379,7 @@ foreach my $infile (@ARGV) { if ($is_node_struct) { - #warn "$infile:$.: could not parse \"$line\"\n"; + #warn "$infile:$lineno: could not parse \"$line\"\n"; } } } @@ -411,10 +428,35 @@ foreach my $infile (@ARGV) my $tmpext = ".tmp$$"; +# opening boilerplate for output files +my $header_comment = + '/*------------------------------------------------------------------------- + * + * %s + * Generated node infrastructure code + * + * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/nodes/gen_node_support.pl + * + *------------------------------------------------------------------------- + */ +'; + + # nodetags.h +push @output_files, 'nodetags.h'; open my $nt, '>', 'nodetags.h' . $tmpext or die $!; +printf $nt $header_comment, 'nodetags.h'; + my $i = 1; foreach my $n (@node_types, @extra_tags) { @@ -437,11 +479,20 @@ foreach my $infile (sort @ARGV) # copyfuncs.c, equalfuncs.c -open my $cff, '>', 'copyfuncs.funcs.c' . $tmpext or die $!; -open my $eff, '>', 'equalfuncs.funcs.c' . $tmpext or die $!; -open my $cfs, '>', 'copyfuncs.switch.c' . $tmpext or die $!; +push @output_files, 'copyfuncs.funcs.c'; +open my $cff, '>', 'copyfuncs.funcs.c' . $tmpext or die $!; +push @output_files, 'equalfuncs.funcs.c'; +open my $eff, '>', 'equalfuncs.funcs.c' . $tmpext or die $!; +push @output_files, 'copyfuncs.switch.c'; +open my $cfs, '>', 'copyfuncs.switch.c' . $tmpext or die $!; +push @output_files, 'equalfuncs.switch.c'; open my $efs, '>', 'equalfuncs.switch.c' . $tmpext or die $!; +printf $cff $header_comment, 'copyfuncs.funcs.c'; +printf $eff $header_comment, 'equalfuncs.funcs.c'; +printf $cfs $header_comment, 'copyfuncs.switch.c'; +printf $efs $header_comment, 'equalfuncs.switch.c'; + # add required #include lines to each file set print $cff $node_includes; print $eff $node_includes; @@ -552,7 +603,7 @@ _equal${n}(const $n *a, const $n *b) my $tt = $1; if (!defined $array_size_field) { - die "no array size defined for $n.$f of type $t"; + die "no array size defined for $n.$f of type $t\n"; } if ($node_type_info{$n}->{field_types}{$array_size_field} eq 'List*') @@ -597,7 +648,8 @@ _equal${n}(const $n *a, const $n *b) } else { - die "could not handle type \"$t\" in struct \"$n\" field \"$f\""; + die + "could not handle type \"$t\" in struct \"$n\" field \"$f\"\n"; } } @@ -619,11 +671,20 @@ close $efs; # outfuncs.c, readfuncs.c -open my $off, '>', 'outfuncs.funcs.c' . $tmpext or die $!; -open my $rff, '>', 'readfuncs.funcs.c' . $tmpext or die $!; -open my $ofs, '>', 'outfuncs.switch.c' . $tmpext or die $!; +push @output_files, 'outfuncs.funcs.c'; +open my $off, '>', 'outfuncs.funcs.c' . $tmpext or die $!; +push @output_files, 'readfuncs.funcs.c'; +open my $rff, '>', 'readfuncs.funcs.c' . $tmpext or die $!; +push @output_files, 'outfuncs.switch.c'; +open my $ofs, '>', 'outfuncs.switch.c' . $tmpext or die $!; +push @output_files, 'readfuncs.switch.c'; open my $rfs, '>', 'readfuncs.switch.c' . $tmpext or die $!; +printf $off $header_comment, 'outfuncs.funcs.c'; +printf $rff $header_comment, 'readfuncs.funcs.c'; +printf $ofs $header_comment, 'outfuncs.switch.c'; +printf $rfs $header_comment, 'readfuncs.switch.c'; + print $off $node_includes; print $rff $node_includes; @@ -814,7 +875,7 @@ _read${n}(void) } if (!defined $array_size_field) { - die "no array size defined for $n.$f of type $t"; + die "no array size defined for $n.$f of type $t\n"; } if ($node_type_info{$n}->{field_types}{$array_size_field} eq 'List*') @@ -886,7 +947,8 @@ _read${n}(void) } else { - die "could not handle type \"$t\" in struct \"$n\" field \"$f\""; + die + "could not handle type \"$t\" in struct \"$n\" field \"$f\"\n"; } # for read_as() without read_write_ignore, we have to read the value @@ -911,10 +973,26 @@ close $ofs; close $rfs; -# now rename the temporary files to their final name -foreach my $file ( - qw(nodetags.h copyfuncs.funcs.c copyfuncs.switch.c equalfuncs.funcs.c equalfuncs.switch.c outfuncs.funcs.c outfuncs.switch.c readfuncs.funcs.c readfuncs.switch.c) - ) +# now rename the temporary files to their final names +foreach my $file (@output_files) { Catalog::RenameTempFile($file, $tmpext); } + + +# Automatically clean up any temp files if the script fails. +END +{ + # take care not to change the script's exit value + my $exit_code = $?; + + if ($exit_code != 0) + { + foreach my $file (@output_files) + { + unlink($file . $tmpext); + } + } + + $? = $exit_code; +}