:: limine / common / lib / misc.s2.c 3.5 KB raw

1
#include <stdint.h>
2
#include <stddef.h>
3
#include <lib/misc.h>
4
#include <lib/print.h>
5
6
bool verbose = false;
7
bool quiet = false;
8
bool serial = false;
9
bool hash_mismatch_panic = false;
10
bool measured_boot = false;
11
12
uint8_t bcd_to_int(uint8_t val) {
13
    return (val & 0x0f) + ((val & 0xf0) >> 4) * 10;
14
}
15
uint8_t int_to_bcd(uint8_t val) {
16
    return (val % 10) | (val / 10) << 4;
17
}
18
19
int digit_to_int(char c) {
20
    if (c >= 'a' && c <= 'f') {
21
        return (c - 'a') + 10;
22
    }
23
    if (c >= 'A' && c <= 'F') {
24
        return (c - 'A') + 10;
25
    }
26
    if (c >= '0' && c <= '9'){
27
        return c - '0';
28
    }
29
30
    return -1;
31
}
32
33
uint64_t strtoui(const char *s, const char **end, int base) {
34
    uint64_t n = 0;
35
    for (size_t i = 0; ; i++) {
36
        int d = digit_to_int(s[i]);
37
        if (d == -1 || d >= base) {
38
            if (end != NULL)
39
                *end = &s[i];
40
            break;
41
        }
42
        uint64_t mul_result = CHECKED_MUL(n, base, ({
43
            if (end != NULL)
44
                *end = &s[i];
45
            return UINT64_MAX;
46
        }));
47
        n = CHECKED_ADD(mul_result, d, ({
48
            if (end != NULL)
49
                *end = &s[i];
50
            return UINT64_MAX;
51
        }));
52
    }
53
    return n;
54
}
55
56
bool get_absolute_path(char *path_ptr, const char *path, const char *pwd, size_t size) {
57
    char *orig_ptr = path_ptr;
58
    char *end_ptr = path_ptr + size - 1;
59
60
    if (size == 0) return false;
61
62
    if (!*path) {
63
        size_t pwd_len = strlen(pwd);
64
        if (pwd_len >= size) return false;
65
        memcpy(path_ptr, pwd, pwd_len + 1);
66
        return true;
67
    }
68
69
    if (*path != '/') {
70
        size_t pwd_len = strlen(pwd);
71
        if (pwd_len >= size) return false;
72
        memcpy(path_ptr, pwd, pwd_len + 1);
73
        path_ptr += pwd_len;
74
    } else {
75
        *path_ptr = '/';
76
        path_ptr++;
77
        path++;
78
    }
79
80
    goto first_run;
81
82
    for (;;) {
83
        switch (*path) {
84
            case '/':
85
                path++;
86
first_run:
87
                if (*path == '/') continue;
88
                if ((!strncmp(path, ".\0", 2))
89
                ||  (!strncmp(path, "./\0", 3))) {
90
                    goto term;
91
                }
92
                if ((!strncmp(path, "..\0", 3))
93
                ||  (!strncmp(path, "../\0", 4))) {
94
                    while (path_ptr > orig_ptr && *path_ptr != '/') path_ptr--;
95
                    if (path_ptr == orig_ptr) path_ptr++;
96
                    goto term;
97
                }
98
                if (!strncmp(path, "../", 3)) {
99
                    while (path_ptr > orig_ptr && *path_ptr != '/') path_ptr--;
100
                    if (path_ptr == orig_ptr) path_ptr++;
101
                    path += 2;
102
                    *path_ptr = 0;
103
                    continue;
104
                }
105
                if (!strncmp(path, "./", 2)) {
106
                    path += 1;
107
                    continue;
108
                }
109
                if (path_ptr > orig_ptr && ((path_ptr - 1) != orig_ptr) && (*(path_ptr - 1) != '/')) {
110
                    if (path_ptr >= end_ptr) return false;
111
                    *path_ptr = '/';
112
                    path_ptr++;
113
                }
114
                continue;
115
            case '\0':
116
term:
117
                if (path_ptr > orig_ptr && (*(path_ptr - 1) == '/') && ((path_ptr - 1) != orig_ptr))
118
                    path_ptr--;
119
                *path_ptr = 0;
120
                return true;
121
            default:
122
                if (path_ptr >= end_ptr) return false;
123
                *path_ptr = *path;
124
                path++;
125
                path_ptr++;
126
                continue;
127
        }
128
    }
129
}
tab: 248 wrap: offon