diff options
Diffstat (limited to 'demos/generate-parser.c')
-rw-r--r-- | demos/generate-parser.c | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/demos/generate-parser.c b/demos/generate-parser.c index 5766223..7856db6 100644 --- a/demos/generate-parser.c +++ b/demos/generate-parser.c @@ -1,9 +1,13 @@ #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> +#include <string.h> +#include <unistd.h> // getopt +#include <assert.h> #define DEFUALT_PATH "./bin" #define DEFUALT_TYPE "lalr-table" +#define DEFAULT_OUTPUT "bin/a" #include "parts/symbol.h" size_t total_symbols; @@ -43,32 +47,52 @@ void *xdlsym(void *handle, char *sym) char *modpath(char *name) { static char fullpath[128]; - char *path = getenv("GENERATE_PARSER_PATH"); - if(!path) path = DEFUALT_PATH; - snprintf(fullpath, 128, "%s/%s.so", path, name); + // TODO: search the GENERATE_PARSER_PATH env var + char *path = DEFUALT_PATH; + + assert(snprintf(fullpath, 128, "%s/%s.so", path, name) < 128); return fullpath; } +char *add_extension(char *str, char *ext) +{ + static char full[128]; + assert((strlen(str) + strlen(ext) + 1) <= 128); + memcpy(full, str, strlen(str)+1); + return strcat(full, ext); +} + +void set_stdout(char *filename) +{ + if(!filename) filename = "/dev/tty"; + assert(freopen(filename, "a+", stdout)); +} + int main(int argc, char **argv) { - if(argc < 2) return -1; - - void *table_handle; - void *def_handle; - - if(argc == 2) { - table_handle = dlopen(modpath(DEFUALT_TYPE), RTLD_LAZY); - if(!table_handle) { fputs(dlerror(), stderr); return 1; } - def_handle = dlopen(argv[1], RTLD_LAZY); - if(!def_handle) { fputs(dlerror(), stderr); return 1; } - } else if(argc == 4 && - argv[1][0] == '-' && argv[1][1] == 't') { - table_handle = dlopen(modpath(argv[2]), RTLD_LAZY); - if(!table_handle) { fputs(dlerror(), stderr); return 1; } - def_handle = dlopen(argv[3], RTLD_LAZY); - if(!def_handle) { fputs(dlerror(), stderr); return 1; } - } else return -1; + char *type = DEFUALT_TYPE; + char *output_path = DEFAULT_OUTPUT; + + int opt; + while((opt = getopt(argc, argv, "t:o:")) != -1) { + switch(opt) { + case 't': type = optarg; break; + case 'o': output_path = optarg; break; + default: fprintf(stderr, "ERROR: Unknown options '%c'\n", optopt); + return 1; + } + } + + if(optind == argc) { + fprintf(stderr, "ERROR: No input file\n"); + return 1; + } + + void *table_handle = dlopen(modpath(type), RTLD_LAZY); + if(!table_handle) { fputs(dlerror(), stderr); return 1; } + void *def_handle = dlopen(argv[optind], RTLD_LAZY); + if(!def_handle) { fputs(dlerror(), stderr); return 1; } GET_VARIABLE(table, table_handle); GET_VARIABLE(table_states, table_handle); @@ -91,6 +115,7 @@ int main(int argc, char **argv) goto cleanup; } + set_stdout(add_extension(output_path, ".c")); printf("size_t total_symbols = %zu;\n", total_symbols); printf("IMPLEMENT_FUNCPTR(int, symbol_is_valid, (symbol s)) {return s < total_symbols;}\n"); @@ -121,6 +146,7 @@ int main(int argc, char **argv) for(size_t i = 0; i < total_productions; i++) printf("__prod%zu_action, ", i); printf("};"); + set_stdout(NULL); cleanup: table_free(); |