musl - musl - an implementation of the standard library for Linux-based systems

index : musl
musl - an implementation of the standard library for Linux-based systems
summary refs log tree commit diff
path: root/src/stdlib/wcstoimax.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011年07月14日 00:51:45 -0400
committerRich Felker <dalias@aerifal.cx>2011年07月14日 00:51:45 -0400
commitecc9c5fcfa4831b290cc1a63c0346cbb0c1fcf42 (patch)
tree2fb20d623af9622cb8ac9f461e542ca23fc6d791 /src/stdlib/wcstoimax.c
parent0e2331c9b6e0c0b4f24019d4062f4c655d28cbaf (diff)
downloadmusl-ecc9c5fcfa4831b290cc1a63c0346cbb0c1fcf42.tar.gz
new restartable integer parsing framework.
this fixes a number of bugs in integer parsing due to lazy haphazard wrapping, as well as some misinterpretations of the standard. the new parser is able to work character-at-a-time or on whole strings, making it easy to support the wide functions without unbounded space for conversion. it will also be possible to update scanf to use the new parser.
Diffstat (limited to 'src/stdlib/wcstoimax.c')
-rw-r--r--src/stdlib/wcstoimax.c 36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/stdlib/wcstoimax.c b/src/stdlib/wcstoimax.c
index 59894f60..b83206b7 100644
--- a/src/stdlib/wcstoimax.c
+++ b/src/stdlib/wcstoimax.c
@@ -2,24 +2,38 @@
#include <wctype.h>
#include <inttypes.h>
#include <errno.h>
+#include "intparse.h"
intmax_t wcstoimax(const wchar_t *s, wchar_t **p, int base)
{
- int sign = 0;
- uintmax_t x;
+ struct intparse ip = {0};
+ unsigned char tmp;
+
+ if (p) *p = (wchar_t *)s;
+
+ if (base && base-2U > 34) {
+ errno = EINVAL;
+ return 0;
+ }
- /* Initial whitespace */
for (; iswspace(*s); s++);
- /* Optional sign */
- if (*s == '-') sign = *s++;
- else if (*s == '+') s++;
+ ip.base = base;
+ for (; *s<256 && (tmp=*s, __intparse(&ip, &tmp, 1)); s++);
+
+ if (p && ip.err != EINVAL)
+ *p = (wchar_t *)s;
+
+ if (ip.err) {
+ errno = ip.err;
+ if (ip.err = EINVAL) return 0;
+ return ip.neg ? INTMAX_MIN : INTMAX_MAX;
+ }
- x = wcstoumax(s, p, base);
- if (x > INTMAX_MAX) {
- if (!sign || -x != INTMAX_MIN)
+ if (ip.val > INTMAX_MAX) {
+ if (!ip.neg || -ip.val != INTMAX_MIN)
errno = ERANGE;
- return sign ? INTMAX_MIN : INTMAX_MAX;
+ return ip.neg ? INTMAX_MIN : INTMAX_MAX;
}
- return sign ? -x : x;
+ return ip.neg ? -ip.val : ip.val;
}
generated by cgit v1.2.1 (git 2.18.0) at 2025年09月29日 20:58:40 +0000

AltStyle によって変換されたページ (->オリジナル) /