code / print

Lines216 C192 Markdown22
1 others 2
make2
(46 lines)
1 #pragma once
3 // This file defines a String(...) macro that works with the Boehm GC
4 // to allocate formatted strings.
5 #include <gc.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/param.h>
11 typedef struct {
12 char **buffer;
13 size_t *size;
14 size_t position;
15 } gc_stream_t;
17 static ssize_t _gc_stream_write(void *cookie, const char *buf, size_t size) {
18 gc_stream_t *stream = (gc_stream_t *)cookie;
19 if (stream->position + size + 1 > *stream->size)
20 *stream->buffer = (char*)GC_REALLOC(*stream->buffer, (*stream->size += MAX(MAX(16, *stream->size/2), size + 1)));
21 memcpy(&(*stream->buffer)[stream->position], buf, size);
22 stream->position += size;
23 (*stream->buffer)[stream->position] = '\0';
24 return size;
27 static FILE *gc_memory_stream(char **buf, size_t *size) {
28 gc_stream_t *stream = (gc_stream_t*)GC_MALLOC(sizeof(gc_stream_t));
29 stream->size = size;
30 stream->buffer = buf;
31 *stream->size = 16;
32 *stream->buffer = (char*)GC_MALLOC_ATOMIC(*stream->size);
33 (*stream->buffer)[0] = '\0';
34 stream->position = 0;
35 cookie_io_functions_t functions = {.write = _gc_stream_write};
36 return fopencookie(stream, "w", functions);
39 #define String(...) ({ \
40 char *_buf = NULL; \
41 size_t _size = 0; \
42 FILE *_stream = gc_memory_stream(&_buf, &_size); \
43 assert(_stream); \
44 _fprint(_stream, __VA_ARGS__); \
45 fflush(_stream); \
46 _buf; })