// Copyright 2011-2022 David Robillard // SPDX-License-Identifier: ISC #include "world.h" #include "caret.h" #include "node.h" #include "serd_config.h" #include "system.h" #include "serd/node.h" #include "serd/string_view.h" #if defined(USE_POSIX_FADVISE) # include #endif #include #include #include #include #include #include FILE* serd_world_fopen(SerdWorld* world, const char* path, const char* mode) { FILE* fd = fopen(path, mode); if (!fd) { char message[1024] = {0}; serd_system_strerror(errno, message, sizeof(message)); serd_world_errorf( world, SERD_BAD_STREAM, "failed to open file %s (%s)\n", path, message); return NULL; } #if USE_POSIX_FADVISE && USE_FILENO (void)posix_fadvise(fileno(fd), 0, 0, POSIX_FADV_SEQUENTIAL); #endif return fd; } SerdStatus serd_world_error(const SerdWorld* const world, const SerdError* const e) { if (world->error_func) { world->error_func(world->error_handle, e); } else { fprintf(stderr, "error: "); if (e->caret) { fprintf(stderr, "%s:%u:%u: ", serd_node_string(e->caret->document), e->caret->line, e->caret->col); } vfprintf(stderr, e->fmt, *e->args); } return e->status; } SerdStatus serd_world_verrorf(const SerdWorld* const world, const SerdStatus st, const char* const fmt, va_list args) { va_list args_copy; va_copy(args_copy, args); const SerdError e = {st, NULL, fmt, &args_copy}; serd_world_error(world, &e); va_end(args_copy); return st; } SerdStatus serd_world_errorf(const SerdWorld* const world, const SerdStatus st, const char* const fmt, ...) { va_list args; // NOLINT(cppcoreguidelines-init-variables) va_start(args, fmt); const SerdError e = {st, NULL, fmt, &args}; serd_world_error(world, &e); va_end(args); return st; } SerdWorld* serd_world_new(void) { SerdWorld* world = (SerdWorld*)calloc(1, sizeof(SerdWorld)); SerdNode* blank_node = serd_new_blank(serd_string("b00000000000")); if (!world || !blank_node) { serd_node_free(blank_node); free(world); return NULL; } world->limits.reader_stack_size = 1048576U; world->limits.writer_max_depth = 128U; world->blank_node = blank_node; return world; } void serd_world_free(SerdWorld* const world) { if (world) { serd_node_free(world->blank_node); free(world); } } SerdLimits serd_world_limits(const SerdWorld* const world) { assert(world); return world->limits; } SerdStatus serd_world_set_limits(SerdWorld* const world, const SerdLimits limits) { assert(world); world->limits = limits; return SERD_SUCCESS; } const SerdNode* serd_world_get_blank(SerdWorld* const world) { #define BLANK_CHARS 12 char* buf = serd_node_buffer(world->blank_node); memset(buf, 0, BLANK_CHARS + 1); world->blank_node->length = (size_t)snprintf(buf, BLANK_CHARS + 1, "b%u", ++world->next_blank_id); return world->blank_node; #undef BLANK_CHARS } void serd_world_set_error_func(SerdWorld* world, SerdErrorFunc error_func, void* handle) { world->error_func = error_func; world->error_handle = handle; }