641 lines
16 KiB
Bash
Executable File
641 lines
16 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-2024 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
|
|
_region ()
|
|
{
|
|
find . -name polyMesh -type d | \
|
|
awk -F '/' '{print \$(NF-1)}' | \
|
|
grep -v constant | \
|
|
sort -u | xargs
|
|
}
|
|
|
|
_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 '[()]'
|
|
}
|
|
|
|
_optSet () {
|
|
_used="\$1"
|
|
_opts="\$2"
|
|
|
|
for _o in \${_opts//-/\\\\-}
|
|
do
|
|
echo "\$_used" | grep -wq "\$_o" && return 0
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
_removeOpts () {
|
|
_opts="\$1"
|
|
_removes="\$2"
|
|
|
|
for _r in \${_removes//-/\\\\-}
|
|
do
|
|
_opts="\${_opts/\$_r/}"
|
|
done
|
|
|
|
echo "\$_opts"
|
|
}
|
|
|
|
_infoArgs ()
|
|
{
|
|
foamToC -all | \\
|
|
grep -wx '[^ _]* [^ ]*.so' | \\
|
|
awk '{print \$1}' | \\
|
|
tr '<>,' '\n' | \\
|
|
sort -u | \\
|
|
xargs
|
|
}
|
|
|
|
_findArgs () {
|
|
_dir="\$1"
|
|
|
|
[ -d "\$_dir" ] || return 1
|
|
|
|
_name="*"
|
|
echo "\$_dir" | grep -wqE "^(\$FOAM_SRC|\$FOAM_APP)" && _name="*.[CHL]"
|
|
|
|
find "\$_dir" -name "\$_name" -type f | \\
|
|
awk -F/ '{print \$NF}' | \\
|
|
sort -u | \\
|
|
xargs
|
|
}
|
|
|
|
_unitArgs ()
|
|
{
|
|
_opts="-help"
|
|
|
|
# If '-dimension' is not selected, it is always an option
|
|
echo "\$@" | grep -q -- "-d" || _opts="\$_opts -dimension"
|
|
|
|
# If '-all' or '-list' is selected, the only other possible option is '-dimension'
|
|
echo "\$@" | grep -q -- "-[al]" && echo "\$_opts" | xargs -n 1 | sort && return 0
|
|
|
|
# If '-all' or '-list' are not selected, they are options
|
|
_opts="\$_opts -all -list"
|
|
|
|
echo "\$@" | grep -q -- "-d" && _args="-d"
|
|
_opts="\$_opts \$(foamUnits -list \$_args | xargs -n 1 | grep '\\[' | tr -d '\\[\\]')"
|
|
echo "\$_opts" | xargs -n 1 | sort
|
|
}
|
|
|
|
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"
|
|
}
|
|
|
|
_foamFind ()
|
|
{
|
|
cat <<EOF
|
|
_foamFind_ ()
|
|
{
|
|
$(declareLocals)
|
|
|
|
opts="\\
|
|
-applications \\
|
|
-dir \\
|
|
-edit \\
|
|
-files \\
|
|
-help \\
|
|
-isearch \\
|
|
-numbers \\
|
|
-modules \\
|
|
-options \\
|
|
-print \\
|
|
-search \\
|
|
-tutorials"
|
|
|
|
for o in \$used ; do opts="\${opts/\$o/}" ; done
|
|
|
|
# use only one of '-edit', '-isearch', '-search', '-print'
|
|
local actions="-edit -isearch -search -print"
|
|
_optSet "\$used" "\$actions" && opts="\$(_removeOpts "\$opts" "\$actions")"
|
|
|
|
# use only one of '-applications', '-dir', '-modules', '-tutorials'
|
|
local paths="-applications -dir -modules -tutorials"
|
|
_optSet "\$used" "\$paths" && opts="\$(_removeOpts "\$opts" "\$paths")"
|
|
|
|
local dir=\$FOAM_SRC
|
|
echo "\$used" | grep -wq "\-applications" && dir=\$FOAM_APP
|
|
echo "\$line" | grep -wq "\-dir" && \\
|
|
dir="\$(echo "\$line" | grep -ow "\-dir[\t ]*[^ ]*" | cut -d" " -f2)"
|
|
echo "\$used" | grep -wq "\-modules" && dir=\$FOAM_MODULES
|
|
echo "\$used" | grep -wq "\-tutorials" && dir=\$FOAM_TUTORIALS
|
|
|
|
echo "\$line" | grep -wq "[^ ]*.[CHL]" || opts="\$opts \$(_findArgs "\$dir")"
|
|
extra=""
|
|
|
|
$(caseStart)
|
|
-dir)
|
|
opts="" ; extra="-d" ;;
|
|
*) ;;
|
|
$(caseEnd)
|
|
}
|
|
complete -o filenames -o nospace -F _foamFind_ foamFind
|
|
|
|
EOF
|
|
}
|
|
|
|
# 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 -region"
|
|
for o in \$used ; do opts="\${opts/\$o/}" ; done
|
|
extra=""
|
|
opts="\${opts} \$(_searchDirs)"
|
|
|
|
$(caseStart)
|
|
-case|-target)
|
|
opts="" ; extra="-d" ;;
|
|
-ext)
|
|
opts="" ; extra="" ;;
|
|
-region)
|
|
opts="\$(_region)"; extra="" ;;
|
|
-*) ;;
|
|
*)
|
|
case "\${COMP_WORDS[COMP_CWORD-2]}" in
|
|
-case|-ext|-target|-region) ;;
|
|
*) 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
|
|
}
|
|
|
|
# shellcheck disable=SC2154
|
|
_foamUnits () {
|
|
cat<<EOF
|
|
_foamUnits_ ()
|
|
{
|
|
$(declareLocals)
|
|
|
|
opts="\$(_unitArgs "\$used")"
|
|
extra=""
|
|
|
|
$(caseStart)
|
|
-*) ;;
|
|
*) opts="" ;;
|
|
$(caseEnd)
|
|
}
|
|
complete -o filenames -o nospace -F _foamUnits_ foamUnits
|
|
|
|
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="\
|
|
foamFind \
|
|
foamGet \
|
|
foamCloneCase \
|
|
foamInfo \
|
|
foamUnits \
|
|
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, -region
|
|
|
|
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|-region)
|
|
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
|
|
|
|
|
|
#------------------------------------------------------------------------------
|