[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: Re: Question about TIMEOUT applet.
From: Harald Becker <ralda () gmx ! de>
Date: 2013-07-16 22:39:33
Message-ID: 20130717003933.45885d4b () ralda ! gmx ! de
[Download RAW message or body]
Hi,
here is a first version of a duration helper function. As
Bernhard suggested, it always works with float (double) values,
but if required we can add a version using only integers and the
bare minimum of required suffixes (d, h, m, s).
The current version allows for the following suffixes:
w = weeks
d = days
h = hours
m = minutes
s = seconds (default if no suffix)
u = microseconds
n = nanoseconds
In addition it understands fancy combined duration specifications
like:
'1m15s'
'1s100u'
'1h+5m'
'1h-5m+15s'
'0.5m+5s'
GNU libc even allows for hexadecimal values:
0xFFFF -> 65535 seconds
This is a first version, looking for comments.
--
Harald
[Attachment #3 (text/x-csrc)]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAXINT(T) (T)( \
((T)-1) > 0 \
? (T)-1 \
: (T)~((T)1 << (sizeof(T)*8-1)) \
)
/* convert string to a duration value in struct timespec format */
/* allows for fractionals and suffixes (w)eeks, (d)ays, (h)ours, */
/* (m)inutes, (s)seconds, (u)=microseconds, (n)anosecons */
/* The function follows the semantics of strtol, strtod, etc. */
/* Returns pointer to duration as struct timespec, or NULL */
/* If endptr is not NULL, store pointer to unconverted part of string */
struct timespec *strtots( char const *nptr, char **endptr, struct timespec *ts )
{
size_t n;
char *p, *s;
double duration, d;
/* maximum value of struct timespec */
#define MAX_TVSEC MAXINT(typeof(ts->tv_sec))
#define MAX_TVNSEC 999999999L
/* allowed sufixes and there multipliers */
#define dur_multipliers (sizeof(dur_mult) / sizeof(float))
static char const dur_sfx[] = "wdhmuns +-";
static float const dur_mult[] = {
7 * 24 * 60 * 60.0,
24 * 60 * 60.0,
60 * 60.0,
60.0,
1e-6,
1e-9,
1.0
};
/* default duration value */
ts->tv_sec = 0;
ts->tv_nsec = 0;
duration = 0;
/* convert given string */
if( nptr )
while( *nptr )
{
/* convert initial part of string */
d = strtod( nptr, &p );
if( p == nptr ) break;
/* check for valid duration suffix */
s = strchr( dur_sfx, *p );
if( s == NULL ) break;
/* remaining part of string */
nptr = p;
/* multiply number by specified suffix */
n = s - dur_sfx;
if( n < dur_multipliers )
{
d *= dur_mult[n];
++nptr;
}
/* sum of duration (in seconds) */
duration += d;
}
/* save pointer to unconverted part of string */
if( endptr ) *endptr = (char*)nptr;
/* don't allow negativ duration */
if( duration < 0 ) return NULL;
/* limit to maximum number of struct timespec */
if( duration > MAX_TVSEC )
{
ts->tv_sec = MAX_TVSEC;
ts->tv_nsec = MAX_TVNSEC;
}
/* else split into seconds and nano seconds */
else
{
ts->tv_sec = duration;
ts->tv_nsec = (duration - ts->tv_sec) * 1e9 + 0.5;
}
/* duration as struct timespec */
return ts;
}
/* Test program for strtots */
int main( int argc, char *argv[] )
{
int i;
struct timespec ts;
char *e;
for( i = 1; i < argc; ++i )
{
printf( "argv[%d]='%s' ts=", i, argv[i] );
if( strtots(argv[i], &e, &ts) == NULL )
printf( "(null)\n" );
else if( *e )
printf( "(failed at '%s')\n", e );
else
printf( "%lds+%ldns\n", ts.tv_sec, ts.tv_nsec );
}
return 0;
}
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic