#!/bin/sh #------------------------------------------------------------------------------ # ========= | # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / O peration | # \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation # \\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd. #------------------------------------------------------------------------------- # License # This file is part of OpenFOAM, licensed under GNU General Public License # . # # Script # foamEtcFile # # Description # Locate user/group/other file as per '#includeEtc'. # # The -mode option is used within etc/{bashrc,cshrc} to ensure # that system prefs are respected: # \code # eval $(foamEtcFile -sh -mode=o prefs.sh) # eval $(foamEtcFile -sh -mode=ug prefs.sh) # \endcode # # The -mode option can also be used when chaining settings. # For example, in the user ~/.OpenFOAM//config.sh/compiler # \code # eval $(foamEtcFile -sh -mode=go config.sh/compiler) # \endcode # # Environment # - WM_PROJECT (unset defaults to OpenFOAM) # - WM_PROJECT_VERSION (unset defaults to detect from path) # - WM_PROJECT_SITE (unset defaults to PREFIX/site) # # Note # This script must exist in one of these locations: # - PREFIX/OpenFOAM-/bin # - PREFIX/openfoam-/bin # - PREFIX/openfoam/bin # #------------------------------------------------------------------------------- printHelp() { cat<&2 echo echo "Error encountered:" while [ "$#" -ge 1 ]; do echo " $1"; shift; done echo echo "See 'foamEtcFile -help' for usage" echo exit 1 } #------------------------------------------------------------------------------- binDir="${0%/*}" # The bin dir projectDir="${binDir%/bin}" # The project dir prefixDir="${projectDir%/*}" # The prefix dir (same as $WM_PROJECT_INST_DIR) # Could not resolve projectDir, prefixDir? (eg, called as ./bin/foamEtcFile) if [ "$prefixDir" = "$projectDir" ] then binDir="$(cd $binDir && pwd -L)" projectDir="${binDir%/bin}" prefixDir="${projectDir%/*}" fi projectDirName="${projectDir##*/}" # The project directory name projectVersion="$WM_PROJECT_VERSION" # Empty? - will be treated later userDir="$HOME/.OpenFOAM" # Hard-coded as per foamVersion.H #------------------------------------------------------------------------------- # Guess project version or simply get the stem part of the projectDirName. # Handle standard naming conventions: # # * OpenFOAM-[-extra...] # * openfoam-[-extra...] # * openfoam # # - projectVersion: update unless already set # # Helper variables: # - dirBase (for reassembling name) == projectDirName without the version unset dirBase guessVersion() { local version case "$projectDirName" in (OpenFOAM-* | openfoam-*) # Dashed naming: OpenFOAM- or openfoam- dirBase="${projectDirName%%-*}-" version="${projectDirName#*-}" version="${version%%*-}" # Extra safety, eg openfoam-version-packager ;; (openfoam[0-9]*) # Debian-style naming: openfoam dirBase="openfoam" version="${projectDirName#openfoam}" ;; (*) die "unknown/unsupported naming convention for '$projectDirName'" ;; esac # Set projectVersion if required : ${projectVersion:=$version} } # Set projectVersion and update versionNum, projectDirName accordingly setVersion() { projectVersion="$1" # Need dirBase when reassembling projectDirName [ -n "$dirBase" ] || guessVersion projectDirName="$dirBase$projectVersion" } #------------------------------------------------------------------------------- optMode=ugo # Default mode is always 'ugo' unset shellOutput verboseOutput unset optAll optConfig optList optVersion # Parse options while [ "$#" -gt 0 ] do case "$1" in -h | -help*) printHelp ;; -a | -all) optAll=true unset shellOutput verboseOutput ;; -l | -list) optList=true ;; -list-test) optList='test' ;; -csh | -sh) shellOutput="${1#-}" unset verboseOutput ;; -csh-verbose | -sh-verbose) shellOutput="${1#-}" verboseOutput="source " # Report: "source FILE" ;; -config) optConfig=true ;; -mode=[ugo]*) optMode="${1#*=}" ;; -prefix=/*) prefixDir="${1#*=}" prefixDir="${prefixDir%/}" ;; -version=*) optVersion="${1#*=}" ;; -m | -mode) optMode="$2" shift # Sanity check. Handles missing argument too. case "$optMode" in ([ugo]*) ;; (*) die "invalid mode '$optMode'" ;; esac ;; -p | -prefix) [ "$#" -ge 2 ] || die "'$1' option requires an argument" prefixDir="${2%/}" shift ;; -q | -quiet) optQuiet=true ;; -s | -silent) optSilent=true ;; -v | -version) [ "$#" -ge 2 ] || die "'$1' option requires an argument" optVersion="$2" shift ;; --) shift break ;; -*) die "unknown option: '$1'" ;; *) break ;; esac shift done #------------------------------------------------------------------------------- # Split arguments into filename (for searching) and trailing bits for shell eval # Silently remove leading ~OpenFOAM/ (as per Foam::findEtcFile) nArgs=$# fileName="${1#~OpenFOAM/}" unset evalArgs if [ "$nArgs" -eq 1 ] then if [ "$1" = "--" ] then nArgs=0 unset fileName fi elif [ "$nArgs" -ge 2 ] then if [ "$2" = "--" ] then nArgs=1 shift 2 evalArgs="$@" fi fi # Get version information if [ -n "$optVersion" ] then setVersion $optVersion elif [ -z "$projectVersion" ] then guessVersion fi # Updates: # - projectDir for changes via -prefix or -version # - groupDir for changes via -prefix projectDir="$prefixDir/$projectDirName" groupDir="${WM_PROJECT_SITE:-$prefixDir/site}" # Debugging: # echo "Installed locations:" 1>&2 # for i in projectDir prefixDir projectDirName projectVersion # do # eval echo "$i=\$$i" 1>&2 # done # Define the various places to be searched: unset dirList case "$optMode" in (*u*) # (U)ser dirList="$dirList $userDir/$projectVersion $userDir" ;; esac case "$optMode" in (*g*) # (G)roup == site dirList="$dirList $groupDir/$projectVersion $groupDir" ;; esac case "$optMode" in (*o*) # (O)ther == shipped dirList="$dirList $projectDir/etc" ;; esac set -- $dirList [ "$#" -ge 1 ] || die "No directories to scan. Programming error?" exitCode=2 # Fallback is a FileNotFound error # # Preliminaries # # Special handling of config.sh/ , config.csh/ directories if [ -n "$optConfig" -a -n "$shellOutput" -a -n "$fileName" ] then case "$shellOutput" in csh*) optConfig="config.csh/" ;; sh*) optConfig="config.sh/" ;; *) unset optConfig ;; esac if [ -n "$optConfig" ] then case "$fileName" in /* | config.csh* | config.sh*) # Does not need or cannot add a prefix unset optConfig ;; *) fileName="$optConfig$fileName" ;; esac fi fi # # The main routine # if [ -n "$optList" ] then # List directories, or potential file locations [ "$nArgs" -le 1 ] || \ die "-list options expect 0 or 1 filename, but $nArgs provided" # A silly combination, but -quiet has absolute precedence [ -n "$optQuiet" ] && exit 0 # Test for directory or file too? if [ "$optList" = "test" ] then if [ "$nArgs" -eq 1 ] then for dir do resolved="$dir/$fileName" if [ -f "$resolved" ] then echo "$resolved" exitCode=0 # OK fi done else for dir do if [ -d "$dir" ] then echo "$dir" exitCode=0 # OK fi done fi else exitCode=0 # OK, already verified that $# != 0 for dir do echo "$dir${fileName:+/}$fileName" done fi else [ "$nArgs" -eq 1 ] || die "One filename expected - $nArgs provided" # Output for sourcing files ("source" for csh, "." for POSIX shell) # Only allow sourcing a single file (disallow combination with -all) case "$shellOutput" in csh*) shellOutput="source " # eg, "source FILE" ;; sh*) shellOutput=". " # eg, ". FILE" ;; esac # Anti-pattern: -all disables shell commands if [ -n "$optAll" ] then unset shellOutput verboseOutput fi for dir do resolved="$dir/$fileName" if [ -f "$resolved" ] then exitCode=0 # OK if [ -n "$optQuiet" ] then break elif [ -n "$verboseOutput" ] then echo "$verboseOutput$resolved" 1>&2 fi if [ -n "$shellOutput" ] then echo "$shellOutput$resolved $evalArgs" else echo "$resolved" fi [ -n "$optAll" ] || break fi done fi exit $exitCode #------------------------------------------------------------------------------