diff --git a/src/stdio/_scanf.c b/src/stdio/_scanf.c index 3023ba8..ea7ad8e 100644 --- a/src/stdio/_scanf.c +++ b/src/stdio/_scanf.c @@ -1,13 +1,52 @@ #include <_libc/stdio.h> +#include #include int __libc_vscanf(const char *format, void *ctx, int (*in)(void *ctx), va_list ap) { - (void) format; - (void) ctx; - (void) in; - (void) ap; - return -1; + size_t n_convert = 0; + union { + uint64_t value_unsigned; + } pv; + char ch; + int ic; + + while ((ch = *format)) { + if (isspace(ch)) { + // Skip whitespace + } else if (ch == '%') { + // Conversion spec + ch = *++format; + + switch (ch) { + case 'u': + pv.value_unsigned = 0; + while ((ic = in(ctx)) != EOF && isdigit(ic)) { + pv.value_unsigned *= 10; + pv.value_unsigned += ic - '0'; + } + *((unsigned int *) va_arg(ap, unsigned int *)) = pv.value_unsigned; + ++n_convert; + ++format; + break; + default: + goto err; + } + } else { + ic = in(ctx); + + if (ic == EOF) { + goto err; + } + } + ++format; + } + +err: + if (!n_convert) { + return -1; + } + return n_convert; } diff --git a/src/stdio/fgetc_unlocked.c b/src/stdio/fgetc_unlocked.c index a77dfb2..bcf5535 100644 --- a/src/stdio/fgetc_unlocked.c +++ b/src/stdio/fgetc_unlocked.c @@ -12,12 +12,12 @@ int fgetc_unlocked(FILE *fp) { } if (fp->flags & FILE_FLAG_EOF) { - return 0; + return EOF; } if (!(fp->flags & FILE_MODE_READ)) { errno = EBADF; fp->flags |= FILE_FLAG_ERROR; - return 0; + return EOF; } __libc_file_flush_write(fp); diff --git a/src/stdio/fgets_unlocked.c b/src/stdio/fgets_unlocked.c index 3f47a21..fbe2ae0 100644 --- a/src/stdio/fgets_unlocked.c +++ b/src/stdio/fgets_unlocked.c @@ -1,3 +1,4 @@ +#include #include char *fgets_unlocked(char *buf, int len, FILE *fp) { @@ -23,7 +24,11 @@ char *fgets_unlocked(char *buf, int len, FILE *fp) { } if (off) { + ygg_debug_trace("fgets -> %d\n", off); buf[off] = 0; + for (size_t i = 0; i < off; ++i) { + ygg_debug_trace("buf[%d] = 0x%x\n", i, buf[i]); + } return buf; } else { return NULL; diff --git a/src/stdio/file.c b/src/stdio/file.c index e7baf95..6d19b1f 100644 --- a/src/stdio/file.c +++ b/src/stdio/file.c @@ -20,6 +20,7 @@ FILE *__libc_file_create(void) { res->free = file_default_free; res->buf = ((void *) res) + sizeof(FILE); + res->ungetc = -1; return res; } @@ -43,9 +44,8 @@ int __libc_file_mode(const char *mode) { } int __libc_file_flush_read(FILE *fp) { + fp->ungetc = -1; if ((fp->flags & FILE_MODE_READ) && fp->seek) { - // Flush ungetc buffer - fp->ungetc = -1; // TODO: off_t long count = fp->rdbuf - fp->rdbufpos; if (count < 0) { diff --git a/src/stdio/file_file.c b/src/stdio/file_file.c index 06bcb51..780c47e 100644 --- a/src/stdio/file_file.c +++ b/src/stdio/file_file.c @@ -17,6 +17,7 @@ FILE _stdin = { .buf_mode = _IOLBF, .ctx = &_stdin, .fd = STDIN_FILENO, + .ungetc = -1, .free = NULL, .read = file_read, .write = file_write, diff --git a/src/stdio/puts.c b/src/stdio/puts.c new file mode 100644 index 0000000..bb5b51d --- /dev/null +++ b/src/stdio/puts.c @@ -0,0 +1,15 @@ +#include + +int puts(const char *s) { + flockfile(stdout); + if (fputs(s, stdout) != 0) { + funlockfile(stdout); + return EOF; + } + if (fputc('\n', stdout) == EOF) { + funlockfile(stdout); + return EOF; + } + funlockfile(stdout); + return 0; +}