mirror of
https://github.com/sheumann/hush.git
synced 2024-12-27 16:31:24 +00:00
sleep: if FANCY && DESKTOP, support fractional seconds, minutes,
hours and so on. It's coreutils compat. bloatcheck is atrocious :( function old new delta sleep_main 71 362 +291 bb_strtod - 127 +127 make_device 1269 1294 +25 getoptscmd 708 713 +5 switch_root_main 402 401 -1 display_speed 90 85 -5 show_entry 295 289 -6 parse_expr 841 833 -8 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 3/4 up/down: 448/-20) Total: 428 bytes
This commit is contained in:
parent
34e8f6a7ac
commit
adbb73bda7
@ -36,28 +36,69 @@ static const struct suffix_mult sfx[] = {
|
|||||||
int sleep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int sleep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int sleep_main(int argc UNUSED_PARAM, char **argv)
|
int sleep_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
|
#if ENABLE_FEATURE_FANCY_SLEEP && ENABLE_DESKTOP
|
||||||
|
double duration;
|
||||||
|
struct timespec ts;
|
||||||
|
#else
|
||||||
unsigned duration;
|
unsigned duration;
|
||||||
|
#endif
|
||||||
|
|
||||||
++argv;
|
++argv;
|
||||||
if (!*argv)
|
if (!*argv)
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
|
|
||||||
#if ENABLE_FEATURE_FANCY_SLEEP
|
#if ENABLE_FEATURE_FANCY_SLEEP && ENABLE_DESKTOP
|
||||||
|
|
||||||
duration = 0;
|
duration = 0;
|
||||||
do {
|
do {
|
||||||
duration += xatoul_range_sfx(*argv, 0, UINT_MAX-duration, sfx);
|
char *arg = *argv;
|
||||||
|
if (strchr(arg, '.')) {
|
||||||
|
double d;
|
||||||
|
int len = strspn(arg, "0123456789.");
|
||||||
|
char sv = arg[len];
|
||||||
|
arg[len] = '\0';
|
||||||
|
d = bb_strtod(arg, NULL);
|
||||||
|
if (errno)
|
||||||
|
bb_show_usage();
|
||||||
|
arg[len] = sv;
|
||||||
|
len--;
|
||||||
|
sv = arg[len];
|
||||||
|
arg[len] = '1';
|
||||||
|
duration += d * xatoul_sfx(&arg[len], sfx);
|
||||||
|
arg[len] = sv;
|
||||||
|
} else
|
||||||
|
duration += xatoul_sfx(arg, sfx);
|
||||||
} while (*++argv);
|
} while (*++argv);
|
||||||
|
|
||||||
#else /* FEATURE_FANCY_SLEEP */
|
ts.tv_sec = MAXINT(typeof(ts.tv_sec));
|
||||||
|
ts.tv_nsec = 0;
|
||||||
|
if (duration >= 0 && duration < ts.tv_sec) {
|
||||||
|
ts.tv_sec = duration;
|
||||||
|
ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
errno = 0;
|
||||||
|
nanosleep(&ts, &ts);
|
||||||
|
} while (errno == EINTR);
|
||||||
|
|
||||||
|
#elif ENABLE_FEATURE_FANCY_SLEEP
|
||||||
|
|
||||||
|
duration = 0;
|
||||||
|
do {
|
||||||
|
duration += xatou_range_sfx(*argv, 0, UINT_MAX - duration, sfx);
|
||||||
|
} while (*++argv);
|
||||||
|
sleep(duration);
|
||||||
|
|
||||||
|
#else /* simple */
|
||||||
|
|
||||||
duration = xatou(*argv);
|
duration = xatou(*argv);
|
||||||
|
sleep(duration);
|
||||||
|
// Off. If it's really needed, provide example why
|
||||||
|
//if (sleep(duration)) {
|
||||||
|
// bb_perror_nomsg_and_die();
|
||||||
|
//}
|
||||||
|
|
||||||
#endif /* FEATURE_FANCY_SLEEP */
|
#endif
|
||||||
|
|
||||||
if (sleep(duration)) {
|
|
||||||
bb_perror_nomsg_and_die();
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ uint32_t bb_strtou32(const char *arg, char **endp, int base)
|
|||||||
|
|
||||||
/* Floating point */
|
/* Floating point */
|
||||||
|
|
||||||
/* double bb_strtod(const char *arg, char **endp); */
|
double bb_strtod(const char *arg, char **endp) FAST_FUNC;
|
||||||
|
|
||||||
#if __GNUC_PREREQ(4,1)
|
#if __GNUC_PREREQ(4,1)
|
||||||
# pragma GCC visibility pop
|
# pragma GCC visibility pop
|
||||||
|
@ -13,6 +13,7 @@ lib-y += bb_basename.o
|
|||||||
lib-y += bb_do_delay.o
|
lib-y += bb_do_delay.o
|
||||||
lib-y += bb_pwd.o
|
lib-y += bb_pwd.o
|
||||||
lib-y += bb_qsort.o
|
lib-y += bb_qsort.o
|
||||||
|
lib-y += bb_strtod.o
|
||||||
lib-y += bb_strtonum.o
|
lib-y += bb_strtonum.o
|
||||||
lib-y += change_identity.o
|
lib-y += change_identity.o
|
||||||
lib-y += chomp.o
|
lib-y += chomp.o
|
||||||
|
85
libbb/bb_strtod.c
Normal file
85
libbb/bb_strtod.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Utility routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libbb.h"
|
||||||
|
#include <math.h> /* just for HUGE_VAL */
|
||||||
|
|
||||||
|
#define NOT_DIGIT(a) (((unsigned char)(a-'0')) > 9)
|
||||||
|
|
||||||
|
double FAST_FUNC bb_strtod(const char *arg, char **endp)
|
||||||
|
{
|
||||||
|
double v;
|
||||||
|
char *endptr;
|
||||||
|
|
||||||
|
if (arg[0] != '-' && NOT_DIGIT(arg[0]))
|
||||||
|
goto err;
|
||||||
|
errno = 0;
|
||||||
|
v = strtod(arg, &endptr);
|
||||||
|
if (endp)
|
||||||
|
*endp = endptr;
|
||||||
|
if (endptr[0]) {
|
||||||
|
/* "1234abcg" or out-of-range? */
|
||||||
|
if (isalnum(endptr[0]) || errno) {
|
||||||
|
err:
|
||||||
|
errno = ERANGE;
|
||||||
|
return HUGE_VAL;
|
||||||
|
}
|
||||||
|
/* good number, just suspicious terminator */
|
||||||
|
errno = EINVAL;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* String to timespec: "NNNN[.NNNNN]" -> struct timespec.
|
||||||
|
* Can be used for other fixed-point needs.
|
||||||
|
* Returns pointer past last converted char,
|
||||||
|
* and returns errno similar to bb_strtoXX functions.
|
||||||
|
*/
|
||||||
|
char* FAST_FUNC bb_str_to_ts(struct timespec *ts, const char *arg)
|
||||||
|
{
|
||||||
|
if (sizeof(ts->tv_sec) <= sizeof(int))
|
||||||
|
ts->tv_sec = bb_strtou(arg, &arg, 10);
|
||||||
|
else if (sizeof(ts->tv_sec) <= sizeof(long))
|
||||||
|
ts->tv_sec = bb_strtoul(arg, &arg, 10);
|
||||||
|
else
|
||||||
|
ts->tv_sec = bb_strtoull(arg, &arg, 10);
|
||||||
|
ts->tv_nsec = 0;
|
||||||
|
|
||||||
|
if (*arg != '.')
|
||||||
|
return arg;
|
||||||
|
|
||||||
|
/* !EINVAL: number is not ok (alphanumeric ending, overflow etc) */
|
||||||
|
if (errno != EINVAL)
|
||||||
|
return arg;
|
||||||
|
|
||||||
|
if (!*++arg) /* "NNN." */
|
||||||
|
return arg;
|
||||||
|
|
||||||
|
{ /* "NNN.xxx" - parse xxx */
|
||||||
|
int ndigits;
|
||||||
|
char *p;
|
||||||
|
char buf[10]; /* we never use more than 9 digits */
|
||||||
|
|
||||||
|
/* Need to make a copy to avoid false overflow */
|
||||||
|
safe_strncpy(buf, arg, 10);
|
||||||
|
ts->tv_nsec = bb_strtou(buf, &p, 10);
|
||||||
|
ndigits = p - buf;
|
||||||
|
arg += ndigits;
|
||||||
|
/* normalize to nsec */
|
||||||
|
while (ndigits < 9) {
|
||||||
|
ndigits++;
|
||||||
|
ts->tv_nsec *= 10;
|
||||||
|
}
|
||||||
|
while (isdigit(*arg)) /* skip possible 10th plus digits */
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
#endif
|
@ -124,33 +124,3 @@ int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base)
|
|||||||
return handle_errors(v, endp, endptr);
|
return handle_errors(v, endp, endptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Floating point */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#include <math.h> /* just for HUGE_VAL */
|
|
||||||
#define NOT_DIGIT(a) (((unsigned char)(a-'0')) > 9)
|
|
||||||
double FAST_FUNC bb_strtod(const char *arg, char **endp)
|
|
||||||
{
|
|
||||||
double v;
|
|
||||||
char *endptr;
|
|
||||||
|
|
||||||
if (arg[0] != '-' && NOT_DIGIT(arg[0])) goto err;
|
|
||||||
errno = 0;
|
|
||||||
v = strtod(arg, &endptr);
|
|
||||||
if (endp) *endp = endptr;
|
|
||||||
if (endptr[0]) {
|
|
||||||
/* "1234abcg" or out-of-range? */
|
|
||||||
if (isalnum(endptr[0]) || errno) {
|
|
||||||
err:
|
|
||||||
errno = ERANGE;
|
|
||||||
return HUGE_VAL;
|
|
||||||
}
|
|
||||||
/* good number, just suspicious terminator */
|
|
||||||
errno = EINVAL;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user