Skip to content
Snippets Groups Projects
foamCleanPath 6.21 KiB
Newer Older
#!/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
#     <http://www.gnu.org/licenses/>.
#
# Script
#     foamCleanPath
#
# Description
#     Usage: foamCleanPath [OPTION] path [filter] .. [filter]
#            foamCleanPath [OPTION] -env=name [filter] .. [filter]
#
#     Prints its argument (which should be a ':' separated path)
#         - duplicate elements
#         - elements matching the specified filter(s)
#         - inaccessible directories (with the -strip option)
#     - false matches possible when the filter contains '.' (sed regex) etc.
#     - a single composite filter can be passed in. This composite filter
#       is assumed to be delimited by whitespace, colons or semi-colons.
#
# Examples for cleaning the path:
#
#     - Using explicit arguments
#       cleaned=$(foamCleanPath "$PATH" dir1:dir2) && PATH=$cleaned
#
#     - Variable to clean passed as an option
#       cleaned=$(foamCleanPath -env=PATH dir1:dir2) && PATH=$cleaned
#
#     - Using shell evaluation for the output
#       eval $(foamCleanPath -sh=PATH $PATH" dir1:dir2)
#       eval "$(foamCleanPath -sh=PATH -env=PATH dir1:dir2)"
#       eval "$(foamCleanPath -sh-env=PATH dir1:dir2)"
#
#     - Similarly for c-shell
#       eval `foamCleanPath -csh-env=PATH dir1:dir2`
#
#------------------------------------------------------------------------------
usage() {
    cat <<USAGE 1>&2
Usage: foamCleanPath [OPTION] path [filter] .. [filter]
       foamCleanPath [OPTION] -env=name [filter] .. [filter]
  -csh=NAME         Produce 'setenv NAME ...' output for csh eval
  -sh=NAME          Produce 'NAME=...' output for sh eval
  -csh-env=NAME     As per -csh, with -env for initial content
  -sh-env=NAME      As per -sh,  with -env for initial content
  -env=NAME         Evaluate NAME to obtain initial content
  -debug            Print debug information to stderr
  -strip            Remove inaccessible directories
  -verbose          Report some progress (input, output, ...)
  -help             Print the usage
Prints its argument (which should be a ':' separated list) cleansed from
  * elements whose start matches one of the filters
  * inaccessible directories (the -strip option)
    2  initial value of 'path' is empty
# Report error and exit
die()
{
    exec 1>&2
    echo
    echo "Error encountered:"
    while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
    echo
    echo "See 'foamCleanPath -help' for usage"
    echo
    exit 1
}

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

# Input and outputs
unset dirList shellOutput
unset optDebug optEnvName optStrip optVerbose
while [ "$#" -gt 0 ]
do
    case "$1" in
    -csh=* | -sh=* | -csh-env=* | -sh-env=*)
        name="${1#*=}"
        [ -n "$name" ] || die "Option '$1' missing an ENVNAME"

        # Output prefix
        case "$1" in
        -csh*)
            shellOutput="setenv $name "     # eg, "setenv PATH xyz"
            ;;
        *)
            shellOutput="$name="            # eg, "PATH=xyz"
            ;;
        esac

        # For (-csh-env | -sh-env) also use name for input evaluation
        case "$1" in
        *-env=*)
            optEnvName="$name"
            ;;
        esac
        ;;
    -env=*)
        name="${1#*=}"
        [ -n "$name" ] || die "Option '$1' missing an ENVNAME"
        optEnvName="$name"
        ;;
# Basic checks
if [ -n "$optEnvName" ]
then
    eval "dirList=\$$optEnvName"
elif [ "$#" -ge 1 ]
then
    dirList="$1"
    shift
else
    die "Requires at least one argument, or use the -env option"
fi
[ -n "$dirList" ] || exit 2     # Quick exit on empty 'dirList'
#-------------------------------------------------------------------------------
# Debugging (optional)
if [ -n "$optDebug" ]
then
    printDebug() { while [ "$#" -ge 1 ]; do echo "$1" 1>&2; shift; done; }
else
    printDebug() { true; }      # No-op
fi

# Optional test for directory existence
    isDir() { test -d "$1"; }   # Check for directory existence
    isDir() { test -n "$1"; }   # Only check for non-zero string
# The "filter ... filterN" may have been passed as a single parameter
# or may contain ':' separators.
# Currently (OCT-2018) also accept split on whitespace too.
oldIFS="$IFS"       # Preserve initial IFS
IFS=':; '           # Split on colon, semicolon, whitespace
if [ -n "$optVerbose" ]
then
    echo "clean: $dirList" 1>&2
    echo "with:  $@" 1>&2
fi

# Apply filters via sed. Path and filter cannot contain '?'.
for filter
        printDebug "remove>$filter<"
        dirList=$(echo "$dirList:" | sed -e "s?${filter}[^:]*:??g")
printDebug "intermediate>$dirList<"
IFS=':'             # Split on colon. No split on whitespace.
    printDebug "check>$dir< in $dirList"
    if isDir "$dir"
        # Detect duplicates (ie, dir already in the list)
        duplicate=$(echo ":$dirList:" | sed -ne '\?:'"$dir"':?p')
            printDebug "duplicate>$dir<"
        else
            dirList="${dirList}${dirList:+:}$dir"
if [ -n "$optVerbose" ]
then
#------------------------------------------------------------------------------