Commit c895e775 authored by Andrew Dunstan's avatar Andrew Dunstan

Reimplement pgbison and pgflex as perl scripts instead of bat files.

In the process, remove almost all knowledge of individual .y and .l files,
and instead get invocation settings from the relevant make files.
The exception is plpgsql's gram.y, which has a target with a different
name. It is hoped that this will make the scripts more future-proof,
so that they won't require adjustment every time we add a new .l or .y
file.

The logic is also notably less tortured than that forced on us
by the idiosyncrasies of the Windows command processor.

The .bat files are kept as thin wrappers for the perl scripts.
parent 14f67192
@echo off @echo off
REM src/tools/msvc/pgbison.bat
IF NOT EXIST src\tools\msvc\buildenv.pl goto nobuildenv
perl -e "require 'src/tools/msvc/buildenv.pl'; while(($k,$v) = each %%ENV) { print qq[\@SET $k=$v\n]; }" > bldenv.bat
CALL bldenv.bat
del bldenv.bat
:nobuildenv
SET BV=
for /F "tokens=4 usebackq" %%f in (`bison -V`) do if "!BV!"=="" SET BV=%%f
if "%BV%"=="" goto novarexp
if %BV% EQU 1.875 goto bisonok
if %BV% GEQ 2.2 goto bisonok
goto nobison
:bisonok
if "%1" == "src\backend\parser\gram.y" call :generate %1 src\backend\parser\gram.c src\backend\parser\gram.h
if "%1" == "src\backend\bootstrap\bootparse.y" call :generate %1 src\backend\bootstrap\bootparse.c
if "%1" == "src\backend\replication\repl_gram.y" call :generate %1 src\backend\replication\repl_gram.c
if "%1" == "src\pl\plpgsql\src\gram.y" call :generate %1 src\pl\plpgsql\src\pl_gram.c src\pl\plpgsql\src\pl_gram.h
if "%1" == "src\test\isolation\specparse.y" call :generate %1 src\test\isolation\specparse.c
if "%1" == "src\interfaces\ecpg\preproc\preproc.y" call :generate %1 src\interfaces\ecpg\preproc\preproc.c src\interfaces\ecpg\preproc\preproc.h
if "%1" == "contrib\cube\cubeparse.y" call :generate %1 contrib\cube\cubeparse.c
if "%1" == "contrib\seg\segparse.y" call :generate %1 contrib\seg\segparse.c
echo Unknown bison input: %1
exit 1
:generate REM src/tools/msvc/pgbison.bat
SET fn=%1 REM all the logic for this now belongs in builddoc.pl. This file really
SET cf=%2 REM only exists so you don't have to type "perl src/tools/msvc/pgbison.pl"
bison.exe -d %fn% -o %cf% REM Resist any temptation to add any logic here.
if errorlevel 1 exit 1 @perl src/tools/msvc/pgbison.pl %*
SET hf=%cf:~0,-2%.h
if not "%hf%"=="%3" (
copy /y %hf% %3
if errorlevel 1 exit 1
del %hf%
)
exit 0
:novarexp
echo pgbison must be called with cmd /V:ON /C pgbison to work!
exit 1
:nobison
echo WARNING! Bison install not found, or unsupported Bison version.
echo Attempting to build without.
exit 0
# -*-perl-*- hey - emacs - this is a perl file
# src/tools/msvc/pgbison.pl
use strict;
use File::Basename;
# assume we are in the postgres source root
require 'src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl';
my ($bisonver) = `bison -V`; # grab first line
$bisonver=(split(/\s+/,$bisonver))[3]; # grab version number
unless ($bisonver eq '1.875' || $bisonver ge '2.2')
{
print "WARNING! Bison install not found, or unsupported Bison version.\n";
print "echo Attempting to build without.\n";
exit 0;
}
my $input = shift;
if ($input !~ /\.y$/)
{
print "Input must be a .y file\n";
exit 1;
}
elsif (!-e $input)
{
print "Input file $input not found\n";
exit 1;
}
(my $output = $input) =~ s/\.y$/.c/;
# plpgsql just has to be different
$output =~ s/gram\.c$/pl_gram.c/ if $input =~ /src.pl.plpgsql.src.gram\.y$/;
my $makefile = dirname($input) . "/Makefile";
my ($mf, $make);
open($mf,$makefile);
local $/ = undef;
$make=<$mf>;
close($mf);
my $headerflag = ($make =~ /\$\(BISON\)\s+-d/ ? '-d' : '');
system("bison $headerflag $input -o $output");
exit $? >> 8;
@echo off @echo off
REM src/tools/msvc/pgflex.bat
REM silence flex bleatings about file path style
SET CYGWIN=nodosfilewarning
IF NOT EXIST src\tools\msvc\buildenv.pl goto nobuildenv
perl -e "require 'src/tools/msvc/buildenv.pl'; while(($k,$v) = each %%ENV) { print qq[\@SET $k=$v\n]; }" > bldenv.bat
CALL bldenv.bat
del bldenv.bat
:nobuildenv
flex -V > NUL
if errorlevel 1 goto noflex
if "%1" == "src\backend\parser\scan.l" call :generate %1 src\backend\parser\scan.c -CF REM src/tools/msvc/pgflex.bat
if "%1" == "src\backend\bootstrap\bootscanner.l" call :generate %1 src\backend\bootstrap\bootscanner.c REM all the logic for this now belongs in builddoc.pl. This file really
if "%1" == "src\backend\utils\misc\guc-file.l" call :generate %1 src\backend\utils\misc\guc-file.c REM only exists so you don't have to type "perl src/tools/msvc/pgflex.pl"
if "%1" == "src\backend\replication\repl_scanner.l" call :generate %1 src\backend\replication\repl_scanner.c REM Resist any temptation to add any logic here.
if "%1" == "src\test\isolation\specscanner.l" call :generate %1 src\test\isolation\specscanner.c @perl src/tools/msvc/pgflex.pl %*
if "%1" == "src\interfaces\ecpg\preproc\pgc.l" call :generate %1 src\interfaces\ecpg\preproc\pgc.c
if "%1" == "src\bin\psql\psqlscan.l" call :generate %1 src\bin\psql\psqlscan.c
if "%1" == "contrib\cube\cubescan.l" call :generate %1 contrib\cube\cubescan.c
if "%1" == "contrib\seg\segscan.l" call :generate %1 contrib\seg\segscan.c
echo Unknown flex input: %1
exit 1
REM For non-reentrant scanners we need to fix up the yywrap macro definition
REM to keep the MS compiler happy.
REM For reentrant scanners (like the core scanner) we do not
REM need to (and must not) change the yywrap definition.
:generate
flex %3 -o%2 %1
if errorlevel 1 exit %errorlevel%
perl -n -e "exit 1 if /^\%%option\s+reentrant/;" %1
if errorlevel 1 exit 0
perl -pi.bak -e "s/yywrap\(n\)/yywrap()/;" %2
if errorlevel 1 exit %errorlevel%
del %2.bak
exit 0
:noflex
echo WARNING! flex install not found, attempting to build without
exit 0
# -*-perl-*- hey - emacs - this is a perl file
# src/tools/msvc/pgflex.pl
# silence flex bleatings about file path style
$ENV{CYGWIN} = 'nodosfilewarning';
use strict;
use File::Basename;
# assume we are in the postgres source root
require 'src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl';
system('flex -V > NUL');
if ($? != 0)
{
print "WARNING! flex install not found, 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 $flexflags = ($make =~ /^\s*FLEXFLAGS\s*=\s*(\S.*)/m ? $1 : '');
system("flex $flexflags -o$output $input");
if ($? == 0)
{
# 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 $lfile;
open($lfile,$input) || die "opening $input for reading: $!";
my $lcode = <$lfile>;
close($lfile);
if ($lcode !~ /\%option\sreentrant/)
{
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 reading: $!";
print $cfile $ccode;
close($cfile);
}
exit 0;
}
else
{
exit $? >> 8;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment