/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "strnum.h"
{
return FALSE;
return FALSE;
str++;
}
return TRUE;
}
{
return FALSE;
if (*str == '.') {
str++;
/* enforce that number follows dot */
continue;
}
return FALSE;
str++;
}
return num_seen;
}
/*
* Unsigned decimal
*/
{ \
uintmax_t l; \
return -1; \
return 0; \
}
STR_PARSE_U__TEMPLATE(str_parse_uint, unsigned int)
STR_PARSE_U__TEMPLATE(str_parse_ulong, unsigned long)
STR_PARSE_U__TEMPLATE(str_parse_ullong, unsigned long long)
{ \
uintmax_t l; \
return -1; \
return 0; \
}
STR_TO_U__TEMPLATE(str_to_uint, unsigned int)
STR_TO_U__TEMPLATE(str_to_ulong, unsigned long)
STR_TO_U__TEMPLATE(str_to_ullong, unsigned long long)
const char **endp_r)
{
uintmax_t n = 0;
return -1;
do {
return -1;
return -1;
}
str++;
*num_r = n;
return 0;
}
{
const char *endp;
uintmax_t n;
return -1;
*num_r = n;
return 0;
}
{
uintmax_t l;
if (str_to_uintmax(str, &l) < 0)
return FALSE;
return l == num;
}
/*
* Unsigned hexadecimal
*/
{ \
uintmax_t l; \
return -1; \
return 0; \
}
STR_PARSE_UHEX__TEMPLATE(str_parse_uint_hex, unsigned int)
STR_PARSE_UHEX__TEMPLATE(str_parse_ulong_hex, unsigned long)
STR_PARSE_UHEX__TEMPLATE(str_parse_ullong_hex, unsigned long long)
{ \
uintmax_t l; \
return -1; \
return 0; \
}
STR_TO_UHEX__TEMPLATE(str_to_uint_hex, unsigned int)
STR_TO_UHEX__TEMPLATE(str_to_ulong_hex, unsigned long)
STR_TO_UHEX__TEMPLATE(str_to_ullong_hex, unsigned long long)
unsigned int *hex_r)
{
switch (ch) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
return 0;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
return 0;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return 0;
default:
break;
}
return -1;
}
const char **endp_r)
{
unsigned int hex;
uintmax_t n = 0;
return -1;
do {
return -1;
n = (n << 4) + hex;
str++;
*num_r = n;
return 0;
}
{
const char *endp;
uintmax_t n;
return -1;
*num_r = n;
return 0;
}
/*
* Unsigned octal
*/
{ \
uintmax_t l; \
return -1; \
return 0; \
}
STR_PARSE_UOCT__TEMPLATE(str_parse_uint_oct, unsigned int)
STR_PARSE_UOCT__TEMPLATE(str_parse_ulong_oct, unsigned long)
STR_PARSE_UOCT__TEMPLATE(str_parse_ullong_oct, unsigned long long)
{ \
uintmax_t l; \
return -1; \
return 0; \
}
STR_TO_UOCT__TEMPLATE(str_to_uint_oct, unsigned int)
STR_TO_UOCT__TEMPLATE(str_to_ulong_oct, unsigned long)
STR_TO_UOCT__TEMPLATE(str_to_ullong_oct, unsigned long long)
const char **endp_r)
{
uintmax_t n = 0;
return -1;
return -1;
}
*num_r = n;
return 0;
}
{
const char *endp;
uintmax_t n;
return -1;
*num_r = n;
return 0;
}
/*
* Signed
*/
{ \
intmax_t l; \
return -1; \
return -1; \
return 0; \
}
{ \
intmax_t l; \
if (str_to_intmax(str, &l) < 0) \
return -1; \
return -1; \
return 0; \
}
const char **endp_r)
{
uintmax_t l;
if (*str == '-') {
str++;
}
return -1;
if (!neg) {
if (l > INTMAX_MAX)
return -1;
} else {
return -1;
}
return 0;
}
{
const char *endp;
intmax_t n;
return -1;
*num_r = n;
return 0;
}
/*
* Special numeric types
*/
{
unsigned int result_bits;
/* we assume that result is a signed type,
but that it can never be negative */
if ((l >> result_bits) != 0)
return -1;
return 0;
}
{
uintmax_t l;
if (str_to_uintmax(str, &l) < 0)
return -1;
if (verify_xid(l, sizeof(*num_r)) < 0)
return -1;
return 0;
}
{
uintmax_t l;
if (str_to_uintmax(str, &l) < 0)
return -1;
/* OS X uses negative GIDs */
#ifndef __APPLE__
if (verify_xid(l, sizeof(*num_r)) < 0)
return -1;
#endif
return 0;
}
{
uintmax_t l;
if (str_to_uintmax(str, &l) < 0)
return -1;
if (verify_xid(l, sizeof(*num_r)) < 0)
return -1;
return 0;
}
{
uintmax_t l;
if (str_to_uintmax(str, &l) < 0)
return -1;
if (verify_xid(l, sizeof(*num_r)) < 0)
return -1;
return 0;
}
{
uintmax_t l;
if (str_to_uintmax(str, &l) < 0)
return -1;
if (l > (uoff_t)-1)
return -1;
return 0;
}
{
intmax_t l;
if (str_to_intmax(str, &l) < 0)
return -1;
return 0;
}
/*
* Error handling
*/
const char *str_num_error(const char *str)
{
if (*str == '-') {
return "Not a valid number";
return "Number too small";
} else {
return "Not a valid number";
return "Number too large";
}
}