build system revision
[vg.git] / vg_opt.c
diff --git a/vg_opt.c b/vg_opt.c
new file mode 100644 (file)
index 0000000..ba0f9c4
--- /dev/null
+++ b/vg_opt.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ */
+
+#include "vg_opt.h"
+#include "vg_platform.h"
+#include "vg_log.h"
+#include <stdlib.h>
+
+/* 
+ * Supported:
+ *   short flags       |  -abc
+ *   short options     |  -a value
+ *   multi-set options |  -ab value
+ *
+ *   long gnu options  |  --long-value=test
+ *   standard agument  |  regular_thing
+ */
+
+static int vg_argi = 1;
+static int vg_argj = 1;
+static int vg_argc = 0;
+static int vg_consume_next = 0;
+static char **vg_argv;
+
+/* Will return 0 if exhausted */
+int vg_argp( int argc, char *argv[] )
+{
+   vg_argv = argv;
+   vg_argc = argc;
+
+   static int delta_i = 0;
+   static int delta_j = 0;
+   
+   if( vg_argj != 1 && !vg_argv[ vg_argi ][ vg_argj ] )
+   {
+      vg_argj = 1;
+      vg_argi ++;      
+   }
+
+   if( vg_consume_next )
+   {
+      vg_consume_next = 0;
+      vg_argi ++;
+   }
+
+   if( vg_argi >= argc )
+      return 0;
+
+   if( (delta_i == vg_argi) && (delta_j == vg_argj) )
+   {
+      char *cur = &vg_argv[ vg_argi ][ vg_argj ];
+   
+      if( *cur != '-' )
+      {
+         vg_error( "Unknown opt '-%c'\n", *cur );
+      }
+      else
+      {
+         vg_error( "Unknown opt '--%s'\n", cur + 1 );
+      }
+      
+      exit(0);
+   }
+   
+   delta_i = vg_argi;
+   delta_j = vg_argj;
+
+   return 1;
+}
+
+/* Example: see if -c is set */
+int vg_opt( char c )
+{
+   char *carg = vg_argv[ vg_argi ];
+
+   if( carg[0] == '-' )
+   {
+      if( carg[1] == '-' )
+         return 0;
+      
+      if( carg[ vg_argj ] == c )
+      {
+         vg_argj ++;
+         
+         return 1;
+      }
+   }
+   
+   return 0;
+}
+
+/* Example: get -c *value* */
+char *vg_opt_arg( char c )
+{
+   if( vg_opt( c ) )
+   {
+      if( vg_argi < vg_argc-1 )
+      {
+         if( vg_argv[ vg_argi + 1 ][0] != '-' )
+         {
+            vg_consume_next = 1;
+            return vg_argv[ vg_argi + 1 ];
+         }
+      }
+      
+      vg_error( "Option '%c' requires argument!\n", c );
+      exit(0);
+   }
+   
+   return NULL;
+}
+
+/* Example see if --big is set */
+int vg_long_opt( char *name )
+{
+   char *carg = vg_argv[ vg_argi ];
+   
+   if( carg[0] == '-' )
+   {
+      if( carg[1] == '-' )
+      {
+         if( !strcmp( name, carg+2 ) )
+         {
+            vg_consume_next = 1;
+            return 1;
+         }
+      }
+   }
+   
+   return 0;
+}
+
+/* Example: get --big=value */
+char *vg_long_opt_arg( char *name )
+{
+   char *carg = vg_argv[ vg_argi ];
+   
+   if( carg[0] == '-' )
+   {
+      if( carg[1] == '-' )
+      {
+         int k = 2; int set = 0;
+         while( carg[ k ] )
+         {
+            if( carg[ k ] == '=' )
+            {
+               set = 1;
+               break;
+            }
+               
+            k ++;
+         }
+         
+         if( !strncmp( name, carg+2, k-2 ) )
+         {
+            vg_consume_next = 1;
+            
+            // the rest
+            if( set )
+            {
+               return carg + k + 1;
+            }
+            else
+            {
+               vg_error( "Long option '%s' requires argument\n", name );
+            }
+         }         
+      }
+   }
+   
+   return NULL;
+}
+
+/* Example: get regular_thing */
+char *vg_arg(void)
+{
+   char *carg = vg_argv[ vg_argi ];
+   
+   if( carg[0] != '-' )
+   {
+      vg_consume_next = 1;
+      return carg;
+   }
+   
+   return NULL;
+}