| # -*-perl-*- hey - emacs - this is a perl file |
| |
| # Copyright (c) 2021, PostgreSQL Global Development Group |
| |
| # src/tools/msvc/pgflex.pl |
| |
| use strict; |
| use warnings; |
| |
| use File::Basename; |
| |
| # silence flex bleatings about file path style |
| $ENV{CYGWIN} = 'nodosfilewarning'; |
| |
| # assume we are in the postgres source root |
| |
| do './src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl'; |
| |
| my ($flexver) = `flex -V`; # grab first line |
| $flexver = (split(/\s+/, $flexver))[1]; |
| $flexver =~ s/[^0-9.]//g; |
| my @verparts = split(/\./, $flexver); |
| unless ($verparts[0] == 2 |
| && ($verparts[1] > 5 || ($verparts[1] == 5 && $verparts[2] >= 31))) |
| { |
| print "WARNING! Flex install not found, or unsupported Flex version.\n"; |
| print "echo Attempting to build without.\n"; |
| exit 0; |
| } |
| |
| my $input = shift; |
| if ($input !~ /\.l$/) |
| { |
| print "Input must be a .l file\n"; |
| exit 1; |
| } |
| elsif (!-e $input) |
| { |
| print "Input file $input not found\n"; |
| exit 1; |
| } |
| |
| (my $output = $input) =~ s/\.l$/.c/; |
| |
| # get flex flags from make file |
| my $makefile = dirname($input) . "/Makefile"; |
| my ($mf, $make); |
| open($mf, '<', $makefile); |
| local $/ = undef; |
| $make = <$mf>; |
| close($mf); |
| my $basetarg = basename($output); |
| my $flexflags = ($make =~ /^$basetarg:\s*FLEXFLAGS\s*=\s*(\S.*)/m ? $1 : ''); |
| |
| system("flex $flexflags -o$output $input"); |
| if ($? == 0) |
| { |
| |
| # Check for "%option reentrant" in .l file. |
| my $lfile; |
| open($lfile, '<', $input) || die "opening $input for reading: $!"; |
| my $lcode = <$lfile>; |
| close($lfile); |
| if ($lcode =~ /\%option\sreentrant/) |
| { |
| |
| # Reentrant scanners usually need a fix to prevent |
| # "unused variable" warnings with older flex versions. |
| system("perl src\\tools\\fix-old-flex-code.pl $output"); |
| } |
| else |
| { |
| |
| # For non-reentrant scanners we need to fix up the yywrap |
| # macro definition to keep the MS compiler happy. |
| # For reentrant scanners (like the core scanner) we do not |
| # need to (and must not) change the yywrap definition. |
| my $cfile; |
| open($cfile, '<', $output) || die "opening $output for reading: $!"; |
| my $ccode = <$cfile>; |
| close($cfile); |
| $ccode =~ s/yywrap\(n\)/yywrap()/; |
| open($cfile, '>', $output) || die "opening $output for writing: $!"; |
| print $cfile $ccode; |
| close($cfile); |
| } |
| if ($flexflags =~ /\s-b\s/) |
| { |
| my $lexback = "lex.backup"; |
| open($lfile, '<', $lexback) || die "opening $lexback for reading: $!"; |
| my $lexbacklines = <$lfile>; |
| close($lfile); |
| my $linecount = $lexbacklines =~ tr /\n/\n/; |
| if ($linecount != 1) |
| { |
| print "Scanner requires backup, see lex.backup.\n"; |
| exit 1; |
| } |
| unlink $lexback; |
| } |
| |
| exit 0; |
| |
| } |
| else |
| { |
| exit $? >> 8; |
| } |