From e0298482010b0f78398b3c94cb0d127db5042a78 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 19 Oct 2026 00:40:55 +0100 Subject: Pure 027's 4f-4: a source of any size (files and standard input read whole), the compiler's tables raised to Pure's widths (4,096 states, 1,024 inputs, 4,096 views and handlers, 1,024 records, 16,384 record fields; 15 MB calloc'd, its unused rooms never touched) and its diagnostics saying so; at most 255 outputs (Pure's store counts them in a byte), a walked or folded list among the first 256 states (its argument's byte), said before Pure would refuse; a wide program checked: 301 states, 40 inputs, 70 views and 20 records in 48 KB of source, run to the last of each --- compiler/main.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'compiler/main.c') diff --git a/compiler/main.c b/compiler/main.c index b822430..212dda4 100644 --- a/compiler/main.c +++ b/compiler/main.c @@ -14,16 +14,28 @@ static int usage(void) { return 2; } -/* Read a whole source (up to one byte past the limit, which the compiler - * reports); NULL if it cannot be read. */ +/* All of a file's bytes, of any size (Pure 027's 4f-4); NULL if they cannot be read. */ +static char *read_all(FILE *file, size_t *length) { + size_t room = 1 << 15, used = 0; + char *bytes = malloc(room); + while (bytes) { + used += fread(bytes + used, 1, room - used, file); + if (used < room || ferror(file)) break; + char *grown = room <= SIZE_MAX / 2 ? realloc(bytes, room *= 2) : NULL; + if (!grown) { free(bytes); bytes = NULL; } + else bytes = grown; + } + if (bytes && ferror(file)) { free(bytes); bytes = NULL; } + *length = bytes ? used : 0; + return bytes; +} + +/* Read a whole source; NULL if it cannot be read. */ static char *read_source(const char *path, size_t *length) { FILE *file = fopen(path, "rb"); if (!file) return NULL; - char *source = malloc(AUP_SOURCE_LIMIT + 1); - *length = source ? fread(source, 1, AUP_SOURCE_LIMIT + 1, file) : 0; - bool failed = !source || ferror(file); + char *source = read_all(file, length); fclose(file); - if (failed) { free(source); return NULL; } return source; } @@ -137,8 +149,7 @@ static int query(const char *app, const char *query_path, const char *out) { if (!app_source) { perror(app); return 2; } char *query_source = NULL; if (strcmp(query_path, "-")) query_source = read_input(&inputs, query_path, &query_length); - else if ((query_source = malloc(AUP_SOURCE_LIMIT + 1))) - query_length = fread(query_source, 1, AUP_SOURCE_LIMIT + 1, stdin); + else query_source = read_all(stdin, &query_length); char *source = query_source ? malloc(app_length + 1 + query_length) : NULL; if (!source) { perror(query_path); -- cgit v1.2.3