summaryrefslogtreecommitdiff
path: root/src/um.c
blob: 4a24937d4cf7f302ce7be79490b13e1e1d878e45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <um.h>

#include <lib/sv.h>

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

LL_IMPL_ADD(manifest, struct pair)
LL_IMPL_FREE(manifest)

struct um_context {
    int in_manifest;
};

static struct um_context context;

static struct string_view manifest_sv = SV("MANIFEST");

struct parser_backend um_backend()
{
    return (struct parser_backend) {
        .on_block_start = um_block_start_cb,
        .on_block_end   = um_block_end_cb,
        .on_kv          = um_kv_cb,
        .on_init        = um_init
    };
}

void um_init()
{
    context.in_manifest = 0;
}

void um_block_start_cb(struct string_view *block, void *userdata)
{
    assert(block != NULL);
    assert(userdata != NULL);
    
    if (sv_equal(&manifest_sv, block)) {
        context.in_manifest = 1;
    } else {
        fprintf(stderr, "[UPSTREAM ERROR] Unknown block: %.*s\n", 
                (int)block->len, block->buf); // (unsafe)
        exit(1);
    }
    printf("[UPSTREAM] Entered block %.*s.\n",
            (int)block->len, block->buf);
}

void um_block_end_cb(struct string_view *block, void *userdata)
{
    assert(block != NULL);
    assert(userdata != NULL);

    if (sv_equal(&manifest_sv, block)) {
        context.in_manifest = 0;
    } else {
        fprintf(stderr, "[UPSTREAM ERROR] Unknown block: %.*s\n", 
                (int)block->len, block->buf); // (unsafe)
        exit(1);
    }
    printf("[UPSTREAM] Left block %.*s.\n",
            (int)block->len, block->buf);
}

void um_kv_cb(struct string_view *key, 
              struct string_view *value,
              void *userdata)
{
    assert(key != NULL);
    assert(value != NULL);
    assert(userdata != NULL);

    if (context.in_manifest == 0) {
        fprintf(stderr, "[UPSTREAM ERROR] You can only define packages inside a manifest block.\n"); 
    }
    
    struct um_user_data *user = (struct um_user_data*)userdata;
    struct string_view ckey = sv_copy(key);
    struct string_view cval = sv_copy(value);

    ll_manifest_add(&user->manifest, (struct pair){.key = ckey, .value = cval});
}