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; +}