86 lines
2.9 KiB
Python
Executable File
86 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
#
|
|
# Wrapper around flex that:
|
|
# - ensures lex.backup is created in a private directory
|
|
# - can error out if lex.backup is created (--no-backup)
|
|
# - can fix warnings (--fix-warnings)
|
|
# - works around concurrency issues with win_flex.exe:
|
|
# https://github.com/lexxmark/winflexbison/issues/86
|
|
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from os.path import abspath
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('--flex', type=abspath, required=True)
|
|
parser.add_argument('--perl', type=abspath, required=True)
|
|
parser.add_argument('--builddir', type=abspath, required=True)
|
|
parser.add_argument('--srcdir', type=abspath, required=True)
|
|
parser.add_argument('--privatedir', type=abspath, required=True,
|
|
help='private directory for target')
|
|
|
|
parser.add_argument('-o', dest='output_file', type=abspath, required=True,
|
|
help='output file')
|
|
parser.add_argument('-i', dest='input_file', type=abspath, help='input file')
|
|
|
|
|
|
parser.add_argument('--fix-warnings', action='store_true',
|
|
help='whether to fix warnings in generated file')
|
|
parser.add_argument('--no-backup', action='store_true',
|
|
help='whether no_backup is enabled or not')
|
|
|
|
parser.add_argument('flex_flags', nargs='*', help='flags passed on to flex')
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Since 'lex.backup' is always named that and ninja uses the top level build
|
|
# directory as current directory for all commands, change directory to
|
|
# temporary directory to avoid conflicts between concurrent flex
|
|
# invocations. Only unreleased versions of flex have an argument to change
|
|
# lex.filename to be named differently.
|
|
if not os.path.isdir(args.privatedir):
|
|
os.mkdir(args.privatedir)
|
|
os.chdir(args.privatedir)
|
|
|
|
# win_flex.exe generates names in a racy way, sometimes leading to random
|
|
# "error deleting file" failures and sometimes to intermingled file
|
|
# contents. Set FLEX_TMP_DIR to the target private directory to avoid
|
|
# that. That environment variable isn't consulted on other platforms, so we
|
|
# don't even need to make this conditional.
|
|
env = {'FLEX_TMP_DIR': args.privatedir}
|
|
|
|
# build flex invocation
|
|
command = [args.flex, '-o', args.output_file]
|
|
if args.no_backup:
|
|
command += ['-b']
|
|
command += args.flex_flags
|
|
command += [args.input_file]
|
|
|
|
# create .c file from .l file
|
|
sp = subprocess.run(command, env=env)
|
|
if sp.returncode != 0:
|
|
sys.exit(sp.returncode)
|
|
|
|
# check lex.backup
|
|
if args.no_backup:
|
|
with open('lex.backup') as lex:
|
|
if len(lex.readlines()) != 1:
|
|
sys.exit('Scanner requires backup; see lex.backup.')
|
|
os.remove('lex.backup')
|
|
|
|
# fix warnings
|
|
if args.fix_warnings:
|
|
fix_warning_script = os.path.join(args.srcdir,
|
|
'src/tools/fix-old-flex-code.pl')
|
|
|
|
command = [args.perl, fix_warning_script, args.output_file]
|
|
sp = subprocess.run(command)
|
|
if sp.returncode != 0:
|
|
sys.exit(sp.returncode)
|
|
|
|
sys.exit(0)
|