ENH: adjust foamSystemCheck, foamInstallationTest

- add clang test, don't complaint about dash, zsh

- don't bother with checking gzip and tar
This commit is contained in:
Mark Olesen 2020-05-28 12:03:09 +02:00
parent 0e480f3d7e
commit bee23c79bd
2 changed files with 247 additions and 190 deletions

View File

@ -10,41 +10,29 @@
# Copyright (C) 2019-2020 OpenCFD Ltd. # Copyright (C) 2019-2020 OpenCFD Ltd.
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
# This file is part of OpenFOAM. # This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
# 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 <http://www.gnu.org/licenses/>.
# #
# Script # Script
# foamInstallationTest # bin/foamInstallationTest
# #
# Description # Description
# Check the machine system, the installation of OpenFOAM, and the user's # Check the machine, software components, and the OpenFOAM environment
# personal configuration for running OpenFOAM. # for running OpenFOAM.
# #
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Base settings # Base settings
MIN_VERSION_GCC=4.8.5 MIN_VERSION_GCC=4.8.5
MIN_VERSION_LLVM=3.7.1
# General # General
WIDTH=20 WIDTH=20
# System variables # System variables
HOST=$(uname -n) HOST="$(uname -n)"
OSTYPE=$(uname -s) OSTYPE="$(uname -s)"
# OpenFOAM application to test for the Version # OpenFOAM application to test for existence. Obtain version from wmake.
foamTestApp=icoFoam foamTestApp=icoFoam
# Global variables # Global variables
@ -62,7 +50,6 @@ hline()
heading() heading()
{ {
echo
echo echo
echo "$1" echo "$1"
} }
@ -99,7 +86,7 @@ reportEnv()
if [ -n "$EXP_ENV" ] if [ -n "$EXP_ENV" ]
then then
if test -e "$EXP_ENV" if [ -e "$EXP_ENV" ]
then then
EXISTS=" yes " EXISTS=" yes "
if [ "$2" != noPath ] if [ "$2" != noPath ]
@ -125,7 +112,7 @@ reportEnv()
fi fi
echo "$(fixlen "$1" 21) $(fixlen "$EXP_ENV" 40) $EXISTS $ON_PATH $CRIT" echo "$(fixlen "$1" 21) $(fixlen "$EXP_ENV" 40) $EXISTS $ON_PATH $CRIT"
else else
echo "$(fixlen "$1" 21) --------- env variable not set --------- $3" echo "$(fixlen "$1" 21) $(fixlen "[env variable unset]" 40) $3"
fi fi
ERROR=false ERROR=false
@ -144,11 +131,17 @@ reportEnv()
findExec() findExec()
{ {
if [ -x "$2" ] && [ ! -d "$2" ]
then
echo "$2"
return 0
fi
oldIFS=$IFS oldIFS=$IFS
IFS=':' IFS=':'
for d in $1 for d in $1
do do
if test ! -d "$d/$2" -a -x "$d/$2" if [ -x "$d/$2" ] && [ ! -d "$d/$2" ]
then then
IFS=$oldIFS IFS=$oldIFS
echo "$d/$2" echo "$d/$2"
@ -201,7 +194,7 @@ vercmp_3()
fi fi
# Patch # Patch
if [ -n "$arg1Patch" -a -n "$arg2Patch" ] if [ -n "$arg1Patch" ] && [ -n "$arg2Patch" ]
then then
if [ "$arg1Patch" -gt "$arg2Patch" ] if [ "$arg1Patch" -gt "$arg2Patch" ]
then then
@ -218,12 +211,14 @@ reportExecutable()
APP_NAME="$1" APP_NAME="$1"
APP_SPEC="$2" APP_SPEC="$2"
APP_PATH="$(findExec $PATH $1)" APP_PATH="$(findExec $PATH $1)"
VERSION="unknown"
if [ -z "$APP_PATH" ] if [ -z "$APP_PATH" ]
then then
echo "$(fixlen "$1" 9)" "*** not installed ***" echo "$(fixlen "${1##*/}" 9)" "*** not installed ***"
VERSION="" VERSION=""
case "$1" in case "$1" in
gcc* | $foamTestApp) *gcc* | *clang* | "$foamTestApp")
echo " CRITICAL ERROR" echo " CRITICAL ERROR"
criticalError="x${criticalError}" criticalError="x${criticalError}"
;; ;;
@ -231,11 +226,21 @@ reportExecutable()
echo echo
return 1 return 1
fi fi
case "$APP_NAME" in case "$APP_NAME" in
$foamTestApp) "$foamTestApp")
VERSION=$($APP_NAME -case /dev/null 2>&1 \ VERSION=$($APP_NAME -help 2>&1 \
| sed -ne 's/^.*Version: *\([^ ][^ ]*\).*/\1/p') | sed -ne 's/^.*Build: *\([^ ][^ ]*\).*/\1/p')
# Cannot do much with the build info:
# Build: 51e3d2a8ae-20200528 (patch=200506)
# so just treat as available/not available
if [ -n "$VERSION" ]
then
VERSION="exists"
fi
;; ;;
flex) flex)
VERSION=$(flex --version /dev/null 2>&1 \ VERSION=$(flex --version /dev/null 2>&1 \
| sed -ne 's/flex \([0-9][0-9.]*\).*/\1/p') | sed -ne 's/flex \([0-9][0-9.]*\).*/\1/p')
@ -243,6 +248,23 @@ reportExecutable()
wmake) wmake)
VERSION="$(wmake --version 2>/dev/null)" VERSION="$(wmake --version 2>/dev/null)"
;; ;;
*clang*)
VERSION=$($APP_NAME --version 2>/dev/null \
| sed -ne '1{s/^.*version \([0-9][.0-9]*\).*/\1/p;}')
if ! vercmp_3 "$MIN_VERSION_LLVM" "$VERSION"
then
case "$APP_NAME" in
(*clang++*) SHORT_NAME=clang++ ;;
(*) SHORT_NAME=clang ;;
esac
echo "ERROR: $SHORT_NAME version is too old for this release of OpenFOAM"
echo " User version : $VERSION"
echo " Minimum required: $MIN_VERSION_GCC"
echo
fatalError="x${fatalError}"
fi
;;
*gcc* | *g++*) *gcc* | *g++*)
VERSION=$($APP_NAME -v 2>&1 \ VERSION=$($APP_NAME -v 2>&1 \
| sed -ne 's/^gcc version \([0-9][0-9.]*\).*/\1/p') | sed -ne 's/^gcc version \([0-9][0-9.]*\).*/\1/p')
@ -250,85 +272,77 @@ reportExecutable()
if ! vercmp_3 "$MIN_VERSION_GCC" "$VERSION" if ! vercmp_3 "$MIN_VERSION_GCC" "$VERSION"
then then
case "$APP_NAME" in case "$APP_NAME" in
gcc*) (*g++*) SHORT_NAME=g++ ;;
SHORT_NAME=gcc (*) SHORT_NAME=gcc ;;
;;
g++*)
SHORT_NAME=g++
;;
esac esac
echo "ERROR: $SHORT_NAME version is too old for this release of OpenFOAM" echo "ERROR: $SHORT_NAME version is too old for this release of OpenFOAM"
echo " User version : $VERSION" echo " User version : $VERSION"
echo " Minimum required: $MIN_VERSION_GCC" echo " Minimum required: $MIN_VERSION_GCC"
echo "" echo
fatalError="x${fatalError}" fatalError="x${fatalError}"
fi fi
;; ;;
gtar)
VERSION=$($APP_PATH --version | head -1)
;;
tar)
VERSION=$($APP_PATH --version | head -1 | cut -d" " -f4)
;;
gzip)
case "$OSTYPE" in
SunOS)
VERSION=$($APP_NAME --version 2>&1 | grep gzip | cut -d" " -f2)
;;
*)
VERSION=$($APP_NAME --version | head -1 | cut -d" " -f2)
;;
esac
;;
esac esac
if [ "$APP_PATH" = "$APP_SPEC" ] || [ -z "$APP_SPEC" ] if [ "$APP_PATH" = "$APP_SPEC" ] || [ -z "$APP_SPEC" ]
then then
echo "$(fixlen "$APP_NAME" 9) $(fixlen "$VERSION" 10) $(fixlen "$APP_PATH" 58)" echo "$(fixlen "${APP_NAME##*/}" 12) $(fixlen "$VERSION" 10) $(fixlen "$APP_PATH" 55)"
else else
echo "$(fixlen "$APP_NAME" 9) $(fixlen "$VERSION" 10)" echo "$(fixlen "${APP_NAME##*/}" 12) $(fixlen "$VERSION" 10)"
echo "WARNING: Conflicting installations:" echo "WARNING: Conflicting installations:"
echo " OpenFOAM settings : $APP_SPEC" echo " OpenFOAM settings : $APP_SPEC"
echo " current path : $APP_PATH" echo " current path : $APP_PATH"
case "$APP_NAME" in case "$APP_NAME" in
gcc | $foamTestApp) *clang* | *gcc* | "$foamTestApp")
echo " CRITICAL ERROR" echo " CRITICAL ERROR"
criticalError="x${criticalError}" criticalError="x${criticalError}"
;; ;;
esac esac
echo "" echo
fi fi
} }
checkOpenFOAMEnvironment() checkEnvironment()
{ {
[ -d "$WM_PROJECT_DIR" ] && [ -d "$WM_THIRD_PARTY_DIR" ] || { if [ -d "$WM_PROJECT_DIR" ]
echo "" then
echo "FATAL ERROR: OpenFOAM environment not configured." echo "$(fixlen OpenFOAM: $WIDTH) ${WM_PROJECT_DIR##*/}"
echo "" else
echo " Please follow the download and installation link in README.html:" echo
echo " <OpenFOAM installation dir>/OpenFOAM-${WM_PROJECT_VERSION}/README.html" echo "ERROR: OpenFOAM environment not configured."
echo
echo " Please see the information in the README.md"
echo " <OpenFOAM installation dir>/OpenFOAM-${WM_PROJECT_VERSION}/README.md"
echo " for information on setting-up the OpenFOAM environment." echo " for information on setting-up the OpenFOAM environment."
echo "" echo
fatalError="x${fatalError}"
exit 1 exit 1
} fi
echo "$(fixlen OpenFOAM: $WIDTH) ${WM_PROJECT_DIR##*/}" if [ -d "$WM_THIRD_PARTY_DIR" ]
echo "$(fixlen ThirdParty: $WIDTH) ${WM_THIRD_PARTY_DIR##*/}" then
echo "$(fixlen ThirdParty: $WIDTH) ${WM_THIRD_PARTY_DIR##*/}"
else
echo "$(fixlen ThirdParty: $WIDTH) [missing]"
echo "This can be intentional, or indicate a faulty installation"
fi
} }
checkUserShell() checkUserShell()
{ {
echo "$(fixlen Shell: $WIDTH) ${SHELL##*/}" echo "$(fixlen Shell: $WIDTH) ${SHELL##*/}"
case $SHELL in case "$SHELL" in
*/csh | */tcsh | */bash | */ksh) */csh | */tcsh | */bash | */ksh)
;; ;;
*/dash | */zsh)
echo "[The ${SHELL##*/} shell is generally okay to use]"
;;
*) *)
echo "FATAL ERROR: Cannot identify the shell you are running." echo "ERROR: Cannot identify the shell you are running."
echo " OpenFOAM ${WM_PROJECT_VERSION} is compatible with " echo " OpenFOAM ${WM_PROJECT_VERSION} is compatible with "
echo " csh, tcsh, ksh and bash." echo " csh, tcsh, bash, ksh (and possibly dash, zsh)"
echo echo
fatalError="x${fatalError}" fatalError="x${fatalError}"
;; ;;
@ -341,10 +355,9 @@ checkHostName()
echo "$(fixlen Host: $WIDTH) $HOST" echo "$(fixlen Host: $WIDTH) $HOST"
if [ -z "$HOST" ] if [ -z "$HOST" ]
then then
echo "FATAL ERROR: Cannot stat hostname." echo "ERROR: Cannot stat hostname."
echo " Contact your system administrator, " echo " OpenFOAM ${WM_PROJECT_VERSION} needs a valid hostname."
echo " OpenFOAM ${WM_PROJECT_VERSION} needs a valid " echo " Contact your system administrator."
echo " hostname to function."
echo echo
fatalError="x${fatalError}" fatalError="x${fatalError}"
fi fi
@ -358,9 +371,9 @@ checkOS()
echo "$(fixlen OS: $WIDTH) $OSTYPE version $(uname -r)" echo "$(fixlen OS: $WIDTH) $OSTYPE version $(uname -r)"
;; ;;
*) *)
echo "FATAL ERROR: Incompatible operating system \"$OSTYPE\"." echo "ERROR: Incompatible operating system \"$OSTYPE\"."
echo " OpenFOAM ${FWM_PROJECT_VERSION} is currently " echo " OpenFOAM ${WM_PROJECT_VERSION} is currently available for"
echo " available for Linux, Darwin and SunOS only." echo " Linux, Darwin and SunOS only."
echo echo
fatalError="x${fatalError}" fatalError="x${fatalError}"
;; ;;
@ -371,13 +384,13 @@ checkOS()
#============================================================================== #==============================================================================
# MAIN SCRIPT # MAIN SCRIPT
#============================================================================== #==============================================================================
#
echo "Executing $0:" echo "Executing ${0##*/}"
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
heading "Basic setup :" heading "Basic setup :"
hline hline
checkOpenFOAMEnvironment checkEnvironment
checkUserShell checkUserShell
checkHostName checkHostName
checkOS checkOS
@ -385,7 +398,7 @@ hline
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
heading "Main OpenFOAM env variables :" heading "Main OpenFOAM env variables :"
COL1=$(fixlen EnvironmentVariable 21) COL1=$(fixlen Environment 21)
COL2=$(fixlen FileOrDirectory 40) COL2=$(fixlen FileOrDirectory 40)
COL3="Valid" COL3="Valid"
COL4="Path" COL4="Path"
@ -394,7 +407,8 @@ hline
echo "$COL1 $COL2 $COL3 $COL5" echo "$COL1 $COL2 $COL3 $COL5"
hline hline
reportEnv '$WM_PROJECT_USER_DIR' noPath no reportEnv '$WM_PROJECT_USER_DIR' noPath no
reportEnv '$WM_THIRD_PARTY_DIR' noPath yes reportEnv '$WM_THIRD_PARTY_DIR' noPath maybe
reportEnv '$WM_PROJECT_SITE' noPath no
hline hline
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -403,7 +417,7 @@ hline
echo "$COL1 $COL2 $COL3 $COL4 $COL5" echo "$COL1 $COL2 $COL3 $COL4 $COL5"
hline hline
reportEnv '$WM_PROJECT_DIR' '$PATH' yes reportEnv '$WM_PROJECT_DIR' '$PATH' yes
echo "" echo
reportEnv '$FOAM_APPBIN' '$PATH' yes reportEnv '$FOAM_APPBIN' '$PATH' yes
reportEnv '$FOAM_SITE_APPBIN' '$PATH' no reportEnv '$FOAM_SITE_APPBIN' '$PATH' no
reportEnv '$FOAM_USER_APPBIN' '$PATH' no reportEnv '$FOAM_USER_APPBIN' '$PATH' no
@ -425,22 +439,25 @@ hline
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
heading "Software Components" heading "Software Components"
hline hline
echo "$(fixlen Software 9) $(fixlen Version 10) $(fixlen Location 10)" echo "$(fixlen Software 12) $(fixlen Version 10) $(fixlen Location 10)"
hline hline
reportExecutable flex reportExecutable flex
reportExecutable wmake reportExecutable wmake
reportExecutable "$(wmake -show-c)"
reportExecutable "$(wmake -show-cxx)"
reportExecutable gzip
if [ "$OSTYPE" = Linux ]
then
reportExecutable tar
else
reportExecutable gtar
fi
reportExecutable $foamTestApp "$FOAM_APPBIN/$foamTestApp"
for compilerType in c cxx
do
compiler="$(wmake -show-path-"$compilerType" 2>/dev/null)"
if [ -n "$compiler" ]
then
reportExecutable "$compiler"
else
echo "unknown $compilerType compiler for $WM_COMPILER"
fatalError="x${fatalError}"
fi
done
hline hline
reportExecutable "$foamTestApp" "$FOAM_APPBIN/$foamTestApp"
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
heading "Summary" heading "Summary"

View File

@ -10,56 +10,50 @@
# Copyright (C) 2020 OpenCFD Ltd. # Copyright (C) 2020 OpenCFD Ltd.
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
# This file is part of OpenFOAM. # This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
# 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 <http://www.gnu.org/licenses/>.
# #
# Script # Script
# foamSystemCheck # bin/foamSystemCheck
# #
# Description # Description
# Checks the machine system and the user's # Check the machine, software components, and the environment
# personal configuration for running OpenFOAM. # for installing OpenFOAM.
# #
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# STATIC VARIABLES # General
# ~~~~~~~~~~~~~~~~ WIDTH=12
HLINE="-----------------------------------------------------------------------"
WIDTH=16 # System variables
unset fatalError HOST="$(uname -n)"
OSTYPE="$(uname -s)"
# Global variables
unset fatalError criticalError
#==============================================================================
# HELPER FUNCTIONS
#==============================================================================
hline()
{
echo "-------------------------------------------------------------------------------"
}
# FUNCTIONS
# ~~~~~~~~~
heading() heading()
{ {
echo echo
echo "$1" echo "$1"
echo "$HLINE"
}
lenBase()
{
echo $1 | tr -d " " | wc -m | tr -d " "
} }
length() length()
{ {
NOCHAR=$(lenBase $1) ## echo "length <$1>" 1>&2
NOCHAR=$(expr $NOCHAR - 1) nChars="$(echo "$1" | tr -d ' ' | wc -c)"
[ $NOCHAR -ge 0 ] || NOCHAR=0 nChars="$((nChars - 1))" # Remove newline from the count
echo $NOCHAR [ "$nChars" -ge 0 ] || nChars=0
echo "$nChars"
} }
fixlen() fixlen()
@ -82,57 +76,102 @@ fixlen()
fi fi
} }
# MAIN CODE
# ~~~~~~~~~ # -----------------------------------------------------------------------------
checkEnvironment()
{
if [ -d "$WM_PROJECT_DIR" ]
then
echo "$(fixlen OpenFOAM: $WIDTH) ${WM_PROJECT_DIR##*/}"
else
echo
echo "ERROR: OpenFOAM environment not configured."
echo
echo " Please see the information in the README.md"
echo " <OpenFOAM installation dir>/OpenFOAM-${WM_PROJECT_VERSION}/README.md"
echo " for information on setting-up the OpenFOAM environment."
echo
fatalError="x${fatalError}"
exit 1
fi
if [ -d "$WM_THIRD_PARTY_DIR" ]
then
echo "$(fixlen ThirdParty: $WIDTH) ${WM_THIRD_PARTY_DIR##*/}"
else
echo "$(fixlen ThirdParty: $WIDTH) [missing]"
echo "This can be intentional, or indicate a faulty installation"
fi
}
checkUserShell()
{
echo "$(fixlen Shell: $WIDTH) ${SHELL##*/}"
case "$SHELL" in
*/csh | */tcsh | */bash | */ksh)
;;
*/dash | */zsh)
echo "[The ${SHELL##*/} shell is generally okay to use]"
;;
*)
echo "ERROR: Cannot identify the shell you are running."
echo " OpenFOAM ${WM_PROJECT_VERSION} is compatible with "
echo " csh, tcsh, bash, ksh (and possibly dash, zsh)"
echo
fatalError="x${fatalError}"
;;
esac
}
checkHostName()
{
echo "$(fixlen Host: $WIDTH) $HOST"
if [ -z "$HOST" ]
then
echo "ERROR: Cannot stat hostname."
echo " OpenFOAM ${WM_PROJECT_VERSION} needs a valid hostname."
echo " Contact your system administrator."
echo
fatalError="x${fatalError}"
fi
}
checkOS()
{
case "$OSTYPE" in
Linux* | Darwin* | SunOS )
echo "$(fixlen OS: $WIDTH) $OSTYPE version $(uname -r)"
;;
*)
echo "ERROR: Incompatible operating system \"$OSTYPE\"."
echo " OpenFOAM ${WM_PROJECT_VERSION} is currently available for"
echo " Linux, Darwin and SunOS only."
echo
fatalError="x${fatalError}"
;;
esac
}
#==============================================================================
# MAIN SCRIPT
#==============================================================================
heading "Checking basic system..." heading "Checking basic system..."
hline
# check shell checkUserShell
echo "$(fixlen Shell: $WIDTH) $SHELL" checkHostName
case "$SHELL" in checkOS
*/csh | */tcsh | */bash | */ksh)
;;
*)
echo "ERROR: Cannot identify the current shell."
echo " OpenFOAM $WM_PROJECT_VERSION is compatible"
echo " with csh, tcsh, ksh and bash."
echo
fatalError=true
;;
esac
# check hostname
HOST=$(uname -n)
echo "$(fixlen Host: $WIDTH) $HOST"
if [ $(length $HOST) -eq 0 ]
then
echo "ERROR: Cannot stat hostname."
echo " OpenFOAM $WM_PROJECT_VERSION needs a valid hostname to"
echo " function. Contact your system administrator."
echo
fatalError=true
fi
# check os
OSTYPE=$(uname -s)
case "$OSTYPE" in
Linux* | Darwin* | SunOS )
echo "$(fixlen OS: $WIDTH) $OSTYPE version $(uname -r)"
;;
*)
echo "ERROR: Incompatible operating system \"$OSTYPE\"."
echo " OpenFOAM $WM_PROJECT_VERSION is currently available for "
echo " Linux, Darwin and SunOS only."
echo
fatalError=true
;;
esac
# check user name # check user name
USER_NAME=$LOGNAME USER_NAME="$LOGNAME"
if [ $(length $USER_NAME) -eq 0 ] if [ $(length $USER_NAME) -eq 0 ]
then then
USER_NAME=$USER USER_NAME="$USER"
fi fi
echo "$(fixlen User: $WIDTH) ${USER_NAME}" echo "$(fixlen User: $WIDTH) ${USER_NAME}"
@ -142,25 +181,26 @@ then
echo " OpenFOAM $WM_PROJECT_VERSION needs a valid user name." echo " OpenFOAM $WM_PROJECT_VERSION needs a valid user name."
echo " Contact your system administrator. " echo " Contact your system administrator. "
echo echo
fatalError=true fatalError="x${fatalError}"
fi fi
echo echo
echo if [ -n "$fatalError" ]
if [ "$fatalError" = true ]
then then
echo "System check: FAIL" cat << FAILED
echo "==================" System check: FAIL
echo "Your system is not currently compatible with OpenFOAM installation " ==================
echo "requirements. Review the error messages and consult the documentation" Your system may not compatible with the current OpenFOAM requirements.
echo "for further instructions." Review the error messages and consult the documentation for further information
echo FAILED
else else
echo "System check: PASS" cat << PASSED
echo "==================" System check: PASS
echo "Continue OpenFOAM installation." ==================
echo Can continue to OpenFOAM installation.
PASSED
fi fi
echo
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------