Mercurial > lbo > hg > ylisp
view src/atom.c @ 174:0c4e9e76a2f2
all: Make ylisp work in Release mode too
by changing the way asserts are used when there are side-effects.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Mon, 09 Sep 2019 19:57:39 +0200 |
parents | 7887550c61c6 |
children |
line wrap: on
line source
#define _GNU_SOURCE #include "atom.h" #include "base/vec.h" #include <assert.h> #include <search.h> #include <stdbool.h> #include <stddef.h> #include <stdio.h> #include <string.h> // TODO: Adjust this later. static const size_t YATOM_MAX_NUM_ATOMS = 256; static const uint64_t YATOM_COUNTER_OFFSET = 0xa0a0a0a0a0; static bool yatom_table_initialized = false; // Table from atom name to atom id. This is not in the hot path of important functions! static struct hsearch_data yatom_table; static yvec_t yatom_names; // Vector of char*. static yatom_t yatom_counter = YATOM_COUNTER_OFFSET; // Make atom IDs recognizable. static void yatom_init_table(void) { if (yatom_table_initialized) return; yatom_table_initialized = true; hcreate_r(YATOM_MAX_NUM_ATOMS, &yatom_table); yvec_init(&yatom_names, sizeof(const char*), YATOM_MAX_NUM_ATOMS); } yatom_t yatom_get_or_add(const char* name) { yatom_init_table(); ENTRY wanted, *found; wanted.key = (char*)name; // Safe, because we only use it for find. if (0 == hsearch_r(wanted, FIND, &found, &yatom_table)) { // Not found -- insert. wanted.key = strdup(name); wanted.data = (void*)yatom_counter++; YVEC_PUSH(&yatom_names, &wanted.key); assert(yatom_names.len == yatom_counter - YATOM_COUNTER_OFFSET); bool atom_found = hsearch_r(wanted, ENTER, &found, &yatom_table); assert(atom_found); return (yatom_t)wanted.data; } else { // Found. return (yatom_t)found->data; } } const char* yatom_name(yatom_t atom) { yatom_init_table(); return *YVEC_AT(&yatom_names, atom - YATOM_COUNTER_OFFSET, yconstchar*); } void yatom_free_all(void) { for (size_t i = 0; i < yatom_counter-YATOM_COUNTER_OFFSET; i++) { free(*YVEC_AT(&yatom_names, i, char*)); } yvec_destroy(&yatom_names); hdestroy_r(&yatom_table); }