scripts/functions
changeset 19 d80e6dedcc13
child 47 7e2539937b6e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/scripts/functions	Mon Mar 12 18:59:31 2007 +0000
     1.3 @@ -0,0 +1,215 @@
     1.4 +# This file contains some usefull common functions
     1.5 +# Copyright 2007 Yann E. MORIN
     1.6 +# Licensed under the GPL v2. See COPYING in the root of this package
     1.7 +
     1.8 +CT_OnError() {
     1.9 +    ret=$?
    1.10 +    CT_DoLog ERROR "Build failed in step \"${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}\""
    1.11 +    for((step=(CT_STEP_COUNT-1); step>1; step--)); do
    1.12 +        CT_DoLog ERROR "      called in step \"${CT_STEP_MESSAGE[${step}]}\""
    1.13 +    done
    1.14 +    CT_DoLog ERROR "Error happened in \"${BASH_SOURCE[1]}\" in function \"${FUNCNAME[1]}\" (line unknown, sorry)"
    1.15 +    for((depth=2; ${BASH_LINENO[$((${depth}-1))]}>0; depth++)); do
    1.16 +        CT_DoLog ERROR "      called from \"${BASH_SOURCE[${depth}]}\" at line # ${BASH_LINENO[${depth}-1]} in function \"${FUNCNAME[${depth}]}\""
    1.17 +    done
    1.18 +    CT_DoLog ERROR "Look at \"${CT_ACTUAL_LOG_FILE}\" for more info on this error."
    1.19 +    exit $ret
    1.20 +}
    1.21 +trap CT_OnError ERR
    1.22 +
    1.23 +set -E
    1.24 +set -o pipefail
    1.25 +
    1.26 +# This is crosstool-ng-0.0.1
    1.27 +CT_VERSION=ng-0.0.1
    1.28 +
    1.29 +# The different log levels:
    1.30 +CT_LOG_LEVEL_ERROR=0
    1.31 +CT_LOG_LEVEL_WARN=1
    1.32 +CT_LOG_LEVEL_INFO=2
    1.33 +CT_LOG_LEVEL_EXTRA=3
    1.34 +CT_LOG_LEVEL_DEBUG=4
    1.35 +
    1.36 +# Attributes
    1.37 +_A_NOR="\\033[0m"
    1.38 +_A_BRI="\\033[1m"
    1.39 +_A_DIM="\\033[2m"
    1.40 +_A_UND="\\033[4m"
    1.41 +_A_BRB="\\033[5m"
    1.42 +_A_REV="\\033[7m"
    1.43 +_A_HID="\\033[8m"
    1.44 +
    1.45 +# Fore colors
    1.46 +_F_BLK="\\033[30m"
    1.47 +_F_RED="\\033[31m"
    1.48 +_F_GRN="\\033[32m"
    1.49 +_F_YEL="\\033[33m"
    1.50 +_F_BLU="\\033[34m"
    1.51 +_F_MAG="\\033[35m"
    1.52 +_F_CYA="\\033[36m"
    1.53 +_F_WHI="\\033[37m"
    1.54 +
    1.55 +# A function to log what is happening
    1.56 +# Different log level are available:
    1.57 +#   - ERROR:   A serious, fatal error occurred
    1.58 +#   - WARN:    A non fatal, non serious error occurred, take your responsbility with the generated build
    1.59 +#   - INFO:    Informational messages
    1.60 +#   - EXTRA:   Extra informational messages
    1.61 +#   - DEBUG:   Debug messages
    1.62 +# Usage: CT_DoLog <level> [message]
    1.63 +# If message is empty, then stdin will be logged.
    1.64 +CT_DoLog() {
    1.65 +    local max_level
    1.66 +    local level
    1.67 +    eval max_level="\${CT_LOG_LEVEL_${CT_LOG_LEVEL_MAX}}"
    1.68 +    # Set the maximum log level to DEBUG if we have none
    1.69 +    [ -z ${max_level} ] && max_level=${CT_LOG_LEVEL_DEBUG}
    1.70 +
    1.71 +    local LEVEL="$1"
    1.72 +    shift
    1.73 +    eval level="\${CT_LOG_LEVEL_${LEVEL}}"
    1.74 +
    1.75 +    if [ $# -eq 0 ]; then
    1.76 +        cat -
    1.77 +    else
    1.78 +        echo "${1}"
    1.79 +    fi |( IFS="\n" # We want the full lines, even leading spaces
    1.80 +          cpt=0
    1.81 +          indent=$((2*CT_STEP_COUNT))
    1.82 +          while read line; do
    1.83 +              l="`printf \"[%-5s]%*s%s%s\" \"${LEVEL}\" \"${indent}\" \" \" \"${line}\"`"
    1.84 +              # There will always be a log file, be it /dev/null
    1.85 +              echo -e "${l}" >>"${CT_ACTUAL_LOG_FILE}"
    1.86 +              color="CT_${LEVEL}_COLOR"
    1.87 +              normal="CT_NORMAL_COLOR"
    1.88 +              if [ ${level} -le ${max_level} ]; then
    1.89 +                  echo -e "${!color}${l}${!normal}"
    1.90 +              else
    1.91 +                  ${CT_PROG_BAR}
    1.92 +              fi
    1.93 +          done
    1.94 +        )
    1.95 +
    1.96 +    return 0
    1.97 +}
    1.98 +
    1.99 +# Abort the execution with a error message
   1.100 +# Usage: CT_Abort <message>
   1.101 +CT_Abort() {
   1.102 +    CT_DoLog ERROR "$1" >&2
   1.103 +    exit 1
   1.104 +}
   1.105 +
   1.106 +# Test a condition, and print a message if satisfied
   1.107 +# Usage: CT_Test <message> <tests>
   1.108 +CT_Test() {
   1.109 +    local ret
   1.110 +    local m="$1"
   1.111 +    shift
   1.112 +    test "$@" && CT_DoLog WARN "$m"
   1.113 +    return 0
   1.114 +}
   1.115 +
   1.116 +# Test a condition, and abort with an error message if satisfied
   1.117 +# Usage: CT_TestAndAbort <message> <tests>
   1.118 +CT_TestAndAbort() {
   1.119 +    local m="$1"
   1.120 +    shift
   1.121 +    test "$@" && CT_Abort "$m"
   1.122 +    return 0
   1.123 +}
   1.124 +
   1.125 +# Test a condition, and abort with an error message if not satisfied
   1.126 +# Usage: CT_TestAndAbort <message> <tests>
   1.127 +CT_TestOrAbort() {
   1.128 +    local m="$1"
   1.129 +    shift
   1.130 +    test "$@" || CT_Abort "$m"
   1.131 +    return 0
   1.132 +}
   1.133 +
   1.134 +# Test the presence of a tool, or abort if not found
   1.135 +# Usage: CT_HasOrAbort <tool>
   1.136 +CT_HasOrAbort() {
   1.137 +    CT_TestAndAbort "\"${1}\" not found and needed for successfull toolchain build." -z "`which \"${1}\"`"
   1.138 +    return 0
   1.139 +}
   1.140 +
   1.141 +# Get current date with nanosecond precision
   1.142 +# On those system not supporting nanosecond precision, faked with rounding down
   1.143 +# to the highest entire second
   1.144 +# Usage: CT_DoDate <fmt>
   1.145 +CT_DoDate() {
   1.146 +    date "$1" |sed -r -e 's/%N$/000000000/;'
   1.147 +}
   1.148 +
   1.149 +CT_STEP_COUNT=1
   1.150 +CT_STEP_MESSAGE[${CT_STEP_COUNT}]="<none>"
   1.151 +# Memorise a step being done so that any error is caught
   1.152 +# Usage: CT_DoStep <loglevel> <message>
   1.153 +CT_DoStep() {
   1.154 +    local start=`CT_DoDate +%s%N`
   1.155 +    CT_DoLog "$1" "================================================================="
   1.156 +    CT_DoLog "$1" "$2"
   1.157 +    CT_STEP_COUNT=$((CT_STEP_COUNT+1))
   1.158 +    CT_STEP_LEVEL[${CT_STEP_COUNT}]="$1"; shift
   1.159 +    CT_STEP_START[${CT_STEP_COUNT}]="${start}"
   1.160 +    CT_STEP_MESSAGE[${CT_STEP_COUNT}]="$1"
   1.161 +    return 0
   1.162 +}
   1.163 +
   1.164 +# End the step just being done
   1.165 +# Usage: CT_EndStep
   1.166 +CT_EndStep() {
   1.167 +    local stop=`CT_DoDate +%s%N`
   1.168 +    local duration=`printf "%032d" $((stop-${CT_STEP_START[${CT_STEP_COUNT}]})) |sed -r -e 's/([[:digit:]]{2})[[:digit:]]{7}$/\.\1/; s/^0+//; s/^\./0\./;'`
   1.169 +    local level="${CT_STEP_LEVEL[${CT_STEP_COUNT}]}"
   1.170 +    local message="${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}"
   1.171 +    CT_STEP_COUNT=$((CT_STEP_COUNT-1))
   1.172 +    CT_DoLog "${level}" "${message}: done in ${duration}s"
   1.173 +    return 0
   1.174 +}
   1.175 +
   1.176 +# Pushes into a directory, and pops back
   1.177 +CT_Pushd() {
   1.178 +    pushd "$1" >/dev/null 2>&1
   1.179 +}
   1.180 +CT_Popd() {
   1.181 +    popd >/dev/null 2>&1
   1.182 +}
   1.183 +
   1.184 +# Makes a path absolute
   1.185 +# Usage: CT_MakeAbsolutePath path
   1.186 +CT_MakeAbsolutePath() {
   1.187 +    # Try to cd in that directory
   1.188 +    if [ -d "$1" ]; then
   1.189 +        CT_Pushd "$1"
   1.190 +        pwd
   1.191 +        CT_Popd
   1.192 +    else
   1.193 +        # No such directory, fail back to guessing
   1.194 +        case "$1" in
   1.195 +            /*)  echo "$1";;
   1.196 +            *)   echo "`pwd`/$1";;
   1.197 +        esac
   1.198 +    fi
   1.199 +    
   1.200 +    return 0
   1.201 +}
   1.202 +
   1.203 +# Creates a temporary directory
   1.204 +# $1: variable to assign to
   1.205 +# Usage: CT_MktempDir foo
   1.206 +CT_MktempDir() {
   1.207 +    # Some mktemp do not allow more than 6 Xs
   1.208 +    eval "$1"="`mktemp -q -d \"${CT_BUILD_DIR}/.XXXXXX\"`"
   1.209 +    CT_TestOrAbort "Could not make temporary directory" -n "${!1}" -a -d "${!1}"
   1.210 +}
   1.211 +
   1.212 +# Echoes the specified string on stdout until the pipe breaks.
   1.213 +# Doesn't fail
   1.214 +# $1: string to echo
   1.215 +# Usage: CT_DoYes "" |make oldconfig
   1.216 +CT_DoYes() {
   1.217 +    yes "$1" || true
   1.218 +}