+2024-12-30 Bruno Haible <bruno@clisp.org>
+
+ mbfile: Allow 2 pushback characters.
+ * lib/mbfile.h: Include <stdlib.h>.
+ (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 <bruno@clisp.org>
bcp47: Handle language variants.
#include <assert.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#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
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;
}
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;
#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)