diff --git a/bin/foamInfo b/bin/foamInfo new file mode 100755 index 000000000..e24ba8374 --- /dev/null +++ b/bin/foamInfo @@ -0,0 +1,367 @@ +#!/bin/sh +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | Copyright (C) 2018 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 . +# +# Script +# foamInfo +# +# Description +# Prints description and usage of an application, a script, or a model +# (including boundary conditions, function objects and fvOptions). +# +#------------------------------------------------------------------------------- +usage() { + cat< +options: + -all | -a list all tutorials that use (otherwise maximum 10) + -browser | -b output C++ source guide web page with specified browser, + e.g. foamInfo -browser "firefox" + -help | -h print the usage + -web | -w output C++ source guide web page with the browser + specified in the global controlDict file + +Prints the following for an application, a script, or a model +(including boundary conditions, function objects and fvOptions). +- File: the location of the relevant source code header file; +- Description details from the header file; +- Usage details from the header file; +- Examples: a list of relevant cases from the tutorials directory. + +For example, run: + foamInfo simpleFoam + foamInfo kEpsilon + foamInfo turbulentIntensityKineticEnergyInlet + foamInfo fixedTemperatureConstraint + foamInfo surfaces + foamInfo foamNewBC + +USAGE +} + +error() { + exec 1>&2 + while [ "$#" -ge 1 ]; do echo "$1"; shift; done + usage + exit 1 +} + +findFiles() { + _pre="$1" + + # Application + _out="$(find "$FOAM_APP" -name "${_pre}.C" -type f)" + + # Script + _out="$(find "$FOAM_SRC/../bin" -name "${_pre}" -type f) $_out" + + # Model + # exact match + _models="$(find "$FOAM_SRC" \ + -name "${_pre}*.H" \ + ! -name "*Fwd.H" \ + ! -name "*Fields.H" \ + ! -name "*I.H" -type f)" + + # otherwise "looser" match + [ "$_models" ] || \ + _models="$(find "$FOAM_SRC" \ + -iname "*${_pre}*.H" \ + ! -name "*Fwd.H" \ + ! -name "*Fields.H" \ + ! -name "*I.H" -type f)" + + _out="$_models $_out" + + for _t in scalar vector tensor + do + echo "$_pre" | grep -oq "$_t" && \ + _mod="$(echo "$_pre" | sed "s/${_t}//g")" && \ + _out="$(find "$FOAM_SRC" -name "${_mod}*.H" -type f) $_out" + done + + # Function + _out="$(find "$FOAM_ETC" -name "${_pre}" -type f) $_out" + + # Remove whitespace + echo "$_out" | xargs -n 1 +} + +nArgs() { + echo "$1" | xargs -n 1 | wc -l +} + +listArgs() { + _i=0 + _suggest="" + _pri=100 + + for _a in $1 + do + _i=$(( _i + 1)) + echo "${_i}) $_a" >&2 + + # Prioritise suggestion locations + _tests="\ + fields/fvPatchFields/ \ + fvMesh/fvPatches/ \ + caseDicts/postProcessing/" + + _n=0 + for _t in $_tests + do + _n=$(( _n + 1)) + [ "$_n" -lt "$_pri" ] && \ + echo "$_a" | grep -q "$_t" && _suggest="$_i" && _pri="$_n" + done + done + + echo "$_suggest" +} + +setFile() { + _files="$1" + _n="$2" + echo "$_files" | xargs -n 1 | awk -v n="${_n}" 'NR==n' +} + +printInfo() { + _file="$1" + echo "File" + printf " %s\n\n" "$_file" + + # Description + sed -e "s/^#.//g" -e "s/^#$//g" "$_file" | \ + sed -n '/^Description/,/^[^ ]/p' | sed \$d + + # Usage + sed -n '/^Usage/,/^[^ ]/p' "$_file" | sed \$d + + return 0 +} + +webInfo() { + # basename of file + _file="$(basename "$1")" + + echo "$_file" | grep -q ".[CH]" || + error "No web documentation for file \"$_file\"" + + _pre="$(echo "$_file" | sed 's/\./_8/g')" + _url="https://cpp.openfoam.org/${VER}/${_pre}.html" + + echo "Running \"$BROWSER $_url\"" + $BROWSER "$_url" + + return 0 +} + +showInfo() { + _file="$1" + _web="$2" + + # Return 1 for web so examples are not printed + [ -n "$_web" ] && webInfo "$_file" && return 1 + printInfo "$_file" +} + +findSolverExamples() { + _pre="$1" + _out="" + + # Solvers + _app="$(find "$FOAM_TUTORIALS" -name "$_pre")" + _dirs="$(find "$_app" -name "system" -type d)" + for _d in $_dirs + do + _out="${_d%/*} $_out" + done + + # Remove whitespace + echo "$_out" | xargs -n 1 +} + +findUtilityExamples() { + _pre="$1" + _out="" + + # Applications + _scripts="$(find "$FOAM_TUTORIALS" -type f -name "All*")" + for _f in $_scripts + do + grep -rq "$_pre" "$_f" && _out="${_f%/*} $_out" + done + + # Remove whitespace + echo "$_out" | xargs -n 1 | sort -u +} + +findModelExamples() { + _pre="$1" + _out="" + + # Field files + _dirs="$(find "$FOAM_TUTORIALS" \ + -type d -name "0*" -o -name "constant" -o -name "system")" + for _d in $_dirs + do + # Space and semicolon pick up exact matches + grep -rq " ${_pre};" "$_d" && _out="${_d%/*} $_out" + done + + # Remove whitespace + echo "$_out" | xargs -n 1 | sort -u +} + +findAllExamples() { + _pre="$1" + _type="$2" + + case "$_type" in + model) findModelExamples "$_pre" ;; + utility|script) findUtilityExamples "$_pre" ;; + solver) findSolverExamples "$_pre" ;; + esac +} + +showTypeExamples() { + _pre="$1" + _type="$2" + _all="$3" + _examples="" + + [ -z "$_pre" ] && echo "Examples: none found" && return 1 + + _nExD=10 + [ -n "$_all" ] && _nExD=1000 + + _examples="$(findAllExamples "$_pre" "$_type")" + + [ -z "$_examples" ] && \ + echo "Examples: cannot find any tutorials using \"$_pre\"" && \ + return 1 + + _nEx="$(nArgs "$_examples")" + + echo "Examples using \"$_pre\"" + [ "$_nEx" -gt "$_nExD" -a -n "_all" ] && \ + echo " *** Listing 10 out of $_nEx;" \ + "run with \"-a\" option to list all ***" + echo "$_examples" | awk -v nExD="$_nExD" 'FNR <= nExD {print " " $1}' +} + +showExamples() { + _pre="$1" + _file="$2" + _all="$3" + + echo "$_file" | grep -q ".H" && _type=model && \ + _pre="$(basename "${file%/*}")" && \ + echo "$_pre" | grep -iq include && _pre="" + echo "$_file" | grep -q "$FOAM_SRC/../bin" && _type=script + echo "$_file" | grep -q "$FOAM_UTILITIES" && _type=utility + echo "$_file" | grep -q "$FOAM_SOLVERS" && _type=solver + + [ -n "$_type" ] && showTypeExamples "$_pre" "$_type" "$_all" && return 0 + return 0 +} + +web="" +all="" +# Global controlDict file +controlDict="$(foamEtcFile controlDict 2> /dev/null)" +BROWSER="$(grep docBrowser "$controlDict" 2> /dev/null | cut -d "\"" -f2)" + +while [ "$#" -gt 0 ] +do + case "$1" in + -a | -all) + all="yes" + shift + ;; + -b | -browser) + [ "$#" -ge 2 ] || error "'$1' option requires an argument" + BROWSER="$2" + web="yes" + shift 2 + ;; + -h | -help) + usage && exit 0 + ;; + -w | -web) + web="yes" + shift + ;; + -*) + error "invalid option '$1'" + ;; + *) + break + ;; + esac +done + +# Check if browsing is possible +VER="${WM_PROJECT_VERSION%%.*}" + +[ -n "$web" ] && \ + ! command -v "$BROWSER" >/dev/null 2>&1 && \ + error "Cannot run browser application: $BROWSER" +[ -n "$web" ] && [ -z "$VER" ] && \ + error "Cannot establish OpenFOAM version: \$WM_PROJECT_VERSION not set" + +[ "$VER" = "dev" ] || VER="v${VER}" + +[ $# -gt 1 ] && error "$# arguments \"$*\" specified: only 1 permitted" +[ $# -eq 1 ] || error "Missing argument: no application, model, script, etc provided" +prefix="$1" + +files="$(findFiles "$prefix")" +[ -z "$files" ] && error "Nothing found with \"$prefix\" in the name" + +nFiles="$(nArgs "$files")" +nFile="" +if [ "$nFiles" -eq 1 ] +then + nFile=1 +else + echo "Multiple items with \"$prefix\" found:" + suggest="$(listArgs "$files")" + + printf "\n%s" "Enter file number (1-$nFiles) to obtain description " + [ -n "$suggest" ] && printf "%s" "(suggest $suggest) " + printf "%s" ": " + + read nFile + [ -z "$nFile" -a -n "$suggest" ] && nFile="$suggest" + [ -z "$nFile" ] && \ + echo "Cannot specify nothing; re-run and enter a file number" && exit 1 + ! [ "$nFile" -eq "$nFile" ] 2>/dev/null && \ + echo "\"$nFile\" is not a number between 1 and $nFiles" && exit 1 + [ "$nFile" -lt 1 -o "$nFile" -gt "$nFiles" ] && \ + echo "\"$nFile\" is not a number between 1 and $nFiles" && exit 1 +fi + +file="$(setFile "$files" "$nFile")" +showInfo "$file" "$web" && showExamples "$prefix" "$file" "$all"