Workshop o mikrokontrolérech na SKSP 2024.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
2.3 KiB

2 months ago
/*
* UCW Library -- Conversions of Strings to Numbers
*
* (c) 2010 Daniel Fiala <danfiala@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
*/
#include <ucw/lib.h>
#include <ucw/string.h>
#include <ucw/chartype.h>
#include <ucw/strtonum.h>
static uint detect_base(const char **pp, const uint flags)
{
if ((flags & STN_BASES0) && **pp == '0')
{
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;
}
}
return 0;
}
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
*sign = 0;
if (flags & (STN_SIGNS))
{
if (*p == '-' && (flags & STN_MINUS))
{
*sign = 1;
p++;
}
else if (*p == '+' && (flags & STN_PLUS))
p++;
}
*base = detect_base(&p, flags) ? : flags & STN_DBASES_MASK;
*pp = p;
return err;
}
static inline uint get_digit(const uint c)
{
if (c <= '9')
return c - '0';
else
{
const int a = c & 0xDF;
uint d = a - 'A';
d &= 0xFF;
d += 10;
return d;
}
}
#define STN_TYPE uint
#define STN_SUFFIX uint
#include <ucw/strtonum-gen.h>
#define STN_TYPE u32
#define STN_SUFFIX u32
#include <ucw/strtonum-gen.h>
#define STN_TYPE u64
#define STN_SUFFIX u64
#include <ucw/strtonum-gen.h>
#define STN_TYPE uintmax_t
#define STN_SUFFIX uintmax
#include <ucw/strtonum-gen.h>
// FIXME: For backward compatibility, will be removed soon
#define STN_TYPE uns
#define STN_SUFFIX uns
#include <ucw/strtonum-gen.h>