#include "memory.h" #include #include #include void *lisp_realloc(void *oldptr, size_t size) { if (!size) { assert(oldptr != NULL); return NULL; } else { void *newptr = realloc(oldptr, size); if (!newptr) { fputs("Allocation failed!", stderr); abort(); } return newptr; } } void *lisp_realloc_gmp(void *oldptr, size_t oldsize, size_t size) { return lisp_realloc(oldptr, size); } void *lisp_malloc(size_t size) { return lisp_realloc(NULL, size); } void *lisp_malloc0(size_t size) { void *ptr = lisp_malloc(size); memset(ptr, 0, size); return ptr; } void *lisp_aligned_alloc(size_t alignment, size_t size) { void *ptr = aligned_alloc(alignment, size); if (!ptr) { fputs("Allocation failed!", stderr); abort(); } return ptr; } void lisp_free_gmp(void *ptr, size_t size) { free(ptr); } #define STRING_STREAM_BLOCK_SIZE 32 static void ensure_string_stream_space(StringStream *restrict stream, size_t space) { size_t min_size = stream->nchars + space; size_t new_size = stream->size; while (new_size < min_size) { new_size += STRING_STREAM_BLOCK_SIZE; } if (new_size != stream->size) { stream->buffer = lisp_realloc(stream->buffer, new_size + 1); } } void string_stream_putc(StringStream *restrict stream, char c) { ensure_string_stream_space(stream, 1); stream->buffer[stream->nchars++] = c; } int string_stream_printf(StringStream *restrict stream, const char *restrict format, ...) { va_list args; va_start(args, format); int rval = string_stream_vprintf(stream, format, args); va_end(args); return rval; } int string_stream_vprintf(StringStream *restrict stream, const char *restrict format, va_list args) { va_list args_copy; va_copy(args_copy, args); int space = vsnprintf(NULL, 0, format, args_copy); if (space < 0) { abort(); } va_end(args_copy); ensure_string_stream_space(stream, space); int rval = vsnprintf(stream->buffer + stream->nchars, stream->size + 1 - stream->nchars, format, args); if (rval < 0) { abort(); } stream->nchars += rval; return rval; } bool strgetline(const char *restrict buf, size_t buf_length, const char **restrict start, size_t *restrict length) { if (!*start) { *start = buf; if (!buf_length) { *length = 0; return true; } } else if (!buf_length) { return false; } else if (*start + *length >= buf + buf_length - 1) { return false; } else /* if (*start) */ { *start += *length + 1; } size_t left = buf_length - (*start - buf); const char *found; if ((found = memchr(*start, '\n', left))) { *length = found - *start; } else { *length = left; } return true; }