152 lines
2.6 KiB
C
152 lines
2.6 KiB
C
#include "utils.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
i64 parse_int(char *s, usize len)
|
|
{
|
|
bool negative = false;
|
|
if (*s == '-') {
|
|
s += 1;
|
|
len -= 1;
|
|
negative = true;
|
|
}
|
|
|
|
u64 int_part = 0;
|
|
for (usize i=0; i < len; i++) {
|
|
int_part = (int_part * 10) + (s[i] - '0');
|
|
}
|
|
|
|
if (negative) {
|
|
int_part *= -1;
|
|
}
|
|
|
|
return int_part;
|
|
}
|
|
|
|
f64 parse_float(char *s, usize len)
|
|
{
|
|
bool negative = false;
|
|
if (*s == '-') {
|
|
s += 1;
|
|
len -= 1;
|
|
negative = true;
|
|
}
|
|
|
|
usize point_pos = 0;
|
|
for (usize i=0; i < len; i++) {
|
|
if (s[i] == '.') {
|
|
point_pos = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
i64 int_part = parse_int(s, point_pos);
|
|
i64 dec_part = parse_int(s+point_pos+1, len-point_pos-1);
|
|
for (usize i=0; i < len-point_pos-1; i++) {
|
|
int_part *= 10;
|
|
}
|
|
|
|
int_part += dec_part;
|
|
|
|
f64 f = (f64) int_part;
|
|
|
|
point_pos += 1;
|
|
|
|
for (usize i=0; i < len - point_pos; i++) {
|
|
f /= 10.0;
|
|
}
|
|
|
|
if (negative) {
|
|
f *= -1;
|
|
}
|
|
|
|
return f;
|
|
}
|
|
|
|
|
|
void trie_insert(trie_node *root, arena *a, char *key, uint16_t value)
|
|
{
|
|
trie_node *node = root;
|
|
while (*key) {
|
|
if (!node->children[(usize)*key]) {
|
|
node->children[(usize)*key] = arena_alloc(a, sizeof(trie_node));
|
|
memset(node->children[(usize)*key], 0x0, sizeof(trie_node));
|
|
}
|
|
node = node->children[(usize)*key];
|
|
|
|
key++;
|
|
}
|
|
|
|
node->value = value;
|
|
}
|
|
|
|
uint16_t trie_get(trie_node *root, char *key, usize len)
|
|
{
|
|
trie_node *node = root;
|
|
for (usize i=0; i < len; i++) {
|
|
if (!node->children[(usize)(key[i])]) {
|
|
return 0;
|
|
}
|
|
node = node->children[(usize)(key[i])];
|
|
}
|
|
|
|
return node->value;
|
|
}
|
|
|
|
#ifndef DEFAULT_ALIGNMENT
|
|
#define DEFAULT_ALIGNMENT (2 * sizeof(void *))
|
|
#endif
|
|
|
|
static usize align_forward(usize ptr, usize align) {
|
|
uintptr_t p = ptr;
|
|
uintptr_t a = (uintptr_t)align;
|
|
uintptr_t modulo = p & (a - 1);
|
|
|
|
if (modulo != 0) {
|
|
p += a - modulo;
|
|
}
|
|
return (usize)p;
|
|
}
|
|
|
|
arena arena_init(usize size)
|
|
{
|
|
void *memory = malloc(size);
|
|
memset(memory, 0x0, size);
|
|
return (arena){
|
|
.capacity = size,
|
|
.position = 0,
|
|
.memory = memory,
|
|
};
|
|
}
|
|
|
|
void *arena_alloc(arena *a, usize size) {
|
|
uintptr_t current_addr = (uintptr_t)a->memory + a->position;
|
|
uintptr_t padding = align_forward(current_addr, DEFAULT_ALIGNMENT) - current_addr;
|
|
if (a->position + padding + size > a->capacity) return NULL;
|
|
void *ret = (unsigned char *)a->memory + a->position + padding;
|
|
a->position += (size + padding);
|
|
|
|
return ret;
|
|
}
|
|
|
|
snapshot arena_snapshot(arena *a)
|
|
{
|
|
return a->position;
|
|
}
|
|
|
|
void arena_reset_to_snapshot(arena *a, snapshot s)
|
|
{
|
|
a->position = s;
|
|
}
|
|
|
|
void arena_reset(arena *a)
|
|
{
|
|
arena_reset_to_snapshot(a, 0);
|
|
}
|
|
|
|
void arena_deinit(arena a)
|
|
{
|
|
free(a.memory);
|
|
}
|