From ff499f62999c93844c5b1ada6de61b7f04748c41 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 28 Mar 2025 14:08:56 -0400 Subject: Tweak fwopen() API --- src/stdlib/print.c | 74 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 31 deletions(-) (limited to 'src/stdlib/print.c') diff --git a/src/stdlib/print.c b/src/stdlib/print.c index fcbc0cb4..219c8647 100644 --- a/src/stdlib/print.c +++ b/src/stdlib/print.c @@ -52,40 +52,52 @@ int _print_quoted(FILE *f, quoted_t quoted) } #if defined(__GLIBC__) && defined(_GNU_SOURCE) - #define HAS_FOPENCOOKIE 1 -#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - #define HAS_FUNOPEN 1 -#endif - -static ssize_t _gc_stream_write(void *cookie, const char *buf, size_t size) { - gc_stream_t *stream = (gc_stream_t *)cookie; - if (stream->position + size + 1 > *stream->size) - *stream->buffer = GC_REALLOC(*stream->buffer, (*stream->size += MAX(MAX(16, *stream->size/2), size + 1))); - memcpy(&(*stream->buffer)[stream->position], buf, size); - stream->position += size; - (*stream->buffer)[stream->position] = '\0'; - return (ssize_t)size; -} + // GLIBC has fopencookie() + static ssize_t _gc_stream_write(void *cookie, const char *buf, size_t size) { + gc_stream_t *stream = (gc_stream_t *)cookie; + if (stream->position + size + 1 > *stream->size) + *stream->buffer = GC_REALLOC(*stream->buffer, (*stream->size += MAX(MAX(16, *stream->size/2), size + 1))); + memcpy(&(*stream->buffer)[stream->position], buf, size); + stream->position += size; + (*stream->buffer)[stream->position] = '\0'; + return (ssize_t)size; + } -FILE *gc_memory_stream(char **buf, size_t *size) { - gc_stream_t *stream = GC_MALLOC(sizeof(gc_stream_t)); - stream->size = size; - stream->buffer = buf; - *stream->size = 16; - *stream->buffer = GC_MALLOC_ATOMIC(*stream->size); - (*stream->buffer)[0] = '\0'; - stream->position = 0; -#ifdef HAS_FOPENCOOKIE + FILE *gc_memory_stream(char **buf, size_t *size) { + gc_stream_t *stream = GC_MALLOC(sizeof(gc_stream_t)); + stream->size = size; + stream->buffer = buf; + *stream->size = 16; + *stream->buffer = GC_MALLOC_ATOMIC(*stream->size); + (*stream->buffer)[0] = '\0'; + stream->position = 0; + cookie_io_functions_t functions = {.write = _gc_stream_write}; + return fopencookie(stream, "w", functions); + } +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + // BSDs have funopen() and fwopen() + static int _gc_stream_write(void *cookie, const char *buf, int size) { + gc_stream_t *stream = (gc_stream_t *)cookie; + if (stream->position + size + 1 > *stream->size) + *stream->buffer = GC_REALLOC(*stream->buffer, (*stream->size += MAX(MAX(16, *stream->size/2), size + 1))); + memcpy(&(*stream->buffer)[stream->position], buf, size); + stream->position += size; + (*stream->buffer)[stream->position] = '\0'; + return size; + } - cookie_io_functions_t functions = {.write = _gc_stream_write}; - return fopencookie(stream, "w", functions); -#else -#ifdef HAS_FUNOPEN - return fwopen(stream, _gc_stream_write); + FILE *gc_memory_stream(char **buf, size_t *size) { + gc_stream_t *stream = GC_MALLOC(sizeof(gc_stream_t)); + stream->size = size; + stream->buffer = buf; + *stream->size = 16; + *stream->buffer = GC_MALLOC_ATOMIC(*stream->size); + (*stream->buffer)[0] = '\0'; + stream->position = 0; + return fwopen(stream, _gc_stream_write); + } #else -#error "This platform does not support fopencookie() or funopen()!" -#endif +# error "This platform doesn't support fopencookie() or funopen()!" #endif -} // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 -- cgit v1.2.3