From a61379f455b80236e251c56c32a16748f2d35af3 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sun, 31 Mar 2024 20:07:51 +0200 Subject: Remove the need for a state in freadrune() --- include/mbio.h | 8 +++----- lib/mbio/freadrune.c | 54 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/include/mbio.h b/include/mbio.h index ef2fcd5..80e703b 100644 --- a/include/mbio.h +++ b/include/mbio.h @@ -6,11 +6,9 @@ #include "__charN_t.h" #include "__rune.h" -typedef struct { - char8_t _buf[4]; - int _fill; -} u8_io_state; +int freadrune(rune *, FILE *); -int freadrune(rune *, u8_io_state *, FILE *); +constexpr rune MBEOF = 0x110000; +constexpr rune MBERR = 0x110001; #endif /* !MLIB_MBIOO_H */ diff --git a/lib/mbio/freadrune.c b/lib/mbio/freadrune.c index efa42b3..5c24f52 100644 --- a/lib/mbio/freadrune.c +++ b/lib/mbio/freadrune.c @@ -1,23 +1,49 @@ -#include #include #include +#include "macros.h" #include "mbio.h" #include "mbstring.h" +#include "rune.h" + +#define RETURN_INVAL \ + do { \ + *ch = RUNE_ERROR; \ + return 3; \ + } while (false) int -freadrune(rune *ch, u8_io_state *st, FILE *stream) +freadrune(rune *ch, FILE *stream) { - size_t n, need; - need = lengthof(st->_buf) - st->_fill; - st->_fill += n = fread(st->_buf + st->_fill, 1, need, stream); - if (n < need && ferror(stream)) - return -1; - if (st->_fill == 0) - return 0; - - int w = u8tor(ch, st->_buf); - memmove(st->_buf, st->_buf + w, lengthof(st->_buf) - w); - st->_fill -= w; - return w; + int c, n = 0; + char8_t buf[U8_LEN_MAX]; + + if ((c = fgetc(stream)) == EOF) + goto eof_or_err; + + buf[0] = (char8_t)c; + n = u8byte1(c) ? 0 : u8byte2(c) ? 1 : u8byte3(c) ? 2 : u8byte4(c) ? 3 : 4; + + if (n == 0) { + *ch = buf[0]; + return 1; + } else if (n == 4) + RETURN_INVAL; + + for (int i = 0; i < n; i++) { + if ((c = fgetc(stream)) == EOF) + goto eof_or_err; + if (!u8bytec(c)) + RETURN_INVAL; + buf[i + 1] = c; + } + + return u8tor(ch, buf); + +eof_or_err: + if (ferror(stream)) + return MBERR; + if (n == 0) + return MBEOF; + RETURN_INVAL; } -- cgit v1.2.3