]> git.sur5r.net Git - openldap/blobdiff - libraries/liblutil/utils.c
cleanup
[openldap] / libraries / liblutil / utils.c
index 2666f85214f9ac04771e21434c82376c08feefc9..77baee98c65b847caf69e2bff2dc641df84f1fd5 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -136,7 +136,7 @@ size_t lutil_localtime( char *s, size_t smax, const struct tm *tm, long delta )
        return ret + 5;
 }
 
-int lutil_tm2time( struct slap_tm *tm, struct slap_timet *tt )
+int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt )
 {
        static int moffset[12] = {
                0, 31, 59, 90, 120,
@@ -173,12 +173,15 @@ int lutil_tm2time( struct slap_tm *tm, struct slap_timet *tt )
        /* add in days in this month */ 
        tt->tt_sec += (tm->tm_mday - 1); 
 
+       /* this function can handle a range of about 17408 years... */
        /* 86400 seconds in a day, divided by 128 = 675 */
        tt->tt_sec *= 675;
+
+       /* move high 7 bits into tt_gsec */
        tt->tt_gsec = tt->tt_sec >> 25;
        tt->tt_sec -= tt->tt_gsec << 25;
 
-       /* convert to hours */ 
+       /* get hours */ 
        sec = tm->tm_hour; 
 
        /* convert to minutes */ 
@@ -189,6 +192,7 @@ int lutil_tm2time( struct slap_tm *tm, struct slap_timet *tt )
        sec *= 60L; 
        sec += tm->tm_sec; 
        
+       /* add remaining seconds */
        tt->tt_sec <<= 7;
        tt->tt_sec += sec;
 
@@ -196,11 +200,11 @@ int lutil_tm2time( struct slap_tm *tm, struct slap_timet *tt )
        return 0; 
 }
 
-int lutil_parsetime( char *atm, struct slap_tm *tm )
+int lutil_parsetime( char *atm, struct lutil_tm *tm )
 {
        while (atm && tm) {
                char *ptr = atm;
-               int i, fracs;
+               unsigned i, fracs;
 
                /* Is the stamp reasonably long? */
                for (i=0; isdigit(atm[i]); i++);
@@ -306,3 +310,185 @@ int mkstemp( char * template )
 #endif
 }
 #endif
+
+/*
+ * Memory Reverse Search
+ */
+void *
+lutil_memrchr(const void *b, int c, size_t n)
+{
+       if (n != 0) {
+               const unsigned char *s, *bb = b, cc = c;
+
+               for ( s = bb + n; s > bb; ) {
+                       if ( *--s == cc ) {
+                               return (void *) s;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
+int
+lutil_atoix( int *v, const char *s, int x )
+{
+       char            *next;
+       long            i;
+
+       assert( s != NULL );
+       assert( v != NULL );
+
+       i = strtol( s, &next, x );
+       if ( next == s || next[ 0 ] != '\0' ) {
+               return -1;
+       }
+
+       if ( (long)(int)i != i ) {
+               return 1;
+       }
+
+       *v = (int)i;
+
+       return 0;
+}
+
+int
+lutil_atoux( unsigned *v, const char *s, int x )
+{
+       char            *next;
+       unsigned long   u;
+
+       assert( s != NULL );
+       assert( v != NULL );
+
+       u = strtoul( s, &next, x );
+       if ( next == s || next[ 0 ] != '\0' ) {
+               return -1;
+       }
+
+       if ( (unsigned long)(unsigned)u != u ) {
+               return 1;
+       }
+
+       *v = u;
+
+       return 0;
+}
+
+int
+lutil_atolx( long *v, const char *s, int x )
+{
+       char            *next;
+       long            l;
+
+       assert( s != NULL );
+       assert( v != NULL );
+
+       l = strtol( s, &next, x );
+       if ( next == s || next[ 0 ] != '\0' ) {
+               return -1;
+       }
+
+       *v = l;
+
+       return 0;
+}
+
+int
+lutil_atoulx( unsigned long *v, const char *s, int x )
+{
+       char            *next;
+       unsigned long   ul;
+
+       assert( s != NULL );
+       assert( v != NULL );
+
+       ul = strtoul( s, &next, x );
+       if ( next == s || next[ 0 ] != '\0' ) {
+               return -1;
+       }
+
+       *v = ul;
+
+       return 0;
+}
+
+static char            time_unit[] = "dhms";
+
+int
+lutil_parse_time(
+       const char      *in,
+       unsigned long   *tp )
+{
+       unsigned long   t = 0;
+       char            *s,
+                       *next;
+       int             sofar = -1,
+                       scale[] = { 86400, 3600, 60, 1 };
+
+       *tp = 0;
+
+       for ( s = (char *)in; s[ 0 ] != '\0'; ) {
+               unsigned long   u;
+               char            *what;
+
+               u = strtoul( s, &next, 10 );
+               if ( next == s ) {
+                       return -1;
+               }
+
+               if ( next[ 0 ] == '\0' ) {
+                       /* assume seconds */
+                       t += u;
+                       break;
+               }
+
+               what = strchr( time_unit, next[ 0 ] );
+               if ( what == NULL ) {
+                       return -1;
+               }
+
+               if ( what - time_unit <= sofar ) {
+                       return -1;
+               }
+
+               sofar = what - time_unit;
+               t += u * scale[ sofar ];
+
+               s = &next[ 1 ];
+       }
+
+       *tp = t;
+       return 0;
+}
+
+int
+lutil_unparse_time(
+       char                    *buf,
+       size_t                  buflen,
+       unsigned long           t )
+{
+       int             len, i;
+       unsigned long   v[ 4 ];
+       char            *ptr = buf;
+
+       v[ 0 ] = t/86400;
+       v[ 1 ] = (t%86400)/3600;
+       v[ 2 ] = (t%3600)/60;
+       v[ 3 ] = t%60;
+
+       for ( i = 0; i < 4; i++ ) {
+               if ( v[i] > 0 || ( i == 3 && ptr == buf ) ) {
+                       len = snprintf( ptr, buflen, "%lu%c", v[ i ], time_unit[ i ] );
+                       if ( len < 0 || (unsigned)len >= buflen ) {
+                               return -1;
+                       }
+                       buflen -= len;
+                       ptr += len;
+               }
+       }
+
+       return 0;
+}
+