diff options
Diffstat (limited to 'libcmd/cmd.c')
-rw-r--r-- | libcmd/cmd.c | 199 |
1 files changed, 188 insertions, 11 deletions
diff --git a/libcmd/cmd.c b/libcmd/cmd.c index c1d43fc..f743a7f 100644 --- a/libcmd/cmd.c +++ b/libcmd/cmd.c @@ -1,4 +1,5 @@ #include "cmd.h" +#include "cmd_parse.h" cmd_tok_t* cmd_tok_create( char *s, char *e, int sz, int type ) { @@ -78,6 +79,9 @@ int cmd_tok_print( cmd_tok_t *tok ) case CMDT_SP: printf("SP"); break; + case CMDT_FLOAT: + printf("FLOAT"); + break; default: printf("UNKNOWN"); } @@ -189,7 +193,6 @@ err_malloc_type: free( ret->argv ); err_malloc_argv: free( ret ); -err_exit: return NULL; } @@ -268,16 +271,21 @@ int cmd_exec( cmd_table_t *tbl, cmd_arg_t *arg ) { int ret = -1; int fret = 0; + int pret = 0; //pre condition return int i; cmd_arg_t *sub_arg = NULL; - if ( arg->argc < 1 ) + //there could be 0 arguments + if ( arg->argc < 0 ) { printf("Hm ... no arguments\n"); return -1; } + if ( arg->argc == 0 ) + return 0; + i = 0; while ( (tbl[i].cmd != NULL) && (tbl[i].clb != NULL) ) { @@ -295,7 +303,18 @@ int cmd_exec( cmd_table_t *tbl, cmd_arg_t *arg ) } sub_arg = cmd_arg_sub( arg ); - fret = tbl[i].clb( sub_arg ); + //execute callback preconditions + if (tbl[i].pre != NULL) + { + pret = tbl[i].pre( sub_arg ); + } else { + pret = 0; //no precond just pass + } + if (pret == 0) + { + //execute callback + fret = tbl[i].clb( sub_arg ); + } //if command whent wrong or not still clean mem if ( sub_arg != NULL ) @@ -303,21 +322,23 @@ int cmd_exec( cmd_table_t *tbl, cmd_arg_t *arg ) cmd_arg_destroy( sub_arg ); } - //command execution whent wrong lets go out - if ( fret != 0 ) + //command execution precondtions met but wrong execution + if ( pret == 0 ) { - printf("Command broken execution\n"); - ret = -1; - break; + //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; } @@ -484,6 +505,162 @@ void cmd_acq_free( struct cmd_acq_head_t *acq ) return; } +char* cmd_mng_history( cmd_mng_t *cmng, int index ) +{ + int idx; + char *ret=NULL; + + if (cmng == NULL) + { + return NULL; + } + + if (cmng->history_size < CMD_HISTORY_SIZE) + { + if (index < cmng->history_size) + { + ret = cmng->history[index]; + } + } else + { + idx = (cmng->history_size-CMD_HISTORY_SIZE+index)%CMD_HISTORY_SIZE; + ret = cmng->history[idx]; + } + + return ret; +} + +char* cmd_mng_autocomplete( cmd_mng_t *cmng, char *cmd, size_t cmd_sz ) +{ + char *ret=NULL; + + cmd_arg_t *args; + cmd_tok_t tl, *ptr = &tl, *iter = NULL; + cmd_table_t *tab = cmng->table; + struct cmd_acq_t *iter_sugg = NULL; + int ac_sz=0,cnt_sz=0; + char *ac_str; + memset( &tl, 0, sizeof( cmd_tok_t )); + + if ( parse_cmd(ptr, cmd, cmd_sz) == -1) + { + printf("Cmd problems\n"); + return NULL; + } + + iter = ptr->next; + args = cmd_arg_create( iter ); + + //if command not found offer auto complete options + if (args->argc > 0) + { + struct cmd_acq_head_t *ac = cmd_acq(tab,args->argv[0]); + if (ac != NULL) + { + //calculate string str + SLIST_FOREACH(iter_sugg,ac,next_sugg) + { + //printf("%s ", iter_sugg->suggestion); + ac_sz += strlen(iter_sugg->suggestion)+1; //1 for " " + } + ac_sz += 2; //"> " + ac_sz += 1; //"\0" + + ac_str = (char *)malloc(ac_sz); + + memcpy( ac_str, "> ", 2 ); + cnt_sz = 2; + cnt_sz = 0; + SLIST_FOREACH(iter_sugg,ac,next_sugg) + { + //double logical usage + ac_sz = strlen(iter_sugg->suggestion); + memcpy( ac_str+cnt_sz, iter_sugg->suggestion, ac_sz); + cnt_sz += ac_sz; + ac_str[cnt_sz] = ' '; + cnt_sz += 1; + } + ac_str[cnt_sz] = '\0'; + ret = ac_str; + } + cmd_acq_free( ac ); + } + + cmd_tok_destroy( ptr->next ); + ptr->next = NULL; + cmd_arg_destroy( args ); + + return ret; +} + +int cmd_mng_exec( cmd_mng_t *cmng, const char *cmd, size_t sz_cmd ) +{ + int ret = CMD_EOK; + int fret = 0; + cmd_tok_t tl, *ptr_tl = &tl, *iter = NULL; + cmd_arg_t *args = NULL; + + // Init values + memset( &tl, 0, sizeof( cmd_tok_t )); + + fret = parse_cmd( ptr_tl, cmd, sz_cmd ); + if ( fret != 0 ) + { + ret = CMD_EEXE; + goto error_exe; //if err memleak from parse_cmd? + } + + iter = ptr_tl->next; + args = cmd_arg_create( iter ); + cmd_tok_destroy( ptr_tl->next ); + ptr_tl->next = NULL; + + if (cmd_exec(cmng->table, args) != 0) + { + ret = CMD_ECMD; + goto error_cmd; + } + + /* if history is on then manage commands */ + if (cmng->flag_history) + { + /*replace with proper datatype in future*/ + char *p = malloc(sz_cmd); + int idx = (cmng->history_size)%CMD_HISTORY_SIZE; + memcpy(p,cmd,sz_cmd); + if (cmng->history[idx]!=NULL) free(cmng->history[idx]); + cmng->history[idx] = p; + cmng->history_size += 1; //one day there could be overflow after 2^31/2^63 cmds, good luck with this bug + } + + cmd_arg_destroy( args ); + + return ret; +error_cmd: + cmd_arg_destroy( args ); + +error_exe: + + return ret; +} + +int cmd_mng_free( cmd_mng_t *cmng) +{ + int ret=0; + int i; + + for (i=0;i<CMD_HISTORY_SIZE;i++) + { + if (cmng->history[i]) + { + free(cmng->history[i]); + cmng->history[i] = NULL; + } + } + + return ret; +} + /* Clothest match function AA AB = (1) equile <100% |