bin/tools/foamGenerateBashCompletion: Improved robustness of bracket parsing

Also minor formatting changes
This commit is contained in:
Will Bainbridge
2020-07-30 16:46:51 +01:00
parent 074dbec0a5
commit e603417ef7
4 changed files with 155 additions and 139 deletions

View File

@ -92,36 +92,26 @@ banner () {
EOF EOF
} }
header_start () { declareLocals () {
cat <<EOF cat <<EOF
{
local cur="\${COMP_WORDS[COMP_CWORD]}" local cur="\${COMP_WORDS[COMP_CWORD]}"
local prev="\${COMP_WORDS[COMP_CWORD-1]}" local prev="\${COMP_WORDS[COMP_CWORD-1]}"
local line=\${COMP_LINE} local line=\${COMP_LINE}
local used=\$(echo "\$line" | grep -oE "\-[a-zA-Z]+ ") local used=\$(echo "\$line" | grep -oE "\-[a-zA-Z]+ ")
EOF EOF
} }
header_end () { caseStart () {
cat <<EOF cat <<EOF
[ "\$COMP_CWORD" = 1 ] || \\ [ "\$COMP_CWORD" = 1 ] || \\
case "\$prev" in case "\$prev" in
EOF EOF
} }
footer () { caseEnd () {
cat <<EOF cat <<EOF
esac esac
COMPREPLY=( \$(compgen -W "\${opts}" \$extra -- \${cur}) ) COMPREPLY=( \$(compgen -W "\${opts}" \$extra -- \${cur}) )
}
EOF
}
close () {
cat<<EOF
#------------------------------------------------------------------------------
EOF EOF
} }
@ -129,7 +119,8 @@ EOF
_foamGet () { _foamGet () {
cat <<EOF cat <<EOF
_foamGet_ () _foamGet_ ()
$(header_start) {
$(declareLocals)
_searchDirs () { _searchDirs () {
_dirs="\\ _dirs="\\
@ -156,7 +147,8 @@ $(header_start)
for o in \$used ; do opts="\${opts/\$o/}" ; done for o in \$used ; do opts="\${opts/\$o/}" ; done
extra="" extra=""
opts="\${opts} \$(_searchDirs)" opts="\${opts} \$(_searchDirs)"
$(header_end)
$(caseStart)
-case|-target) -case|-target)
opts="" ; extra="-d" ;; opts="" ; extra="-d" ;;
-ext) -ext)
@ -168,7 +160,8 @@ $(header_end)
*) opts=""; extra="" ;; *) opts=""; extra="" ;;
esac esac
;; ;;
$(footer) $(caseEnd)
}
complete -o filenames -o nospace -F _foamGet_ foamGet complete -o filenames -o nospace -F _foamGet_ foamGet
EOF EOF
@ -178,13 +171,16 @@ EOF
_foamCloneCase () { _foamCloneCase () {
cat <<EOF cat <<EOF
_foamCloneCase_ () _foamCloneCase_ ()
$(header_start) {
$(declareLocals)
opts="-add -help -latestTime -no-orig -no-scripts -processor -template" opts="-add -help -latestTime -no-orig -no-scripts -processor -template"
for o in \$used ; do opts="\${opts/\$o/}" ; done for o in \$used ; do opts="\${opts/\$o/}" ; done
extra="-d" extra="-d"
$(header_end)
$(footer) $(caseStart)
$(caseEnd)
}
complete -o filenames -o nospace -F _foamCloneCase_ foamCloneCase complete -o filenames -o nospace -F _foamCloneCase_ foamCloneCase
EOF EOF
@ -208,156 +204,176 @@ do
echo "Configuring $appName" echo "Configuring $appName"
# Check for special configurations # If a special configurations is defined for this app, use it and continue
echo "$specialApps" | grep -qsw "$appName" && "_$appName" >> "$file" && continue echo "$specialApps" | \
grep -qsw "$appName" && "_$appName" >> "$file" && continue
# ARGUMENTS between <> and [] # Get arguments. Anything on the usage line in <> or [] brackets.
usage=$($app -help | grep ^Usage) argList=$($app -help | \
args=$(echo "$usage" | awk -F '[]<>[]' '{for(i=2;i<=NF;++i)print $i}' | sed '/^[\t ]*$/d') grep ^Usage | \
awk -F '[]>]' '{for(i=1;i<=NF;++i) print $i}' | \
awk -F ' [<[]' '{print $2}')
# Entries without "output", ending "file" # Categorise arguments ...
input_file_args=$(echo "$args" | while read -r line
do
echo "$line" | grep -v output | grep -E "file$"
done)
n_input_file_args=$(echo "$input_file_args" | sed '/^$/d' | wc -l)
# Entries without "output", including "case" or "dir*" # File arguments. Entries without "output", ending in "file".
input_dir_args=$(echo "$args" | while read -r line inputFileArgs=$(echo "$argList" | while read -r line
do do
echo "$line" | grep -v output | grep -Ei "(case|dir).*" echo "$line" | grep -v output | grep -E "file$"
done) done)
n_input_dir_args=$(echo "$input_dir_args" | sed '/^$/d' | wc -l) nInputFileArgs=$(echo "$inputFileArgs" | sed '/^$/d' | wc -l)
# OPTIONS # Directory arguments. Entries without "output", including "case" or "dir*".
opt_list=$($app -help | \ inputDirArgs=$(echo "$argList" | while read -r line
sed -n '/^options/,/^$/p' | \ do
grep -E "^[\t ]*-" | \ echo "$line" | grep -v output | grep -Ei "(case|dir).*"
tr -s " ") done)
nInputDirArgs=$(echo "$inputDirArgs" | sed '/^$/d' | wc -l)
argless_opts="" # options without arguments # Options. Anything in the between "options" and the next empty line.
dir_opts="" # options with directory arguments optList=$($app -help | \
file_opts="" # options with file arguments sed -n '/^options/,/^$/p' | \
handler_opts="" # file handler options -fileHandler grep -E "^[\t ]*-" | \
ranges_opts="" # ranges options -time tr -s " ")
arg_opts="" # options with unspecified arguments
# 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
while read -r line while read -r line
do do
# Get the option
opt=$(echo "$line" | cut -d " " -f1 | tr -d " ") opt=$(echo "$line" | cut -d " " -f1 | tr -d " ")
# Get the string in <>. Hack cuts beyond field 5 to avoid (fvPatchField<vector>) # Get the adjacent string in <> brackets
next=$(echo "$line" | \ next=$(echo "$line" | \
cut -d " " -f1-5 | \ sed 's/ \<.*\>.*//g' | \
awk -F '[<>]' '{print $2}' | \ awk -F '>' '{print $1}' | \
tr -d \) | tr -d \() awk -F ' <' '{print $2}' |
tr -d \) | \
tr -d \()
# Check the last word in string # Categorise by the the last word in the string
case "${next##* }" in case "${next##* }" in
"") argless_opts="$argless_opts $opt" ;; "") arglessOpts="$arglessOpts $opt" ;;
dir) dir_opts="$dir_opts $opt" ;; dir) dirOpts="$dirOpts $opt" ;;
file) file_opts="$file_opts $opt";; file) fileOpts="$fileOpts $opt";;
handler) handler_opts="$handler_opts $opt";; handler) handlerOpts="$handlerOpts $opt";;
ranges) ranges_opts="$ranges_opts $opt";; ranges) rangesOpts="$rangesOpts $opt";;
*) arg_opts="$arg_opts $opt";; *) argOpts="$argOpts $opt";;
esac esac
done<<< "$opt_list" done<<< "$optList"
# Combine options into a single list
# shellcheck disable=SC2086 # shellcheck disable=SC2086
all_opts=$(printf '%s\n' $argless_opts $dir_opts $file_opts $handler_opts $ranges_opts $arg_opts | sort) allOpts=$(printf '%s\n' \
$arglessOpts $dirOpts $fileOpts $handlerOpts $rangesOpts $argOpts | \
sort)
# WRITE FUNCTION # Write the completion function ...
# shellcheck disable=SC2086 # shellcheck disable=SC2086
{ {
echo "_${appName}_ ()"
echo "{"
declareLocals
echo ""
echo "_${appName}_ ()" # shellcheck disable=SC2027,SC2086
header_start echo " opts=\""$allOpts"\""
echo " for o in \$used ; do opts=\"\${opts/\$o/}\" ; done"
# shellcheck disable=SC2027,SC2086 if [ ! "$nInputFileArgs" = 0 ]
echo " opts=\""$all_opts"\"" then
echo " for o in \$used ; do opts=\"\${opts/\$o/}\" ; done" echo " extra=\"-d -f\""
elif [ ! "$nInputDirArgs" = 0 ]
then
echo " extra=\"-d\""
else
echo " extra=\"\""
fi
if [ ! "$n_input_file_args" = 0 ] echo ""
then caseStart
echo " extra=\"-d -f\""
elif [ ! "$n_input_dir_args" = 0 ]
then
echo " extra=\"-d\""
else
echo " extra=\"\""
fi
header_end if [ -n "$dirOpts" ]
then
printf " %s)\n" "$(echo $dirOpts | tr " " "|")"
echo " opts=\"\" ; extra=\"-d\" ;;"
fi
if [ -n "$dir_opts" ] if [ -n "$fileOpts" ]
then then
printf " %s)\n" "$(echo $dir_opts | tr " " "|")" printf " %s)\n" "$(echo $fileOpts | tr " " "|")"
echo " opts=\"\" ; extra=\"-d\" ;;" echo " opts=\"\" ; extra=\"-d -f\" ;;"
fi fi
if [ -n "$file_opts" ] if [ -n "$handlerOpts" ]
then then
printf " %s)\n" "$(echo $file_opts | tr " " "|")" printf " %s)\n" "$(echo $handlerOpts | tr " " "|")"
echo " opts=\"\" ; extra=\"-d -f\" ;;" echo " opts=\"uncollated collated masterUncollated\" ; extra=\"\" ;;"
fi fi
if [ -n "$handler_opts" ] if [ -n "$rangesOpts" ]
then then
printf " %s)\n" "$(echo $handler_opts | tr " " "|")" printf " %s)\n" "$(echo $rangesOpts | tr " " "|")"
echo " opts=\"uncollated collated masterUncollated\" ; extra=\"\" ;;" echo " opts=\"\$(foamListTimes -withZero 2> /dev/null)\" ; extra=\"\" ;;"
fi fi
if [ -n "$ranges_opts" ] if [ -n "$argOpts" ]
then then
printf " %s)\n" "$(echo $ranges_opts | tr " " "|")" printf " %s)\n" "$(echo $argOpts | tr " " "|")"
echo " opts=\"\$(foamListTimes -withZero 2> /dev/null)\" ; extra=\"\" ;;" echo " opts=\"\" ; extra=\"\" ;;"
fi fi
if [ -n "$arg_opts" ] # Set argOpts to all options with arguments
then argOpts="$argOpts $dirOpts $fileOpts $handlerOpts $rangesOpts"
printf " %s)\n" "$(echo $arg_opts | tr " " "|")"
echo " opts=\"\" ; extra=\"\" ;;"
fi
# Set arg_opts to all options with arguments # Get the max of nInputFileArgs and nInputDirArgs
arg_opts="$arg_opts $dir_opts $file_opts $handler_opts $ranges_opts" nMaxFileDirArgs=$nInputFileArgs
[ "$nInputDirArgs" -gt "$nMaxFileDirArgs" ] && \
nMaxFileDirArgs=$nInputDirArgs
# Get the max of n_input_file_args and n_input_dir_args # Stop optional arguments once mandatory arguments are entered
n_max_file_dir_args=$n_input_file_args case "$nMaxFileDirArgs" in
[ "$n_input_dir_args" -gt "$n_max_file_dir_args" ] && \ 0) echo " *) ;;" ;;
n_max_file_dir_args=$n_input_dir_args 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
# Stop optional arguments once mandatory arguments are entered caseEnd
case "$n_max_file_dir_args" in echo "}"
0) echo " *) ;;" ;;
1)
echo " -*) ;;"
echo " *)"
if [ -z "${arg_opts// }" ]
then
echo " opts=\"\"; extra=\"\""
else
echo " case \"\${COMP_WORDS[COMP_CWORD-2]}\" in"
printf " %s) ;;\n" "$(echo $arg_opts | tr " " "|")"
echo " *) opts=\"\"; extra=\"\" ;;"
echo " esac"
fi
echo " ;;"
;;
*)
echo " -*) ;;"
echo " *) opts=\"\";;"
;;
esac
footer echo "complete -o filenames -o nospace -F _${appName}_ ${appName}"
echo ""
echo "complete -o filenames -o nospace -F _${appName}_ ${appName}"
echo ""
} >> "$file" } >> "$file"
done done
close >> "$file" cat<<\EOF >> "$file"
#------------------------------------------------------------------------------
EOF
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------

View File

@ -5509,7 +5509,7 @@ _foamInfo_ ()
[ "$COMP_CWORD" = 1 ] || \ [ "$COMP_CWORD" = 1 ] || \
case "$prev" in case "$prev" in
-browser|-keyword) -browser)
opts="" ; extra="" ;; opts="" ; extra="" ;;
*) ;; *) ;;
esac esac

View File

@ -3,7 +3,7 @@
# ========= | # ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org # \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation # \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
# \\/ M anipulation | # \\/ M anipulation |
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
@ -39,7 +39,7 @@ unset quietOpt
usage() { usage() {
cat<<USAGE cat<<USAGE
Usage: $Script [OPTION] dirName Usage: $Script [OPTION] [dir]
options: options:
-quiet | -q suppress all normal output -quiet | -q suppress all normal output

View File

@ -3,7 +3,7 @@
# ========= | # ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org # \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation # \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
# \\/ M anipulation | # \\/ M anipulation |
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
@ -43,7 +43,7 @@ Script=${0##*/}
usage() { usage() {
cat<<USAGE cat<<USAGE
Usage: $Script [OPTION] dir Usage: $Script [OPTION] [dir]
options: options:
-update | -u update -update | -u update