]> git.mdlowis.com Git - proto/aos.git/commitdiff
Started specifying option parsing logic
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 14 Dec 2020 22:02:42 +0000 (17:02 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 14 Dec 2020 22:02:42 +0000 (17:02 -0500)
inc/liba.h
lib/a/opts_parse.c [new file with mode: 0644]

index d18dbf18bd11f3f72d8f12106e93452365b99e49..5a5ebe3ff7b5e928a433e12258214c4429ba6791 100644 (file)
 /* we're only targeting unixes */
 #include <unistd.h>
 
-/* 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 (file)
index 0000000..b446747
--- /dev/null
@@ -0,0 +1,7 @@
+#include <liba.h>
+
+void opts_parse(int argc, char** argv)
+{
+    (void)argc;
+    (void)argv;
+}