diff options
Diffstat (limited to 'src/stdlib/print.c')
| -rw-r--r-- | src/stdlib/print.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/stdlib/print.c b/src/stdlib/print.c new file mode 100644 index 00000000..023af986 --- /dev/null +++ b/src/stdlib/print.c @@ -0,0 +1,76 @@ +// This file defines some of the helper functions used for printing values +#include "print.h" + +#include <stdio.h> + +int _print_char(FILE *f, char c) +{ +#if PRINT_COLOR +#define ESC(e) "\033[35m'\033[34;1m\\" e "\033[0;35m'\033[m" +#else +#define ESC(e) "'\\" e "'" +#endif + const char *named[256] = {['\n']=ESC("n"), ['\t']=ESC("t"), ['\r']=ESC("r"), + ['\033']=ESC("e"), ['\v']=ESC("v"), ['\a']=ESC("a"), ['\b']=ESC("b")}; + const char *name = named[(uint8_t)c]; + if (name != NULL) + return fputs(name, f); + else if (isprint(c)) +#if PRINT_COLOR + return fprintf(f, "\033[35m'%c'\033[m"), c); +#else + return fprintf(f, "'%c'", c); +#endif + else + return fprintf(f, ESC("x%02X"), (uint8_t)c); +#undef ESC +} + +int _print_quoted(FILE *f, quoted_t quoted) +{ +#if PRINT_COLOR +#define ESC(e) "\033[34;1m\\" e "\033[0;35m" +#else +#define ESC(e) "\\" e +#endif + const char *named[256] = {['\n']=ESC("n"), ['\t']=ESC("t"), ['\r']=ESC("r"), + ['\033']=ESC("e"), ['\v']=ESC("v"), ['\a']=ESC("a"), ['\b']=ESC("b")}; + int printed = fputs("\033[35m\"", f); + for (const char *p = quoted.str; *p; p++) { + const char *name = named[(uint8_t)*p]; + if (name != NULL) { + printed += fputs(name, f); + } else if (isprint(*p) || (uint8_t)*p > 0x7F) { + printed += fputc(*p, f); + } else { + printed += fprintf(f, ESC("x%02X"), (uint8_t)*p); + } + } + printed += fputs("\"\033[m", f); +#undef ESC + return printed; +} + +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; + cookie_io_functions_t functions = {.write = _gc_stream_write}; + return fopencookie(stream, "w", functions); +} + +// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 |
