118 lines
3.0 KiB
C
118 lines
3.0 KiB
C
#include "memory.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
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;
|
|
}
|