From: Michael D. Lowis Date: Mon, 14 Dec 2020 22:02:42 +0000 (-0500) Subject: Started specifying option parsing logic X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=1fb598b37983881aa2fcb837e4fed9ca928045b7;p=proto%2Faos.git Started specifying option parsing logic --- diff --git a/inc/liba.h b/inc/liba.h index d18dbf1..5a5ebe3 100644 --- a/inc/liba.h +++ b/inc/liba.h @@ -18,102 +18,6 @@ /* we're only targeting unixes */ #include -/* This variable contains the value of argv[0] so that it can be referenced - * again once the option parsing is done. This variable must be defined by the - * program. */ -extern char* ARGV0; - -/* Option Parsing - ******************************************************************************* - * This following macros implement a simple POSIX-style option parsing strategy. - * They are heavily influenced and inspired by the arg.h file from suckless.org - * (http://git.suckless.org/libsl/tree/arg.h). That file is in turn inspired by - * the corresponding macros defined in plan9 libc.h. - * - * The interface assumes that the main function will have the following - * prototype: - * - * int main(int argc, char** argv); - * - * An example usage of the interface would look something like the follwoing: - * - * char* ARGV0; - * int main(int argc, char** argv) { - * OPTBEGIN { - * case 'a': printf("Simple option\n"); break; - * case 'b': printf("Option with arg: %s\n", OPTARG()); break; - * default: printf("Unknown option!\n"); - * } OPTEND; - * return 0; - * } - */ - -/* This is a helper function used by the following macros to parse the next - * option from the command line. */ -static inline char* _getopt_(int* p_argc, char*** p_argv) { - if (!(*p_argv)[0][1] && !(*p_argv)[1]) { - return (char*)0; - } else if ((*p_argv)[0][1]) { - return &(*p_argv)[0][1]; - } else { - *p_argv = *p_argv + 1; - *p_argc = *p_argc - 1; - return (*p_argv)[0]; - } -} - -/* This macro is almost identical to the ARGBEGIN macro from suckless.org. If - * it ain't broke, don't fix it. */ -#define OPTBEGIN \ - for ( \ - ARGV0 = *argv, argc--, argv++; \ - argv[0] && argv[0][1] && argv[0][0] == '-'; \ - argc--, argv++ \ - ) { \ - int brk_; char argc_ , **argv_, *optarg_; \ - if (argv[0][1] == '-' && !argv[0][2]) { \ - argv++, argc--; break; \ - } \ - for (brk_=0, argv[0]++, argv_=argv; argv[0][0] && !brk_; argv[0]++) { \ - if (argv_ != argv) break; \ - argc_ = argv[0][0]; \ - switch (argc_) - -/* Terminate the option parsing. */ -#define OPTEND }} - -/* Get the current option character */ -#define OPTC() (argc_) - -/* Get an argument from the command line and return it as a string. If no - * argument is available, this macro returns NULL */ -#define OPTARG() \ - (optarg_ = _getopt_(&argc,&argv), brk_ = (optarg_!=0), optarg_) - -/* Get an argument from the command line and return it as a string. If no - * argument is available, this macro executes the provided code. If that code - * returns, then abort is called. */ -#define EOPTARG(code) \ - (optarg_ = _getopt_(&argc,&argv), \ - (!optarg_ ? ((code), abort(), (char*)0) : (brk_ = 1, optarg_))) - -/* Helper macro to recognize number options */ -#define OPTNUM \ - case '0': \ - case '1': \ - case '2': \ - case '3': \ - case '4': \ - case '5': \ - case '6': \ - case '7': \ - case '8': \ - case '9' - -/* Helper macro to recognize "long" options ala GNU style. */ -#define OPTLONG \ - case '-' - /* Miscellaneous Macros ******************************************************************************/ #ifndef nelem @@ -126,29 +30,45 @@ static inline char* _getopt_(int* p_argc, char*** p_argv) { (type*)((uintptr_t)obj - offsetof(type, member)) #endif -#define concat(a,b) \ - a##b - -#define ident(a) \ - concat(id, a) - -#define unique_id \ - ident(__LINE__) - -#ifndef static_assert - #define static_assert(expr) \ - typedef char unique_id[( expr )?1:-1] -#endif - +/* + Basic Runtime Facilities +*/ /* rename user's main routine so GC is auto-initialized */ extern int usermain(int, char**); #define main usermain +/* This variable contains the value of argv[0] so that it can be referenced + * again once the option parsing is done. This variable must be defined by the + * program. */ +extern char* ARGV0; + void* gc_alloc(size_t sz); void gc_addref(void* p); void gc_delref(void* p); +typedef struct { + char* name; + char* desc; +} Option_T; + +/* + { .name = "v" } // Error + { .name = "v," } + { .name = ",foo" } + { .name = "b,bar" } + { .name = ":b,bar" } + { .name = ":,bar" } + { .name = ":b," } +*/ + +extern Option_T Options[]; + +void opts_parse(int argc, char** argv); + +/* + Standard Library Helpers +*/ void fatal(const char* fmt, ...); void warn(const char* fmt, ...); void esignal(int sig, void (*func)(int)); diff --git a/lib/a/opts_parse.c b/lib/a/opts_parse.c new file mode 100644 index 0000000..b446747 --- /dev/null +++ b/lib/a/opts_parse.c @@ -0,0 +1,7 @@ +#include + +void opts_parse(int argc, char** argv) +{ + (void)argc; + (void)argv; +}