1 /* vi: set sw=4 ts=4: */ 2 /* 3 * Utility routines. 4 * 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 */ 9 #include "libbb.h" 10 #include <math.h> /* just for HUGE_VAL */ 11 12 #define NOT_DIGIT(a) (((unsigned char)(a-'0')) > 9) 13 14 #if 0 // UNUSED 15 double FAST_FUNC bb_strtod(const char *arg, char **endp) 16 { 17 double v; 18 char *endptr; 19 20 /* Allow .NN form. People want to use "sleep .15" etc */ 21 if (arg[0] != '-' && arg[0] != '.' && NOT_DIGIT(arg[0])) 22 goto err; 23 errno = 0; 24 v = strtod(arg, &endptr); 25 if (endp) 26 *endp = endptr; 27 if (endptr[0]) { 28 /* "1234abcg" or out-of-range? */ 29 if (isalnum(endptr[0]) || errno) { 30 err: 31 errno = ERANGE; 32 return HUGE_VAL; 33 } 34 /* good number, just suspicious terminator */ 35 errno = EINVAL; 36 } 37 return v; 38 } 39 #endif 40 41 #if 0 42 /* String to timespec: "NNNN[.NNNNN]" -> struct timespec. 43 * Can be used for other fixed-point needs. 44 * Returns pointer past last converted char, 45 * and returns errno similar to bb_strtoXX functions. 46 */ 47 char* FAST_FUNC bb_str_to_ts(struct timespec *ts, const char *arg) 48 { 49 if (sizeof(ts->tv_sec) <= sizeof(int)) 50 ts->tv_sec = bb_strtou(arg, &arg, 10); 51 else if (sizeof(ts->tv_sec) <= sizeof(long)) 52 ts->tv_sec = bb_strtoul(arg, &arg, 10); 53 else 54 ts->tv_sec = bb_strtoull(arg, &arg, 10); 55 ts->tv_nsec = 0; 56 57 if (*arg != '.') 58 return arg; 59 60 /* !EINVAL: number is not ok (alphanumeric ending, overflow etc) */ 61 if (errno != EINVAL) 62 return arg; 63 64 if (!*++arg) /* "NNN." */ 65 return arg; 66 67 { /* "NNN.xxx" - parse xxx */ 68 int ndigits; 69 char *p; 70 char buf[10]; /* we never use more than 9 digits */ 71 72 /* Need to make a copy to avoid false overflow */ 73 safe_strncpy(buf, arg, 10); 74 ts->tv_nsec = bb_strtou(buf, &p, 10); 75 ndigits = p - buf; 76 arg += ndigits; 77 /* normalize to nsec */ 78 while (ndigits < 9) { 79 ndigits++; 80 ts->tv_nsec *= 10; 81 } 82 while (isdigit(*arg)) /* skip possible 10th plus digits */ 83 arg++; 84 } 85 return arg; 86 } 87 #endif 88