#include #include #include #include #include "oberon-internals.h" #include "generator.h" struct string_stack { char * string; struct string_stack * next; }; static oberon_context_t * ctx; static oberon_module_t * mod; static const char * module; static const char * out_path; static struct string_stack * path_list; static void add_to_stack(struct string_stack ** stack, char * string) { struct string_stack * p = malloc(sizeof *p); p -> string = string; p -> next = *stack; *stack = p; } static FILE * open_file(struct string_stack * path, const char * ext, const char * name, const char * mode, oberon_scanner_t * res) { char fname[256]; memset(fname, 0, 256); FILE * fp = NULL; while(fp == NULL && path != NULL) { snprintf(fname, 256, "%s/%s.%s", path -> string, name, ext); fp = fopen(fname, mode); path = path -> next; } if(fp == NULL) { snprintf(fname, 256, "%s.%s", name, ext); fp = fopen(fname, mode); } size_t len = strlen(fname); res -> source = malloc(len + 1); memcpy(res -> source, fname, len + 1); return fp; } static oberon_scanner_t * import_module(const char * name) { oberon_scanner_t * res = malloc(sizeof *res); memset(res, 0, sizeof *res); FILE * fp; fp = open_file(path_list, "obn", name, "r", res); if(fp == NULL) { return NULL; } size_t len; fseek(fp, 0, SEEK_END); len = ftell(fp); fseek(fp, 0, SEEK_SET); res -> code = calloc(1, len + 1); fread(res -> code, len, 1, fp); return res; } static void init(int argc, char ** argv) { int i = 1; out_path = "."; while(argc > 2) { if(argc > 2 && strcmp(argv[i], "-d") == 0) { out_path = argv[i + 1]; argc -= 2; i += 2; } else if(argc > 2 && strcmp(argv[i], "-I") == 0) { add_to_stack(&path_list, argv[i + 1]); argc -= 2; i += 2; } else { break; } } if(argc != 2 || argv[i][0] == '-') { printf("usage: obn [-d out_dir] module\n"); exit(1); } module = argv[i]; } int main(int argc, char ** argv) { oberon_scanner_t * s; init(argc, argv); s = import_module(module); if(s == NULL) { printf("can't open module source %s\n", module); return 0; } ctx = oberon_create_context(import_module); oberon_set_out_directory(ctx, out_path); mod = oberon_compile_module(ctx, s); oberon_destroy_context(ctx); return 0; }