| |
| |
| |
| |
| #ifndef P2S_UTILS_H |
| #define P2S_UTILS_H |
|
|
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdarg.h> |
| #include <stdbool.h> |
| #include <stdint.h> |
| #include <assert.h> |
| #include <ctype.h> |
|
|
| |
|
|
| #define ARENA_BLOCK_SIZE (64 * 1024) |
|
|
| typedef struct ArenaBlock { |
| struct ArenaBlock *next; |
| size_t size; |
| size_t used; |
| char data[]; |
| } ArenaBlock; |
|
|
| typedef struct Arena { |
| ArenaBlock *head; |
| ArenaBlock *current; |
| size_t total_alloc; |
| } Arena; |
|
|
| Arena *arena_create(void); |
| void *arena_alloc(Arena *a, size_t size); |
| char *arena_strdup(Arena *a, const char *s); |
| char *arena_strndup(Arena *a, const char *s, size_t n); |
| void arena_destroy(Arena *a); |
|
|
| |
|
|
| #define VEC_INIT_CAP 8 |
|
|
| #define VEC_TYPEDEF(T, Name) \ |
| typedef struct { \ |
| T *data; \ |
| size_t len; \ |
| size_t cap; \ |
| } Name |
|
|
| #define vec_init(v) do { (v)->data = NULL; (v)->len = 0; (v)->cap = 0; } while(0) |
|
|
| #define vec_push(v, item) do { \ |
| if ((v)->len >= (v)->cap) { \ |
| (v)->cap = (v)->cap ? (v)->cap * 2 : VEC_INIT_CAP; \ |
| (v)->data = realloc((v)->data, (v)->cap * sizeof(*(v)->data)); \ |
| if (!(v)->data) { fprintf(stderr, "OOM\n"); exit(1); } \ |
| } \ |
| (v)->data[(v)->len++] = (item); \ |
| } while(0) |
|
|
| #define vec_free(v) do { free((v)->data); vec_init(v); } while(0) |
|
|
| |
|
|
| typedef struct StrBuf { |
| char *data; |
| size_t len; |
| size_t cap; |
| } StrBuf; |
|
|
| void strbuf_init(StrBuf *sb); |
| void strbuf_append(StrBuf *sb, const char *fmt, ...); |
| void strbuf_append_char(StrBuf *sb, char c); |
| void strbuf_append_indent(StrBuf *sb, int indent); |
| char *strbuf_detach(StrBuf *sb); |
| void strbuf_free(StrBuf *sb); |
|
|
| |
|
|
| typedef struct SourceLoc { |
| const char *filename; |
| int line; |
| int col; |
| } SourceLoc; |
|
|
| void p2s_error(SourceLoc loc, const char *fmt, ...); |
| void p2s_warn(SourceLoc loc, const char *fmt, ...); |
| void p2s_note(const char *fmt, ...); |
| void p2s_fatal(const char *fmt, ...); |
|
|
| |
|
|
| #define HASHMAP_INIT_CAP 64 |
|
|
| typedef struct HashEntry { |
| char *key; |
| void *val; |
| struct HashEntry *next; |
| } HashEntry; |
|
|
| typedef struct HashMap { |
| HashEntry **buckets; |
| size_t cap; |
| size_t len; |
| } HashMap; |
|
|
| HashMap *hashmap_create(void); |
| void hashmap_put(HashMap *m, const char *key, void *val); |
| void *hashmap_get(HashMap *m, const char *key); |
| bool hashmap_has(HashMap *m, const char *key); |
| void hashmap_destroy(HashMap *m); |
|
|
| |
|
|
| char *read_file(const char *path, size_t *out_len); |
|
|
| |
| #ifndef P2S_MIN |
| #define P2S_MIN(a, b) ((a) < (b) ? (a) : (b)) |
| #define P2S_MAX(a, b) ((a) > (b) ? (a) : (b)) |
| #endif |
|
|
| #endif |
|
|