summaryrefslogtreecommitdiff
path: root/libcmd/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcmd/cmd.c')
-rw-r--r--libcmd/cmd.c199
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%