]> git.mdlowis.com Git - proto/aos.git/commitdiff
implemented basic parsing of long options
authorMichael D. Lowis <mike.lowis@gentex.com>
Tue, 15 Dec 2020 17:07:01 +0000 (12:07 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Tue, 15 Dec 2020 17:07:01 +0000 (12:07 -0500)
inc/liba.h
lib/a/gc.c
lib/a/options.c [new file with mode: 0644]
lib/a/opts_parse.c
lib/a/opts_printhelp.c
tools/build.c

index 52e3867601471e35bf6c0006d373989c59dd410c..68d4039f524f31aa2ce86ffe442391d04ce7b24e 100644 (file)
@@ -35,7 +35,7 @@
 */
 
 /* rename user's main routine so GC is auto-initialized and options parsed */
-extern int usermain(int, char**);
+extern int usermain(int argc, char** argv);
 #define main usermain
 
 /*
index b60578d2036929a84608787c3f7d3c9163a65cf7..5c0699dbbc5938f95d23667d6c7f2fdd32625416 100644 (file)
@@ -87,7 +87,7 @@ void gc_delref(void* p)
 
 int main(int argc, char** argv)
 {
-    (void)argc, (void)argv;
+    opts_parse(argc, argv);
     Stack_Bot = &(intptr_t){0};
     Log.index = 0;
     hash_init(&ZCT,0);
diff --git a/lib/a/options.c b/lib/a/options.c
new file mode 100644 (file)
index 0000000..edc18c8
--- /dev/null
@@ -0,0 +1,3 @@
+#include <liba.h>
+
+Option_T Options[] = { {0,0} };
\ No newline at end of file
index b446747373fd50c93a07b446008ee03f595eccfd..1e18855683c7c38aee8ae4eaf7527d4a52b6b090 100644 (file)
@@ -1,7 +1,113 @@
 #include <liba.h>
 
+static OptionDescriptor_T* lookup_opt(int optc, OptionDescriptor_T* optv, char* flag)
+{
+    OptionDescriptor_T* opt = NULL;
+
+    for (int i = 0; i < optc; i++)
+    {
+        int match = (
+               (flag[1]  && !strcmp(optv[i].lname, flag))
+            || (!flag[1] && flag[0] == optv[i].sname)
+        );
+        if (match)
+        {
+            opt = &optv[i];
+            break;
+        }
+    }
+
+    return opt;
+}
+
+static void parse_longopt(int optc, OptionDescriptor_T* optv, int* currp, char** argv)
+{
+    /* get the option and the arg if there is one */
+    char* flag = argv[*currp] + 2;
+    char* split = strchr(flag, '=');
+    char* arg = NULL;
+    if (split)
+    {
+        *split = '\0';
+        arg = split+1;
+    }
+
+    OptionDescriptor_T* od = lookup_opt(optc, optv, flag);
+    if (!od)
+    {
+        fatal("unknown option: '%s'", flag);
+    }
+    else if (arg && !od->hasarg)
+    {
+        fatal("unexpected argument to option: --%s=%s", flag, arg);
+    }
+    else
+    {
+        if (od->hasarg && !arg)
+        {
+            *currp += 1;
+            arg = argv[*currp];
+            if (!arg)
+            {
+                fatal("expected argument for option: '%s'", flag);
+            }
+        }
+        printf("handled option: '--%s=%s'\n", flag, arg);
+    }
+
+    /* now repair the split if we made one */
+    if (split && *split)
+    {
+        *split = '=';
+    }
+    *currp += 1;
+}
+
+static void parse_shortopt(int optc, OptionDescriptor_T* optv, int* currp, char** argv)
+{
+    (void)optc, (void)optv;
+    printf("short: %s\n", argv[*currp]);
+    *currp += 1;
+}
+
 void opts_parse(int argc, char** argv)
 {
-    (void)argc;
-    (void)argv;
+    /* parse the option descriptors for easy usage during parsing */
+    int capacity = 32;
+    int optc = 1;
+    OptionDescriptor_T* optv = malloc(capacity * sizeof(OptionDescriptor_T));
+    opts_parsespec("h,help", optv);
+    for (Option_T* curr = Options; curr->name; curr++)
+    {
+        if (optc == capacity)
+        {
+            capacity <<= 1;
+            optv = realloc(optv, capacity * sizeof(OptionDescriptor_T));
+        }
+        opts_parsespec(curr->name, &optv[optc]);
+        optc++;
+    }
+
+    /* Record the program name */
+    ARGV0 = argv[0];
+
+    /* now parse the arguments */
+    for (int i = 1; i < argc;)
+    {
+        if (argv[i][0] == '-' && argv[i][1] == '-')
+        {
+            parse_longopt(optc, optv, &i, argv);
+        }
+        else if (argv[i][0] == '-')
+        {
+            parse_shortopt(optc, optv, &i, argv);
+        }
+        else
+        {
+            printf("posarg: %s\n", argv[i]);
+            i++;
+        }
+    }
+
+    free(optv);
 }
index 5b8096a707703a7c17a82e7d756dc74198e8bcaf..20f1d89c66c90f8ee75a0b8ec02fe4ab80f0acfa 100644 (file)
@@ -1,5 +1,10 @@
 #include <liba.h>
 
+/*
+    TODO:
+        * Print -h, --help in the help output
+*/
+
 void opts_printhelp(void)
 {
     Option_T* opts = Options;
index cdb0721203a0b8c00de4dea902f891cf42b69697..54927f3740501a9885f6b8c422bcdedd284111d4 100644 (file)
@@ -27,7 +27,7 @@ char* CCCMD[] = {
     "-I/usr/X11/include/",
     "-I/usr/X11/include/freetype2",
     "-I/usr/include/freetype2/",
-    "-c", "-o",
+    "-g", "-c", "-o",
     /* output */
     /* inputs */
     NULL
@@ -42,7 +42,7 @@ char* LDCMD[] = {
     "cc",
     "-L./build/lib",
     "-L/usr/X11/lib/",
-    "-o",
+    "-g", "-o",
     /* output */
     /* inputs */
     /* LIBS */
@@ -219,7 +219,6 @@ int should_rebuild(char** outputs, char** inputs)
 
 void object(Target* tgt)
 {
-    printf("Object %s\n", tgt->outputs[0]);
     char** cmd = make_cmd((char**[]){ CCCMD, tgt->outputs, tgt->inputs, NULL });
     print_cmd(cmd);
     make_dirs(tgt->outputs);
@@ -228,7 +227,6 @@ void object(Target* tgt)
 
 void library(Target* tgt)
 {
-    printf("Library %s\n", tgt->outputs[0]);
     char** cmd = make_cmd((char**[]){ ARCMD, tgt->outputs, tgt->inputs, NULL });
     print_cmd(cmd);
     exit(execvp(cmd[0], cmd));
@@ -236,7 +234,6 @@ void library(Target* tgt)
 
 void binary(Target* tgt)
 {
-    printf("Binary %s\n", tgt->outputs[0]);
     char** cmd = make_cmd((char**[]){
         LDCMD, tgt->outputs, tgt->inputs, LIBS, NULL });
     print_cmd(cmd);
@@ -327,7 +324,7 @@ void build_targets(Target* targets)
         int pid = fork();
         if (pid == 0)
         {
-            if (should_rebuild(targets->outputs, targets->inputs))
+            if (targets->build == binary || should_rebuild(targets->outputs, targets->inputs))
             {
                 targets->build(targets);
             }