diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-09-02 15:52:40 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-09-02 15:52:40 +0100 |
commit | 89b9c0f94d290d5fb774af7fec5868deda0fd878 (patch) | |
tree | df1c3b6e8c4d9bec5cd88cf28f36b343d96f8a95 | |
parent | 7d369f6fadfe7a2ff589fb11c2ba3eaa98675373 (diff) | |
download | obf-89b9c0f94d290d5fb774af7fec5868deda0fd878.tar.gz obf-89b9c0f94d290d5fb774af7fec5868deda0fd878.tar.bz2 obf-89b9c0f94d290d5fb774af7fec5868deda0fd878.zip |
Chunk allocator for file handling
Apparently you can't just `fseek` because it's "not portable" and
"deeply offensive" or whatever, so here's a really dirty chunk based
allocator which uses `fread` to just read chunks of data at a time and
basically runs around this issue.
While it's slower than an fseek solution for general files, this
solution allows pipes and other _weird_ things that count as "files"
to just werk.
-rw-r--r-- | main.c | 46 |
1 files changed, 41 insertions, 5 deletions
@@ -203,22 +203,58 @@ char *ast_to_str(node_t *ast, size_t size) return out; } +#define MAX(a, b) (a > b ? a : b) + +char *fread_all(FILE *fp) +{ + const size_t CHUNK_SIZE = 1024, MULT = 2; + struct + { + char *data; + size_t used, available; + } buffer = {calloc(CHUNK_SIZE, sizeof(*buffer.data)), 0, CHUNK_SIZE}; + + size_t acc = 0, bytes_read = 0; + while ((bytes_read = fread(buffer.data + acc, sizeof(*buffer.data), + CHUNK_SIZE, fp)) != 0) + { + buffer.used += bytes_read; + acc += bytes_read; + if (buffer.used + CHUNK_SIZE >= buffer.available) + { + buffer.available = MAX(buffer.available * MULT, buffer.used + CHUNK_SIZE); + buffer.data = realloc(buffer.data, buffer.available); + } + } + buffer.data = realloc(buffer.data, buffer.used + 1); + buffer.data[buffer.used] = '\0'; + return buffer.data; +} + int main(void) { - const char input[] = "[->+<]]"; - buffer_t *buffer = - buffer_init_str("*internal*", input, sizeof(input) / sizeof(input[0])); + const char *filepath = "./input.txt"; + FILE *handle = fopen(filepath, "r"); + char *file_data = fread_all(handle); + fclose(handle); + buffer_t *buffer = buffer_init_str(filepath, file_data, strlen(file_data)); struct PResult res = parse_input(buffer); if (res.nodes == NULL) { fputs("Exiting early...\n", stderr); - free(buffer); - return 1; + goto error; } char *str = ast_to_str(res.nodes, res.size); free(str); free(res.nodes); free(buffer); + free(file_data); return 0; +error: + if (buffer) + free(buffer); + if (res.nodes) + free(res.nodes); + return 1; } |