[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