#!/bin/sh #------------------------------------------------------------------------------ # ========= | # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / O peration | Website: https://openfoam.org # \\ / A nd | Copyright (C) 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 . # # Script # foamFind # # Description # Finds one or more files in OpenFOAM and optionally processes the contents # by printing the file or lines matching a search string # #------------------------------------------------------------------------------ usage () { cat < options: -a | -applications search for the file from the \$FOAM_APP directory -d | -dir specify search directory -e | -edit open the file in a file editor, see below for info -f | -files find wmake 'files' file associated with searched file -h | -help help -i | -isearch searches files for a , case insensitive -m | -modules search for the file from the \$FOAM_MODULES directory -n | -numbers print line numbers with file output -o | -options find wmake 'options' file associated with searched file -p | -print print the file(s) -s | -search searches files for a , case sensitive -t | -tutorials search for the file from the \$FOAM_TUTORIALS directory Finds one or more files in OpenFOAM and optionally processes the contents by: + printing the file(s) ('-print' option); + printing lines within the file matching a search string ('-search' option); + opening a single (only) file in a text editor ('-edit' option). The '-edit' option required the user to specify their choice of text editor by setting the EDITOR environment variable. For example, to set the 'gedit' editor, they could add to their \$HOME/.bashrc file, the line: export EDITOR=gedit With source code files, can locate the 'files' and 'options' files associated with their compilation using 'wmake'. By default, files are searched from the src (\$FOAM_SRC) directory. Alternatively the '-dir' option allows the user to specify the search directory The '-applications', '-modules' and '-tutorials' options specifically set the search path to the \$FOAM_APP, \$FOAM_MODULES and \$FOAM_TUTORIALS directories, respectively. Examples: foamFind -print wallHeatFlux.C | less + click space bar to scroll down + enter line number (after ":") to jump to line + enter "/text" to search for "text" (or any other string) foamFind -applications -isearch "momentumtransport" -options fluid.C foamFind -numbers -search laminar BirdCarreau.C USAGE } error() { exec 1>&2 while [ "$#" -ge 1 ]; do echo "$1"; shift; done usage exit 1 } findWmakeFiles () { _file="$1" ; shift _wmakeFiles="$*" # Check if file is source code ! file -b "$_file" | grep -Eq "C.*source" && \ "'-$_filename' invalid, file is not source code" >&2 && \ return 1 _files="" while true do _oldFile="$_file" _file="${_file%/*}" # cannot contract the path further [ "$_oldFile" = "$_file" ] && break # search for 'files' and/or 'options' [ -d "$_file" ] && \ for _w in $_wmakeFiles do _files="$(echo "$_files" \ "$(find "$_file" -name "$_w" -type f)" | xargs)" done [ "$_files" ] && break done ! [ "$_files" ] && \ error "no '$_filename' file found for '-files' or '-options'" >&2 && \ return 1 echo "$_files" return 0 } nParams () { [ "$1" ] || return 1 echo "$1" | xargs | awk -F' ' '{print NF}' return 0 } selectFile () { _filename="$1"; shift _files="$*" _nFiles="$(nParams "$_files")" # Return file if only one [ "$_nFiles" -eq 1 ] && echo "$_files" && exit 0 printf "Multiple files" >&2 [ "$_filename" ] && printf " with name '%s'" "$_filename" >&2 printf " found:\n" >&2 _i=1 for _f in $_files do printf "%i) %s\n" "$_i" "$_f" >&2 _i=$((_i + 1)) done printf "Type ENTER to select all, or " >&2 printf "enter file number (1-%s) for specific file: " \ "$_nFiles" >&2 read -r _nFile # Enter nothing [ -z "$_nFile" ] && echo "$_files" && return 0 # Check incorrect number ! [ "$_nFile" -eq "$_nFile" ] 2>/dev/null && \ echo "\"$_nFile\" is not a number" >&2 && \ return 1 { [ "$_nFile" -lt 1 ] || [ "$_nFile" -gt "$_nFiles" ] ; } && \ echo "\"$_nFile\" is not a number between 1 and $_nFiles" >&2 && \ return 1 # Enter number corresponding to file # shellcheck disable=SC2086 echo $_files | awk -v n="$_nFile" '{print $n}' return 0 } setFile () { _files="$1" _n="$2" echo "$_files" | xargs -n 1 | awk -v n="${_n}" 'NR==n' } isSrcDir () { echo "$1" | grep -wqE "^($FOAM_SRC|$FOAM_APP)" } listFiles () { _dir="$1" _filename="$2" _search="$3" _ins="" [ "$4" = "on" ] && _ins="i" # Specify code files if _dir is in $FOAM_SRC or $FOAM_APP _name="*" isSrcDir "$dir" && _name="*.[CHL]" [ "$_filename" ] && _name="$_filename" [ "$_search" ] && \ find "$_dir" -name "$_name" -type f -print0 | \ xargs -0 grep -l$_ins "$search" && \ return 0 # Remove "\n" find "$dir" -name "$filename" -type f -print0 | xargs -0 } grepFile () { _string="$1" _file="$2" _ins="" [ "$3" = "on" ] && _ins="i" _arg="$4" # use $_arg for different cases: test, and with and without line numbers case "$_arg" in test) grep -q"$_ins" "$_string" "$_file" ;; numbers) grep -hn"$_ins" "$_string" "$_file" | \ awk '{ split($0,f,":"); sub(/^([^:]+:)/,"",$0); printf "%6i %s\n", f[1], $0 }' ;; *) grep -h"$_ins" "$_string" "$_file" ;; esac } dirError () { cat< can only be omitted if a search string is specified" \ "with the '-search' option" # If '-files' or '-options' is selected, ensure is set ! [ "$filename" ] && [ "$wmakeFiles" ] && \ error "With '-files' or '-options', must be specified" # Find files files="$(listFiles "$dir" "$filename" "$search" "$insensitive")" # Ensure there is at least one file nParams "$files" > /dev/null || error "No file '$filename' found in '$dir'" # Select files when more than one is found files="$(selectFile "$filename" "$files")" || error # With '-files' and/or '-options', reuse file variable as the file { [ "$wmakeFiles" ] || [ "$edit" ] ; } && \ [ "$(nParams "$files")" -ne 1 ] && \ error "With '-files', '-options' or '-edit', a single file must be selected" [ "$wmakeFiles" ] && ! files="$(findWmakeFiles "$files" "$wmakeFiles")" && error # Output for f in $files do printf "\nFile: %s\n" "$f" # Printing entire files [ "$print" ] && \ printf ">>>\n" && \ { [ "$numbers" ] && cat -n "$f" || cat "$f" ; } && \ printf "<<<\n" # Opening files in a editor [ "$edit" ] && "$edit" "$f" # Printing lines matching strings [ "$search" ] || continue ! grepFile "$search" "$f" "$insensitive" test && \ echo "Search: no match" && continue printf ">>>\n" grepFile "$search" "$f" "$insensitive" "$numbers" printf "<<<\n" done