aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2023-09-02 15:52:40 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2023-09-02 15:52:40 +0100
commit89b9c0f94d290d5fb774af7fec5868deda0fd878 (patch)
treedf1c3b6e8c4d9bec5cd88cf28f36b343d96f8a95
parent7d369f6fadfe7a2ff589fb11c2ba3eaa98675373 (diff)
downloadobf-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.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/main.c b/main.c
index 28dbb77..41039b3 100644
--- a/main.c
+++ b/main.c
@@ -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;
}