summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreeArtMan <=>2016-01-24 13:13:09 +0000
committerFreeArtMan <=>2016-01-24 13:13:09 +0000
commit14ff7106da7e79432a85805e8ce49296f1cf9216 (patch)
tree02c100de21977c7222535e528c5348d988bd6dd1
downloadlibarg-14ff7106da7e79432a85805e8ce49296f1cf9216.tar.gz
libarg-14ff7106da7e79432a85805e8ce49296f1cf9216.zip
Initial
-rw-r--r--.gitignore3
-rw-r--r--Makefile26
-rw-r--r--README.md15
-rw-r--r--arg.c478
-rw-r--r--arg.h167
-rw-r--r--test/.gitignore2
-rw-r--r--test/Makefile7
-rw-r--r--test/test1.c86
8 files changed, 784 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d3399f6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.o
+*.a
+*.so
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..71d41c0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+PROJ=libarg
+CC=gcc
+CFLAGS=-g3
+LDFLAGS=
+
+SOURCE=arg
+OBJECTS=$(SOURCE:=.o)
+SOURCES=$(SOURCE:=.c)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $<
+
+make: dynamic static
+
+dynamic: CFLAGS+=-fPIC
+dynamic: clean $(OBJECTS)
+ $(CC) $(CFLAGS) $(OBJECTS) -shared -o $(PROJ).so
+
+static: clean $(OBJECTS)
+ ar rcs $(PROJ).a $(OBJECTS)
+
+
+clean:
+ rm -rf *.o
+ rm -rf *.a
+ rm -rf *.so \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3d44447
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+# arg - comand line argument library
+
+Small replacment for getopt functionality, remove messing around with standart
+while loop and just add argument definitions and get back values. Removes from
+process define new value where to store and and adding new case in swithch
+inside loop.
+
+## Supports
+Now is supported trigering flag and string.
+
+
+## TODO
+ Add list of values, IP4, IP6, ranges, custom callback support, float
+numbers,file path,direcotry,linux socket, specific devices? like loop one.
+Something more that could make usual life of smashing keyboard more non routine? \ No newline at end of file
diff --git a/arg.c b/arg.c
new file mode 100644
index 0000000..82f635a
--- /dev/null
+++ b/arg.c
@@ -0,0 +1,478 @@
+#include "arg.h"
+
+//for local usage only?
+int __search_arg( char *in, def_arg *arg );
+void* __create_arg( int type, void *val );
+int __add_arg( arg_t *arg, int type,void *val );
+
+
+#define CHK_ARG(ARG,NUM) if ((ARG+NUM)>=argc) {\
+printf("not enought arguments for %s ",argv[ARG]);break;}
+
+arg_t* arg_load( int argc, char **argv, def_arg *argl )
+{
+ arg_t *ret = NULL;
+ uint8_t *used; //count unused arguments, there should be no unused
+ //elements at the end
+ int i = 0;
+ int pos = -1; //position of argv inside def_arg table
+ void *arg_def_val = NULL;
+
+ //prepare return value
+ ret = malloc( sizeof(arg_t) );
+ memset( ret, 0, sizeof(arg_t) );
+
+ used = malloc(sizeof(uint8_t)*argc);
+ memset( used, 0, sizeof(uint8_t)*argc );
+
+ i = 1; //we can ignore first as first arg is name of programm
+ while ( i < argc )
+ {
+ //printf("%s ",argv[i]);
+ pos = __search_arg(argv[i], argl);
+ //printf("TAB:%d\n", pos );
+
+ switch (argl[pos].type)
+ {
+ case ARGT_NONE:
+ {
+ //printf("No arg\n");
+ break;
+ }
+ case ARGT_IP:
+ {
+ //printf("%d is ip\n",i);
+ /*
+ arg_ip *ip = __create_arg( argl[i].type, argl[i].def );
+
+ //if ip is 0.0.0.0 then probably no default value for ip
+ if ( ((s_arg_ip*)argl[i].def)->ip == 0 )
+ ip->def = 0;
+ //ip->ptr = argv[i+1];
+ ip->used = 1;
+ i+=1;
+ */
+ break;
+ }
+ case ARGT_RANGE:
+ {
+ //printf("%d is range\n",i);
+ break;
+ }
+ case ARGT_FLOAT:
+ {
+ //printf("%d is float\n",i);
+ break;
+ }
+ case ARGT_LIST:
+ {
+ //printf("%d is list\n",i);
+ break;
+ }
+ case ARGT_FILE:
+ {
+ //printf("%d is file\n",i);
+
+ break;
+ }
+ // we need one argument after flag
+ case ARGT_VAL:
+ {
+ //printf("%d is !val\n",i);
+ CHK_ARG(i,1);
+
+ if (argl[pos].used == 1)
+ {
+ printf("Allready used %s\n", argv[i]);
+ break;
+ }
+
+ arg_val *val = __create_arg( argl[pos].type, argl[pos].def );
+
+ if (((s_arg_val*)argl[pos].def)->ptr != NULL)
+ val->def = 0;
+ val->used = 1;
+ val->ptr = argv[i+1];
+
+ __add_arg( ret, ARGT_VAL, val );
+ //set that requied option allready where at cmd
+ argl[pos].used = 1;
+
+ //set used cmd arg
+ used[i ] = 1;
+ used[i+1] = 1;
+
+ i += 1;
+
+ break;
+ }
+ // enouht that this is triggered
+ case ARGT_FLAG:
+ {
+ arg_flag *flg = NULL;
+
+ //printf("%d is flag\n", i);
+
+ if ( argl[pos].used == 1 )
+ {
+ printf("Allready used %s\n", argv[i]);
+ break;
+ }
+
+ flg = __create_arg( argl[pos].type, argl[pos].def );
+
+ flg->used = 1;
+ flg->flag = 1;
+
+ __add_arg( ret, ARGT_FLAG, flg );
+
+
+ argl[pos].used = 1;
+ used[i] = 1;
+
+ break;
+ }
+ default:
+ printf("Unknown arg %d \"%s\"\n", i, argv[i]);
+
+ }
+
+ i++;
+ }
+
+ //printf("arg ");
+ for (i=1;i<argc;i++)
+ {
+ if (used[i] == 0)
+ {
+ //printf("%d ",i);
+ }
+ }
+ //printf("\n");
+
+ free(used);
+
+
+ return ret;
+}
+
+
+void arg_free( arg_t *arg )
+{
+ int i;
+
+ for (i=0;i<arg->size;i++)
+ {
+ free( arg->arg[i]->val );
+ free( arg->arg[i] );
+ }
+ free( arg->arg );
+
+ free( arg );
+}
+
+int arg_type( arg_t *arg, int num )
+{
+ int ret = ARGT_NONE;
+
+
+
+ return ret;
+}
+
+
+argv_t* arg_get( arg_t *arg, int num )
+{
+ argv_t *ret = NULL;
+
+
+
+ return ret;
+}
+
+
+arg_ip* arg_c_ip( uint32_t ip, uint16_t port )
+{
+ arg_ip *ret = NULL;
+
+ ret = malloc( sizeof(arg_ip) );
+ memset(ret,0,sizeof(arg_ip));
+
+ ret->default_ip = ip;
+ ret->default_port = port;
+
+ return ret;
+}
+
+
+arg_range* arg_c_range( uint32_t start, uint32_t end, uint32_t step )
+{
+ arg_range* ret = NULL;
+
+ ret = malloc( sizeof(arg_range) );
+ memset( ret, 0, sizeof(arg_range) );
+
+ ret->default_start = start;
+ ret->default_end = end;
+ ret->default_step = step;
+
+ return ret;
+}
+
+
+arg_float* arg_c_float( float val )
+{
+ arg_float* ret = NULL;
+
+ ret = malloc( sizeof(arg_float) );
+ memset( ret, 0, sizeof(arg_float) );
+
+ ret->default_val = val;
+
+ return ret;
+}
+
+
+arg_list* arg_c_list( uint32_t num, void **vals, void *def )
+{
+ arg_list *ret = NULL;
+
+ ret = malloc( sizeof(arg_list) );
+ memset( ret, 0, sizeof(arg_list) );
+
+ ret->num = num;
+ ret->vals = vals;
+ ret->default_val = def;
+
+ return ret;
+}
+
+
+arg_file* arg_c_file( char *name )
+{
+ arg_file *ret = NULL;
+
+ ret = malloc( sizeof(arg_file) );
+ memset( ret, 0, sizeof(arg_file) );
+
+ ret->default_name = name;
+
+ return ret;
+}
+
+
+arg_val* arg_c_val( char *ptr )
+{
+ arg_val *ret = NULL;
+
+ ret = malloc( sizeof(arg_val) );
+ memset( ret, 0, sizeof(arg_val) );
+
+ ret->default_ptr = ptr;
+
+ return ret;
+}
+
+
+arg_flag* arg_c_flag()
+{
+ arg_flag *ret = NULL;
+
+ ret = malloc( sizeof(arg_flag) );
+ memset( ret, 0, sizeof(arg_flag) );
+
+ ret->flag = 0;
+
+ return ret;
+}
+
+
+void arg_print( arg_t *arg )
+{
+ int i = 0;
+ argv_t *v = NULL;
+
+ if ( arg == NULL )
+ {
+ printf("Nothing to print\n");
+ return;
+ }
+
+ printf("| NUM |\n");
+ for ( i=0; i<arg->size;i++ )
+ {
+ printf("| %02d |\n", i);
+ v = arg->arg[i];
+ if (v == NULL)
+ continue;
+ printf(" ->| %02d | ", v->type);
+ switch( v->type )
+ {
+ case ARGT_NONE:
+ {
+ printf("None\n");
+ break;
+ }
+ case ARGT_IP:
+ {
+ printf("IP\n");
+ break;
+ }
+ case ARGT_VAL:
+ {
+ arg_val *val = (void *)v->val;
+ printf("Val | ");
+
+ printf("%s\n",val->ptr);
+
+ break;
+ }
+ case ARGT_FLAG:
+ {
+ arg_flag *flag = (void *)v->val;
+ printf("FLg | ");
+
+ printf("%d\n",flag->flag);
+
+ break;
+ }
+ default:
+ printf("Unknown\n");
+ }
+
+ }
+
+}
+
+
+int __search_arg( char *in, def_arg *arg)
+{
+ int ret = -1;
+ int i = 0;
+
+ i = 0;
+ while ( arg[i].param != NULL )
+ {
+ if (strncmp(arg[i].param,in,strlen(in)) == 0)
+ return i;
+ i++;
+ }
+
+
+ return ret;
+}
+
+
+void* __create_arg( int type, void *val )
+{
+ void *ret = NULL;
+
+ switch ( type )
+ {
+ case ARGT_NONE:
+ {
+ break;
+ }
+
+ case ARGT_IP:
+ {
+ arg_ip *ip = NULL;
+ s_arg_ip *s_ip= val;
+
+ ip = arg_c_ip( s_ip->ip, s_ip->port );
+
+ ret = ip;
+ break;
+ }
+
+ case ARGT_RANGE:
+ {
+ arg_range *range = NULL;
+ s_arg_range *s_range = val;
+
+ range = arg_c_range( s_range->start, s_range->end, s_range->end );
+
+ ret = range;
+ break;
+ }
+
+ case ARGT_FLOAT:
+ {
+ arg_float *fl = NULL;
+ s_arg_float *s_fl = val;
+
+ fl = arg_c_float( s_fl->val );
+
+ ret = fl;
+ break;
+ }
+
+ case ARGT_LIST:
+ {
+ arg_list *list = NULL;
+ s_arg_list *s_list = NULL;
+
+ list = arg_c_list( s_list->num, s_list->vals, s_list->default_val );
+
+ ret = list;
+ break;
+ }
+
+ case ARGT_FILE:
+ {
+ arg_file *f = NULL;
+ s_arg_file *s_f = val;
+
+ f = arg_c_file( s_f->name );
+
+ ret = f;
+ break;
+ }
+
+ case ARGT_VAL:
+ {
+ arg_val *v = NULL;
+ s_arg_val *s_v = val;
+
+ v = arg_c_val( s_v->ptr );
+
+ ret = v;
+ break;
+ }
+ case ARGT_FLAG:
+ {
+ arg_flag *flag = NULL;
+
+ flag = arg_c_flag();
+
+ ret = flag;
+ break;
+ }
+
+ default:
+ printf("Unknown type\n");
+ }
+
+ return ret;
+}
+
+
+int __add_arg( arg_t *arg, int type, void *val )
+{
+ int ret = 0;
+ argv_t *argv = NULL;
+
+ arg->arg = realloc( arg->arg, sizeof(void*)*(arg->size+1) );
+ arg->size += 1;
+
+ argv = malloc(sizeof(argv_t));
+ memset(argv, 0, sizeof(argv_t));
+ argv->type = type;
+ argv->val = val;
+
+ arg->arg[arg->size-1] = argv;
+
+ return ret;
+}
+
+
diff --git a/arg.h b/arg.h
new file mode 100644
index 0000000..7dff3de
--- /dev/null
+++ b/arg.h
@@ -0,0 +1,167 @@
+#ifndef __ARG_H
+#define __ARG_H
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ARGT_NONE 0 //nothing
+#define ARGT_IP 1 //ip addr
+#define ARGT_RANGE 2 //range of values
+#define ARGT_FLOAT 3 //could be float
+#define ARGT_LIST 4 //list of values
+#define ARGT_FILE 5 //path to file
+#define ARGT_VAL 6 //command line direct val
+#define ARGT_FLAG 7 //flag value on/off
+
+#define ARG_ENTRY(P,T,V) {.param=P,.type=ARGT_##T,.def=V,.used=0}
+
+typedef struct def_arg
+{
+ char *param; //parametr that comes from shell
+ uint32_t type; //type of argument
+ void *def; //define default values, NULL if no default values
+ uint8_t used;
+} def_arg;
+
+typedef struct argv_t
+{
+ int type;
+ uint8_t *val; // points to arg_{ip|range|..}
+} argv_t;
+
+
+typedef struct arg_t
+{
+ int size;
+ argv_t **arg;
+} arg_t;
+
+
+typedef struct arg_ip
+{
+ int used; //value is in cmd
+ int def; //says if default should be used if no value in cmd
+ uint32_t ip;
+ uint32_t default_ip;
+ uint16_t port;
+ uint32_t default_port;
+} arg_ip;
+
+typedef struct s_arg_ip
+{
+ uint32_t ip;
+ uint16_t port;
+} s_arg_ip;
+
+
+typedef struct arg_range
+{
+ int used;
+ int def;
+ uint32_t start;
+ uint32_t default_start;
+ uint32_t end;
+ uint32_t default_end;
+ uint32_t step;
+ uint32_t default_step;
+} arg_range;
+
+typedef struct s_arg_range
+{
+ uint32_t start;
+ uint32_t end;
+ uint32_t step;
+} s_arg_range;
+
+
+typedef struct arg_float
+{
+ int used;
+ int def;
+ float val;
+ float default_val;
+} arg_float;
+
+typedef struct s_arg_float
+{
+ float val;
+} s_arg_float;
+
+
+typedef struct arg_list
+{
+ int used;
+ int def;
+ uint32_t num;
+ void **vals;
+ char *default_val;
+} arg_list;
+
+typedef struct s_arg_list
+{
+ uint32_t num;
+ void *default_val;
+ void **vals;
+} s_arg_list;
+
+
+typedef struct arg_file
+{
+ int used;
+ int def;
+ char *name;
+ char *default_name;
+ char *abspath; //dire where to search stuff?
+ char *default_abspath;
+} arg_file;
+
+typedef struct s_arg_file
+{
+ char *name;
+ char *abspath;
+} s_arg_file;
+
+
+typedef struct arg_val
+{
+ int used;
+ int def;
+ char *ptr;
+ char *default_ptr;
+} arg_val;
+
+typedef struct s_arg_val
+{
+ char *ptr;
+} s_arg_val;
+
+typedef struct arg_flag
+{
+ int used;
+ int flag;
+} arg_flag;
+
+//no need as there is no default values
+/*
+typedef struct s_arg_flag
+{
+ int flag;
+} s_arg_flag;
+*/
+
+arg_t* arg_load( int argc, char **argv, def_arg *argl );
+void arg_free( arg_t *arg );
+int arg_type( arg_t *arg, int num );
+argv_t* arg_get( arg_t *arg, int num );
+arg_ip* arg_c_ip( uint32_t ip, uint16_t port );
+arg_range* arg_c_range( uint32_t start, uint32_t end, uint32_t step );
+arg_float* arg_c_float( float val );
+arg_list* arg_c_list( uint32_t num, void **vals, void *def );
+arg_file* arg_c_file( char *name );
+arg_val* arg_c_val( char *ptr );
+arg_flag* arg_c_flag();
+void arg_print( arg_t *arg );
+
+#endif \ No newline at end of file
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..92746d2
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,2 @@
+log.txt
+test1
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..7297e92
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,7 @@
+CC=gcc
+CLFAGS=
+make:
+ $(CC) $(CFLAGS) test1.c ../arg.o -o test1
+
+leak:
+ valgrind --leak-check=full --track-origins=yes --log-file=log.txt ./test1 -f -g -e ads \ No newline at end of file
diff --git a/test/test1.c b/test/test1.c
new file mode 100644
index 0000000..dacae2e
--- /dev/null
+++ b/test/test1.c
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../arg.h"
+
+s_arg_ip src_ip =
+{
+ .port = 8080,
+ .ip = 0x7f000001
+};
+
+s_arg_range freq_range =
+{
+ .start = 88,
+ .end = 108,
+ .step = 100e3
+};
+
+s_arg_float ratio_float =
+{
+ .val = 0.8
+};
+
+s_arg_list color_name_list =
+{
+ .num = 3,
+ .default_val = "RED",
+ .vals = {"RED","GREEN","BLUE"}
+};
+
+s_arg_val number_val =
+{
+ .ptr = NULL
+};
+
+def_arg cmd_arg[] =
+{
+ ARG_ENTRY("-a",IP,&src_ip),
+ ARG_ENTRY("-b",RANGE,&freq_range),
+ ARG_ENTRY("-c",FLOAT,&ratio_float),
+ ARG_ENTRY("-d",LIST,&color_name_list),
+ ARG_ENTRY("-e",VAL,&number_val),
+ ARG_ENTRY("-f",FLAG,NULL),
+ ARG_ENTRY("-g",FLAG,NULL),
+ {NULL,0,NULL}
+};
+
+
+int main( int argc, char **argv )
+{
+
+ int i=0;
+ arg_t *cfg = NULL;
+
+ i = 0;
+ while ( cmd_arg[i].param != NULL )
+ {
+ printf("%s\n",cmd_arg[i].param);
+ i++;
+ }
+
+ cfg = arg_load( argc, argv, cmd_arg );
+
+ if (cfg->size == 0)
+ {
+ printf("No arguments found\n");
+ goto exit_error;
+ }
+
+ for (i=0;i<cfg->size;i++)
+ {
+ printf("TYPE:%d\n", cfg->arg[i]->type);
+ }
+
+ arg_print( cfg );
+
+ arg_free( cfg );
+
+ return 0;
+
+exit_error:
+ arg_free( cfg );
+
+ return -1;
+
+}