aboutsummaryrefslogtreecommitdiff
path: root/demos/generate-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'demos/generate-parser.c')
-rw-r--r--demos/generate-parser.c66
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();