diff options
author | FreeArtMan <dos21h@gmail.com> | 2016-05-10 22:42:11 +0100 |
---|---|---|
committer | FreeArtMan <dos21h@gmail.com> | 2016-05-10 22:42:11 +0100 |
commit | 44dedb90f005bb0de9bddbd592a5c78f28bc67d1 (patch) | |
tree | 274b9cea44df3f96a965c564e26cdac42d3af94f /libcmd/cmd.c | |
parent | bb426577c85f6d97cc28ab677e98e2b1f73eadac (diff) | |
download | ihe-44dedb90f005bb0de9bddbd592a5c78f28bc67d1.tar.gz ihe-44dedb90f005bb0de9bddbd592a5c78f28bc67d1.zip |
Replace cmd first part
Diffstat (limited to 'libcmd/cmd.c')
-rw-r--r-- | libcmd/cmd.c | 544 |
1 files changed, 544 insertions, 0 deletions
diff --git a/libcmd/cmd.c b/libcmd/cmd.c new file mode 100644 index 0000000..c1d43fc --- /dev/null +++ b/libcmd/cmd.c @@ -0,0 +1,544 @@ +#include "cmd.h" + +cmd_tok_t* cmd_tok_create( char *s, char *e, int sz, int type ) +{ + cmd_tok_t *ret = NULL; + + ret = malloc( sizeof(cmd_tok_t) ); + if ( ret == NULL ) + return ret; + + memset( ret, 0, sizeof(cmd_tok_t) ); + + ret->s = s; + ret->e = e; + ret->sz = sz; + ret->type = type; + ret->next = NULL; //no need, but sec programming says we need it + + return ret; +} + + +int cmd_tok_add( cmd_tok_t *tok, cmd_tok_t *next ) +{ + int ret = 0; + + if ( tok == NULL ) + { + return -1; + } + + if ( next == NULL ) + { + return -1; + } + + if ( tok->next != NULL ) + { + printf("next token allready set\n"); + return -1; + } + + tok->next = next; + + return ret; +} + + +int cmd_tok_print( cmd_tok_t *tok ) +{ + int ret = 0; + + printf("TOK %p\n",tok); + if (tok) + { + printf("S:%p E:%p SZ:%d \n", tok->s, tok->e, tok->sz); + printf("TYPE: "); + switch (tok->type) + { + case CMDT_NONE: + printf("NONE"); + break; + case CMDT_INT: + printf("INT"); + break; + case CMDT_HEX: + printf("HEX"); + break; + case CMDT_BIN: + printf("BIN"); + break; + case CMDT_STR: + printf("STR"); + break; + case CMDT_WORD: + printf("WORD"); + break; + case CMDT_SP: + printf("SP"); + break; + default: + printf("UNKNOWN"); + } + printf("\n"); + printf("NEXT: %p\n", tok->next ); + } + + return ret; +} + + +void cmd_tok_destroy( cmd_tok_t *tok ) +{ + cmd_tok_t *t=NULL, *n=NULL; + + if (tok == NULL) + { + return; + } + + if ( tok->next == NULL ) + { + free( tok ); + return; + } + + t = tok; + n = t; + while ( n != NULL) + { + n = t->next; + t->next = NULL; + free(t); + t = n; + } +} + + +int cmd_tok_count( cmd_tok_t *tok ) +{ + int ret = 0; + cmd_tok_t *iter = NULL; + + if (tok == NULL) + return 0; + + iter = tok; + while( iter != NULL ) + { + ret += 1; + iter = iter->next; + } + + return ret; +} + + + +cmd_arg_t* cmd_arg_create( cmd_tok_t *tok ) +{ + cmd_arg_t *ret = NULL; + int argc = -1; + cmd_tok_t *iter = NULL; + int i = 0; + + ret = malloc( sizeof(cmd_arg_t) ); + if ( ret == NULL ) + { + return NULL; + } + memset( ret, 0, sizeof( cmd_arg_t )); + + //get number of arguments in command line + argc = cmd_tok_count( tok ); + ret->argc = argc; + + + //alloc mem for argument string values + ret->argv = malloc( sizeof(int*)*argc ); + if ( ret->argv == NULL ) + { + //printf("ERR:err_malloc_argv\n"); + goto err_malloc_argv; + } + memset( ret->argv, 0, sizeof(int*)*argc ); + + //alloc mem for argument type values + ret->type = malloc( sizeof(int)*argc ); + if ( ret->type == NULL ) + { + //printf("ERR:err_malloc_type\n"); + goto err_malloc_type; + } + memset( ret->type, 0, sizeof(int)*argc ); + + //create for each cmd token string and set type + iter = tok; + for (i=0; i<argc; i++,iter=iter->next) + { + ret->argv[i] = malloc( iter->sz+1 ); + memcpy(ret->argv[i], iter->s, iter->sz ); + ret->argv[i][iter->sz] = 0x0; + ret->type[i] = iter->type; + } + + return ret; + +err_malloc_type: + free( ret->argv ); +err_malloc_argv: + free( ret ); +err_exit: + return NULL; +} + + +cmd_arg_t* cmd_arg_sub( cmd_arg_t *arg ) +{ + cmd_arg_t *ret = NULL; + + int i=0; + + if ( arg == NULL ) + return NULL; + + if ( arg->argc == 1 ) + { + ret = cmd_arg_sub_empty(); + return ret; + } + + ret = malloc( sizeof(cmd_arg_t) ); + + ret->argc = arg->argc-1; + + ret->type = malloc(sizeof(int)*(arg->argc-1)); + memset(ret->type, 0, sizeof(int)*(arg->argc-1) ); + + ret->argv = malloc( sizeof(char*)*(arg->argc-1) ); + memset(ret->argv, 0, sizeof(char*)*(arg->argc-1) ); + + ret->__sub_cmd = 1; + + for (i=0; i<ret->argc; i++) + { + ret->argv[i] = arg->argv[i+1]; + ret->type[i] = arg->type[i+1]; + } + + return ret; +} + + +cmd_arg_t* cmd_arg_sub_empty() +{ + cmd_arg_t *ret = NULL; + + ret = malloc( sizeof(cmd_arg_t) ); + ret->argc = 0; + ret->argv = NULL; + ret->type = NULL; + ret->__sub_cmd = 1; + + return ret; +} + +void cmd_arg_destroy( cmd_arg_t *arg ) +{ + int i; + + if ( arg == NULL ) + return; + + for ( i=0; i<arg->argc; i++) + { + if ( arg->__sub_cmd == 0 ) + free( arg->argv[i] ); + } + + free( arg->argv ); + + free( arg->type ); + + free( arg ); +} + +int cmd_exec( cmd_table_t *tbl, cmd_arg_t *arg ) +{ + int ret = -1; + int fret = 0; + int i; + + cmd_arg_t *sub_arg = NULL; + + if ( arg->argc < 1 ) + { + printf("Hm ... no arguments\n"); + return -1; + } + + i = 0; + while ( (tbl[i].cmd != NULL) && (tbl[i].clb != NULL) ) + { + //printf("tbl.cmd %s\n", tbl[i].cmd ); + if ((strlen(tbl[i].cmd) == strlen(arg->argv[0])) //if there is 0 args then here could be non-0 and we get troubles + && (strlen(tbl[i].cmd) != 0)) //combo if + if ( strncmp( tbl[i].cmd, arg->argv[0], strlen(arg->argv[0]) ) == 0 ) + { + //never will exec becouse of statment in while + if ( tbl[i].clb == NULL ) + { + printf("Empty callback %s\n", tbl[i].cmd); + ret = -1; + break; + } + + sub_arg = cmd_arg_sub( arg ); + fret = tbl[i].clb( sub_arg ); + + //if command whent wrong or not still clean mem + if ( sub_arg != NULL ) + { + cmd_arg_destroy( sub_arg ); + } + + //command execution whent wrong lets go out + if ( fret != 0 ) + { + printf("Command broken execution\n"); + ret = -1; + break; + } + ret = 0; //succesfull execution + break; + } + + i++; + } + + + + return ret; +} + +int cmd_exec_ev( cmd_table_t *tbl, cmd_arg_t *arg, int event ) +{ + int ret = -1; + int fret = 0; + int i; + + cmd_arg_t *sub_arg = NULL; + + if ( arg->argc < 1 ) + { + printf("Hm ... no arguments\n"); + return -1; + } + + i = 0; + while ( (tbl[i].cmd != NULL) && (tbl[i].clb != NULL) ) + { + //printf("tbl.cmd %s\n", tbl[i].cmd ); + if ((strlen(tbl[i].cmd) == strlen(arg->argv[0])) //if there is 0 args then here could be non-0 and we get troubles + && (strlen(tbl[i].cmd) != 0)) //combo if + if ( strncmp( tbl[i].cmd, arg->argv[0], strlen(arg->argv[0]) ) == 0 ) + { + //never will exec becouse of statment in while + if ( tbl[i].clb == NULL ) + { + printf("Empty callback %s\n", tbl[i].cmd); + ret = -1; + break; + } + + sub_arg = cmd_arg_sub( arg ); + + if ( sub_arg == NULL ) + sub_arg = cmd_arg_sub_empty(); + + fret = tbl[i].clb( sub_arg ); + + //if command whent wrong or not still clean mem + if ( sub_arg != NULL ) + { + cmd_arg_destroy( sub_arg ); + } + + //command execution whent wrong lets go out + if ( fret != 0 ) + { + printf("Command broken execution\n"); + ret = -1; + break; + } + ret = 0; + break; + } + + i++; + } + + + return ret; +} + +/* +For now support only first command autocomplete, and return first cmd +RETURN: string to command, dont modify it +*/ +char* cmd_ac( cmd_table_t *tbl, const char *s ) +{ + char *ret = NULL; + int i = -1; + int idx = -1, match=-1;//best match + int ret_match; + int str_ac_sz = strlen(s); + + + i = 0; + while ( (tbl[i].cmd != NULL) && (tbl[i].clb != NULL) ) + { + ret_match = strncmp_ac( s, tbl[i].cmd, str_ac_sz ); + if (ret_match > 0) + { + if (ret_match == str_ac_sz+1) + { + idx = i; + break; + } else + { + if (ret_match > match) + { + idx = i; + match = ret_match; + } + } + } + i++; + } + + if ( idx >= 0 ) + { + ret = tbl[idx].cmd; + } + + return ret; +} + +struct cmd_acq_head_t* cmd_acq( cmd_table_t *tbl, const char *s ) +{ + struct cmd_acq_head_t *ret = NULL; + + int i = -1; + int ret_match; + int str_ac_sz = strlen(s); + + struct cmd_acq_head_t *ac = malloc(sizeof(struct cmd_acq_t)); + + SLIST_INIT(ac); + i = 0; + while ( (tbl[i].cmd != NULL) && (tbl[i].clb != NULL) ) + { + ret_match = strncmp_ac( s, tbl[i].cmd, str_ac_sz ); + if (ret_match > 0) + { + //found 100% match + if (ret_match == str_ac_sz+1) + { + PRINT("Unknown state\n"); + break; + //partial match + } else + { + struct cmd_acq_t *acq = malloc(sizeof(struct cmd_acq_t)); + acq->suggestion = tbl[i].cmd; + SLIST_INSERT_HEAD(ac,acq,next_sugg); + } + } + i++; + } + + ret = ac; + + return ret; +} + +void cmd_acq_free( struct cmd_acq_head_t *acq ) +{ + struct cmd_acq_t *iter; + struct cmd_acq_t *prev; + + prev = NULL; + iter = NULL; + SLIST_FOREACH(iter,acq,next_sugg) + { + if ( prev != NULL ) + { + free( prev ); + prev = NULL; + } + prev = iter; + } + + return; +} + +/* +Clothest match function +AA AB = (1) equile <100% +AA AA = (3) equite 100% +AA AAA = (2) equile 100% but there is more +A B = (0) not equile at all +*/ +int strncmp_ac(const char *s1, const char *s2, const int n) +{ + int i=0; + + if (n<0) + { + printf("n<0 wrong argument value\n"); + return 0; + } + + /* not equile at all */ + /* A B */ + if ( s1[0] != s2[0] ) + { + return 0; + } + + i = 0; + while ( (s1[i] == s2[i]) && (i<n)) + { + i++; + } + + //printf("i"); + /* AA AA */ + if ( (s1[i]==0x00) && (s2[i]==0x0) && (i==n) ) + { + //printf("1 "); + return i+1; + /* AA AAA */ + } else if ( (s1[i]==0x0) && (s2[i]!=0x0) && (i==n) ) + { + //printf("2 "); + return i; + /* AAA AA */ + } else if ( (s1[i]!=0x0) && (s2[i]==0x0) && (i<n) ) + { + //printf("3 "); + return -i; + /* AA AB */ + } else if ( (s1[i]!=0x0) && (s2[i]!=0x0) && (s1[i]!=s2[i]) && (i<n) ) + { + //printf("4 "); + return -i; + } else + { + printf("Unknown condition\n"); + } + + return 0; +}
\ No newline at end of file |