From 19e7884c90ce718bedf6330055e8a635a8a5d770 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 18 Dec 2020 16:50:15 -0500 Subject: [PATCH] completed option parser. Just need to implement default option hook --- inc/liba.h | 7 +++-- lib/a/opts_parse.c | 58 ++++++++++++++++++++++++++++++++++++++++-- lib/a/opts_printhelp.c | 6 ++++- lib/a/usage.c | 3 +++ 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 lib/a/usage.c diff --git a/inc/liba.h b/inc/liba.h index 68d4039..dfb52d1 100644 --- a/inc/liba.h +++ b/inc/liba.h @@ -35,8 +35,11 @@ */ /* rename user's main routine so GC is auto-initialized and options parsed */ -extern int usermain(int argc, char** argv); -#define main usermain +extern int user_main(int argc, char** argv); +#define main user_main + +extern void opts_setoption(int sname, char* lname, char* arg); + /* Garbage Collector Interface diff --git a/lib/a/opts_parse.c b/lib/a/opts_parse.c index 1e18855..6f88b27 100644 --- a/lib/a/opts_parse.c +++ b/lib/a/opts_parse.c @@ -1,5 +1,19 @@ #include +extern void opts_setoption(int sname, char* lname, char* arg) +{ + if (sname == 'h') + { + opts_printhelp(); + exit(1); + } + else + { + printf(" --%s=%s\n", lname, arg); + } +} + + static OptionDescriptor_T* lookup_opt(int optc, OptionDescriptor_T* optv, char* flag) { OptionDescriptor_T* opt = NULL; @@ -53,6 +67,7 @@ static void parse_longopt(int optc, OptionDescriptor_T* optv, int* currp, char** } } printf("handled option: '--%s=%s'\n", flag, arg); + opts_setoption(od->sname, od->lname, arg); } /* now repair the split if we made one */ @@ -65,8 +80,47 @@ static void parse_longopt(int optc, OptionDescriptor_T* optv, int* currp, char** static void parse_shortopt(int optc, OptionDescriptor_T* optv, int* currp, char** argv) { - (void)optc, (void)optv; - printf("short: %s\n", argv[*currp]); + char* argstr = argv[*currp]+1; + char flag[] = "\0\0"; + for (; *argstr; argstr++) + { + /* get the flag and the possible argument */ + flag[0] = *argstr; + OptionDescriptor_T* od = lookup_opt(optc, optv, flag); + if (!od) + { + fatal("unknown option: '%s'", flag); + } + else if (od->hasarg) + { + char* arg = argstr+1; + if (*arg != '\0') + { + arg += (*arg == '=' ? 1 : 0); + opts_setoption(od->sname, od->lname, arg); + break; + } + else if (!*arg) + { + arg = argv[*currp + 1]; + if (!arg) + { + fatal("expected argument for option: '%s'", flag); + } + opts_setoption(od->sname, od->lname, arg); + *currp += 1; + break; + } + else + { + fatal("expected argument for option: '%s'", flag); + } + } + else + { + opts_setoption(od->sname, od->lname, NULL); + } + } *currp += 1; } diff --git a/lib/a/opts_printhelp.c b/lib/a/opts_printhelp.c index 20f1d89..ad03d5d 100644 --- a/lib/a/opts_printhelp.c +++ b/lib/a/opts_printhelp.c @@ -34,8 +34,12 @@ void opts_printhelp(void) } } + if (Usage) + { + printf("usage: %s\n\n", Usage); + } + /* print option help messages */ - printf("usage: %s\n\n", Usage); for (Option_T* curr = opts; curr->name; curr++) { int remain = padding; diff --git a/lib/a/usage.c b/lib/a/usage.c new file mode 100644 index 0000000..6eac852 --- /dev/null +++ b/lib/a/usage.c @@ -0,0 +1,3 @@ +#include + +char* Usage = 0; \ No newline at end of file -- 2.55.0