Coverage Report

Created: 2026-02-23 20:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/Users/alexjokela/projects/lattice/src/intern.c
Line
Count
Source
1
#include "intern.h"
2
#include <stdint.h>
3
#include <stdlib.h>
4
#include <string.h>
5
6
3.41k
#define INTERN_INIT_CAP 256
7
8
typedef struct {
9
    char **entries;
10
    size_t count;
11
    size_t cap;
12
} InternTable;
13
14
static InternTable g_intern = {0};
15
16
3.41k
void intern_init(void) {
17
3.41k
    g_intern.cap = INTERN_INIT_CAP;
18
3.41k
    g_intern.count = 0;
19
3.41k
    g_intern.entries = calloc(g_intern.cap, sizeof(char *));
20
3.41k
}
21
22
1.70k
void intern_free(void) {
23
438k
    for (size_t i = 0; i < g_intern.cap; i++)
24
436k
        free(g_intern.entries[i]);
25
1.70k
    free(g_intern.entries);
26
1.70k
    g_intern.entries = NULL;
27
1.70k
    g_intern.count = 0;
28
1.70k
    g_intern.cap = 0;
29
1.70k
}
30
31
0
static uint32_t intern_hash(const char *s) {
32
0
    uint32_t h = 5381;
33
0
    while (*s) h = h * 33 + (unsigned char)*s++;
34
0
    return h;
35
0
}
36
37
0
static void intern_grow(void) {
38
0
    size_t new_cap = g_intern.cap * 2;
39
0
    char **new_entries = calloc(new_cap, sizeof(char *));
40
0
    for (size_t i = 0; i < g_intern.cap; i++) {
41
0
        if (!g_intern.entries[i]) continue;
42
0
        uint32_t h = intern_hash(g_intern.entries[i]) & (uint32_t)(new_cap - 1);
43
0
        while (new_entries[h]) h = (h + 1) & (uint32_t)(new_cap - 1);
44
0
        new_entries[h] = g_intern.entries[i];
45
0
    }
46
0
    free(g_intern.entries);
47
0
    g_intern.entries = new_entries;
48
0
    g_intern.cap = new_cap;
49
0
}
50
51
0
const char *intern(const char *s) {
52
0
    if (!s) return NULL;
53
0
    if (!g_intern.entries) intern_init();
54
55
0
    if (g_intern.count * 2 >= g_intern.cap)
56
0
        intern_grow();
57
58
0
    uint32_t mask = (uint32_t)(g_intern.cap - 1);
59
0
    uint32_t h = intern_hash(s) & mask;
60
0
    while (g_intern.entries[h]) {
61
0
        if (strcmp(g_intern.entries[h], s) == 0)
62
0
            return g_intern.entries[h];
63
0
        h = (h + 1) & mask;
64
0
    }
65
0
    g_intern.entries[h] = strdup(s);
66
0
    g_intern.count++;
67
0
    return g_intern.entries[h];
68
0
}