X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=inline;f=ucw%2Fstrtonum.c;h=e8fa486445e0868175c24bd3ef34e8f91412e93a;hb=b8667492cf36a609939ee35ac42900ff0b0cc80f;hp=5a494165642413cfcfc3ba9711510271d4c12209;hpb=2c7483b13f06f97b8a3d98f27ebe5ebf003be1c2;p=libucw.git diff --git a/ucw/strtonum.c b/ucw/strtonum.c index 5a494165..e8fa4864 100644 --- a/ucw/strtonum.c +++ b/ucw/strtonum.c @@ -7,39 +7,48 @@ * of the GNU Lesser General Public License. */ -#include "ucw/lib.h" -#include "ucw/string.h" -#include "ucw/chartype.h" -#include "ucw/strtonum.h" +#include +#include +#include +#include -static const char err_numeric_overflow[] = "Numeric overflow"; -static const char err_no_digits[] = "Number contains no digits"; -static const char err_invalid_character[] = "Invalid character"; -static const char err_unknown_base[] = "Unknown base"; - -static uns detect_base(const char *p, const uns flags) +static uint detect_base(const char **pp, const uint flags) { - if ((flags & STN_BASES) && *p == '0') + if ((flags & STN_BASES0) && **pp == '0') { - switch (p[1] & 0xDF) + switch ( (*pp)[1] ) { + case 'x': case 'X': if (flags & STN_HEX) { + *pp += 2; return 16; } break; + case 'b': case 'B': if (flags & STN_BIN) { + *pp += 2; return 2; } break; + case 'o': case 'O': if (flags & STN_OCT) { + *pp += 2; + return 8; + } + break; + + case '0'...'7': + if (flags & STN_OCT0) + { + (*pp)++; return 8; } break; @@ -49,14 +58,14 @@ static uns detect_base(const char *p, const uns flags) return 0; } -static const char *str_to_num_init(const char **pp, const uns flags, uns *sign, uns *base) +static const char *str_to_num_init(const char **pp, const uint flags, uint *sign, uint *base) { ASSERT(*pp); const char *err = NULL; const char *p = *pp; - // Parse sign + // Parse sign *sign = 0; if (flags & (STN_SIGNS)) { @@ -69,41 +78,43 @@ static const char *str_to_num_init(const char **pp, const uns flags, uns *sign, p++; } - const uns prefix_base = detect_base(p, flags); - if (prefix_base) - { - p += 2; - *base = prefix_base; - } - else - { - *base = flags & STN_DBASES_MASK; - } + *base = detect_base(&p, flags) ? : flags & STN_DBASES_MASK; *pp = p; return err; } -static inline uns get_digit(const uns c) +static inline uint get_digit(const uint c) { if (c <= '9') - { - return c - '0'; - } + return c - '0'; else { const int a = c & 0xDF; - unsigned d = a - 'A'; + uint d = a - 'A'; d &= 0xFF; d += 10; return d; } } -#define STN_TYPE uns -#define STN_SUFFIX uns -#include "ucw/strtonum-gen.h" +#define STN_TYPE uint +#define STN_SUFFIX uint +#include + +#define STN_TYPE u32 +#define STN_SUFFIX u32 +#include + +#define STN_TYPE u64 +#define STN_SUFFIX u64 +#include #define STN_TYPE uintmax_t #define STN_SUFFIX uintmax -#include "ucw/strtonum-gen.h" +#include + +// FIXME: For backwards compatibility, will be removed soon +#define STN_TYPE uns +#define STN_SUFFIX uns +#include