diff options
Diffstat (limited to 'src/common/console.c')
-rw-r--r-- | src/common/console.c | 223 |
1 files changed, 222 insertions, 1 deletions
diff --git a/src/common/console.c b/src/common/console.c index 67897ee81..db914db98 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -8,6 +8,8 @@ #include "console.h" #ifndef MINICORE + #include "../common/ers.h" + #include "../common/malloc.h" #include "../common/atomic.h" #include "../common/spinlock.h" #include "../common/thread.h" @@ -77,7 +79,212 @@ int console_parse_key_pressed(void) { return FD_ISSET(STDIN_FILENO, &fds); } #endif /* _WIN32 */ +CPCMD(exit) { + runflag = 0; +} +CPCMD(ers_report) { + ers_report(); +} +CPCMD(help) { + unsigned int i = 0; + for ( i = 0; i < console->cmd_list_count; i++ ) { + if( console->cmd_list[i]->next_count ) { + ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n",console->cmd_list[i]->cmd); + console->parse_list_subs(console->cmd_list[i],2); + } else { + ShowInfo("- '"CL_WHITE"%s"CL_RESET"'\n",console->cmd_list[i]->cmd); + } + } +} +/* [Ind/Hercules] */ +CPCMD(malloc_usage) { + unsigned int val = (unsigned int)malloc_usage(); + ShowInfo("malloc_usage: %.2f MB\n",(double)(val)/1024); +} +#define CP_DEF_C(x) { #x , NULL , NULL, NULL } +#define CP_DEF_C2(x,y) { #x , NULL , #y, NULL } +#define CP_DEF_S(x,y) { #x , console_parse_ ## x , #y, NULL } +#define CP_DEF(x) { #x , console_parse_ ## x , NULL, NULL } +void console_load_defaults(void) { + struct { + char *name; + CParseFunc func; + char *connect; + struct CParseEntry *self; + } default_list[] = { + CP_DEF(help), + CP_DEF_C(server), + CP_DEF_S(ers_report,server), + CP_DEF_S(malloc_usage,server), + CP_DEF_S(exit,server), + }; + unsigned int i, len = ARRAYLENGTH(default_list); + struct CParseEntry *cmd; + + RECREATE(console->cmds,struct CParseEntry *, len); + + for(i = 0; i < len; i++) { + CREATE(cmd, struct CParseEntry, 1); + + safestrncpy(cmd->cmd, default_list[i].name, CP_CMD_LENGTH); + + if( default_list[i].func ) + cmd->u.func = default_list[i].func; + else + cmd->u.next = NULL; + + cmd->next_count = 0; + + console->cmd_count++; + console->cmds[i] = cmd; + default_list[i].self = cmd; + if( !default_list[i].connect ) { + RECREATE(console->cmd_list,struct CParseEntry *, ++console->cmd_list_count); + console->cmd_list[console->cmd_list_count - 1] = cmd; + } + } + + for(i = 0; i < len; i++) { + unsigned int k; + if( !default_list[i].connect ) + continue; + for(k = 0; k < console->cmd_count; k++) { + if( strcmpi(default_list[i].connect,console->cmds[k]->cmd) == 0 ) { + cmd = default_list[i].self; + RECREATE(console->cmds[k]->u.next, struct CParseEntry *, ++console->cmds[k]->next_count); + console->cmds[k]->u.next[console->cmds[k]->next_count - 1] = cmd; + break; + } + } + } +} +void console_parse_create(char *name, CParseFunc func) { + unsigned int i; + char *tok; + char sublist[CP_CMD_LENGTH * 5]; + struct CParseEntry *cmd; + + safestrncpy(sublist, name, CP_CMD_LENGTH * 5); + tok = strtok(sublist,":"); + + for ( i = 0; i < console->cmd_list_count; i++ ) { + if( strcmpi(tok,console->cmd_list[i]->cmd) == 0 ) + break; + } + if( i == console->cmd_list_count ) { + RECREATE(console->cmds,struct CParseEntry *, ++console->cmd_count); + CREATE(cmd, struct CParseEntry, 1); + safestrncpy(cmd->cmd, tok, CP_CMD_LENGTH); + cmd->next_count = 0; + console->cmds[console->cmd_count - 1] = cmd; + RECREATE(console->cmd_list,struct CParseEntry *, ++console->cmd_list_count); + console->cmd_list[console->cmd_list_count - 1] = cmd; + i = console->cmd_list_count - 1; + } + + cmd = console->cmd_list[i]; + while( ( tok = strtok(NULL, ":") ) != NULL ) { + + for(i = 0; i < cmd->next_count; i++) { + if( strcmpi(cmd->u.next[i]->cmd,tok) == 0 ) + break; + } + + if ( i == cmd->next_count ) { + RECREATE(console->cmds,struct CParseEntry *, ++console->cmd_count); + CREATE(console->cmds[console->cmd_count-1], struct CParseEntry, 1); + safestrncpy(console->cmds[console->cmd_count-1]->cmd, tok, CP_CMD_LENGTH); + console->cmds[console->cmd_count-1]->next_count = 0; + RECREATE(cmd->u.next, struct CParseEntry *, ++cmd->next_count); + cmd->u.next[cmd->next_count - 1] = console->cmds[console->cmd_count-1]; + cmd = console->cmds[console->cmd_count-1]; + continue; + } + + } + cmd->u.func = func; +} +void console_parse_list_subs(struct CParseEntry *cmd, unsigned char depth) { + unsigned int i; + char msg[CP_CMD_LENGTH * 2]; + for( i = 0; i < cmd->next_count; i++ ) { + if( cmd->u.next[i]->next_count ) { + memset(msg, '-', depth); + snprintf(msg + depth,CP_CMD_LENGTH * 2, " '"CL_WHITE"%s"CL_RESET"'",cmd->u.next[i]->cmd); + ShowInfo("%s subs\n",msg); + console->parse_list_subs(cmd->u.next[i],depth + 1); + } else { + memset(msg, '-', depth); + snprintf(msg + depth,CP_CMD_LENGTH * 2, " %s",cmd->u.next[i]->cmd); + ShowInfo("%s\n",msg); + } + } +} +void console_parse_sub(char *line) { + struct CParseEntry *cmd; + char bline[200]; + char *tok; + char sublist[CP_CMD_LENGTH * 5]; + unsigned int i, len = 0; + memcpy(bline, line, 200); + tok = strtok(line, " "); + for ( i = 0; i < console->cmd_list_count; i++ ) { + if( strcmpi(tok,console->cmd_list[i]->cmd) == 0 ) + break; + } + + if( i == console->cmd_list_count ) { + ShowError("'"CL_WHITE"%s"CL_RESET"' is not a known command, type '"CL_WHITE"help"CL_RESET"' to list all commands\n",line); + return; + } + + cmd = console->cmd_list[i]; + + len += snprintf(sublist,CP_CMD_LENGTH * 5,"%s", cmd->cmd) + 1; + + if( cmd->next_count == 0 && console->cmd_list[i]->u.func ) { + char *r = NULL; + if( (tok = strtok(NULL, " ")) ) { + r = bline; + r += len + 1; + } + cmd->u.func(r); + } else { + while( ( tok = strtok(NULL, " ") ) != NULL ) { + for( i = 0; i < cmd->next_count; i++ ) { + if( strcmpi(cmd->u.next[i]->cmd,tok) == 0 ) + break; + } + if( i == cmd->next_count ) { + if( strcmpi("help",tok) == 0 ) { + if( cmd->next_count ) { + ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n",sublist); + console->parse_list_subs(cmd,2); + } else { + ShowError("'"CL_WHITE"%s"CL_RESET"' doesn't possess any subcommands\n",sublist); + } + return; + } + ShowError("'"CL_WHITE"%s"CL_RESET"' is not a known subcommand of '"CL_WHITE"%s"CL_RESET"'\n",tok,cmd->cmd); + ShowError("type '"CL_WHITE"%s help"CL_RESET"' to list its subcommands\n",sublist); + return; + } + if( cmd->u.next[i]->next_count == 0 && cmd->u.next[i]->u.func ) { + char *r = NULL; + if( (tok = strtok(NULL, " ")) ) { + r = bline; + r += len + strlen(cmd->u.next[i]->cmd) + 1; + } + cmd->u.next[i]->u.func(r); + return; + } else + cmd = cmd->u.next[i]; + len += snprintf(sublist + len,CP_CMD_LENGTH * 5,":%s", cmd->cmd); + } + ShowError("it is only a category, type '"CL_WHITE"%s help"CL_RESET"' to list its subcommands\n",sublist); + } +} void console_parse(char* line) { int c, i = 0, len = MAX_CONSOLE_INPUT - 1;/* we leave room for the \0 :P */ @@ -122,7 +329,7 @@ int console_parse_timer(int tid, unsigned int tick, int id, intptr_t data) { int i; EnterSpinLock(&console->ptlock); for(i = 0; i < cinput.count; i++) { - parse_console(cinput.queue[i]); + console->parse_sub(cinput.queue[i]); } cinput.count = 0; LeaveSpinLock(&console->ptlock); @@ -163,12 +370,22 @@ void console_parse_init(void) { void console_init (void) { #ifdef CONSOLE_INPUT + console->cmd_count = console->cmd_list_count = 0; + console->load_defaults(); console->parse_init(); #endif } void console_final(void) { #ifdef CONSOLE_INPUT + int i; console->parse_final(); + for( i = 0; i < console->cmd_count; i++ ) { + if( console->cmds[i]->next_count ) + aFree(console->cmds[i]->u.next); + aFree(console->cmds[i]); + } + aFree(console->cmds); + aFree(console->cmd_list); #endif } void console_defaults(void) { @@ -182,6 +399,10 @@ void console_defaults(void) { console->parse_timer = console_parse_timer; console->pthread_main = cThread_main; console->parse = console_parse; + console->parse_sub = console_parse_sub; console->key_pressed = console_parse_key_pressed; + console->load_defaults = console_load_defaults; + console->parse_list_subs = console_parse_list_subs; + console->addCommand = console_parse_create; #endif } |