aboutsummaryrefslogtreecommitdiff
path: root/system/lib/libc/musl/src/stdlib
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-01-15 17:01:19 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-01-15 17:01:19 -0800
commitc42b937808924f6b922b29d2e0fd1fe1d1b0411c (patch)
tree4027d435b6638a7e72b9519990298fb9314ecc96 /system/lib/libc/musl/src/stdlib
parent8478d6aee54d6c52de16d8c58309534afbf5bf9e (diff)
parente5ccf17e84e7a5102bf9e05ffef01e6672b4c15a (diff)
Merge branch 'incoming'
Diffstat (limited to 'system/lib/libc/musl/src/stdlib')
-rw-r--r--system/lib/libc/musl/src/stdlib/atof.c6
-rw-r--r--system/lib/libc/musl/src/stdlib/strtod.c52
-rw-r--r--system/lib/libc/musl/src/stdlib/wcstod.c64
-rw-r--r--system/lib/libc/musl/src/stdlib/wcstol.c82
4 files changed, 204 insertions, 0 deletions
diff --git a/system/lib/libc/musl/src/stdlib/atof.c b/system/lib/libc/musl/src/stdlib/atof.c
new file mode 100644
index 00000000..f7fcd826
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/atof.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+double atof(const char *s)
+{
+ return strtod(s, 0);
+}
diff --git a/system/lib/libc/musl/src/stdlib/strtod.c b/system/lib/libc/musl/src/stdlib/strtod.c
new file mode 100644
index 00000000..35f640da
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/strtod.c
@@ -0,0 +1,52 @@
+#include <stdlib.h>
+#include "shgetc.h"
+#include "floatscan.h"
+#include "stdio_impl.h"
+#include "libc.h"
+
+static long double strtox(const char *s, char **p, int prec)
+{
+ FILE f = {
+ .buf = (void *)s, .rpos = (void *)s,
+ .rend = (void *)-1, .lock = -1
+ };
+ shlim(&f, 0);
+ long double y = __floatscan(&f, prec, 1);
+ off_t cnt = shcnt(&f);
+ if (p) *p = cnt ? (char *)s + cnt : (char *)s;
+ return y;
+}
+
+float strtof(const char *restrict s, char **restrict p)
+{
+ return strtox(s, p, 0);
+}
+
+double strtod(const char *restrict s, char **restrict p)
+{
+ return strtox(s, p, 1);
+}
+
+long double strtold(const char *restrict s, char **restrict p)
+{
+ return strtox(s, p, 2);
+}
+
+float strtof_l(const char *restrict s, char **restrict p, struct __locale_struct *loc)
+{
+ return strtof(s, p);
+}
+
+double strtod_l(const char *restrict s, char **restrict p, struct __locale_struct *loc)
+{
+ return strtod(s, p);
+}
+
+long double strtold_l(const char *restrict s, char **restrict p, struct __locale_struct *loc)
+{
+ return strtold(s, p);
+}
+
+weak_alias(strtof_l, __strtof_l);
+weak_alias(strtod_l, __strtod_l);
+weak_alias(strtold_l, __strtold_l);
diff --git a/system/lib/libc/musl/src/stdlib/wcstod.c b/system/lib/libc/musl/src/stdlib/wcstod.c
new file mode 100644
index 00000000..83f308d3
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/wcstod.c
@@ -0,0 +1,64 @@
+#include "shgetc.h"
+#include "floatscan.h"
+#include "stdio_impl.h"
+#include <wctype.h>
+
+/* This read function heavily cheats. It knows:
+ * (1) len will always be 1
+ * (2) non-ascii characters don't matter */
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+ size_t i;
+ const wchar_t *wcs = f->cookie;
+
+ if (!wcs[0]) wcs=L"@";
+ for (i=0; i<f->buf_size && wcs[i]; i++)
+ f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
+ f->rpos = f->buf;
+ f->rend = f->buf + i;
+ f->cookie = (void *)(wcs+i);
+
+ if (i && len) {
+ *buf = *f->rpos++;
+ return 1;
+ }
+ return 0;
+}
+
+static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
+{
+ wchar_t *t = (wchar_t *)s;
+ unsigned char buf[64];
+ FILE f = {0};
+ f.flags = 0;
+ f.rpos = f.rend = 0;
+ f.buf = buf + 4;
+ f.buf_size = sizeof buf - 4;
+ f.lock = -1;
+ f.read = do_read;
+ while (iswspace(*t)) t++;
+ f.cookie = (void *)t;
+ shlim(&f, 0);
+ long double y = __floatscan(&f, prec, 1);
+ if (p) {
+ size_t cnt = shcnt(&f);
+ *p = cnt ? t + cnt : (wchar_t *)s;
+ }
+ return y;
+}
+
+float wcstof(const wchar_t *restrict s, wchar_t **restrict p)
+{
+ return wcstox(s, p, 0);
+}
+
+double wcstod(const wchar_t *restrict s, wchar_t **restrict p)
+{
+ return wcstox(s, p, 1);
+}
+
+long double wcstold(const wchar_t *restrict s, wchar_t **restrict p)
+{
+ return wcstox(s, p, 2);
+}
diff --git a/system/lib/libc/musl/src/stdlib/wcstol.c b/system/lib/libc/musl/src/stdlib/wcstol.c
new file mode 100644
index 00000000..4443f577
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/wcstol.c
@@ -0,0 +1,82 @@
+#include "stdio_impl.h"
+#include "intscan.h"
+#include "shgetc.h"
+#include <inttypes.h>
+#include <limits.h>
+#include <wctype.h>
+#include <wchar.h>
+
+/* This read function heavily cheats. It knows:
+ * (1) len will always be 1
+ * (2) non-ascii characters don't matter */
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+ size_t i;
+ const wchar_t *wcs = f->cookie;
+
+ if (!wcs[0]) wcs=L"@";
+ for (i=0; i<f->buf_size && wcs[i]; i++)
+ f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
+ f->rpos = f->buf;
+ f->rend = f->buf + i;
+ f->cookie = (void *)(wcs+i);
+
+ if (i && len) {
+ *buf = *f->rpos++;
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim)
+{
+ wchar_t *t = (wchar_t *)s;
+ unsigned char buf[64];
+ FILE f = {0};
+ f.flags = 0;
+ f.rpos = f.rend = 0;
+ f.buf = buf + 4;
+ f.buf_size = sizeof buf - 4;
+ f.lock = -1;
+ f.read = do_read;
+ while (iswspace(*t)) t++;
+ f.cookie = (void *)t;
+ shlim(&f, 0);
+ unsigned long long y = __intscan(&f, base, 1, lim);
+ if (p) {
+ size_t cnt = shcnt(&f);
+ *p = cnt ? t + cnt : (wchar_t *)s;
+ }
+ return y;
+}
+
+unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+ return wcstox(s, p, base, ULLONG_MAX);
+}
+
+long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+ return wcstox(s, p, base, LLONG_MIN);
+}
+
+unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+ return wcstox(s, p, base, ULONG_MAX);
+}
+
+long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+ return wcstox(s, p, base, 0UL+LONG_MIN);
+}
+
+intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+ return wcstoll(s, p, base);
+}
+
+uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+ return wcstoull(s, p, base);
+}