123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- __require_tool_version_compare ()
- {
- (
- # Locally ignore failures, otherwise we'll exit whenever $1 and $2
- # are not equal!
- set +e
- awk_strverscmp='
- # Use only awk features that work with 7th edition Unix awk (1978).
- # My, what an old awk you have, Mr. Solaris!
- END {
- while (length(v1) || length(v2)) {
- # Set d1 to be the next thing to compare from v1, and likewise for d2.
- # Normally this is a single character, but if v1 and v2 contain digits,
- # compare them as integers and fractions as strverscmp does.
- if (v1 ~ /^[0-9]/ && v2 ~ /^[0-9]/) {
- # Split v1 and v2 into their leading digit string components d1 and d2,
- # and advance v1 and v2 past the leading digit strings.
- for (len1 = 1; substr(v1, len1 + 1) ~ /^[0-9]/; len1++) continue
- for (len2 = 1; substr(v2, len2 + 1) ~ /^[0-9]/; len2++) continue
- d1 = substr(v1, 1, len1); v1 = substr(v1, len1 + 1)
- d2 = substr(v2, 1, len2); v2 = substr(v2, len2 + 1)
- if (d1 ~ /^0/) {
- if (d2 ~ /^0/) {
- # Compare two fractions.
- while (d1 ~ /^0/ && d2 ~ /^0/) {
- d1 = substr(d1, 2); len1--
- d2 = substr(d2, 2); len2--
- }
- if (len1 != len2 && ! (len1 && len2 && substr(d1, 1, 1) == substr(d2, 1, 1))) {
- # The two components differ in length, and the common prefix
- # contains only leading zeros. Consider the longer to be less.
- d1 = -len1
- d2 = -len2
- } else {
- # Otherwise, compare as strings.
- d1 = "x" d1
- d2 = "x" d2
- }
- } else {
- # A fraction is less than an integer.
- exit 1
- }
- } else {
- if (d2 ~ /^0/) {
- # An integer is greater than a fraction.
- exit 2
- } else {
- # Compare two integers.
- d1 += 0
- d2 += 0
- }
- }
- } else {
- # The normal case, without worrying about digits.
- if (v1 == "") d1 = v1; else { d1 = substr(v1, 1, 1); v1 = substr(v1,2) }
- if (v2 == "") d2 = v2; else { d2 = substr(v2, 1, 1); v2 = substr(v2,2) }
- }
- if (d1 < d2) exit 1
- if (d1 > d2) exit 2
- }
- }
- '
- awk "$awk_strverscmp" v1="$1" v2="$2" /dev/null
- case $? in
- 1) echo '<';;
- 0) echo '=';;
- 2) echo '>';;
- esac
- )
- }
- __require_tool_fatal ()
- {
- echo $@ >/dev/stderr
- return 1
- }
- # Usage: require_tool program version
- # Returns: 0 if $1 version if greater equals than $2, 1 otherwise.
- # In case of error, message is written on error output.
- #
- # Example: require_tool gcc 4.6
- # Use GCC environment variable if defined instead of lookup for the tool
- # in the environment.
- require_tool ()
- {
- envvar_name=$(echo $1 | tr '[:lower:]' '[:upper:]')
- tool=$(printenv $envvar_name || echo $1)
- local version=$($tool --version 2>/dev/null| \
- sed -n 's/.*[^0-9.]\([0-9]*\.[0-9.]*\).*/\1/p;q')
- if test x"$version" = x ; then
- echo "$tool is required" >/dev/stderr
- return 1
- fi
- case $(__require_tool_version_compare "$2" "$version") in
- '>')
- echo "$1 $2 or better is required: this is $tool $version" >/dev/stderr
- return 1
- ;;
- esac
- }
- usage() {
- cat <<EOF
- NAME
- require_tool.sh - Ensure version of a tool is greater than the one expected
- SYNOPSIS
- require_tool.sh [ -h ]
- [ --help ]
- [ TOOL MIN_VERSION ]
- DESCRIPTION
- TOOL is the name or path of the program to check. If the name is specified, its
- path is deduced from PATH environment variable. If environment variable TOOL
- (in upper-case characters) is defined, considers its value as path to the tool.
- MIN_VERSION is a string representing the minimum required version.
- BEHAVIOR
- * locate path to the program.
- * execute $ TOOL_PATH --version
- * extract version from standard output.
- * compare this version to the expected one.
- OPTIONS
- -h --help
- Display this message and exit 0
- ERRORS
- if program is not found or its version is prior to expected version,
- a message is written to error output.
- EXIT VALUE
- returns 0 if program version if greater equals than expected version,
- returns 1 otherwise.
- EXAMPLE
- $ require_tool.sh emacs 23
- $ CC=g++ require_tool.sh cc 4.6
- $ require_tool.sh zsh 4.5
- EOF
- }
- for arg in $@; do
- case $arg in
- -h|--help)
- usage
- exit 0
- ;;
- esac
- done
- if [ $# -gt 2 ] ; then
- echo "ERROR: expecting 2 parameters. Please see option --help"
- exit 1
- fi
- require_tool $@
|