aboutsummaryrefslogtreecommitdiff
path: root/src/util.cpp
blob: 65b1fe30823107ee1346391afbb42c093c5f43d5 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * Copyright (c) 2015 Andrew Kelley
 *
 * This file is part of zig, which is MIT licensed.
 * See http://opensource.org/licenses/MIT
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#include "util.hpp"
#include "userland.h"

void zig_panic(const char *format, ...) {
    va_list ap;
    va_start(ap, format);
    vfprintf(stderr, format, ap);
    fflush(stderr);
    va_end(ap);
    stage2_panic(nullptr, 0);
    abort();
}

void assert(bool ok) {
    if (!ok) {
        const char *msg = "Assertion failed. This is a bug in the Zig compiler.";
        stage2_panic(msg, strlen(msg));
    }
}

uint32_t int_hash(int i) {
    return (uint32_t)(i % UINT32_MAX);
}
bool int_eq(int a, int b) {
    return a == b;
}

uint32_t uint64_hash(uint64_t i) {
    return (uint32_t)(i % UINT32_MAX);
}

bool uint64_eq(uint64_t a, uint64_t b) {
    return a == b;
}

uint32_t ptr_hash(const void *ptr) {
    return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX);
}

bool ptr_eq(const void *a, const void *b) {
    return a == b;
}

// Ported from std/mem.zig.
bool SplitIterator_isSplitByte(SplitIterator *self, uint8_t byte) {
    for (size_t i = 0; i < self->split_bytes.len; i += 1) {
        if (byte == self->split_bytes.ptr[i]) {
            return true;
        }
    }
    return false;
}

// Ported from std/mem.zig.
Optional<Slice<uint8_t>> SplitIterator_next(SplitIterator *self) {
    // move to beginning of token
    while (self->index < self->buffer.len &&
        SplitIterator_isSplitByte(self, self->buffer.ptr[self->index]))
    {
        self->index += 1;
    }
    size_t start = self->index;
    if (start == self->buffer.len) {
        return {};
    }

    // move to end of token
    while (self->index < self->buffer.len &&
        !SplitIterator_isSplitByte(self, self->buffer.ptr[self->index]))
    {
        self->index += 1;
    }
    size_t end = self->index;

    return Optional<Slice<uint8_t>>::some(self->buffer.slice(start, end));
}

// Ported from std/mem.zig.
// This one won't collapse multiple separators into one, so you could use it, for example,
// to parse Comma Separated Value format.
Optional<Slice<uint8_t>> SplitIterator_next_separate(SplitIterator *self) {
    // move to beginning of token
    if (self->index < self->buffer.len &&
        SplitIterator_isSplitByte(self, self->buffer.ptr[self->index]))
    {
        self->index += 1;
    }
    size_t start = self->index;
    if (start == self->buffer.len) {
        return {};
    }

    // move to end of token
    while (self->index < self->buffer.len &&
        !SplitIterator_isSplitByte(self, self->buffer.ptr[self->index]))
    {
        self->index += 1;
    }
    size_t end = self->index;

    return Optional<Slice<uint8_t>>::some(self->buffer.slice(start, end));
}

// Ported from std/mem.zig
Slice<uint8_t> SplitIterator_rest(SplitIterator *self) {
    // move to beginning of token
    size_t index = self->index;
    while (index < self->buffer.len && SplitIterator_isSplitByte(self, self->buffer.ptr[index])) {
        index += 1;
    }
    return self->buffer.sliceFrom(index);
}

// Ported from std/mem.zig
SplitIterator memSplit(Slice<uint8_t> buffer, Slice<uint8_t> split_bytes) {
    return SplitIterator{0, buffer, split_bytes};
}