]> git.mdlowis.com Git - proto/aos.git/commitdiff
reworked option parsing to get rid of malloc and work off of static array
authorMichael D. Lowis <mike.lowis@gentex.com>
Wed, 15 Dec 2021 18:21:02 +0000 (13:21 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Wed, 15 Dec 2021 18:21:02 +0000 (13:21 -0500)
bin/dial.c
bin/edit.c
inc/liba.h
lib/a/options.c
lib/a/opts_parse.c
lib/a/opts_parsespec.c [deleted file]
lib/a/opts_printhelp.c [deleted file]

index 16d8430ad99b47c6dfdebad6ad3020ebc5b3a2f5..21bd61b421bd21bc373143edb4dd89da779f68a4 100644 (file)
@@ -2,6 +2,14 @@
 #include <libnet.h>
 #include <sys/poll.h>
 
+char* Usage = "dial [OPTIONS] DIALSTR [CMD [ARG...]]";
+
+//void set_option(int sname, char* lname, char* arg)
+//{
+//
+//}
+
+
 int copy_data(int fromfd, int tofd, int events)
 {
     char buf[16384];
@@ -32,40 +40,42 @@ int copy_data(int fromfd, int tofd, int events)
 
 int main(int argc, char** argv)
 {
-    if (argc < 2)
-    {
-        fprintf(stderr, "usage: dial DIALSTR [CMD [ARG...]]\n");
-        return 1;
-    }
-
-    int running  = 1;
-    int sockfd   = netdial(argv[1]);
-    int cmdinfd  = STDIN_FILENO;
-    int cmdoutfd = STDOUT_FILENO;
-    if (argc > 2)
-    {
-        cmdinfd  = forkexec(&argv[2]);
-        cmdoutfd = cmdinfd;
-        if (cmdinfd < 0)
-        {
-            fatal("forkexec():");
-        }
-    }
+    (void)argc, (void)argv;
 
-    while (running)
-    {
-        struct pollfd fds[] = {
-            { .fd = sockfd,  .events = POLLIN },
-            { .fd = cmdinfd, .events = POLLIN },
-        };
-        if (poll(fds, nelem(fds), -1) < 0)
-        {
-            fatal("poll():");
-        }
-        running = running && copy_data(sockfd, cmdoutfd, fds[0].revents);
-        running = running && copy_data(cmdinfd, sockfd, fds[1].revents);
-    }
-    close(sockfd);
+//    if (argc < 2)
+//    {
+//        fprintf(stderr, "usage: dial DIALSTR [CMD [ARG...]]\n");
+//        return 1;
+//    }
+//
+//    int running  = 1;
+//    int sockfd   = netdial(argv[1]);
+//    int cmdinfd  = STDIN_FILENO;
+//    int cmdoutfd = STDOUT_FILENO;
+//    if (argc > 2)
+//    {
+//        cmdinfd  = forkexec(&argv[2]);
+//        cmdoutfd = cmdinfd;
+//        if (cmdinfd < 0)
+//        {
+//            fatal("forkexec():");
+//        }
+//    }
+//
+//    while (running)
+//    {
+//        struct pollfd fds[] = {
+//            { .fd = sockfd,  .events = POLLIN },
+//            { .fd = cmdinfd, .events = POLLIN },
+//        };
+//        if (poll(fds, nelem(fds), -1) < 0)
+//        {
+//            fatal("poll():");
+//        }
+//        running = running && copy_data(sockfd, cmdoutfd, fds[0].revents);
+//        running = running && copy_data(cmdinfd, sockfd, fds[1].revents);
+//    }
+//    close(sockfd);
 
     return 0;
 }
\ No newline at end of file
index 3ea9348677813dcdd93ec3ae81456f349a860e38..3db827f91fd70b49e65339c2fb93edd4793b3542 100644 (file)
@@ -1,14 +1,16 @@
 #include <liba.h>
 
 char* Usage = "edit [FLAGS...] [FILES...]";
+
 Option_T Options[] = {
-    { "v,verbose", "enable verbose mode" },
-    { ":f,flag", "flag with an arg" },
-    { "F,noflag", "flag without an arg" },
-    { "a,noflag", "flag without an arg" },
-    { "b,noflag", "flag without an arg" },
-    { "c,noflag", "flag without an arg" },
-    { 0, 0 }
+    { .s = 'h', .l = "help",    .a = 0, .d = "print this help message" },
+    { .s = 'v', .l = "verbose", .a = 0, .d = "enable verbose mode" },
+    { .s = 'f', .l = "flag",    .a = 1, .d = "flag with an arg"    },
+    { .s = 'F', .l = "noflag",  .a = 0, .d = "flag without an arg" },
+    { .s = 'a', .l = "noflag",  .a = 0, .d = "flag without an arg" },
+    { .s = 'b', .l = "noflag",  .a = 0, .d = "flag without an arg" },
+    { .s = 'c', .l = "noflag",  .a = 0, .d = "flag without an arg" },
+    {0}
 };
 
 int main(int argc, char** argv)
index f417a7c44726d900a5c2c358e07613ce350891af..3e9fbd1c4e1867169a4df28077102de1e5c88ff9 100644 (file)
@@ -41,20 +41,20 @@ void gc_delref(void* p);
     Option Parsing
 */
 typedef struct {
-    char* name;
-    char* desc;
+    char* l;
+    char* d;
+    char s;
+    int a : 1;
 } Option_T;
 
-typedef struct {
-    char* lname;
-    char sname;
-    int hasarg : 1;
-} OptionDescriptor_T;
-
 void opts_parse(int argc, char** argv);
-void opts_parsespec(char* spec, OptionDescriptor_T* opt);
+void opts_parsespec(char* spec, Option_T* opt);
 void opts_printhelp(void);
 
+//void Options_Parse(int argc, char** argv);
+//void Options_ParseSpec(char* spec, Option_T* opt);
+//void Options_PrintHelp(void);
+
 /*
     Standard Library Helpers
 */
index edc18c85f855ab13945208d4bab82dbaa007798e..e23d73810e8ba60dc7dc990837d677a7049746ae 100644 (file)
@@ -1,3 +1,3 @@
 #include <liba.h>
 
-Option_T Options[] = { {0,0} };
\ No newline at end of file
+Option_T Options[] = { {0} };
\ No newline at end of file
index 71c2924798e88dab817c401947c189917b32b8fb..942ffa9d88ff6c6f2dcb5102e943b85f02ff7357 100644 (file)
@@ -1,32 +1,32 @@
 #include <liba.h>
 
-static void handle_option(int sname, char* lname, char* arg)
+static void handle_option(int s, char* l, char* arg)
 {
-    if (sname == 'h')
+    if (s == 'h')
     {
         opts_printhelp();
         exit(1);
     }
     else
     {
-        printf(" --%s=%s\n", lname, arg);
-        set_option(sname, lname, arg);
+        printf(" --%s=%s\n", l, arg);
+        set_option(s, l, arg);
     }
 }
 
-static OptionDescriptor_T* lookup_opt(int optc, OptionDescriptor_T* optv, char* flag)
+static Option_T* lookup_opt(char* flag)
 {
-    OptionDescriptor_T* opt = NULL;
+    Option_T* opt = NULL;
 
-    for (int i = 0; i < optc; i++)
+    for (int i = 0; Options[i].s || Options[i].l; i++)
     {
         int match = (
-               (flag[1]  && !strcmp(optv[i].lname, flag))
-            || (!flag[1] && flag[0] == optv[i].sname)
+               (flag[1]  && !strcmp(Options[i].l, flag))
+            || (!flag[1] && flag[0] == Options[i].s)
         );
         if (match)
         {
-            opt = &optv[i];
+            opt = &Options[i];
             break;
         }
     }
@@ -34,7 +34,7 @@ static OptionDescriptor_T* lookup_opt(int optc, OptionDescriptor_T* optv, char*
     return opt;
 }
 
-static void parse_longopt(int optc, OptionDescriptor_T* optv, int* currp, char** argv)
+static inline void parse_longopt(int* currp, char** argv)
 {
     /* get the option and the arg if there is one */
     char* flag = argv[*currp] + 2;
@@ -46,18 +46,18 @@ static void parse_longopt(int optc, OptionDescriptor_T* optv, int* currp, char**
         arg = split+1;
     }
 
-    OptionDescriptor_T* od = lookup_opt(optc, optv, flag);
+    Option_T* od = lookup_opt(flag);
     if (!od)
     {
         fatal("unknown option: '%s'", flag);
     }
-    else if (arg && !od->hasarg)
+    else if (arg && !od->a)
     {
         fatal("unexpected argument to option: --%s=%s", flag, arg);
     }
     else
     {
-        if (od->hasarg && !arg)
+        if (od->a && !arg)
         {
             *currp += 1;
             arg = argv[*currp];
@@ -67,7 +67,7 @@ static void parse_longopt(int optc, OptionDescriptor_T* optv, int* currp, char**
             }
         }
         printf("handled option: '--%s=%s'\n", flag, arg);
-        handle_option(od->sname, od->lname, arg);
+        handle_option(od->s, od->l, arg);
     }
 
     /* now repair the split if we made one */
@@ -78,7 +78,7 @@ static void parse_longopt(int optc, OptionDescriptor_T* optv, int* currp, char**
     *currp += 1;
 }
 
-static void parse_shortopt(int optc, OptionDescriptor_T* optv, int* currp, char** argv)
+static inline void parse_shortopt(int* currp, char** argv)
 {
     char* argstr = argv[*currp]+1;
     char flag[] = "\0\0";
@@ -86,18 +86,18 @@ static void parse_shortopt(int optc, OptionDescriptor_T* optv, int* currp, char*
     {
         /* get the flag and the possible argument */
         flag[0] = *argstr;
-        OptionDescriptor_T* od = lookup_opt(optc, optv, flag);
+        Option_T* od = lookup_opt(flag);
         if (!od)
         {
             fatal("unknown option: '%s'", flag);
         }
-        else if (od->hasarg)
+        else if (od->a)
         {
             char* arg = argstr+1;
             if (*arg != '\0')
             {
                 arg += (*arg == '=' ? 1 : 0);
-                handle_option(od->sname, od->lname, arg);
+                handle_option(od->s, od->l, arg);
                 break;
             }
             else if (!*arg)
@@ -107,7 +107,7 @@ static void parse_shortopt(int optc, OptionDescriptor_T* optv, int* currp, char*
                 {
                     fatal("expected argument for option: '%s'", flag);
                 }
-                set_option(od->sname, od->lname, arg);
+                handle_option(od->s, od->l, arg);
                 *currp += 1;
                 break;
             }
@@ -118,7 +118,7 @@ static void parse_shortopt(int optc, OptionDescriptor_T* optv, int* currp, char*
         }
         else
         {
-            set_option(od->sname, od->lname, NULL);
+            handle_option(od->s, od->l, NULL);
         }
     }
     *currp += 1;
@@ -126,22 +126,6 @@ static void parse_shortopt(int optc, OptionDescriptor_T* optv, int* currp, char*
 
 void opts_parse(int argc, char** 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];
 
@@ -150,11 +134,11 @@ void opts_parse(int argc, char** argv)
     {
         if (argv[i][0] == '-' && argv[i][1] == '-')
         {
-            parse_longopt(optc, optv, &i, argv);
+            parse_longopt(&i, argv);
         }
         else if (argv[i][0] == '-')
         {
-            parse_shortopt(optc, optv, &i, argv);
+            parse_shortopt(&i, argv);
         }
         else
         {
@@ -162,6 +146,54 @@ void opts_parse(int argc, char** argv)
             i++;
         }
     }
+}
 
-    free(optv);
+void opts_printhelp(void)
+{
+    /* calculate padding */
+    size_t padding = 0;
+    for (int i = 0; Options[i].s || Options[i].l; i++)
+    {
+        size_t pad = 4;
+        if (Options[i].s)
+        {
+            pad += 2;
+        }
+        if (Options[i].l)
+        {
+            pad += (Options[i].s ? 2 : 0) + 2 + strlen(Options[i].l);
+        }
+        if (Options[i].a)
+        {
+            pad += 4;
+        }
+        if (pad > padding)
+        {
+            padding = pad;
+        }
+    }
+
+    if (Usage)
+    {
+        printf("usage: %s\n\n", Usage);
+    }
+
+    /* print option help messages */
+    for (int i = 0; Options[i].s || Options[i].l; i++)
+    {
+        int remain = padding;
+        if (Options[i].s)
+        {
+            remain -= printf("-%c", Options[i].s);
+        }
+        if (Options[i].l)
+        {
+            remain -= printf("%s--%s", (Options[i].s ? ", " : ""), Options[i].l);
+        }
+        if (Options[i].a)
+        {
+            remain -= printf(" ARG");
+        }
+        printf("%*c%s\n", remain, ' ', (Options[i].d ? Options[i].d : ""));
+    }
 }
diff --git a/lib/a/opts_parsespec.c b/lib/a/opts_parsespec.c
deleted file mode 100644 (file)
index 91c4d23..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <liba.h>
-
-void opts_parsespec(char* spec, OptionDescriptor_T* opt)
-{
-    char* fullspec = spec;
-    memset(opt, 0, sizeof(OptionDescriptor_T));
-
-    /* parse optional arg specifier */
-    if (*spec == ':')
-    {
-        opt->hasarg = 1;
-        spec++;
-    }
-
-    /* parse optional short name */
-    if (*spec != ',')
-    {
-        opt->sname = *(spec++);
-    }
-
-    /* we need a comma at a minimum and if no short name was parsed,a
-       long name must be provided. bail if we don't meet these constraints */
-    if (*spec != ',' || (!opt->sname && spec[1] == '\0'))
-    {
-        fatal("opts_parsespec(): bad option specification '%s'", fullspec);
-    }
-
-    if (*(++spec))
-    {
-        opt->lname = spec;
-    }
-}
diff --git a/lib/a/opts_printhelp.c b/lib/a/opts_printhelp.c
deleted file mode 100644 (file)
index ad03d5d..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <liba.h>
-
-/*
-    TODO:
-        * Print -h, --help in the help output
-*/
-
-void opts_printhelp(void)
-{
-    Option_T* opts = Options;
-    OptionDescriptor_T od = {0};
-    size_t padding = 0;
-
-    /* calculate padding */
-    for (Option_T* curr = opts; curr->name; curr++)
-    {
-        size_t pad = 4;
-        opts_parsespec(curr->name, &od);
-        if (od.sname)
-        {
-            pad += 2;
-        }
-        if (od.lname)
-        {
-            pad += (od.sname ? 2 : 0) + 2 + strlen(od.lname);
-        }
-        if (od.hasarg)
-        {
-            pad += 4;
-        }
-        if (pad > padding)
-        {
-            padding = pad;
-        }
-    }
-
-    if (Usage)
-    {
-        printf("usage: %s\n\n", Usage);
-    }
-
-    /* print option help messages */
-    for (Option_T* curr = opts; curr->name; curr++)
-    {
-        int remain = padding;
-        opts_parsespec(curr->name, &od);
-        if (od.sname)
-        {
-            remain -= printf("-%c", od.sname);
-        }
-        if (od.lname)
-        {
-            remain -= printf("%s--%s", (od.sname ? ", " : ""), od.lname);
-        }
-        if (od.hasarg)
-        {
-            remain -= printf(" ARG");
-        }
-        printf("%*c%s\n", remain, ' ', (curr->desc ? curr->desc : ""));
-    }
-}