From 5b6965f90e164d9c117e50037f5dca7d7c4f9bad Mon Sep 17 00:00:00 2001 From: FreeArtMan Date: Sun, 4 Jun 2017 11:10:44 +0100 Subject: Added new argument parsing library --- extlibs/arg.c | 659 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ extlibs/arg.h | 197 ++++++++++++++++++ 2 files changed, 856 insertions(+) create mode 100644 extlibs/arg.c create mode 100644 extlibs/arg.h (limited to 'extlibs') diff --git a/extlibs/arg.c b/extlibs/arg.c new file mode 100644 index 0000000..3d4475b --- /dev/null +++ b/extlibs/arg.c @@ -0,0 +1,659 @@ +#include "arg.h" + +#include "debug.h" + +//for local usage only? +int __search_arg( char *in, def_arg *arg ); +/*from s_arg_[TYPE] create type arg_[TYPE]*/ +void* __create_arg( int type, void *val ); +/*add to argument list new parsed/recognized argument*/ +int __add_arg( arg_t *arg, int type, void *val ); + + +/* +check if command line argument 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 ); + + /*************************************************************************** + Go troght all define arguments and try to parse and match all found arguments. + Prepare list of all recognized arguments + ***************************************************************************/ + 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); + /* + CHK_ARG(i,1); + + if (argl[pos].used == 1) + { + printf("Allready used %s\n",argv[i]); + break; + } + + arg_range *range = __create_arg(argl[pos].type, argl[pos].def); + + + + i += 1; + + */ + + break; + } + case ARGT_FLOAT: + { + //printf("%d is float\n",i); + break; + } + case ARGT_LIST: + { + int j=0; + int num=0; + char **parse_params = NULL; + int param_num = 0; + s_arg_list *declared_params = argl[pos].def; + char *iter=NULL, *st=NULL, *s=NULL; + + //printf("%d is list\n",i); + CHK_ARG(i,1); + + + if (argl[pos].used == 1) + { + printf("Allready used %d\n", argv[i]); + break; + } + + //super algo for parsing + iter = argv[i+1]; + st = iter; + while ((*iter)!='\0') + { + if ((*iter)=='|') + { + if ((iter)>st) + { + s = malloc(iter-st+1); + memcpy(s, st, iter-st); + s[iter-st]=0; + + //TODO double flags will be passed in =P + for (j=0;jnum;j++) + { + int n1 = strlen(s); + int n2 = strlen(declared_params->vals[j]); + int n = n1 > n2 ? n1 : n2; + if (strncmp(s,declared_params->vals[j],n)==0) + { + //PNL(); + param_num += 1; + char **realoc_ptr = realloc(parse_params, sizeof(char *)*param_num); + if (realoc_ptr) + { + parse_params = (char **)realoc_ptr; + parse_params[param_num-1] = s; + } else + { + param_num -= 1; + } + } + } + st = iter+1; + } else + { + st = iter+1; + } + } + iter++; + if (*iter=='\0') + { + if ((iter)>st) + { + s = malloc(iter-st+1); + memcpy(s, st, iter-st); + s[iter-st]=0; + + //some hash table could be nice to use here =p + //TODO double flags will be passed in =P + for (j=0;jnum;j++) + { + int n1 = strlen(s); + int n2 = strlen(declared_params->vals[j]); + int n = n1 > n2 ? n1 : n2; + if (strncmp(s,declared_params->vals[j],n)==0) + { + param_num += 1; + char **realoc_ptr = realloc(parse_params, sizeof(char *)*param_num); + if (realoc_ptr) + { + parse_params = (char **)realoc_ptr; + parse_params[param_num-1] = s; + } else + { + param_num -= 1; + } + } + } + + st = iter+1; + } + } + } + + arg_list *list=NULL; + { + //PNL(); + //hack depends on __create_arg logic + s_arg_list arg; + arg.num = param_num; + arg.vals = parse_params; + list = __create_arg(argl[pos].type, &arg); + } + + //check param values + + if (-1 == __add_arg(ret, ARGT_LIST, list)) + { + ENL(); + } + + + argl[pos].used = 1; + + used[i] = 1; + used[i+1] = 1; + + i+=1; + 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; + } + // enought 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;isize;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->ip = ip; + ret->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->start = start; + ret->end = end; + ret->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->val = val; + + return ret; +} + + +arg_list* arg_c_list( uint32_t num, char **vals) +{ + int i; + arg_list *ret = NULL; + char **ptr_c=NULL; + + ret = malloc( sizeof(arg_list) ); + memset( ret, 0, sizeof(arg_list) ); + + ptr_c = malloc(sizeof(char*)*num); + for (i=0;inum = num; + ret->vals = ptr_c; + + 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->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->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; isize;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_LIST: + { + int k; + arg_list *lst = (arg_list *)v->val; + printf("Lst | "); + for (k=0;knum;k++) + { + printf("%s ", lst->vals[k]); + } + printf("\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 = val; + + //so NULL where given as we use *->* then be carefull + if (s_list != NULL) + { + list = arg_c_list( s_list->num, s_list->vals ); + } + + 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 ) +{ + argv_t *argv = NULL; + + void *new_ptr = NULL; + + new_ptr = realloc( arg->arg, sizeof(void*)*(arg->size+1) ); + if (new_ptr == NULL) + { + ENL(); + return -1; + } + arg->arg = new_ptr; + arg->size += 1; + + argv = malloc(sizeof(argv_t)); + if (argv == NULL) + { + //do resize back reallocated arg->arg + ENL(); + return -1; + } + memset(argv, 0, sizeof(argv_t)); + argv->type = type; + argv->val = val; + + arg->arg[arg->size-1] = argv; + + return 0; +} + + diff --git a/extlibs/arg.h b/extlibs/arg.h new file mode 100644 index 0000000..18105dc --- /dev/null +++ b/extlibs/arg.h @@ -0,0 +1,197 @@ +#ifndef __ARG_H +#define __ARG_H + +#include +#include +#include +#include + +#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,H) {.param=P,.type=ARGT_##T,.def=V,.used=0,.help=H} + +/* +used to define table with predefine arguments +*/ +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; + char *help; //command description +} def_arg; + +typedef struct argv_t +{ + int type; + uint8_t *val; // points to arg_{ip|range|..} +} argv_t; + + +typedef struct arg_t +{ + int size; //number of arguments + argv_t **arg; //list of pointers to arguments +} arg_t; + +//ip argument default behaviour structure +/* +Supported ip addresses: +...1 = 127.0.0.1:[default port] +:80 = [default ip]:80 +*/ +typedef struct s_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; +} s_arg_ip; + +//resulting structure with ip/port values +typedef struct arg_ip +{ + uint32_t ip; //IP4 ip addrers + uint16_t port;//port number +} arg_ip; + +//configure range argument behaviour +/* +number format decimal ones +1k = 1000 +1m = 1000k = 1000000 +1g = 1000m = 1000000k = 1000000000 +10:100 - from 10 till 100 step [default step] +100: - from 100 till [default end] [default step] +:200 - from [default start] till +100:200:1 - from 100 till 200 with step 1 +*/ +typedef struct s_arg_range +{ + int used; + int def; //says if default should be used if no value in cmd + uint32_t start; + uint32_t default_start; //default start value + uint32_t end; // + uint32_t default_end; //default end value + uint32_t step; // + uint32_t default_step; //default step value +} s_arg_range; + +//configuration structure for range argument +typedef struct arg_range +{ + uint32_t start; + uint32_t end; + uint32_t step; +} arg_range; + +//configuration structure for float argument +typedef struct s_arg_float +{ + int used; + int def; //says if default should be used if no value in cmd + float val; + float default_val; +} s_arg_float; + +typedef struct arg_float +{ + float val; +} arg_float; + +//configuration structure for list argument +/* +list arguments by name + +supports +PARAM1|PARAM2|PARAM3 +*/ + +typedef struct s_arg_list +{ + int used; + int def; //says if default should be used if no value in cmd + uint32_t num; + char **vals; //list of supported arguments + char *default_val; //points to default arguments in da list +} s_arg_list; + +typedef struct arg_list +{ + uint32_t num; + char **vals; +} arg_list; + +/* +configuration structure to default file argument +*/ +typedef struct s_arg_file +{ + int used; + int def; //says if default should be used if no value in cmd + char *name; //current filename + char *default_name; //default filename + char *abspath; //dire where to search stuff? + char *default_abspath; //default absoulute file path +} s_arg_file; + +/* +resulting structure for file argument +*/ +typedef struct arg_file +{ + char *name; + char *abspath; +} arg_file; + + +typedef struct s_arg_val +{ + int used; + int def; //says if default should be used if no value in cmd + char *ptr; + char *default_ptr; +} s_arg_val; + +typedef struct arg_val +{ + char *ptr; +} arg_val; + +typedef struct s_arg_flag +{ + int used; + int flag; +} s_arg_flag; + +//no need as there is no default values +typedef struct arg_flag +{ + int flag; +} 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, char **vals); +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 -- cgit v1.2.3