mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix the max precision of the 'time' keyword (#72)
This commit backports the required fixes from ksh2020 for using
millisecond precision with the 'time' keyword. The bugfix refactors
a decent amount of code to rely on the BSD 'timeradd' and
'timersub' macros for calculating the total amount of time elapsed
(as these aren't standard, they are selectively implemented in an
iffe feature test for platforms without them). getrusage(3) is now
preferred since it usually has higher precision than times(3) (the
latter is used as a fallback).
There are three other fixes as well:
src/lib/libast/features/time:
- Test for getrusage with an iffe feature test rather than
assume _sys_times == _lib_getrusage.
src/cmd/ksh93/sh/xec.c:
- A single percent at the end of a format specifier is now
treated as a literal '%' (like in Bash).
- Zero-pad seconds if seconds < 10. This was already done for
the times builtin in commit 5c677a4c
, although it wasn't
applied to the time keyword.
- Backport the ksh2020 bugfix for the time keyword by using
timeradd and timersub with gettimeofday (which is used with
a timeofday macro). Prefer getrusage when it is available.
- Allow compiling without the 'timeofday' ifdef for better
portability.
This is the order of priority for getting the elapsed time:
1) getrusage (most precise)
2) times + gettimeofday (best fallback)
3) only times (doesn't support millisecond precision)
This was tested by using debug '#undef' statements in xec.c.
src/cmd/ksh93/features/time:
- Implement feature tests for the 'timeradd' and 'timersub'
macros.
- Do a feature test for getrusage like in the libast time test.
src/cmd/ksh93/tests/basic.sh:
- Add test for millisecond precision.
- Add test for handling of '%' at the end of a format specifier.
- Add test for locale-specific radix point.
This commit is contained in:
parent
fc655f1a26
commit
70fc1da73e
6 changed files with 262 additions and 47 deletions
|
@ -552,5 +552,41 @@ $SHELL 2> /dev/null -c $'for i;\ndo :;done' || err_exit 'for i ; <newline> not v
|
|||
"$SHELL" main.ksh 2>/dev/null
|
||||
) || err_exit "crash when sourcing multiple files (exit status $?)"
|
||||
|
||||
# ======
|
||||
# The time keyword should correctly handle millisecond precision.
|
||||
# This can be checked by verifying the last digit is not a zero
|
||||
# when 'time sleep .002' is run.
|
||||
result=$(
|
||||
TIMEFORMAT=$'\%3R'
|
||||
redirect 2>&1
|
||||
time sleep .002
|
||||
)
|
||||
[[ ${result: -1} == 0 ]] && err_exit "the 'time' keyword doesn't properly support millisecond precision"
|
||||
|
||||
# A single '%' after a format specifier should not be a syntax
|
||||
# error (it should be treated as a literal '%').
|
||||
IFS=' '
|
||||
result=( $(
|
||||
TIMEFORMAT=$'%0S%'
|
||||
redirect 2>&1
|
||||
time :
|
||||
) )
|
||||
[[ ${result[4]} == bad ]] && err_exit "'%' is not treated literally when placed after a format specifier"
|
||||
|
||||
# The locale's radix point shouldn't be ignored
|
||||
us=$(
|
||||
LC_ALL='C.UTF-8' # radix point '.'
|
||||
TIMEFORMAT='%1U' # catch -1.99 bug as well by getting user time
|
||||
redirect 2>&1
|
||||
time sleep 0
|
||||
)
|
||||
eu=$(
|
||||
LC_ALL='C_EU.UTF-8' # radix point ','
|
||||
TIMEFORMAT='%1U'
|
||||
redirect 2>&1
|
||||
time sleep 0
|
||||
)
|
||||
[[ ${us:1:1} == ${eu:1:1} ]] && err_exit "The time keyword ignores the locale's radix point (both are ${eu:1:1})"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue