diff --git a/src/globals.c b/src/globals.c index a0c09933..f6107e41 100644 --- a/src/globals.c +++ b/src/globals.c @@ -911,7 +911,7 @@ void add_insn(block_t *block, bb->insn_list.tail = n; } -source_t *create_source(int init_capacity) +source_t *source_create(int init_capacity) { source_t *array = malloc(sizeof(source_t)); if (!array) @@ -928,12 +928,18 @@ source_t *create_source(int init_capacity) return array; } -bool source_expand(source_t *src) +bool source_extend(source_t *src, int len) { - if (src->size < src->capacity) + int new_size = src->size + len; + + if (new_size < src->capacity) return true; - src->capacity <<= 1; + if (new_size > src->capacity << 1) + src->capacity = new_size; + else + src->capacity <<= 1; + char *new_arr = malloc(src->capacity * sizeof(char)); if (!new_arr) @@ -949,7 +955,7 @@ bool source_expand(source_t *src) bool source_push(source_t *src, char value) { - if (!source_expand(src)) + if (!source_extend(src, 1)) return false; src->elements[src->size] = value; @@ -958,7 +964,20 @@ bool source_push(source_t *src, char value) return true; } -void source_release(source_t *src) +bool source_push_str(source_t *src, char *value) +{ + int len = strlen(value); + + if (!source_extend(src, len)) + return false; + + strncpy(src->elements + src->size, value, len); + src->size += len; + + return true; +} + +void source_free(source_t *src) { if (!src) return; @@ -985,7 +1004,7 @@ void global_init() BB_ARENA = arena_init(DEFAULT_ARENA_SIZE); PH2_IR_FLATTEN = malloc(MAX_IR_INSTR * sizeof(ph2_ir_t *)); LABEL_LUT = malloc(MAX_LABEL * sizeof(label_lut_t)); - SOURCE = create_source(MAX_SOURCE); + SOURCE = source_create(MAX_SOURCE); INCLUSION_MAP = hashmap_create(MAX_INCLUSIONS); ALIASES = malloc(MAX_ALIASES * sizeof(alias_t)); CONSTANTS = malloc(MAX_CONSTANTS * sizeof(constant_t)); @@ -1018,7 +1037,7 @@ void global_release() arena_free(BB_ARENA); free(PH2_IR_FLATTEN); free(LABEL_LUT); - source_release(SOURCE); + source_free(SOURCE); hashmap_free(INCLUSION_MAP); free(ALIASES); free(CONSTANTS); diff --git a/src/parser.c b/src/parser.c index d70913e7..661c13b9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -3428,8 +3428,7 @@ void load_source_file(char *file) snprintf(path + c + 1, inclusion_path_len, "%s", buffer + 10); load_source_file(path); } else { - strcpy(SOURCE->elements + SOURCE->size, buffer); - SOURCE->size += strlen(buffer); + source_push_str(SOURCE, buffer); } } diff --git a/tools/inliner.c b/tools/inliner.c index 952c412c..56cf7be1 100644 --- a/tools/inliner.c +++ b/tools/inliner.c @@ -12,24 +12,98 @@ * C runtime and essential libraries. */ +#include #include #include +#include #define MAX_LINE_LEN 200 -#define MAX_SIZE 65536 +#define DEFAULT_SOURCE_SIZE 65536 -char *SOURCE; -int source_idx; +#define write_char(c) source_push(SOURCE, c) +#define write_str(s) source_push_str(SOURCE, s) -void write_char(char c) +typedef struct { + int size; + int capacity; + char *elements; +} source_t; + +source_t *SOURCE; + +source_t *source_create(int init_capacity) +{ + source_t *array = malloc(sizeof(source_t)); + if (!array) + return NULL; + + array->size = 0; + array->capacity = init_capacity; + array->elements = malloc(array->capacity * sizeof(char)); + if (!array->elements) { + free(array); + return NULL; + } + + return array; +} + +bool source_extend(source_t *src, int len) +{ + int new_size = src->size + len; + + if (new_size < src->capacity) + return true; + + if (new_size > src->capacity << 1) + src->capacity = new_size; + else + src->capacity <<= 1; + + char *new_arr = malloc(src->capacity * sizeof(char)); + + if (!new_arr) + return false; + + memcpy(new_arr, src->elements, src->size * sizeof(char)); + + free(src->elements); + src->elements = new_arr; + + return true; +} + +bool source_push(source_t *src, char value) { - SOURCE[source_idx++] = c; + if (!source_extend(src, 1)) + return false; + + src->elements[src->size] = value; + src->size++; + + return true; } -void write_str(char *str) +bool source_push_str(source_t *src, char *value) { - for (int i = 0; str[i]; i++) - write_char(str[i]); + int len = strlen(value); + + if (!source_extend(src, len)) + return false; + + strncpy(src->elements + src->size, value, len); + src->size += len; + + return true; +} + +void source_free(source_t *src) +{ + if (!src) + return; + + free(src->elements); + free(src); } void write_line(char *src) @@ -66,8 +140,8 @@ void load_from(char *file) void save_to(char *file) { FILE *f = fopen(file, "wb"); - for (int i = 0; i < source_idx; i++) - fputc(SOURCE[i], f); + for (int i = 0; i < SOURCE->size; i++) + fputc(SOURCE->elements[i], f); fclose(f); } @@ -78,8 +152,7 @@ int main(int argc, char *argv[]) return -1; } - source_idx = 0; - SOURCE = malloc(MAX_SIZE); + SOURCE = source_create(DEFAULT_SOURCE_SIZE); write_str("/* Created by tools/inliner - DO NOT EDIT. */\n"); @@ -94,14 +167,14 @@ int main(int argc, char *argv[]) * __c("}\n"); */ write_str("void __c(char *src) {\n"); - write_str(" for (int i = 0; src[i]; i++)\n"); - write_str(" source_push(SOURCE, src[i]);\n"); + write_str(" source_push_str(SOURCE, src);\n"); write_str("}\n"); write_str("void libc_generate() {\n"); load_from(argv[1]); write_str("}\n"); save_to(argv[2]); + source_free(SOURCE); return 0; }