#define STR_IMPLEMENTATION #include "str.h" #include "aoc.h" #include Arena *make_arena(ptrdiff_t size) { void *mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); Arena *arena = arena_init(mem, size); return arena; } str read_file(Arena *arena, const char *filename) { FILE *f = fopen(filename, "r"); ASSERT(f); fseek(f, 0, SEEK_END); size_t size = ftell(f); fseek(f, 0, SEEK_SET); char *data = ARENA_ALLOC_ARRAY(arena, char, size + 1); size_t read_size = fread(data, 1, size, f); ASSERT(read_size == size); data[size] = '\0'; fclose(f); return make_str((uint8_t *) data, size); } Tokens str_tokenize(Arena *arena, str s, str delim) { // 1st pass: count number of tokens str stuff = s; isize token_count = 0; for (; stuff.len > 0; str_next_token(&stuff, delim)) { token_count++; } // 2nd pass: allocate memory and copy tokens Tokens result = { .len = token_count, .tokens = ARENA_ALLOC_ARRAY(arena, str, token_count) }; ASSERT(result.tokens); stuff = s; for (isize i = 0; i < token_count; ++i) { result.tokens[i] = str_next_token(&stuff, delim); } return result; } Tokens read_lines(Arena *arena, const char *path) { str file = read_file(arena, path); Tokens lines = str_tokenize(arena, file, STR("\n")); return lines; } char * str_to_cstr(str s, Arena *a) { char *result = ARENA_ALLOC_ARRAY(a, char, s.len + 1); memcpy(result, s.data, s.len); result[s.len] = '\0'; return result; } i64 parse_i64(str s, Arena temp) { char *cs = str_to_cstr(s, &temp); char *endptr; i64 result = strtol(cs, &endptr, 10); ASSERT(*endptr == '\0'); return result; } Grid parse_grid(str input, Arena *arena) { Tokens lines = str_tokenize(arena, str_trim(input), STR("\n")); ASSERT(lines.len > 0); i32 width = lines.tokens[0].len; for (i32 i = 0; i < lines.len; i++) { ASSERT(lines.tokens[i].len == width); } Grid grid = { .width = width, .height = lines.len }; grid.grid = ARENA_ALLOC_ARRAY(arena, u8, grid.width * grid.height); for (i32 i = 0; i < lines.len; i++) { memcpy(grid.grid + i * grid.width, lines.tokens[i].data, grid.width); } return grid; }