return 0;
}
-/* Just like virStrToLong_i, above, but produce an "unsigned int" value. */
+/* Just like virStrToLong_i, above, but produce an "unsigned int"
+ * value. This version allows twos-complement wraparound of negative
+ * numbers. */
int
virStrToLong_ui(char const *s, char **end_ptr, int base, unsigned int *result)
{
return 0;
}
+/* Just like virStrToLong_i, above, but produce an "unsigned int"
+ * value. This version rejects any negative signs. */
+int
+virStrToLong_uip(char const *s, char **end_ptr, int base, unsigned int *result)
+{
+ unsigned long int val;
+ char *p;
+ bool err = false;
+
+ errno = 0;
+ val = strtoul(s, &p, base); /* exempt from syntax-check */
+ err = (memchr(s, '-', p - s) ||
+ errno || (!end_ptr && *p) || p == s || (unsigned int) val != val);
+ if (end_ptr)
+ *end_ptr = p;
+ if (err)
+ return -1;
+ *result = val;
+ return 0;
+}
+
/* Just like virStrToLong_i, above, but produce a "long" value. */
int
virStrToLong_l(char const *s, char **end_ptr, int base, long *result)
return 0;
}
-/* Just like virStrToLong_i, above, but produce an "unsigned long" value. */
+/* Just like virStrToLong_i, above, but produce an "unsigned long"
+ * value. This version allows twos-complement wraparound of negative
+ * numbers. */
int
virStrToLong_ul(char const *s, char **end_ptr, int base, unsigned long *result)
{
return 0;
}
+/* Just like virStrToLong_i, above, but produce an "unsigned long"
+ * value. This version rejects any negative signs. */
+int
+virStrToLong_ulp(char const *s, char **end_ptr, int base,
+ unsigned long *result)
+{
+ unsigned long int val;
+ char *p;
+ int err;
+
+ errno = 0;
+ val = strtoul(s, &p, base); /* exempt from syntax-check */
+ err = (memchr(s, '-', p - s) ||
+ errno || (!end_ptr && *p) || p == s);
+ if (end_ptr)
+ *end_ptr = p;
+ if (err)
+ return -1;
+ *result = val;
+ return 0;
+}
+
/* Just like virStrToLong_i, above, but produce a "long long" value. */
int
virStrToLong_ll(char const *s, char **end_ptr, int base, long long *result)
return 0;
}
-/* Just like virStrToLong_i, above, but produce an "unsigned long long" value. */
+/* Just like virStrToLong_i, above, but produce an "unsigned long
+ * long" value. This version allows twos-complement wraparound of
+ * negative numbers. */
int
-virStrToLong_ull(char const *s, char **end_ptr, int base, unsigned long long *result)
+virStrToLong_ull(char const *s, char **end_ptr, int base,
+ unsigned long long *result)
{
unsigned long long val;
char *p;
return 0;
}
+/* Just like virStrToLong_i, above, but produce an "unsigned long
+ * long" value. This version rejects any negative signs. */
+int
+virStrToLong_ullp(char const *s, char **end_ptr, int base,
+ unsigned long long *result)
+{
+ unsigned long long val;
+ char *p;
+ int err;
+
+ errno = 0;
+ val = strtoull(s, &p, base); /* exempt from syntax-check */
+ err = (memchr(s, '-', p - s) ||
+ errno || (!end_ptr && *p) || p == s);
+ if (end_ptr)
+ *end_ptr = p;
+ if (err)
+ return -1;
+ *result = val;
+ return 0;
+}
+
int
virStrToDouble(char const *s,
char **end_ptr,
/*
- * Copyright (C) 2007-2012 Red Hat, Inc.
+ * Copyright (C) 2007-2014 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
char **end_ptr,
int base,
unsigned int *result);
+int virStrToLong_uip(char const *s,
+ char **end_ptr,
+ int base,
+ unsigned int *result);
int virStrToLong_l(char const *s,
char **end_ptr,
int base,
char **end_ptr,
int base,
unsigned long *result);
+int virStrToLong_ulp(char const *s,
+ char **end_ptr,
+ int base,
+ unsigned long *result);
int virStrToLong_ll(char const *s,
char **end_ptr,
int base,
char **end_ptr,
int base,
unsigned long long *result);
+int virStrToLong_ullp(char const *s,
+ char **end_ptr,
+ int base,
+ unsigned long long *result);
int virStrToDouble(char const *s,
char **end_ptr,
double *result);
char *end;
long l;
unsigned long ul;
+ bool negative;
+
+ if (data->suffix)
+ negative = !!memchr(data->str, '-',
+ strlen(data->str) - strlen(data->suffix));
+ else
+ negative = !!strchr(data->str, '-');
#define TEST_ONE(Str, Suff, Type, Fn, Fmt, Exp, Exp_ret) \
do { \
data->si, data->si_ret);
TEST_ONE(data->str, data->suffix, unsigned int, ui, "%u",
data->ui, data->ui_ret);
+ if (negative)
+ TEST_ONE(data->str, data->suffix, unsigned int, uip, "%u", 0U, -1);
+ else
+ TEST_ONE(data->str, data->suffix, unsigned int, uip, "%u",
+ data->ui, data->ui_ret);
/* We hate adding new API with 'long', and prefer 'int' or 'long
* long' instead, since platform-specific results are evil */
ul = (sizeof(int) == sizeof(long)) ? data->ui : data->ull;
TEST_ONE(data->str, data->suffix, unsigned long, ul, "%lu",
ul, (sizeof(int) == sizeof(long)) ? data->ui_ret : data->ull_ret);
+ if (negative)
+ TEST_ONE(data->str, data->suffix, unsigned long, ulp, "%lu", 0UL, -1);
+ else
+ TEST_ONE(data->str, data->suffix, unsigned long, ulp, "%lu", ul,
+ (sizeof(int) == sizeof(long)) ? data->ui_ret : data->ull_ret);
TEST_ONE(data->str, data->suffix, long long, ll, "%lld",
data->ll, data->ll_ret);
TEST_ONE(data->str, data->suffix, unsigned long long, ull, "%llu",
data->ull, data->ull_ret);
+ if (negative)
+ TEST_ONE(data->str, data->suffix, unsigned long long, ullp, "%llu",
+ 0ULL, -1);
+ else
+ TEST_ONE(data->str, data->suffix, unsigned long long, ullp, "%llu",
+ data->ull, data->ull_ret);
#undef TEST_ONE