63af3e907b
The unification of memory pools also fixed some memory leaks and hopefully reduced the mallocs of identifier strings significantly by giving them the same pool as the token stream.
178 lines
6.0 KiB
C
178 lines
6.0 KiB
C
#include "util.h"
|
|
|
|
#include <stdarg.h>
|
|
|
|
char errbuf[ERRSZ];
|
|
bool err;
|
|
size_t err_ln, err_col;
|
|
|
|
static intmax_t stoimax_digits[256] = {
|
|
[0] = -1, [1] = -1, [2] = -1, [3] = -1, [4] = -1, [5] = -1, [6] = -1, [7] = -1,
|
|
[8] = -1, [9] = -1, [10] = -1, [11] = -1, [12] = -1, [13] = -1, [14] = -1, [15] = -1,
|
|
[16] = -1, [17] = -1, [18] = -1, [19] = -1, [20] = -1, [21] = -1, [22] = -1, [23] = -1,
|
|
[24] = -1, [25] = -1, [26] = -1, [27] = -1, [28] = -1, [29] = -1, [30] = -1, [31] = -1,
|
|
[32] = -1, [33] = -1, [34] = -1, [35] = -1, [36] = -1, [37] = -1, [38] = -1, [39] = -1,
|
|
[40] = -1, [41] = -1, [42] = -1, [43] = -1, [44] = -1, [45] = -1, [46] = -1, [47] = -1,
|
|
['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4, ['5'] = 5, ['6'] = 6, ['7'] = 7,
|
|
['8'] = 8, ['9'] = 9, [58] = -1, [59] = -1, [60] = -1, [61] = -1, [62] = -1, [63] = -1,
|
|
[64] = -1, ['A'] = 10, ['B'] = 11, ['C'] = 12, ['D'] = 13, ['E'] = 14, ['F'] = 15, [71] = -1,
|
|
[72] = -1, [73] = -1, [74] = -1, [75] = -1, [76] = -1, [77] = -1, [78] = -1, [79] = -1,
|
|
[80] = -1, [81] = -1, [82] = -1, [83] = -1, [84] = -1, [85] = -1, [86] = -1, [87] = -1,
|
|
[88] = -1, [89] = -1, [90] = -1, [91] = -1, [92] = -1, [93] = -1, [94] = -1, [95] = -1,
|
|
[96] = -1, ['a'] = 10, ['b'] = 11, ['c'] = 12, ['d'] = 13, ['e'] = 14, ['f'] = 15, [103] = -1,
|
|
[104] = -1, [105] = -1, [106] = -1, [107] = -1, [108] = -1, [109] = -1, [110] = -1, [111] = -1,
|
|
[112] = -1, [113] = -1, [114] = -1, [115] = -1, [116] = -1, [117] = -1, [118] = -1, [119] = -1,
|
|
[120] = -1, [121] = -1, [122] = -1, [123] = -1, [124] = -1, [125] = -1, [126] = -1, [127] = -1,
|
|
[128] = -1, [129] = -1, [130] = -1, [131] = -1, [132] = -1, [133] = -1, [134] = -1, [135] = -1,
|
|
[136] = -1, [137] = -1, [138] = -1, [139] = -1, [140] = -1, [141] = -1, [142] = -1, [143] = -1,
|
|
[144] = -1, [145] = -1, [146] = -1, [147] = -1, [148] = -1, [149] = -1, [150] = -1, [151] = -1,
|
|
[152] = -1, [153] = -1, [154] = -1, [155] = -1, [156] = -1, [157] = -1, [158] = -1, [159] = -1,
|
|
[160] = -1, [161] = -1, [162] = -1, [163] = -1, [164] = -1, [165] = -1, [166] = -1, [167] = -1,
|
|
[168] = -1, [169] = -1, [170] = -1, [171] = -1, [172] = -1, [173] = -1, [174] = -1, [175] = -1,
|
|
[176] = -1, [177] = -1, [178] = -1, [179] = -1, [180] = -1, [181] = -1, [182] = -1, [183] = -1,
|
|
[184] = -1, [185] = -1, [186] = -1, [187] = -1, [188] = -1, [189] = -1, [190] = -1, [191] = -1,
|
|
[192] = -1, [193] = -1, [194] = -1, [195] = -1, [196] = -1, [197] = -1, [198] = -1, [199] = -1,
|
|
[200] = -1, [201] = -1, [202] = -1, [203] = -1, [204] = -1, [205] = -1, [206] = -1, [207] = -1,
|
|
[208] = -1, [209] = -1, [210] = -1, [211] = -1, [212] = -1, [213] = -1, [214] = -1, [215] = -1,
|
|
[216] = -1, [217] = -1, [218] = -1, [219] = -1, [220] = -1, [221] = -1, [222] = -1, [223] = -1,
|
|
[224] = -1, [225] = -1, [226] = -1, [227] = -1, [228] = -1, [229] = -1, [230] = -1, [231] = -1,
|
|
[232] = -1, [233] = -1, [234] = -1, [235] = -1, [236] = -1, [237] = -1, [238] = -1, [239] = -1,
|
|
[240] = -1, [241] = -1, [242] = -1, [243] = -1, [244] = -1, [245] = -1, [246] = -1, [247] = -1,
|
|
[248] = -1, [249] = -1, [250] = -1, [251] = -1, [252] = -1, [253] = -1, [254] = -1, [255] = -1,
|
|
};
|
|
|
|
void set_err(const char *fmt, ...) {
|
|
err = true;
|
|
va_list va;
|
|
va_start(va, fmt);
|
|
vsnprintf(errbuf, ERRSZ, fmt, va);
|
|
va_end(va);
|
|
}
|
|
|
|
Pool *pool_new(size_t init_cap) {
|
|
Pool *p = malloc(sizeof(Pool) + init_cap);
|
|
p->len = 0;
|
|
p->cap = init_cap;
|
|
p->data = p + 1;
|
|
p->next = NULL;
|
|
return p;
|
|
}
|
|
|
|
void pool_term(Pool *p) {
|
|
for (Pool *i = p; i != NULL;) {
|
|
Pool *next = i->next;
|
|
free(i);
|
|
i = next;
|
|
}
|
|
}
|
|
|
|
void *pool_alloc(Pool *p, size_t bytes) {
|
|
for (Pool *i = p;; i = i->next) {
|
|
if (i->len + bytes < i->cap) {
|
|
void *ret = (uint8_t*)i->data + i->len;
|
|
i->len += bytes;
|
|
return ret;
|
|
}
|
|
if (!i->next) {
|
|
i->next = pool_new(bytes + i->cap * 2);
|
|
i->next->len = bytes;
|
|
return i->next->data;
|
|
}
|
|
}
|
|
}
|
|
|
|
char *sndup(const char *s, size_t n) {
|
|
char *ret = malloc(n+1);
|
|
if (ret) {
|
|
memcpy(ret, s, n);
|
|
ret[n] = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
char *psndup(Pool *p, const char *s, size_t n) {
|
|
char *ret = pool_alloc(p, n+1);
|
|
memcpy(ret, s, n);
|
|
ret[n] = 0;
|
|
return ret;
|
|
}
|
|
|
|
intmax_t stoimax(const char *s, size_t n, size_t base, ssize_t *endpos) {
|
|
for (size_t i = 0; i < n; i++) { if (s[i] == 0) { n = i; break; } }
|
|
intmax_t res = 0;
|
|
intmax_t order = 1;
|
|
for (ssize_t i = n - 1; i >= 0; i--) {
|
|
intmax_t dig = stoimax_digits[(size_t)s[i]];
|
|
if (dig == -1 || (size_t)dig >= base) {
|
|
if (endpos)
|
|
*endpos = i;
|
|
return 0;
|
|
}
|
|
res += order * dig;
|
|
order *= base;
|
|
}
|
|
if (endpos)
|
|
*endpos = -1;
|
|
return res;
|
|
}
|
|
|
|
double stod(const char *s, size_t n, ssize_t *endpos) {
|
|
for (size_t i = 0; i < n; i++) { if (s[i] == 0) { n = i; break; } }
|
|
double res = 0.0;
|
|
double order = 1.0;
|
|
size_t point_pos = n;
|
|
for (size_t i = 0; i < n; i++) { if (s[i] == '.') { point_pos = i; break; } }
|
|
for (ssize_t i = point_pos - 1; i >= 0; i--) {
|
|
if (!IS_NUM(s[i])) {
|
|
if (endpos)
|
|
*endpos = i;
|
|
return 0.0;
|
|
}
|
|
double dig = s[i] - '0';
|
|
res += order * dig;
|
|
order *= 10.0;
|
|
}
|
|
order = 0.1;
|
|
for (size_t i = point_pos + 1; i < n; i++) {
|
|
if (!IS_NUM(s[i])) {
|
|
if (endpos)
|
|
*endpos = i;
|
|
return 0.0;
|
|
}
|
|
double dig = s[i] - '0';
|
|
res += order * dig;
|
|
order *= 0.1;
|
|
}
|
|
if (endpos)
|
|
*endpos = -1;
|
|
return res;
|
|
}
|
|
|
|
char *mreadfile(FILE *fp) {
|
|
if (fseek(fp, 0l, SEEK_END) == -1)
|
|
return NULL;
|
|
long size = ftell(fp);
|
|
if (size == -1)
|
|
return NULL;
|
|
rewind(fp);
|
|
char *buf = malloc(size + 1);
|
|
if (!buf)
|
|
return NULL;
|
|
size_t read = fread(buf, size, 1, fp);
|
|
if (read != 1) {
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
buf[size] = 0;
|
|
return buf;
|
|
}
|
|
|
|
uint32_t fnv1a32(const void *data, size_t n) {
|
|
uint32_t res = 2166136261u;
|
|
for (size_t i = 0; i < n; i++) {
|
|
res ^= ((uint8_t*)data)[i];
|
|
res *= 16777619u;
|
|
}
|
|
return res;
|
|
}
|