From: Bruno Haible Date: Tue, 31 Dec 2024 00:39:03 +0000 (+0100) Subject: mbfile: Allow 2 pushback characters. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=87ee7ef66ee5867e0b2c3797653cc16ae7a92e38;p=gnulib.git mbfile: Allow 2 pushback characters. * lib/mbfile.h: Include . (MBFILE_MAX_PUSHBACK): New macro. (struct mbfile_multi): Replace field 'have_pushback' with 'pushback_count'. Make field 'pushback' an array. (mbfile_multi_getc, mbfile_multi_ungetc): Handle multiple pushback characters. (mbf_init): Update. --- diff --git a/ChangeLog b/ChangeLog index dac48eccfd..fa02cafc98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2024-12-30 Bruno Haible + + mbfile: Allow 2 pushback characters. + * lib/mbfile.h: Include . + (MBFILE_MAX_PUSHBACK): New macro. + (struct mbfile_multi): Replace field 'have_pushback' with + 'pushback_count'. Make field 'pushback' an array. + (mbfile_multi_getc, mbfile_multi_ungetc): Handle multiple pushback + characters. + (mbf_init): Update. + 2024-12-30 Bruno Haible bcp47: Handle language variants. diff --git a/lib/mbfile.h b/lib/mbfile.h index fe83eb648b..b110aff229 100644 --- a/lib/mbfile.h +++ b/lib/mbfile.h @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -69,14 +70,17 @@ extern "C" { #endif +/* Guarantee two characters of pushback. */ +#define MBFILE_MAX_PUSHBACK 2 + struct mbfile_multi { FILE *fp; bool eof_seen; - bool have_pushback; + unsigned int pushback_count; /* <= MBFILE_MAX_PUSHBACK */ mbstate_t state; unsigned int bufcount; char buf[MBCHAR_BUF_SIZE]; - struct mbchar pushback; + struct mbchar pushback[MBFILE_MAX_PUSHBACK]; }; MBFILE_INLINE void @@ -91,10 +95,10 @@ mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) goto eof; /* Return character pushed back, if there is one. */ - if (mbf->have_pushback) + if (mbf->pushback_count > 0) { - mb_copy (mbc, &mbf->pushback); - mbf->have_pushback = false; + mb_copy (mbc, &mbf->pushback[mbf->pushback_count - 1]); + mbf->pushback_count--; return; } @@ -246,8 +250,10 @@ eof: MBFILE_INLINE void mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) { - mb_copy (&mbf->pushback, mbc); - mbf->have_pushback = true; + if (mbf->pushback_count == MBFILE_MAX_PUSHBACK) + abort (); + mb_copy (&mbf->pushback[mbf->pushback_count], mbc); + mbf->pushback_count++; } typedef struct mbfile_multi mb_file_t; @@ -257,7 +263,7 @@ typedef mbchar_t mbf_char_t; #define mbf_init(mbf, stream) \ ((mbf).fp = (stream), \ (mbf).eof_seen = false, \ - (mbf).have_pushback = false, \ + (mbf).pushback_count = 0, \ mbszero (&(mbf).state), \ (mbf).bufcount = 0)