]> CyberLeo.Net >> Repos - CDN/shlib.git/blob - lib/sh/stopwatch.sh
Add explicit copyright to all library files
[CDN/shlib.git] / lib / sh / stopwatch.sh
1 if [ -z "${__stopwatch_sh_loaded}" ]
2 then
3   __stopwatch_sh_loaded=yes
4
5   __stopwatch_sh_VERSION="Stopwatch v0.1"
6   __stopwatch_sh_DESCRIPTION="Stopwatch implementation supporting multiple tagged timers"
7   __stopwatch_sh_COPYRIGHT=$( cat <<"END_OF_COPYRIGHT"
8
9 Copyright (c) 2000-2012, CyberLeo
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14
15     * Redistributions of the source code must retain the above copyright
16       notice, this list of conditions, and the following disclaimer.
17     * Redistributions in binary form must reproduce the above copyright
18       notice, this list of conditions, and the following disclaimer in the
19       documentation and/or other materials provided with the distribution.
20     * Neither the name of the organization nor the names of its contributors
21       may be used to endorse or promote products derived from this software
22       without specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
28 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
30 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 HOWEVER CAUSED AND ON ANY THEORY OF LIABILTY, WHETHER IN CONTRACT, STRICT
32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 END_OF_COPYRIGHT
36 )
37
38   [ "${kvs}" ] || kvs="$(mktemp -t ".stopwatch.XXXXXXXX")"
39   want kvs
40
41   stopwatch_help() {
42     cat <<EOF >&2
43 ${__stopwatch_sh_VERSION}
44 ${__stopwatch_sh_DESCRIPTION}
45
46 ${__stopwatch_sh_COPYRIGHT}
47
48 Usage: stopwatch <tag> <start|lap|stop|reset>
49
50 Simple bourne shell based stopwatch
51 Requires 'kvs' and the id 'stopwatch' therein
52 so make sure you set 'kvs' before sourcing this script if necessary.
53
54 After loading, the following commands are available:
55
56 Start a stopwatch
57   stopwatch <tag> start
58
59 'Lap' a stopwatch (emit timer value without stopping)
60   stopwatch <tag> lap
61
62 Stop a stopwatch; can be resumed later with 'start'
63   stopwatch <tag> stop
64
65 Reset a stopwatch back to zero
66   stopwatch <tag> reset
67
68 EOF
69     kill -ABRT $$
70   }
71
72   # Try and format a passed integer number of seconds into something more
73   # useful (like 6m10s or something)
74   _stopwatch_timefmt() {
75     local secs mins hurs days
76     [ "${1}" -a "$(echo "${1}" | tr -Cd '0-9')" = "${1}" ] || return 255
77     secs="${1}"
78     mins=0
79     hurs=0
80     [ "${secs}" -lt 60 ] || {
81       mins=$(( ${secs} / 60 ))
82       secs=$(( ${secs} % 60 ))
83     }
84     [ "${secs}" -gt 0 ] || secs=""
85     [ "${mins}" -lt 60 ] || {
86       hurs=$(( ${mins} / 60 ))
87       mins=$(( ${mins} % 60 ))
88     }
89     [ "${mins}" -gt 0 ] || mins=""
90     [ "${hurs}" -lt 24 ] || {
91       days=$(( ${hurs} / 24 ))
92       hurs=$(( ${hurs} % 24 ))
93     }
94     [ "${hurs}" -gt 0 ] || hurs=""
95
96     [ "${days}" -o "${hurs}" -o "${mins}" -o "${secs}" ] || printf "0s"
97     printf "%s%s%s%s" "${days:+${days}d}" "${hurs:+${hurs}h}" "${mins:+${mins}m}" "${secs:+${secs}s}"
98   }
99
100   # Start a named stopwatch, but do nothing if the named stopwatch is already
101   # running.
102   stopwatch_start() {
103     name="${1:-stopwatch}"
104     [ "${nao}" ] || nao="$(date +%s)"
105     # Is the stopwatch running?
106     if kvs_has_key stopwatch "${name}"
107     then
108       printf "Stopwatch: %s is already running.\n" "${name}"
109     else
110       # start the stopwatch
111       accum="$(kvs_get stopwatch "${name}_accumulator")"
112       kvs_set stopwatch "${name}" "${nao}"
113       [ "${accum}" ] && restart="$(printf " at %s" "$(_stopwatch_timefmt "${accum}")")"
114       printf "Stopwatch: %s starts running%s.\n" "${name}" "${restart}"
115     fi
116   }
117
118   # 'Lap' the named stopwatch: print out a line indicating how long the named
119   # stopwatch has been running, but do not stop nor reset the stopwatch.
120   stopwatch_lap() {
121     name="${1:-stopwatch}"
122     [ "${nao}" ] || nao="$(date +%s)"
123     # Is the stopwatch running?
124     if kvs_has_key stopwatch "${name}"
125     then
126       # emit a line indicating how long it has been running
127       start="$(kvs_get stopwatch "${name}")"
128       accum="$(kvs_get stopwatch "${name}_accumulator")"
129       delta="$(( ${nao} - ${start} ))"
130       [ "${accum}" ] && delta="$(( ${delta} + ${accum} ))"
131       printf "Stopwatch: %s is running at %s.\n" "${name}" "$(_stopwatch_timefmt "${delta}")"
132     else
133       accum="$(kvs_get stopwatch "${name}_accumulator")"
134       [ "${accum}" ] && printf "Stopwatch: %s is stopped at %s.\n" "${name}" "$(_stopwatch_timefmt "${accum}")"
135     fi
136   }
137
138   # Stop the named stopwatch and print out a line indicating how long it had
139   # been running up until that point; do not reset the stopwatch.
140   stopwatch_stop() {
141     name="${1:-stopwatch}"
142     [ "${nao}" ] || nao="$(date +%s)"
143     if kvs_has_key stopwatch "${name}"
144     then
145       start="$(kvs_get stopwatch "${name}")"
146       accum="$(kvs_get stopwatch "${name}_accumulator")"
147       delta="$(( ${nao} - ${start} ))"
148       [ "${accum}" ] && delta="$(( ${delta} + ${accum} ))"
149       kvs_set stopwatch "${name}_accumulator" "${delta}"
150       kvs_unset stopwatch "${name}"
151       printf "Stopwatch: %s stops running at %s.\n" "${name}" "$(_stopwatch_timefmt "${delta}")"
152     else
153       accum="$(kvs_get stopwatch "${name}_accumulator")"
154       [ "${accum}" ] && printf "Stopwatch: %s is already stopped at %s.\n" "${name}" "$(_stopwatch_timefmt "${accum}")"
155     fi
156   }
157
158   # Reset the named stopwatch back to zero.
159   stopwatch_reset() {
160     name="${1:-stopwatch}"
161     [ "${nao}" ] || nao="$(date +%s)"
162     kvs_unset stopwatch "${name}"
163     kvs_unset stopwatch "${name}_accumulator"
164     printf "Stopwatch: %s is reset to 0s.\n" "${name}"
165   }
166
167   stopwatch() {
168     [ "${1}" -a "${2}" ] || stopwatch_help;
169     nao="$(date +%s)"
170     case "${2}" in
171     [Ss][Tt][Aa][Rr][Tt])  stopwatch_start "${1}"  ;;
172     [Ll][Aa][Pp])          stopwatch_lap "${1}"    ;;
173     [Ss][Tt][Oo][Pp])      stopwatch_stop "${1}"   ;;
174     [Rr][Ee][Ss][Ee][Tt])  stopwatch_reset "${1}"  ;;
175     *)                     stopwatch_help          ;;
176     esac
177   }
178 fi