From 0c0873803d1428718b485fdbc19837ab97aa04d9 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 12 Aug 2010 23:32:37 +0000 Subject: [PATCH] add parsing support for [unsigned] long long (ITS#6622) --- configure | 4 +- configure.in | 1 + include/lutil.h | 14 +++++ include/portable.hin | 3 + libraries/liblutil/utils.c | 112 +++++++++++++++++++++++++++++++++++-- 5 files changed, 128 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 1f2974ce07..fbcd91451f 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.704 2009/09/29 21:53:43 hyc Exp . +# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.705 2010/04/13 20:17:30 kurt Exp . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61. # @@ -37034,6 +37034,7 @@ fi + for ac_func in \ @@ -37084,6 +37085,7 @@ for ac_func in \ strtoq \ strtouq \ strtoll \ + strtoull \ strspn \ sysconf \ waitpid \ diff --git a/configure.in b/configure.in index 4e8302f68a..56c3f7701d 100644 --- a/configure.in +++ b/configure.in @@ -2458,6 +2458,7 @@ AC_CHECK_FUNCS( \ strtoq \ strtouq \ strtoll \ + strtoull \ strspn \ sysconf \ waitpid \ diff --git a/include/lutil.h b/include/lutil.h index e078aaef88..a0dd1166c8 100644 --- a/include/lutil.h +++ b/include/lutil.h @@ -299,6 +299,20 @@ lutil_atoulx( unsigned long *v, const char *s, int x ); #define lutil_atol(v, s) lutil_atolx((v), (s), 10) #define lutil_atoul(v, s) lutil_atoulx((v), (s), 10) +#ifdef HAVE_LONG_LONG +#if defined(HAVE_STRTOLL) || defined(HAVE_STRTOQ) +LDAP_LUTIL_F (int) +lutil_atollx( long long *v, const char *s, int x ); +#define lutil_atoll(v, s) lutil_atollx((v), (s), 10) +#endif /* HAVE_STRTOLL || HAVE_STRTOQ */ + +#if defined(HAVE_STRTOULL) || defined(HAVE_STRTOUQ) +LDAP_LUTIL_F (int) +lutil_atoullx( unsigned long long *v, const char *s, int x ); +#define lutil_atoull(v, s) lutil_atoullx((v), (s), 10) +#endif /* HAVE_STRTOULL || HAVE_STRTOUQ */ +#endif /* HAVE_LONG_LONG */ + LDAP_LUTIL_F (int) lutil_str2bin( struct berval *in, struct berval *out, void *ctx ); diff --git a/include/portable.hin b/include/portable.hin index 56f8178129..900de8a261 100644 --- a/include/portable.hin +++ b/include/portable.hin @@ -610,6 +610,9 @@ /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL +/* Define to 1 if you have the `strtoull' function. */ +#undef HAVE_STRTOULL + /* Define to 1 if you have the `strtouq' function. */ #undef HAVE_STRTOUQ diff --git a/libraries/liblutil/utils.c b/libraries/liblutil/utils.c index 65a0980a20..303610dc95 100644 --- a/libraries/liblutil/utils.c +++ b/libraries/liblutil/utils.c @@ -15,6 +15,7 @@ #include "portable.h" +#include #include #include #include @@ -514,17 +515,28 @@ lutil_atoux( unsigned *v, const char *s, int x ) int lutil_atolx( long *v, const char *s, int x ) { - char *next; - long l; + char *next; + long l; + int save_errno; assert( s != NULL ); assert( v != NULL ); + if ( isspace( s[ 0 ] ) ) { + return -1; + } + + errno = 0; l = strtol( s, &next, x ); + save_errno = errno; if ( next == s || next[ 0 ] != '\0' ) { return -1; } + if ( ( l == LONG_MIN || l == LONG_MAX ) && save_errno != 0 ) { + return -1; + } + *v = l; return 0; @@ -533,27 +545,117 @@ lutil_atolx( long *v, const char *s, int x ) int lutil_atoulx( unsigned long *v, const char *s, int x ) { - char *next; - unsigned long ul; + char *next; + unsigned long ul; + int save_errno; assert( s != NULL ); assert( v != NULL ); /* strtoul() has an odd interface */ - if ( s[ 0 ] == '-' ) { + if ( s[ 0 ] == '-' || isspace( s[ 0 ] ) ) { return -1; } + errno = 0; ul = strtoul( s, &next, x ); + save_errno = errno; if ( next == s || next[ 0 ] != '\0' ) { return -1; } +//#ifdef ULONG_MAX + if ( ( ul == 0 || ul == ULONG_MAX ) && save_errno != 0 ) { + return -1; + } +//#endif /* ULONG_MAX */ + *v = ul; return 0; } +#ifdef HAVE_LONG_LONG +#if defined(HAVE_STRTOLL) || defined(HAVE_STRTOQ) +int +lutil_atollx( long long *v, const char *s, int x ) +{ + char *next; + long long ll; + int save_errno; + + assert( s != NULL ); + assert( v != NULL ); + + if ( isspace( s[ 0 ] ) ) { + return -1; + } + + errno = 0; +#ifdef HAVE_STRTOLL + ll = strtoll( s, &next, x ); +#else /* HAVE_STRTOQ */ + ll = (unsigned long long)strtoq( s, &next, x ); +#endif /* HAVE_STRTOQ */ + save_errno = errno; + if ( next == s || next[ 0 ] != '\0' ) { + return -1; + } + + /* LLONG_MIN, LLONG_MAX are C99 only */ +#if defined (LLONG_MIN) && defined(LLONG_MAX) + if ( ( ll == LLONG_MIN || ll == LLONG_MAX ) && save_errno != 0 ) { + return -1; + } +#endif /* LLONG_MIN && LLONG_MAX */ + + *v = ll; + + return 0; +} +#endif /* HAVE_STRTOLL || HAVE_STRTOQ */ + +#if defined(HAVE_STRTOULL) || defined(HAVE_STRTOUQ) +int +lutil_atoullx( unsigned long long *v, const char *s, int x ) +{ + char *next; + unsigned long long ull; + int save_errno; + + assert( s != NULL ); + assert( v != NULL ); + + /* strtoull() has an odd interface */ + if ( s[ 0 ] == '-' || isspace( s[ 0 ] ) ) { + return -1; + } + + errno = 0; +#ifdef HAVE_STRTOULL + ull = strtoull( s, &next, x ); +#else /* HAVE_STRTOUQ */ + ull = (unsigned long long)strtouq( s, &next, x ); +#endif /* HAVE_STRTOUQ */ + save_errno = errno; + if ( next == s || next[ 0 ] != '\0' ) { + return -1; + } + + /* ULLONG_MAX is C99 only */ +#if defined(ULLONG_MAX) + if ( ( ull == 0 || ull == ULLONG_MAX ) && save_errno != 0 ) { + return -1; + } +#endif /* ULLONG_MAX */ + + *v = ull; + + return 0; +} +#endif /* HAVE_STRTOULL || HAVE_STRTOUQ */ +#endif /* HAVE_LONG_LONG */ + /* Multiply an integer by 100000000 and add new */ typedef struct lutil_int_decnum { unsigned char *buf; -- 2.39.5