diff options
| author | eunhhu <[email protected]> | 2026-10-19 00:40:55 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-19 00:40:55 +0100 |
| commit | e0298482010b0f78398b3c94cb0d127db5042a78 (patch) | |
| tree | 8d0715d1ceee9719f93996c0e0b0fa69d0e9e6ed /compiler/main.c | |
| parent | 9480b493e4b919245e84799417641e7ccb7401a1 (diff) | |
| download | aup-e0298482010b0f78398b3c94cb0d127db5042a78.tar.gz aup-e0298482010b0f78398b3c94cb0d127db5042a78.zip | |
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
Diffstat (limited to 'compiler/main.c')
| -rw-r--r-- | compiler/main.c | 27 |
1 files changed, 19 insertions, 8 deletions
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); |
