summaryrefslogtreecommitdiff
path: root/src/stdio/vswscanf.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-04-17 14:19:46 -0400
committerRich Felker <dalias@aerifal.cx>2012-04-17 14:19:46 -0400
commit73ec1d0495bb676012fd69491900ca8beb989ef7 (patch)
tree5cd15ae1c3b430b7703cdb919a09998f1ffa8577 /src/stdio/vswscanf.c
parent8b57a81577980e4b440addaa8f2bbed454be2a59 (diff)
downloadmusl-73ec1d0495bb676012fd69491900ca8beb989ef7.tar.gz
introduce new wide scanf code and remove the last remnants of old scanf
at this point, strto* and all scanf family functions are using the new unified integer and floating point parser/converter code. the wide scanf is largely a wrapper for ordinary byte-based scanf; since numbers can only contain ascii characters, only strings need to be handled specially.
Diffstat (limited to 'src/stdio/vswscanf.c')
-rw-r--r--src/stdio/vswscanf.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/stdio/vswscanf.c b/src/stdio/vswscanf.c
index 2c4ffbe0..4396d7df 100644
--- a/src/stdio/vswscanf.c
+++ b/src/stdio/vswscanf.c
@@ -1,19 +1,35 @@
-#include <stdio.h>
-#include <string.h>
-#include <wchar.h>
-#include <wctype.h>
+#include "stdio_impl.h"
-#include "__scanf.h"
-
-static void s_read(rctx_t *r)
+static size_t wstring_read(FILE *f, unsigned char *buf, size_t len)
{
- wchar_t *s = r->opaque;
- if (!s[r->l]) r->c = -1;
- else r->c = s[r->l++];
+ const wchar_t *src = f->cookie;
+ size_t k;
+
+ if (!src) return 0;
+
+ k = wcsrtombs((void *)f->buf, &src, f->buf_size, 0);
+ if (k==(size_t)-1) {
+ f->rpos = f->rend = 0;
+ return 0;
+ }
+
+ f->rpos = f->buf;
+ f->rend = f->buf + k;
+ f->cookie = (void *)src;
+
+ if (!len) return 0;
+
+ *buf = *f->rpos++;
+ return 1;
}
int vswscanf(const wchar_t *s, const wchar_t *fmt, va_list ap)
{
- rctx_t r = { s_read, (void *)s, 1, iswspace };
- return __scanf(&r, fmt, ap);
+ unsigned char buf[256];
+ FILE f = {
+ .buf = buf, .buf_size = sizeof buf,
+ .cookie = (void *)s,
+ .read = wstring_read, .lock = -1
+ };
+ return vfwscanf(&f, fmt, ap);
}