#
# Bash source file for fine elapsed time reporting
# based on /proc/timer_list, display elapsed time in nanosecs
# or /proc/uptime if timer_list not present, for 100th of secs.
#
# (C) 2011-2012 Felix Hauri - felix@f-hauri.ch
# Licensed under terms of LGPL v3. www.gnu.org

# Usage:
#   load script into bash using ``source elap.bash''
#
# Syntaxe: elap [ [ -r | -R ] | [ -n ] [ -t | -T ] [<simple text report>] ]
#   -r reset first counter only, don't output anything, like -R...
#   -R reset both counters, (both -r and -R must by unique argument)
#   -n don't reset any counter (just print)
#   -t print both counters (reset first counter)
#   -T print and reset
#
# nota: using ``-n'' in combinaison with any of ``-r'' or ``-R'' is buggy.

export _elaP_now _elaP_last _elaP_elap _elaP_last2 \
    _elaP_file _elaP_line _elaP_field _elaP_dec

if [ -e /proc/timer_list ] ;then
    _elaP_file=/proc/timer_list
    _elaP_dec=9
    _elaP_field=2
    mapfile < $_elaP_file _elaP_now
    _elaP_line=0
    while [ "${_elaP_now[_elaP_line]}" == \
	"${_elaP_now[_elaP_line]#*now at}" ] ;do
	((_elaP_line++))
    done
else
    if [ -f /proc/uptime ] ;then
	_elaP_file=/proc/uptime
	_elaP_dec=2
	_elaP_field=0
	_elaP_line=0
	mapfile < $_elaP_file _elaP_now
    else
	
	return -1
    fi
fi

elap() {
    local _Z9=000000000
    local _elaP_setLast=true
    [ "$1" == "-n" ] && shift && _elaP_setLast=false
    [ "$2" == "-n" ] && set -- $1 ${@:3} && _elaP_setLast=false
    mapfile -n 1 -s $_elaP_line <$_elaP_file _elaP_now
    _elaP_now=($_elaP_now)
    _elaP_now=${_elaP_now[_elaP_field]//./}
    _elaP_elap=$((_elaP_now - _elaP_last))
    [ ${#_elaP_elap} -lt $_elaP_dec ] && \
	_elaP_elap=${_Z9:0:_elaP_dec-${#_elaP_elap}}$_elaP_elap
    [ "${*}" == "-R" ] &&  _elaP_last2=$_elaP_now || \
	[ "${*}" == "-r" ] || if [ "$1" == "-t" ] || [ "$1" == "-T" ] ;then
	local _elaP_setLast2=false
	[ "$1" == "-T" ] && _elaP_setLast2=true
	shift
       	_elaP_elap2=$((_elaP_now - _elaP_last2))
	[ ${#_elaP_elap2} -lt $_elaP_dec ] && \
	    _elaP_elap2="${_Z9:0:_elaP_dec-${#_elaP_elap2}}$_elaP_elap2"
        printf "%6d.%s %6d.%s %s\n" \
	    "${_elaP_elap:0:${#_elaP_elap}-$_elaP_dec}" \
	    "${_elaP_elap:${#_elaP_elap}-_elaP_dec}" \
	    "${_elaP_elap2:0:${#_elaP_elap2}-$_elaP_dec}" \
	    "${_elaP_elap2:${#_elaP_elap2}-_elaP_dec}"      "${*}"
	$_elaP_setLast2 && _elaP_last2=$_elaP_now
    else
        printf "%6d.%s %s\n" \
	    "${_elaP_elap:0:${#_elaP_elap}-$_elaP_dec}" \
	    "${_elaP_elap:${#_elaP_elap}-_elaP_dec}"        "${*}"
    fi
    $_elaP_setLast && _elaP_last=$_elaP_now
}
    
export -f elap
