@@ -34,6 +34,8 @@ sub elem
3434 return grep { $_ eq $x } @_ ;
3535}
3636
37+ # output file names
38+ my @output_files ;
3739
3840# collect node names
3941my @node_types = qw( Node) ;
@@ -124,19 +126,31 @@ sub elem
124126 my $supertype_field ;
125127
126128 my $node_attrs = ' ' ;
129+ my $node_attrs_lineno ;
127130 my @my_fields ;
128131 my %my_field_types ;
129132 my %my_field_attrs ;
130133
131134 open my $ifh , ' <' , $infile or die " could not open \" $infile \" : $! " ;
132135
133- my $file_content = do { local $/ ; <$ifh > };
136+ my $raw_file_content = do { local $/ ; <$ifh > };
134137
135- # strip C comments
136- $file_content =~ s { /\* .*?\* /} {} gs ;
138+ # strip C comments, preserving newlines so we can count lines correctly
139+ my $file_content = ' ' ;
140+ while ($raw_file_content =~ m { ^(.*?)(/\* .*?\* /)(.*)$} s )
141+ {
142+ $file_content .= $1 ;
143+ my $comment = $2 ;
144+ $raw_file_content = $3 ;
145+ $comment =~ tr / \n// cd;
146+ $file_content .= $comment ;
147+ }
148+ $file_content .= $raw_file_content ;
137149
150+ my $lineno = 0;
138151 foreach my $line (split /\n/, $file_content )
139152 {
153+ $lineno ++;
140154 chomp $line ;
141155 $line =~ s /\s *$// ;
142156 next if $line eq ' ' ;
@@ -153,13 +167,14 @@ sub elem
153167 $is_node_struct = 0;
154168 $supertype = undef ;
155169 next if $line eq ' {' ;
156- die " $infile :$. : expected opening brace\n " ;
170+ die " $infile :$lineno : expected opening brace\n " ;
157171 }
158172 # second line could be node attributes
159173 elsif ($subline == 2
160174 && $line =~ / ^\s *pg_node_attr\( ([\w (), ]*)\) $ / )
161175 {
162- $node_attrs = $1 ;
176+ $node_attrs = $1 ;
177+ $node_attrs_lineno = $lineno ;
163178 # hack: don't count the line
164179 $subline --;
165180 next ;
@@ -236,7 +251,7 @@ sub elem
236251 else
237252 {
238253 die
239- " $infile :$. : unrecognized attribute \" $attr \"\n " ;
254+ " $infile :$node_attrs_lineno : unrecognized attribute \" $attr \"\n " ;
240255 }
241256 }
242257
@@ -330,7 +345,9 @@ sub elem
330345 # strip space between type and "*" (pointer) */
331346 $type =~ s /\s +\* $/ */ ;
332347
333- die if $type eq ' ' ;
348+ die
349+ " $infile :$lineno : cannot parse data type in \" $line \"\n "
350+ if $type eq ' ' ;
334351
335352 my @attrs ;
336353 if ($attrs )
@@ -347,7 +364,7 @@ sub elem
347364 )
348365 {
349366 die
350- " $infile :$. : unrecognized attribute \" $attr \"\n " ;
367+ " $infile :$lineno : unrecognized attribute \" $attr \"\n " ;
351368 }
352369 }
353370 }
@@ -362,7 +379,7 @@ sub elem
362379 {
363380 if ($is_node_struct )
364381 {
365- # warn "$infile:$. : could not parse \"$line\"\n";
382+ # warn "$infile:$lineno : could not parse \"$line\"\n";
366383 }
367384 }
368385 }
@@ -411,10 +428,35 @@ sub elem
411428
412429my $tmpext = " .tmp$$ " ;
413430
431+ # opening boilerplate for output files
432+ my $header_comment =
433+ ' /*-------------------------------------------------------------------------
434+ *
435+ * %s
436+ * Generated node infrastructure code
437+ *
438+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
439+ * Portions Copyright (c) 1994, Regents of the University of California
440+ *
441+ * NOTES
442+ * ******************************
443+ * *** DO NOT EDIT THIS FILE! ***
444+ * ******************************
445+ *
446+ * It has been GENERATED by src/backend/nodes/gen_node_support.pl
447+ *
448+ *-------------------------------------------------------------------------
449+ */
450+ ' ;
451+
452+
414453# nodetags.h
415454
455+ push @output_files , ' nodetags.h' ;
416456open my $nt , ' >' , ' nodetags.h' . $tmpext or die $! ;
417457
458+ printf $nt $header_comment , ' nodetags.h' ;
459+
418460my $i = 1;
419461foreach my $n (@node_types , @extra_tags )
420462{
@@ -437,11 +479,20 @@ sub elem
437479
438480# copyfuncs.c, equalfuncs.c
439481
440- open my $cff , ' >' , ' copyfuncs.funcs.c' . $tmpext or die $! ;
441- open my $eff , ' >' , ' equalfuncs.funcs.c' . $tmpext or die $! ;
442- open my $cfs , ' >' , ' copyfuncs.switch.c' . $tmpext or die $! ;
482+ push @output_files , ' copyfuncs.funcs.c' ;
483+ open my $cff , ' >' , ' copyfuncs.funcs.c' . $tmpext or die $! ;
484+ push @output_files , ' equalfuncs.funcs.c' ;
485+ open my $eff , ' >' , ' equalfuncs.funcs.c' . $tmpext or die $! ;
486+ push @output_files , ' copyfuncs.switch.c' ;
487+ open my $cfs , ' >' , ' copyfuncs.switch.c' . $tmpext or die $! ;
488+ push @output_files , ' equalfuncs.switch.c' ;
443489open my $efs , ' >' , ' equalfuncs.switch.c' . $tmpext or die $! ;
444490
491+ printf $cff $header_comment , ' copyfuncs.funcs.c' ;
492+ printf $eff $header_comment , ' equalfuncs.funcs.c' ;
493+ printf $cfs $header_comment , ' copyfuncs.switch.c' ;
494+ printf $efs $header_comment , ' equalfuncs.switch.c' ;
495+
445496# add required #include lines to each file set
446497print $cff $node_includes ;
447498print $eff $node_includes ;
@@ -552,7 +603,7 @@ sub elem
552603 my $tt = $1 ;
553604 if (!defined $array_size_field )
554605 {
555- die " no array size defined for $n .$f of type $t " ;
606+ die " no array size defined for $n .$f of type $t \n " ;
556607 }
557608 if ($node_type_info {$n }-> {field_types }{$array_size_field } eq
558609 ' List*' )
@@ -597,7 +648,8 @@ sub elem
597648 }
598649 else
599650 {
600- die " could not handle type \" $t \" in struct \" $n \" field \" $f \" " ;
651+ die
652+ " could not handle type \" $t \" in struct \" $n \" field \" $f \"\n " ;
601653 }
602654 }
603655
@@ -619,11 +671,20 @@ sub elem
619671
620672# outfuncs.c, readfuncs.c
621673
622- open my $off , ' >' , ' outfuncs.funcs.c' . $tmpext or die $! ;
623- open my $rff , ' >' , ' readfuncs.funcs.c' . $tmpext or die $! ;
624- open my $ofs , ' >' , ' outfuncs.switch.c' . $tmpext or die $! ;
674+ push @output_files , ' outfuncs.funcs.c' ;
675+ open my $off , ' >' , ' outfuncs.funcs.c' . $tmpext or die $! ;
676+ push @output_files , ' readfuncs.funcs.c' ;
677+ open my $rff , ' >' , ' readfuncs.funcs.c' . $tmpext or die $! ;
678+ push @output_files , ' outfuncs.switch.c' ;
679+ open my $ofs , ' >' , ' outfuncs.switch.c' . $tmpext or die $! ;
680+ push @output_files , ' readfuncs.switch.c' ;
625681open my $rfs , ' >' , ' readfuncs.switch.c' . $tmpext or die $! ;
626682
683+ printf $off $header_comment , ' outfuncs.funcs.c' ;
684+ printf $rff $header_comment , ' readfuncs.funcs.c' ;
685+ printf $ofs $header_comment , ' outfuncs.switch.c' ;
686+ printf $rfs $header_comment , ' readfuncs.switch.c' ;
687+
627688print $off $node_includes ;
628689print $rff $node_includes ;
629690
@@ -814,7 +875,7 @@ sub elem
814875 }
815876 if (!defined $array_size_field )
816877 {
817- die " no array size defined for $n .$f of type $t " ;
878+ die " no array size defined for $n .$f of type $t \n " ;
818879 }
819880 if ($node_type_info {$n }-> {field_types }{$array_size_field } eq
820881 ' List*' )
@@ -886,7 +947,8 @@ sub elem
886947 }
887948 else
888949 {
889- die " could not handle type \" $t \" in struct \" $n \" field \" $f \" " ;
950+ die
951+ " could not handle type \" $t \" in struct \" $n \" field \" $f \"\n " ;
890952 }
891953
892954 # for read_as() without read_write_ignore, we have to read the value
@@ -911,10 +973,26 @@ sub elem
911973close $rfs ;
912974
913975
914- # now rename the temporary files to their final name
915- foreach my $file (
916- 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)
917- )
976+ # now rename the temporary files to their final names
977+ foreach my $file (@output_files )
918978{
919979 Catalog::RenameTempFile($file , $tmpext );
920980}
981+
982+
983+ # Automatically clean up any temp files if the script fails.
984+ END
985+ {
986+ # take care not to change the script's exit value
987+ my $exit_code = $? ;
988+
989+ if ($exit_code != 0)
990+ {
991+ foreach my $file (@output_files )
992+ {
993+ unlink ($file . $tmpext );
994+ }
995+ }
996+
997+ $? = $exit_code ;
998+ }
0 commit comments