Skip to content
Snippets Groups Projects
foamEtcFile 10.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Olesen's avatar
    Mark Olesen committed
    #!/bin/sh
    #------------------------------------------------------------------------------
    # =========                 |
    # \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    #  \\    /   O peration     |
    
    Henry Weller's avatar
    Henry Weller committed
    #   \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
    
    #    \\/     M anipulation  | Copyright (C) 2017-2018 OpenCFD Ltd.
    
    Mark Olesen's avatar
    Mark Olesen committed
    #-------------------------------------------------------------------------------
    # License
    
    #     This file is part of OpenFOAM, licensed under GNU General Public License
    #     <http://www.gnu.org/licenses/>.
    
    Mark Olesen's avatar
    Mark Olesen committed
    #
    # 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:
    
    #        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 api value from wmake/rules, or meta-info and exit
      -show-patch       Print patch value from meta-info 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
    
    #-------------------------------------------------------------------------------
    
    # The API locations. See wmake/wmakeBuildInfo
    rulesFile="$projectDir/wmake/rules/General/general"
    metaInfoDir="$projectDir/META-INFO"
    
    # Get api from rules/General/general
    
    # Failure modes:
    # - No api information (can't find file etc).
    #   -> Fatal for building, but could be OK for a stripped down version
    
        value="$(sed -ne '/^ *#/!{ /WM_VERSION.*OPENFOAM=/{ s@^.*OPENFOAM= *\([0-9][0-9]*\).*@\1@p; q }}' $rulesFile 2>/dev/null)"
        if [ -z "$value" ] && [ -f "$metaInfoDir/api-info" ]
        then
            # Fallback. Get from api-info
            value="$(sed -ne 's@^ *api *= *\([0-9][0-9]*\).*@\1@p' $metaInfoDir/api-info 2>/dev/null)"
        fi
    
        if [ -n "$value" ]
        then
            echo "$value"
        else
            return 1
        fi
    
    # Get patch from meta-info / api-info
    #
    # Failure modes:
    # - No patch information (can't find file etc).
    #
    getPatchLevel()
    
        # Fallback. Get from api-info
        value="$(sed -ne 's@^ *patch *= *\([0-9][0-9]*\).*@\1@p' $metaInfoDir/api-info 2>/dev/null)"
    
        if [ -n "$value" ]
        then
            echo "$value"
        else
            return 1
        fi
    
    #-------------------------------------------------------------------------------
    
    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
            getApi
            exit $?
            ;;
        -show-patch)
            # Show patch level and exit
            getPatchLevel
            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
    
    #-------------------------------------------------------------------------------
    
    
    # Establish the API value
    [ -n "$projectApi" ] || projectApi=$(getApi)
    
    
    
    # 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
    
    #------------------------------------------------------------------------------