X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=blobdiff_plain;f=src%2Fmain.c;h=05ea89235061fc67b83013bfd2386ebeb2e3cbc4;hp=a97f2d7d71606da039bf0ded4764654dd8b64005;hb=HEAD;hpb=bc1691627adee054210acf7e801361fa574f8086 diff --git a/src/main.c b/src/main.c index a97f2d7..05ea892 100644 --- a/src/main.c +++ b/src/main.c @@ -3,56 +3,137 @@ #include #include -#include "../include/oberon.h" +#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 const char * +static oberon_scanner_t * import_module(const char * name) { - assert(name); + oberon_scanner_t * res = malloc(sizeof *res); + memset(res, 0, sizeof *res); FILE * fp; - char fname[256]; - snprintf(fname, 256, "%s.obn", name); - fp = fopen(fname, "r"); + fp = open_file(path_list, "obn", name, "r", res); if(fp == NULL) { - printf("can't open file %s\n", fname); - exit(1); return NULL; } - char * source; size_t len; fseek(fp, 0, SEEK_END); len = ftell(fp); fseek(fp, 0, SEEK_SET); - source = calloc(1, len + 1); - fread(source, len, 1, fp); + res -> code = calloc(1, len + 1); + fread(res -> code, len, 1, fp); - return source; + 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) { - const char * code; + oberon_scanner_t * s; - if(argc != 2) + init(argc, argv); + + s = import_module(module); + if(s == NULL) { - printf("use: %s \n", argv[0]); - return 1; + printf("can't open module source %s\n", module); + return 0; } - code = import_module(argv[1]); - ctx = oberon_create_context(import_module); - mod = oberon_compile_module(ctx, code); + oberon_set_out_directory(ctx, out_path); + + mod = oberon_compile_module(ctx, s); oberon_destroy_context(ctx); + return 0; }