1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/scripts/functions Tue Apr 10 16:07:30 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 +}