"README.md" did not exist on "8e968f5647c05990b2c58a6170704abff92580c5"
Newer
Older
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# Copyright (C) 2019-2021 OpenCFD Ltd.
#-------------------------------------------------------------------------------
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
# Script
# wrap-lemon
#
# Usage
# wrap-lemon [options] [lemon options/args]
#
# Description
# A wrapper to use lemon compiled with OpenFOAM with the appropriate
# parser template.
#
# When called with m4 wrapping, it sets the m4 -I include to have
# the following:
# - the directory of the parser.
# - include/ in the top-level source tree of the current target
# (eg, src/finiteVolume/include/ when compiling libfiniteVolume)
# - include/ from OpenFOAM
#
#------------------------------------------------------------------------------
binDir="${WMAKE_BIN:-$WM_PROJECT_DIR/platforms/tools/$WM_ARCH$WM_COMPILER}"
etcDir="${WM_DIR:-$WM_PROJECT_DIR/wmake}/etc"
# Executable and skeleton locations
skel="-T${etcDir}/lempar.c"
cat<<USAGE
Usage: ${0##*/} [options] [lemon args/options]
options:
-header Generate header only, suppressing other output
-dry-run Process m4 only (output on stdout)
-grammar Output grammar tables (stdout)
-no-tmp Do not retain temporary m4 processed files
-h, -help Print the usage
A lemon wrapper using predefined executable and skeleton locations.
Files ending with 'm4' (eg, .lyym4, .lyy-m4) will be filtered through
the m4(1) macro processor and lemon will be called with 'm4' as a macro
definition, which can be used in conditions (%ifdef m4, %ifndef m4)
USAGE
}
#------------------------------------------------------------------------------
# Parse arguments and options
#------------------------------------------------------------------------------
# Eg, wrap-lemon -header
unset optDryRun optHeader optGrammar optRemoveTmp m4Flags
while [ "$#" -gt 0 ]
do
case "$1" in
(-dry-run) optDryRun=true ;;
(-head*) optHeader=true ;;
(-gram*) optGrammar=true ;;
(-no-tmp) optRemoveTmp=true ;;
(*) break ;;
esac
shift
done
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#------------------------------------------------------------------------------
# Additional m4Flags (for includes etc)
#
# $1 : path-qualified name of the parser
#
# Set includes accordingly to
# - the directory containing the parser
# - include/ in the top-level source tree of the current target
# - include/ from OpenFOAM
defineM4Flags()
{
# Always include the directory containing the parser file
m4Flags="$m4Flags${m4Flags:+ }-I$(dirname ${1:-.})"
local proj="$WM_PROJECT_DIR/src/${WM_PROJECT:-OpenFOAM}"
local curr="$PWD"
# Called from the Makefile (PWD contains the parser source)
# or from elsewhere (eg, createCode)?
if [ ! -f "$curr/Make/options" ]
then
# No Make/options (eg createCode) - discover with "wmake -pwd"
curr="$(wmake -pwd 2>/dev/null)"
fi
# Avoid examining twice
[ "$curr" != "$proj" ] || unset curr
if [ -n "$curr" ] && [ -d "$curr/include" ]
then
m4Flags="$m4Flags -I$curr/include"
fi
if [ -n "$proj" ] && [ -d "$proj/include" ]
then
m4Flags="$m4Flags -I$proj/include"
fi
}
#------------------------------------------------------------------------------
# Get some information based on the lemon options
# * '-dXX' for the output directory
# * '-eXX' for the output extension
# The last argument is the input file
unset tmpDir tmpFile outputDir parser extCode
findLemonOptions()
{
while [ "$#" -gt 1 ]
do
case "$1" in
(-d*) outputDir="${1#-d}" ;;
(-e*) extCode="${1#-e}" ;;
esac
shift
done
if [ "$#" -eq 1 ]
then
parser="$1"
fi
}
findLemonOptions "$@"
unset parserFlags extParser usingM4
# Detect m4 use (defines parser macro too) and get extension without m4
case "$parser" in
(*.*m4)
usingM4=true
parserFlags="-Dm4"
defineM4Flags "$parser"
extParser=".${parser##*.}" # The extension (with dot)
extParser="${extParser%m4}" # Without trailing m4
extParser="${extParser/%[-_]/}" # Without - or _ separators
if [ -n "$optGrammar" ]
then
parserFlags="${parserFlags}${parserFlags:+ }-g"
fi
exitCode=0 # No failures
#------------------------------------------------------------------------------
# Dry-run
if [ "$optDryRun" = true ]
then
if [ "$usingM4" = true ]
then
echo "m4 flags: $m4Flags" 1>&2
m4 $m4Flags "$parser"; exitCode=$?
else
echo "Nothing to do - not using m4" 2>/dev/null
fi
[ "$exitCode" -eq 0 ] || echo "m4 failed" 2>/dev/null
exit "$exitCode" # Done
fi
#------------------------------------------------------------------------------
unset tmpFile tmpDir
if [ -n "$optHeader" ]
then
## echo "${0##*/} : generate header" 1>&2
# Drop last argument (the parser input file)
set -- "${@:1:${#}-1}"
# Header only, which means we create a temp directory for the output
tmpDir="lemonWrapper-$$"
rm -rf "$tmpDir" 2>/dev/null
mkdir "$tmpDir" 2>/dev/null
trap 'rm -rf $tmpDir; exit $exitCode' EXIT TERM INT
if [ "$usingM4" = true ]
then
# Using m4 - redirect to a temporary file
tmpFile="$tmpDir/${parser##*/}"
tmpFile="${tmpFile%.*}$extParser" # Eg, from .lyy-m4 -> .lyy
if m4 $m4Flags "$parser" > "$tmpFile" && [ -f "$tmpFile" ]
then
parser="$tmpFile"
else
echo "m4 stage failed on $parser" 2>/dev/null
fi
fi
if [ "$exitCode" -eq 0 ]
then
"$lemon" "$skel" "-d$tmpDir" "$@" $parserFlags "$parser"
exitCode=$?
fi
if [ "$exitCode" -eq 0 ]
then
for src in "$tmpDir"/*.h
do
dst="${src##*/}"
if [ -f "$src" ]
if ! cmp "$src" "$dst" 2>/dev/null
then
mv "$src" "$dst"
echo "Updating $dst" 1>&2
fi
elif [ "$usingM4" = true ]
## echo "${0##*/} : generate code (with m4 filtering)" 1>&2
# Drop last argument (the parser input file)
set -- "${@:1:${#}-1}"
# Filter via m4
if [ -n "$outputDir" ]
then
tmpFile="$outputDir/${parser##*/}"
else
tmpFile="${parser}"
fi
tmpFile="${tmpFile%.*}$extParser" # Eg, from .lyy-m4 -> .lyy
if [ -n "$optRemoveTmp" ]
then
trap 'rm -f $tmpFile; exit $exitCode' EXIT TERM INT
fi
if m4 $m4Flags "$parser" > "$tmpFile" && [ -f "$tmpFile" ]
"$lemon" "$skel" "$@" $parserFlags "$tmpFile"
exitCode=$?
else
echo "m4 stage failed on $parser" 2>/dev/null
echo "Retaining intermediate: $tmpFile" 2>/dev/null
fi
else
# No special handling
## echo "${0##*/} : generate code" 1>&2
"$lemon" "$skel" "$@"
exit "$exitCode" # Exit with lemon return code
#------------------------------------------------------------------------------