scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 0f88acf52504636f56b73132285c7355b1beb0af
parent 84128eaf37e33fed023f271018b157b7398ad91c
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Mon,  5 Jan 2026 20:24:01 +0100

libc: Include a mbstate_t in FILE

Several of the file operations related to wchar require
a mbstate_t, and every stream should have its own mbstate_t
and not using the hidden state of several of the conversion
functions.

Diffstat:
Minclude/scc/bits/amd64/arch/cdefs.h | 9+++------
Minclude/scc/bits/arm/arch/cdefs.h | 9+++------
Minclude/scc/bits/arm64/arch/cdefs.h | 9+++------
Minclude/scc/bits/i386/arch/cdefs.h | 9+++------
Minclude/scc/bits/ppc/arch/cdefs.h | 9+++------
Ainclude/scc/bits/wchar.h | 8++++++++
Minclude/scc/bits/z80/arch/cdefs.h | 9+++------
Minclude/scc/stdarg.h | 1-
Minclude/scc/stdio.h | 3++-
Minclude/scc/wchar.h | 8++------
Msrc/libc/stdio/_fpopen.c | 3+++
Msrc/libc/stdio/clearerr.c | 3+++
Msrc/libc/wchar/fputwc.c | 2+-
13 files changed, 37 insertions(+), 45 deletions(-)

diff --git a/include/scc/bits/amd64/arch/cdefs.h b/include/scc/bits/amd64/arch/cdefs.h @@ -1,9 +1,6 @@ -#ifdef _NEED_VA_LIST -#ifndef _VA_LIST +#ifndef _CDEF_H typedef __builtin_va_list __va_list; -#define _VA_LIST -#endif -#undef _NEED_VA_LIST +typedef int __wchar_t; #endif #ifdef _NEED_SIZET @@ -31,7 +28,7 @@ typedef long ptrdiff_t; #ifdef _NEED_WCHART #ifndef _WCHART -typedef int wchar_t; +typedef __wchar_t wchar_t; #define _WCHART #endif #undef _NEED_WCHART diff --git a/include/scc/bits/arm/arch/cdefs.h b/include/scc/bits/arm/arch/cdefs.h @@ -1,9 +1,6 @@ -#ifdef _NEED_VA_LIST -#ifndef _VA_LIST +#ifndef _CDEF_H typedef __builtin_va_list __va_list; -#define _VA_LIST -#endif -#undef _NEED_VA_LIST +typedef int __wchar_t; #endif #ifdef _NEED_SIZET @@ -31,7 +28,7 @@ typedef long ptrdiff_t; #ifdef _NEED_WCHART #ifndef _WCHART -typedef int wchar_t; +typedef __wchar_t wchar_t; #define _WCHART #endif #undef _NEED_WCHART diff --git a/include/scc/bits/arm64/arch/cdefs.h b/include/scc/bits/arm64/arch/cdefs.h @@ -1,9 +1,6 @@ -#ifdef _NEED_VA_LIST -#ifndef _VA_LIST +#ifndef _CDEF_H typedef __builtin_va_list __va_list; -#define _VA_LIST -#endif -#undef _NEED_VA_LIST +typedef int __wchar_t; #endif #ifdef _NEED_SIZET @@ -31,7 +28,7 @@ typedef long ptrdiff_t; #ifdef _NEED_WCHART #ifndef _WCHART -typedef int wchar_t; +typedef __wchar_t wchar_t; #define _WCHART #endif #undef _NEED_WCHART diff --git a/include/scc/bits/i386/arch/cdefs.h b/include/scc/bits/i386/arch/cdefs.h @@ -1,9 +1,6 @@ -#ifdef _NEED_VA_LIST -#ifndef _VA_LIST +#ifndef _CDEF_H typedef __builtin_va_list __va_list; -#define _VA_LIST -#endif -#undef _NEED_VA_LIST +typedef int __wchar_t; #endif #ifdef _NEED_SIZET @@ -31,7 +28,7 @@ typedef long ptrdiff_t; #ifdef _NEED_WCHART #ifndef _WCHART -typedef int wchar_t; +typedef __wchar_t wchar_t; #define _WCHART #endif #undef _NEED_WCHART diff --git a/include/scc/bits/ppc/arch/cdefs.h b/include/scc/bits/ppc/arch/cdefs.h @@ -1,9 +1,6 @@ -#ifdef _NEED_VA_LIST -#ifndef _VA_LIST +#ifndef _CDEF_H typedef __builtin_va_list __va_list; -#define _VA_LIST -#endif -#undef _NEED_VA_LIST +typedef int __wchar_t; #endif #ifdef _NEED_SIZET @@ -31,7 +28,7 @@ typedef long ptrdiff_t; #ifdef _NEED_WCHART #ifndef _WCHART -typedef int wchar_t; +typedef __wchar_t wchar_t; #define _WCHART #endif #undef _NEED_WCHART diff --git a/include/scc/bits/wchar.h b/include/scc/bits/wchar.h @@ -0,0 +1,8 @@ +#ifndef BITS_WCHAR_H +#define BITS_WCHAR_H +typedef struct { + unsigned char oc; + unsigned char sh; + __wchar_t wc; +} __mbstate_t; +#endif diff --git a/include/scc/bits/z80/arch/cdefs.h b/include/scc/bits/z80/arch/cdefs.h @@ -1,9 +1,6 @@ -#ifdef _NEED_VA_LIST -#ifndef _VA_LIST +#ifndef _CDEF_H typedef __builtin_va_list __va_list; -#define _VA_LIST -#endif -#undef _NEED_VA_LIST +typedef int __wchar_t; #endif #ifdef _NEED_SIZET @@ -31,7 +28,7 @@ typedef short ptrdiff_t; #ifdef _NEED_WCHART #ifndef _WCHART -typedef int wchar_t; +typedef __wchar_t wchar_t; #define _WCHART #endif #undef _NEED_WCHART diff --git a/include/scc/stdarg.h b/include/scc/stdarg.h @@ -1,7 +1,6 @@ #ifndef _STDARG_H #define _STDARG_H -#define _NEED_VA_LIST #include <arch/cdefs.h> typedef __va_list va_list; diff --git a/include/scc/stdio.h b/include/scc/stdio.h @@ -3,9 +3,9 @@ #define _NEED_NULL #define _NEED_SIZET -#define _NEED_VA_LIST #include <sys/stdio.h> #include <arch/cdefs.h> +#include <bits/wchar.h> #ifndef FOPEN_MAX #define FOPEN_MAX 12 @@ -64,6 +64,7 @@ typedef struct _FILE { size_t len; unsigned short flags; unsigned char unbuf[1]; + __mbstate_t mbs; } FILE; extern FILE __iob[FOPEN_MAX]; diff --git a/include/scc/wchar.h b/include/scc/wchar.h @@ -7,15 +7,11 @@ #define _NEED_WEOF #define _NEED_WCHARLIM #define _NEED_WINT -#define _NEED_VA_LIST #include <arch/cdefs.h> #include <sys/cdefs.h> +#include <bits/wchar.h> -typedef struct { - unsigned char oc; - unsigned char sh; - wchar_t wc; -} mbstate_t; +typedef __mbstate_t mbstate_t; struct tm; struct _FILE; diff --git a/src/libc/stdio/_fpopen.c b/src/libc/stdio/_fpopen.c @@ -1,6 +1,8 @@ #include <errno.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <wchar.h> #include <sys.h> @@ -62,6 +64,7 @@ _fpopen(const char *restrict fname, if ((fd = _open(fname, flags, rights)) < 0) return NULL; + memset(&fp->mbs, 0, sizeof(mbstate_t)); fp->buf = NULL; fp->fd = fd; diff --git a/src/libc/stdio/clearerr.c b/src/libc/stdio/clearerr.c @@ -1,4 +1,6 @@ #include <stdio.h> +#include <string.h> +#include <wchar.h> #undef clearerr @@ -6,4 +8,5 @@ void clearerr(FILE *fp) { fp->flags &= ~(_IOERR | _IOEOF); + memset(&fp->mbs, 0, sizeof(mbstate_t)); } diff --git a/src/libc/wchar/fputwc.c b/src/libc/wchar/fputwc.c @@ -11,7 +11,7 @@ _fputwc(wchar_t wc, FILE *fp, int *np) int n; char buf[MB_LEN_MAX]; - if ((n = wcrtomb(buf, wc, NULL)) == -1) + if ((n = wcrtomb(buf, wc, &fp->mbs)) == -1) goto err; if (fwrite(buf, 1, n, fp) < n) goto err;