Files
OpenFOAM-12/bin/tools/foamGenerateBashCompletion
2023-08-29 18:16:56 +01:00

498 lines
13 KiB
Bash
Executable File

#!/bin/bash
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2020-2023 OpenFOAM Foundation
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# foamGenerateBashCompletion
#
# Description
# Generate the bash_completion file
#
#------------------------------------------------------------------------------
usage() {
cat<<USAGE
Usage: ${0##*/}
USAGE
}
error() {
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
usage
exit 1
}
file=$WM_PROJECT_DIR/etc/config.sh/bash_completion
case "$1" in
(-h | -help)
usage && exit 0
;;
(-l | -local)
file=${file##*/}
shift 1
;;
-*)
error "$1 is not a valid option/filename"
;;
esac
#------------------------------------------------------------------------------
banner () {
cat<<EOF
#----------------------------------*-sh-*--------------------------------------
# ========= |
# \\\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\\\ / O peration | Website: https://openfoam.org
# \\\\ / A nd | Copyright (C) 2017-$(date +%Y) OpenFOAM Foundation
# \\\\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
#
# File
# etc/config.sh/bash_completion
#
# Description
# Bash [TAB] completion file from OpenFOAM
# Sourced from /etc/bashrc
#
#------------------------------------------------------------------------------
# shellcheck disable=SC2155,SC2207,SC2086
EOF
}
optionFunctions () {
cat<<EOF
_solver ()
{
foamToC -table solver | sed '1,/Contents/d' | awk '{print \$1}' | xargs
}
_table ()
{
[ -z "\${1// }" ] && \\
foamToC -tables | \\
sed '1,/Run-time/d' | \\
sed 's/[[:space:]]\{4\}//' | grep -v ' ' && exit 0
foamToC -tables | sed '1,/Run-time/d' | tr -d " "
}
_func ()
{
foamPostProcess -list | sed -n '/^(/,/^)/p' | grep -v '[()]'
}
_infoArgs ()
{
foamToC -all | \\
grep -wx '[^ _]* [^ ]*.so' | \\
awk '{print \$1}' | \\
tr '<>,' '\n' | \\
sort -u | \\
xargs
}
EOF
}
declareLocals () {
cat <<EOF
local cur="\${COMP_WORDS[COMP_CWORD]}"
local prev="\${COMP_WORDS[COMP_CWORD-1]}"
local line=\${COMP_LINE}
local used=\$(echo "\$line" | grep -oE "\-[a-zA-Z]+ ")
EOF
}
caseStart () {
cat <<EOF
[ "\$COMP_CWORD" = 1 ] || \\
case "\$prev" in
EOF
}
caseEnd () {
cat <<EOF
esac
COMPREPLY=( \$(compgen -W "\${opts}" \$extra -- \${cur}) )
EOF
}
isScript () {
file "$(command -v "$1")" | grep -q "POSIX shell script"
}
# shellcheck disable=SC2154
_foamGet () {
cat <<EOF
_foamGet_ ()
{
$(declareLocals)
_searchDirs () {
_dirs="\\
\${HOME}/.OpenFOAM/\$WM_PROJECT_VERSION \\
\${HOME}/.OpenFOAM"
[ -n "\$WM_PROJECT_SITE" ] && _dirs=" \\
\$WM_PROJECT_SITE/\$WM_PROJECT_VERSION/etc \\
\$WM_PROJECT_SITE/etc"
_dirs+=" \\
\$WM_PROJECT_INST_DIR/site/\$WM_PROJECT_VERSION/etc \\
\$WM_PROJECT_INST_DIR/site/etc \\
\$FOAM_ETC/caseDicts"
_files=""
for _d in \$_dirs
do
[ -d "\$_d" ] && \\
_files="\$_files \$(find "\$_d" -type f ! -name "*.*" -exec basename {} \;)"
done
echo "\${_files}" | xargs -n 1 | sort -u
}
opts="-case -ext -help -no-ext -target"
for o in \$used ; do opts="\${opts/\$o/}" ; done
extra=""
opts="\${opts} \$(_searchDirs)"
$(caseStart)
-case|-target)
opts="" ; extra="-d" ;;
-ext)
opts="" ; extra="" ;;
-*) ;;
*)
case "\${COMP_WORDS[COMP_CWORD-2]}" in
-case|-ext|-target) ;;
*) opts=""; extra="" ;;
esac
;;
$(caseEnd)
}
complete -o filenames -o nospace -F _foamGet_ foamGet
EOF
}
# shellcheck disable=SC2154
_foamCloneCase () {
cat <<EOF
_foamCloneCase_ ()
{
$(declareLocals)
opts="-add -help -latestTime -no-orig -no-scripts \
-processor -startFrom -template"
for o in \$used ; do opts="\${opts/\$o/}" ; done
extra="-d"
$(caseStart)
$(caseEnd)
}
complete -o filenames -o nospace -F _foamCloneCase_ foamCloneCase
EOF
}
# shellcheck disable=SC2154
_surfaceTransformPoints () {
cat<<EOF
_surfaceTransformPoints_ ()
{
$(declareLocals)
opts="-doc -help -srcDoc"
for o in \$used ; do opts="\${opts/\$o/}" ; done
extra="-d -f"
$(caseStart)
-*) ;;
*)
case "\${COMP_WORDS[COMP_CWORD-2]}" in
*) opts=""; extra="-d -f" ;;
esac
;;
$(caseEnd)
}
complete -o filenames -o nospace -F _surfaceTransformPoints_ surfaceTransformPoints
EOF
}
# shellcheck disable=SC2154
_foamInfo () {
cat<<EOF
_foamInfo_ ()
{
$(declareLocals)
opts="-all -browser -help -keyword -web"
for o in \$used ; do opts="\${opts/\$o/}" ; done
opts="\$opts \$(_infoArgs) \$(ls \$FOAM_APPBIN)"
extra=""
$(caseStart)
-browser)
opts="" ; extra="" ;;
*) ;;
$(caseEnd)
}
complete -o filenames -o nospace -F _foamInfo_ foamInfo
EOF
}
#------------------------------------------------------------------------------
apps="$(ls "$FOAM_APPBIN") \
$(find "$WM_PROJECT_DIR/bin" -maxdepth 1 -type f | sort) \
$(find "$WM_PROJECT_DIR/wmake" -maxdepth 1 -type f | sort)"
specialApps="foamGet foamCloneCase foamInfo surfaceTransformPoints"
banner > "$file"
optionFunctions >> "$file"
for app in $apps
do
appName="${app##*/}"
echo "Configuring $appName"
# If a special configurations is defined for this app, use it and continue
echo "$specialApps" | \
grep -qsw "$appName" && "_$appName" >> "$file" && continue
# Get arguments. Anything on the usage line in <> or [] brackets.
argList=$($app -help | \
grep ^Usage | \
awk -F '[]>]' '{for(i=1;i<=NF;++i) print $i}' | \
awk -F ' [<[]' '{print $2}')
# Categorise arguments ...
# File arguments. Entries without "output", ending in "file".
inputFileArgs=$(echo "$argList" | while read -r line
do
echo "$line" | grep -v output | grep -E "file$"
done)
nInputFileArgs=$(echo "$inputFileArgs" | sed '/^$/d' | wc -l)
# Directory arguments. Entries without "output", including "case" or "dir*".
inputDirArgs=$(echo "$argList" | while read -r line
do
echo "$line" | grep -v output | grep -Ei "(case|dir).*"
done)
nInputDirArgs=$(echo "$inputDirArgs" | sed '/^$/d' | wc -l)
# Options. Anything in the between "options" and the next empty line.
optList=$($app -help | \
sed -n '/^options/,/^$/p' | \
grep -E "^[\t ]*-" | \
tr -s " ")
[ -z "$optList" ] && continue
# Categorise options ...
arglessOpts="" # options without arguments
dirOpts="" # options with directory arguments
fileOpts="" # options with file arguments
handlerOpts="" # file handler options -fileHandler
rangesOpts="" # ranges options -time
argOpts="" # options with unspecified arguments
specialOpts="" # -solver, -table, -func
while read -r line
do
# Clear the variable
unset next
# Get the option
opt=$(echo "$line" | cut -d " " -f1 | tr -d " ")
# Ignore "-solver" if app is a script
[ "$opt" = "-solver" ] && isScript "$appName" && continue
# Deal with quoted option arguments for -libs
[ "$opt" = "-libs" ] && next=libList
case "$opt" in
-solver|-table|-func)
specialOpts="$specialOpts $opt"
continue
;;
esac
# Get the adjacent string in <> brackets
[ "$next" ] || \
next=$(echo "$line" | \
sed 's/ \<.*\>.*//g' | \
awk -F '>' '{print $1}' | \
awk -F ' <' '{print $2}' |
tr -d \) | \
tr -d \()
# Categorise by the the last word in the string
case "${next##* }" in
"") arglessOpts="$arglessOpts $opt" ;;
dir) dirOpts="$dirOpts $opt" ;;
file) fileOpts="$fileOpts $opt";;
handler) handlerOpts="$handlerOpts $opt";;
ranges) rangesOpts="$rangesOpts $opt";;
*) argOpts="$argOpts $opt";;
esac
done<<< "$optList"
# Combine options into a single list
# shellcheck disable=SC2086
allOpts=$(printf '%s\n' \
$arglessOpts $dirOpts $fileOpts $handlerOpts $rangesOpts $argOpts $specialOpts | \
sort)
# Write the completion function ...
# shellcheck disable=SC2086
{
echo "_${appName}_ ()"
echo "{"
declareLocals
echo ""
# shellcheck disable=SC2027,SC2086
echo " opts=\""$allOpts"\""
echo " for o in \$used ; do opts=\"\${opts/\$o/}\" ; done"
if [ ! "$nInputFileArgs" = 0 ]
then
echo " extra=\"-d -f\""
elif [ ! "$nInputDirArgs" = 0 ]
then
echo " extra=\"-d\""
else
echo " extra=\"\""
fi
echo ""
caseStart
if [ -n "$dirOpts" ]
then
printf " %s)\n" "$(echo $dirOpts | tr " " "|")"
echo " opts=\"\" ; extra=\"-d\" ;;"
fi
if [ -n "$fileOpts" ]
then
printf " %s)\n" "$(echo $fileOpts | tr " " "|")"
echo " opts=\"\" ; extra=\"-d -f\" ;;"
fi
if [ -n "$handlerOpts" ]
then
printf " %s)\n" "$(echo $handlerOpts | tr " " "|")"
echo " opts=\"uncollated collated masterUncollated\" ; extra=\"\" ;;"
fi
if [ -n "$rangesOpts" ]
then
printf " %s)\n" "$(echo $rangesOpts | tr " " "|")"
echo " opts=\"\$(foamListTimes -withZero 2> /dev/null)\" ; extra=\"\" ;;"
fi
if [ -n "$argOpts" ]
then
printf " %s)\n" "$(echo $argOpts | tr " " "|")"
echo " opts=\"\" ; extra=\"\" ;;"
fi
for sopt in $specialOpts
do
printf " %s) opts=\"\$(_%s \${cur})\" ;;\n" "$sopt" "${sopt#-}"
done
# Set argOpts to all options with arguments
argOpts="$argOpts $dirOpts $fileOpts $handlerOpts $rangesOpts"
# Get the max of nInputFileArgs and nInputDirArgs
nMaxFileDirArgs=$nInputFileArgs
[ "$nInputDirArgs" -gt "$nMaxFileDirArgs" ] && \
nMaxFileDirArgs=$nInputDirArgs
# Stop optional arguments once mandatory arguments are entered
case "$nMaxFileDirArgs" in
0) echo " *) ;;" ;;
1)
echo " -*) ;;"
echo " *)"
if [ -z "${argOpts// }" ]
then
echo " opts=\"\"; extra=\"\""
else
echo " case \"\${COMP_WORDS[COMP_CWORD-2]}\" in"
printf " %s) ;;\n" \
"$(echo $argOpts | tr " " "|")"
echo " *) opts=\"\"; extra=\"\" ;;"
echo " esac"
fi
echo " ;;"
;;
*)
echo " -*) ;;"
echo " *) opts=\"\";;"
;;
esac
caseEnd
echo "}"
echo "complete -o filenames -o nospace -F _${appName}_ ${appName}"
echo ""
} >> "$file"
done
cat<<\EOF >> "$file"
#------------------------------------------------------------------------------
EOF
#------------------------------------------------------------------------------