Skip to content
Snippets Groups Projects
foamEtcFile 10.1 KiB
Newer Older
Mark Olesen's avatar
Mark Olesen committed
#!/bin/sh
#------------------------------------------------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     |
OpenFOAM bot's avatar
OpenFOAM bot committed
#   \\  /    A nd           | www.openfoam.com
#    \\/     M anipulation  |
OpenFOAM bot's avatar
OpenFOAM bot committed
#------------------------------------------------------------------------------
#     Copyright (C) 2011-2016 OpenFOAM Foundation
#     Copyright (C) 2017-2020 OpenCFD Ltd.
#------------------------------------------------------------------------------
Mark Olesen's avatar
Mark Olesen committed
# License
#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Mark Olesen's avatar
Mark Olesen committed
#
# Script
Mark Olesen's avatar
Mark Olesen committed
#
# 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:
#        eval $(foamEtcFile -sh -mode=o  prefs.sh)
#        eval $(foamEtcFile -sh -mode=ug prefs.sh)
Mark Olesen's avatar
Mark Olesen committed
#
#     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_SITE         (unset defaults to PROJECT/site)
#     This script must exist in the project 'bin' directory
#
#     The '-show-api' and '-show-patch' options implement partial logic
#     from wmake/wmakeBuildInfo.
#     Make sure that any changes there are also reflected here.
Mark Olesen's avatar
Mark Olesen committed
#-------------------------------------------------------------------------------
Mark Olesen's avatar
Mark Olesen committed
    cat<<USAGE

Usage: foamEtcFile [OPTION] fileName [-- args]
       foamEtcFile [OPTION] [-list|-list-test] [fileName]

Mark Olesen's avatar
Mark Olesen committed
options:
  -all (-a)         Return all files (otherwise stop after the first match)
  -list (-l)        List directories or files to be checked
  -list-test        List (existing) directories or files to be checked
  -mode=MODE        Any combination of u(user), g(group), o(other)
  -csh              Produce 'source FILE' output for a csh eval
  -sh               Produce '. FILE' output for a sh eval
  -csh-verbose      As per -csh, with additional verbosity
  -sh-verbose       As per -sh,  with additional verbosity
  -config           Add config directory prefix for shell type:
                        with -csh* for a config.csh/ prefix
                        with -sh*  for a config.sh/ prefix
  -show-api         Print META-INFO api value and exit
  -show-patch       Print META-INFO patch value and exit
  -with-api=NUM     Specify alternative api value to search with
  -quiet (-q)       Suppress all normal output
  -silent (-s)      Suppress stderr, except -csh-verbose, -sh-verbose output
  -help             Print the usage

Locate user/group/other file as per '#includeEtc'
Do not group single character options.
Equivalent options:
  |  -mode=MODE     |  -mode MODE     | -m MODE
  |  -prefix=DIR    |  -prefix DIR    | -p DIR   [obsolete 1812]
  |  -version=VER   |  -version VER   | -v VER   [obsolete 1812]

Exit status
    0  when the file is found. Print resolved path to stdout.
    1  for miscellaneous errors.
    2  when the file is not found.
Mark Olesen's avatar
Mark Olesen committed

USAGE
# Report error and exit
die()
{
    [ "${optQuiet:-$optSilent}" = true ] && exit 1
    exec 1>&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="$(\cd $(dirname $binDir) && \pwd -L)"   # Project dir
userDir="$HOME/.OpenFOAM"                           # As per foamVersion.H
groupDir="${WM_PROJECT_SITE:-$projectDir/site}"     # As per foamVersion.H
#-------------------------------------------------------------------------------
# Get a value from META-INFO/api-info
# $1 : keyword
getApiInfo()
    value="$(sed -ne 's@^'"$1"' *= *\([0-9][0-9]*\).*@\1@p' "$projectDir"/META-INFO/api-info 2>/dev/null)"
        echo "Could not determine OPENFOAM '$1' value" 1>&2
#-------------------------------------------------------------------------------
optMode=ugo         # Default mode is always 'ugo'
unset shellOutput verboseOutput
unset optAll optConfig optList projectApi
# Parse options
Mark Olesen's avatar
Mark Olesen committed
while [ "$#" -gt 0 ]
do
    case "$1" in
Mark Olesen's avatar
Mark Olesen committed
        ;;
    -show-api)  # Show API and exit
        getApiInfo api
    -show-patch)  # Show patch level and exit
        getApiInfo patch
        exit $?
        ;;
    -with-api=*)
        projectApi="${1#*=}"
        ;;
        unset shellOutput verboseOutput
Mark Olesen's avatar
Mark Olesen committed
    -l | -list)
    -list-test)
        optList='test'
        ;;
    -csh | -sh)
        shellOutput="${1#-}"
        unset verboseOutput
        ;;
    -csh-verbose | -sh-verbose)
        shellOutput="${1#-}"
        verboseOutput="source "         # Report: "source FILE"
        ;;
    -config)
        optConfig=true
Mark Olesen's avatar
Mark Olesen committed
        ;;
        optMode="${1#*=}"
        optMode="$2"
        shift
        # Sanity check. Handles missing argument too.
        case "$optMode" in
        (*)
            die "invalid mode '$optMode'"
Mark Olesen's avatar
Mark Olesen committed
    -q | -quiet)
Mark Olesen's avatar
Mark Olesen committed
        ;;

    -prefix=* | -version=*)
        echo "ignored defunct option '${1%%=*}'" 1>&2
        ;;
    -p | -prefix | -v | -version)
        # Ignored, but still need to check/discard its argument
        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
        echo "ignored defunct option '$1'" 1>&2
Mark Olesen's avatar
Mark Olesen committed
    -*)
        die "unknown option: '$1'"
Mark Olesen's avatar
Mark Olesen committed
        ;;
    *)
        break
        ;;
    esac
#-------------------------------------------------------------------------------

[ -n "$projectApi" ] || projectApi=$(getApiInfo api)
# 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


# Debugging:
# echo "Installed locations:" 1>&2
# Define the various places to be searched:
case "$optMode" in (*[au]*) # (A)ll or (U)ser
    dirList="$dirList $userDir/$projectApi $userDir"
case "$optMode" in (*[ag]*) # (A)ll or (G)roup == site
    dirList="$dirList $groupDir/$projectApi/etc $groupDir/etc"
case "$optMode" in (*[ao]*) # (A)ll or (O)ther == shipped
    dirList="$dirList $projectDir/etc"
[ "$#" -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

Mark Olesen's avatar
Mark Olesen committed

#
# The main routine
#

if [ -n "$optList" ]
    # 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
Mark Olesen's avatar
Mark Olesen committed
        if [ "$nArgs" -eq 1 ]
        then
            for dir
            do
                resolved="$dir/$fileName"
                if [ -f "$resolved" ]
                then
                    echo "$resolved"
                    exitCode=0  # OK
                fi
            done
Mark Olesen's avatar
Mark Olesen committed
        else
            for dir
            do
                if [ -d "$dir" ]
                then
                    echo "$dir"
                    exitCode=0  # OK
                fi
            done
Mark Olesen's avatar
Mark Olesen committed
        fi
        exitCode=0  # OK, already verified that $# != 0
        for dir
        do
            echo "$dir${fileName:+/}$fileName"
        done
    fi
    [ "$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
Mark Olesen's avatar
Mark Olesen committed
    for dir
    do
        resolved="$dir/$fileName"
        if [ -f "$resolved" ]
Mark Olesen's avatar
Mark Olesen committed
        then
            exitCode=0  # OK
            if [ -n "$optQuiet" ]
            then
            elif [ -n "$verboseOutput" ]
            then
                echo "$verboseOutput$resolved" 1>&2
            fi

            if [ -n "$shellOutput" ]
            then
                echo "$shellOutput$resolved $evalArgs"
            else
                echo "$resolved"
            fi
Mark Olesen's avatar
Mark Olesen committed

#------------------------------------------------------------------------------