From b1dd87824f4fa0bca7817a030f71a7aca2dd7c6e Mon Sep 17 00:00:00 2001 From: Haru Date: Tue, 15 Sep 2015 15:53:01 +0200 Subject: Changed console->input->cmd_list to a VECTOR and renamed to console->input->command_list Signed-off-by: Haru --- src/common/console.c | 134 +++++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 62 deletions(-) (limited to 'src/common/console.c') diff --git a/src/common/console.c b/src/common/console.c index eb55d7462..7e565897c 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -124,14 +124,16 @@ CPCMD_C(mem_report,server) { /** * Displays command list **/ -CPCMD(help) { - unsigned int i = 0; - for ( i = 0; i < console->input->cmd_list_count; i++ ) { - if( console->input->cmd_list[i]->next_count ) { - ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n",console->input->cmd_list[i]->cmd); - console->input->parse_list_subs(console->input->cmd_list[i],2); +CPCMD(help) +{ + int i; + for (i = 0; i < VECTOR_LENGTH(console->input->command_list); i++) { + struct CParseEntry *entry = VECTOR_INDEX(console->input->command_list, i); + if (entry->next_count > 0) { + ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n", entry->cmd); + console->input->parse_list_subs(entry, 2); } else { - ShowInfo("- '"CL_WHITE"%s"CL_RESET"'\n",console->input->cmd_list[i]->cmd); + ShowInfo("- '"CL_WHITE"%s"CL_RESET"'\n", entry->cmd); } } } @@ -235,9 +237,9 @@ void console_load_defaults(void) console->input->cmd_count++; console->input->cmds[i] = cmd; default_list[i].self = cmd; - if( !default_list[i].connect ) { - RECREATE(console->input->cmd_list,struct CParseEntry *, ++console->input->cmd_list_count); - console->input->cmd_list[console->input->cmd_list_count - 1] = cmd; + if (!default_list[i].connect) { + VECTOR_ENSURE(console->input->command_list, 1, 1); + VECTOR_PUSH(console->input->command_list, cmd); } } @@ -260,8 +262,15 @@ void console_load_defaults(void) #undef CP_DEF } -void console_parse_create(char *name, CParseFunc func) { - unsigned int i; +/** + * Creates a new console command entry. + * + * @param name The command name. + * @param func The command callback. + */ +void console_parse_create(char *name, CParseFunc func) +{ + int i; char *tok; char sublist[CP_CMD_LENGTH * 5]; struct CParseEntry *cmd; @@ -269,23 +278,19 @@ void console_parse_create(char *name, CParseFunc func) { safestrncpy(sublist, name, CP_CMD_LENGTH * 5); tok = strtok(sublist,":"); - for ( i = 0; i < console->input->cmd_list_count; i++ ) { - if( strcmpi(tok,console->input->cmd_list[i]->cmd) == 0 ) - break; - } + ARR_FIND(0, VECTOR_LENGTH(console->input->command_list), i, strcmpi(tok, VECTOR_INDEX(console->input->command_list, i)->cmd) == 0); - if( i == console->input->cmd_list_count ) { + if (i == VECTOR_LENGTH(console->input->command_list)) { RECREATE(console->input->cmds,struct CParseEntry *, ++console->input->cmd_count); CREATE(cmd, struct CParseEntry, 1); safestrncpy(cmd->cmd, tok, CP_CMD_LENGTH); cmd->next_count = 0; console->input->cmds[console->input->cmd_count - 1] = cmd; - RECREATE(console->input->cmd_list,struct CParseEntry *, ++console->input->cmd_list_count); - console->input->cmd_list[console->input->cmd_list_count - 1] = cmd; - i = console->input->cmd_list_count - 1; + VECTOR_ENSURE(console->input->command_list, 1, 1); + VECTOR_PUSH(console->input->command_list, cmd); } - cmd = console->input->cmd_list[i]; + cmd = VECTOR_INDEX(console->input->command_list, i); while( ( tok = strtok(NULL, ":") ) != NULL ) { for(i = 0; i < cmd->next_count; i++) { if( strcmpi(cmd->u.next[i]->cmd,tok) == 0 ) @@ -321,71 +326,75 @@ void console_parse_list_subs(struct CParseEntry *cmd, unsigned char depth) { } } } + +/** + * Parses a console command. + * + * @param line The input line. + */ 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; + int i; + unsigned int len = 0; memcpy(bline, line, 200); tok = strtok(line, " "); - for ( i = 0; i < console->input->cmd_list_count; i++ ) { - if( strcmpi(tok,console->input->cmd_list[i]->cmd) == 0 ) - break; - } - - if( i == console->input->cmd_list_count ) { + ARR_FIND(0, VECTOR_LENGTH(console->input->command_list), i, strcmpi(tok, VECTOR_INDEX(console->input->command_list, i)->cmd) == 0); + if (i == VECTOR_LENGTH(console->input->command_list)) { 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->input->cmd_list[i]; + cmd = VECTOR_INDEX(console->input->command_list, i); - len += snprintf(sublist,CP_CMD_LENGTH * 5,"%s", cmd->cmd) + 1; + len += snprintf(sublist,CP_CMD_LENGTH * 5,"%s", cmd->cmd); - if( cmd->next_count == 0 && console->input->cmd_list[i]->u.func ) { + if (cmd->next_count == 0 && cmd->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->input->parse_list_subs(cmd,2); - } else { - ShowError("'"CL_WHITE"%s"CL_RESET"' doesn't possess any subcommands\n",sublist); - } - return; + return; + } + + 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->input->parse_list_subs(cmd,2); + } else { + ShowError("'"CL_WHITE"%s"CL_RESET"' doesn't possess any subcommands\n",sublist); } - 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) - len,":%s", cmd->cmd); + 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; } - ShowError("Is only a category, type '"CL_WHITE"%s help"CL_RESET"' to list its subcommands\n",sublist); + 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) - len," %s", cmd->cmd); } + ShowError("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 */ @@ -474,7 +483,8 @@ void console_setSQL(Sql *SQL_handle) { void console_init (void) { #ifdef CONSOLE_INPUT - console->input->cmd_count = console->input->cmd_list_count = 0; + VECTOR_INIT(console->input->command_list); + console->input->cmd_count = 0; console->input->load_defaults(); console->input->parse_init(); #endif @@ -488,8 +498,8 @@ void console_final(void) { aFree(console->input->cmds[i]->u.next); aFree(console->input->cmds[i]); } + VECTOR_CLEAR(console->input->command_list); aFree(console->input->cmds); - aFree(console->input->cmd_list); #endif } void console_defaults(void) { -- cgit v1.2.3-70-g09d2 From 80bbb08f18b9a99813adb08b1d5c14fd7f81e1a2 Mon Sep 17 00:00:00 2001 From: Haru Date: Tue, 15 Sep 2015 16:12:44 +0200 Subject: Changed console->input->cmds to a VECTOR and renamed to console->input->commands Signed-off-by: Haru --- src/common/console.c | 67 ++++++++++++++++++++++++++-------------------------- src/common/console.h | 3 +-- 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src/common/console.c') diff --git a/src/common/console.c b/src/common/console.c index 7e565897c..e7a9dcf17 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -217,10 +217,11 @@ void console_load_defaults(void) CP_DEF_C2(update,sql), CP_DEF_S(skip,update), }; - unsigned int i, len = ARRAYLENGTH(default_list); + int len = ARRAYLENGTH(default_list); struct CParseEntry *cmd; + int i; - RECREATE(console->input->cmds,struct CParseEntry *, len); + VECTOR_ENSURE(console->input->commands, len, 1); for(i = 0; i < len; i++) { CREATE(cmd, struct CParseEntry, 1); @@ -234,8 +235,7 @@ void console_load_defaults(void) cmd->next_count = 0; - console->input->cmd_count++; - console->input->cmds[i] = cmd; + VECTOR_PUSH(console->input->commands, cmd); default_list[i].self = cmd; if (!default_list[i].connect) { VECTOR_ENSURE(console->input->command_list, 1, 1); @@ -243,17 +243,16 @@ void console_load_defaults(void) } } - for(i = 0; i < len; i++) { - unsigned int k; - if( !default_list[i].connect ) + for (i = 0; i < len; i++) { + int k; + if (!default_list[i].connect) continue; - for(k = 0; k < console->input->cmd_count; k++) { - if( strcmpi(default_list[i].connect,console->input->cmds[k]->cmd) == 0 ) { - cmd = default_list[i].self; - RECREATE(console->input->cmds[k]->u.next, struct CParseEntry *, ++console->input->cmds[k]->next_count); - console->input->cmds[k]->u.next[console->input->cmds[k]->next_count - 1] = cmd; - break; - } + ARR_FIND(0, VECTOR_LENGTH(console->input->commands), k, strcmpi(default_list[i].connect, VECTOR_INDEX(console->input->commands, k)->cmd) == 0); + if (k != VECTOR_LENGTH(console->input->commands)) { + struct CParseEntry *parent = VECTOR_INDEX(console->input->commands, k); + cmd = default_list[i].self; + RECREATE(parent->u.next, struct CParseEntry *, ++parent->next_count); + parent->u.next[parent->next_count - 1] = cmd; } } #undef CP_DEF_C @@ -281,30 +280,32 @@ void console_parse_create(char *name, CParseFunc func) ARR_FIND(0, VECTOR_LENGTH(console->input->command_list), i, strcmpi(tok, VECTOR_INDEX(console->input->command_list, i)->cmd) == 0); if (i == VECTOR_LENGTH(console->input->command_list)) { - RECREATE(console->input->cmds,struct CParseEntry *, ++console->input->cmd_count); CREATE(cmd, struct CParseEntry, 1); safestrncpy(cmd->cmd, tok, CP_CMD_LENGTH); cmd->next_count = 0; - console->input->cmds[console->input->cmd_count - 1] = cmd; + VECTOR_ENSURE(console->input->commands, 1, 1); + VECTOR_PUSH(console->input->commands, cmd); VECTOR_ENSURE(console->input->command_list, 1, 1); VECTOR_PUSH(console->input->command_list, cmd); } cmd = VECTOR_INDEX(console->input->command_list, i); - while( ( tok = strtok(NULL, ":") ) != NULL ) { - for(i = 0; i < cmd->next_count; i++) { - if( strcmpi(cmd->u.next[i]->cmd,tok) == 0 ) + 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->input->cmds,struct CParseEntry *, ++console->input->cmd_count); - CREATE(console->input->cmds[console->input->cmd_count-1], struct CParseEntry, 1); - safestrncpy(console->input->cmds[console->input->cmd_count-1]->cmd, tok, CP_CMD_LENGTH); - console->input->cmds[console->input->cmd_count-1]->next_count = 0; + if (i == cmd->next_count) { + struct CParseEntry *entry; + CREATE(entry, struct CParseEntry, 1); + safestrncpy(entry->cmd, tok, CP_CMD_LENGTH); + entry->next_count = 0; + VECTOR_ENSURE(console->input->commands, 1, 1); + VECTOR_PUSH(console->input->commands, entry); RECREATE(cmd->u.next, struct CParseEntry *, ++cmd->next_count); - cmd->u.next[cmd->next_count - 1] = console->input->cmds[console->input->cmd_count-1]; - cmd = console->input->cmds[console->input->cmd_count-1]; + cmd->u.next[cmd->next_count - 1] = entry; + cmd = entry; continue; } } @@ -484,22 +485,22 @@ void console_setSQL(Sql *SQL_handle) { void console_init (void) { #ifdef CONSOLE_INPUT VECTOR_INIT(console->input->command_list); - console->input->cmd_count = 0; + VECTOR_INIT(console->input->commands); console->input->load_defaults(); console->input->parse_init(); #endif } void console_final(void) { #ifdef CONSOLE_INPUT - unsigned int i; console->input->parse_final(); - for( i = 0; i < console->input->cmd_count; i++ ) { - if( console->input->cmds[i]->next_count ) - aFree(console->input->cmds[i]->u.next); - aFree(console->input->cmds[i]); + while (VECTOR_LENGTH(console->input->commands)) { + struct CParseEntry *entry = VECTOR_POP(console->input->commands); + if (entry->next_count) + aFree(entry->u.next); + aFree(entry); } + VECTOR_CLEAR(console->input->commands); VECTOR_CLEAR(console->input->command_list); - aFree(console->input->cmds); #endif } void console_defaults(void) { diff --git a/src/common/console.h b/src/common/console.h index 35a83da52..50e40506c 100644 --- a/src/common/console.h +++ b/src/common/console.h @@ -53,8 +53,7 @@ struct console_input_interface { racond *ptcond;/* parse thread cond */ /* */ VECTOR_DECL(struct CParseEntry *) command_list; - struct CParseEntry **cmds; - unsigned int cmd_count; + VECTOR_DECL(struct CParseEntry *) commands; /* */ Sql *SQL; /* */ -- cgit v1.2.3-70-g09d2 From 53bbcf013e3260d67ab0a67624de40cf1312ff73 Mon Sep 17 00:00:00 2001 From: Haru Date: Tue, 15 Sep 2015 17:50:53 +0200 Subject: Changed struct CParseEntry::u.next to VECTOR and renamed to u.children Added a 'type' field to describe the command type (function, category) Signed-off-by: Haru --- src/common/console.c | 137 +++++++++++++++++++++++++++++++-------------------- src/common/console.h | 11 ++++- 2 files changed, 93 insertions(+), 55 deletions(-) (limited to 'src/common/console.c') diff --git a/src/common/console.c b/src/common/console.c index e7a9dcf17..7633471c0 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -9,6 +9,7 @@ #include "common/cbasetypes.h" #include "common/core.h" +#include "common/nullpo.h" #include "common/showmsg.h" #include "common/sysinfo.h" @@ -129,7 +130,7 @@ CPCMD(help) int i; for (i = 0; i < VECTOR_LENGTH(console->input->command_list); i++) { struct CParseEntry *entry = VECTOR_INDEX(console->input->command_list, i); - if (entry->next_count > 0) { + if (entry->type == CPET_CATEGORY) { ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n", entry->cmd); console->input->parse_list_subs(entry, 2); } else { @@ -173,7 +174,7 @@ void console_load_defaults(void) * 'sql' is the main category * CP_DEF_C(category) **/ -#define CP_DEF_C(x) { #x , NULL , NULL, NULL } +#define CP_DEF_C(x) { #x , CPET_CATEGORY, NULL , NULL, NULL } /** * Defines a sub-category. * @@ -183,20 +184,21 @@ void console_load_defaults(void) * 'update' is a sub-category * CP_DEF_C2(command, category) **/ -#define CP_DEF_C2(x,y) { #x , NULL , #y, NULL } +#define CP_DEF_C2(x,y) { #x , CPET_CATEGORY, NULL , #y, NULL } /** * Defines a command that is inside a category or sub-category * CP_DEF_S(command, category/sub-category) **/ -#define CP_DEF_S(x,y) { #x, CPCMD_C_A(x,y), #y, NULL } +#define CP_DEF_S(x,y) { #x, CPET_FUNCTION, CPCMD_C_A(x,y), #y, NULL } /** * Defines a command that is _not_ inside any category * CP_DEF_S(command) **/ -#define CP_DEF(x) { #x , CPCMD_A(x), NULL, NULL } +#define CP_DEF(x) { #x , CPET_FUNCTION, CPCMD_A(x), NULL, NULL } struct { char *name; + int type; CParseFunc func; char *connect; struct CParseEntry *self; @@ -228,12 +230,18 @@ void console_load_defaults(void) 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->type = default_list[i].type; - cmd->next_count = 0; + switch (cmd->type) { + case CPET_FUNCTION: + cmd->u.func = default_list[i].func; + break; + case CPET_CATEGORY: + VECTOR_INIT(cmd->u.children); + break; + case CPET_UNKNOWN: + break; + } VECTOR_PUSH(console->input->commands, cmd); default_list[i].self = cmd; @@ -250,9 +258,10 @@ void console_load_defaults(void) ARR_FIND(0, VECTOR_LENGTH(console->input->commands), k, strcmpi(default_list[i].connect, VECTOR_INDEX(console->input->commands, k)->cmd) == 0); if (k != VECTOR_LENGTH(console->input->commands)) { struct CParseEntry *parent = VECTOR_INDEX(console->input->commands, k); + Assert_retb(parent->type == CPET_CATEGORY); cmd = default_list[i].self; - RECREATE(parent->u.next, struct CParseEntry *, ++parent->next_count); - parent->u.next[parent->next_count - 1] = cmd; + VECTOR_ENSURE(parent->u.children, 1, 1); + VECTOR_PUSH(parent->u.children, cmd); } } #undef CP_DEF_C @@ -282,7 +291,7 @@ void console_parse_create(char *name, CParseFunc func) if (i == VECTOR_LENGTH(console->input->command_list)) { CREATE(cmd, struct CParseEntry, 1); safestrncpy(cmd->cmd, tok, CP_CMD_LENGTH); - cmd->next_count = 0; + cmd->type = CPET_UNKNOWN; VECTOR_ENSURE(console->input->commands, 1, 1); VECTOR_PUSH(console->input->commands, cmd); VECTOR_ENSURE(console->input->command_list, 1, 1); @@ -290,40 +299,53 @@ void console_parse_create(char *name, CParseFunc func) } cmd = VECTOR_INDEX(console->input->command_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; + while ((tok = strtok(NULL, ":")) != NULL) { + if (cmd->type == CPET_UNKNOWN) { + cmd->type = CPET_CATEGORY; + VECTOR_INIT(cmd->u.children); } + Assert_retv(cmd->type == CPET_CATEGORY); - if (i == cmd->next_count) { + ARR_FIND(0, VECTOR_LENGTH(cmd->u.children), i, strcmpi(VECTOR_INDEX(cmd->u.children, i)->cmd,tok) == 0); + if (i == VECTOR_LENGTH(cmd->u.children)) { struct CParseEntry *entry; CREATE(entry, struct CParseEntry, 1); safestrncpy(entry->cmd, tok, CP_CMD_LENGTH); - entry->next_count = 0; + entry->type = CPET_UNKNOWN; VECTOR_ENSURE(console->input->commands, 1, 1); VECTOR_PUSH(console->input->commands, entry); - RECREATE(cmd->u.next, struct CParseEntry *, ++cmd->next_count); - cmd->u.next[cmd->next_count - 1] = entry; + VECTOR_ENSURE(cmd->u.children, 1, 1); + VECTOR_PUSH(cmd->u.children, entry); cmd = entry; continue; } + // FIXME: This should advance cmd to VECTOR_INDEX(cmd->u.children, i) } + Assert_retv(cmd->type != CPET_CATEGORY); + cmd->type = CPET_FUNCTION; cmd->u.func = func; } -void console_parse_list_subs(struct CParseEntry *cmd, unsigned char depth) { - unsigned int i; + +/** + * Shows the help message for a console command category. + * + * @param cmd The command entry. + * @param depth The current tree depth (for display purposes). + */ +void console_parse_list_subs(struct CParseEntry *cmd, unsigned char depth) +{ + 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 ) - depth, " '"CL_WHITE"%s"CL_RESET"'",cmd->u.next[i]->cmd); - ShowInfo("%s subs\n",msg); - console->input->parse_list_subs(cmd->u.next[i],depth + 1); - } else { - memset(msg, '-', depth); - snprintf(msg + depth,(CP_CMD_LENGTH * 2) - depth, " %s",cmd->u.next[i]->cmd); + Assert_retv(cmd->type == CPET_CATEGORY); + for (i = 0; i < VECTOR_LENGTH(cmd->u.children); i++) { + struct CParseEntry *child = VECTOR_INDEX(cmd->u.children, i); + memset(msg, '-', depth); + snprintf(msg + depth, (CP_CMD_LENGTH * 2) - depth, " '"CL_WHITE"%s"CL_RESET"'", child->cmd); + if (child->type == CPET_FUNCTION) { ShowInfo("%s\n",msg); + } else { + ShowInfo("%s subs\n",msg); + console->input->parse_list_subs(child,depth + 1); } } } @@ -333,7 +355,8 @@ void console_parse_list_subs(struct CParseEntry *cmd, unsigned char depth) { * * @param line The input line. */ -void console_parse_sub(char *line) { +void console_parse_sub(char *line) +{ struct CParseEntry *cmd; char bline[200]; char *tok; @@ -354,7 +377,7 @@ void console_parse_sub(char *line) { len += snprintf(sublist,CP_CMD_LENGTH * 5,"%s", cmd->cmd); - if (cmd->next_count == 0 && cmd->u.func) { + if (cmd->type == CPET_FUNCTION) { char *r = NULL; if( (tok = strtok(NULL, " ")) ) { r = bline; @@ -364,14 +387,15 @@ void console_parse_sub(char *line) { return; } - 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 ) { + while (( tok = strtok(NULL, " ") ) != NULL) { + struct CParseEntry *entry = NULL; + + Assert_retv(cmd->type == CPET_CATEGORY); + + ARR_FIND(0, VECTOR_LENGTH(cmd->u.children), i, strcmpi(VECTOR_INDEX(cmd->u.children, i)->cmd, tok) == 0); + if (i == VECTOR_LENGTH(cmd->u.children)) { + if (strcmpi("help", tok) == 0) { + if (VECTOR_LENGTH(cmd->u.children)) { ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n",sublist); console->input->parse_list_subs(cmd,2); } else { @@ -383,16 +407,18 @@ void console_parse_sub(char *line) { 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 ) { + entry = VECTOR_INDEX(cmd->u.children, i); + if (entry->type == CPET_FUNCTION) { char *r = NULL; - if( (tok = strtok(NULL, " ")) ) { + if ((tok = strtok(NULL, " "))) { r = bline; - r += len + strlen(cmd->u.next[i]->cmd) + 1; + r += len + strlen(entry->cmd) + 1; } - cmd->u.next[i]->u.func(r); + entry->u.func(r); return; - } else - cmd = cmd->u.next[i]; + } + + cmd = entry; len += snprintf(sublist + len,(CP_CMD_LENGTH * 5) - len," %s", cmd->cmd); } ShowError("Is only a category, type '"CL_WHITE"%s help"CL_RESET"' to list its subcommands\n",sublist); @@ -482,7 +508,8 @@ void console_setSQL(Sql *SQL_handle) { } #endif /* CONSOLE_INPUT */ -void console_init (void) { +void console_init(void) +{ #ifdef CONSOLE_INPUT VECTOR_INIT(console->input->command_list); VECTOR_INIT(console->input->commands); @@ -490,20 +517,24 @@ void console_init (void) { console->input->parse_init(); #endif } -void console_final(void) { + +void console_final(void) +{ #ifdef CONSOLE_INPUT console->input->parse_final(); while (VECTOR_LENGTH(console->input->commands)) { struct CParseEntry *entry = VECTOR_POP(console->input->commands); - if (entry->next_count) - aFree(entry->u.next); + if (entry->type == CPET_CATEGORY) + VECTOR_CLEAR(entry->u.children); aFree(entry); } VECTOR_CLEAR(console->input->commands); VECTOR_CLEAR(console->input->command_list); #endif } -void console_defaults(void) { + +void console_defaults(void) +{ console = &console_s; console->init = console_init; console->final = console_final; diff --git a/src/common/console.h b/src/common/console.h index 50e40506c..ef6db0cb4 100644 --- a/src/common/console.h +++ b/src/common/console.h @@ -34,13 +34,20 @@ typedef void (*CParseFunc)(char *line); #define CPCMD_C_A(x,y) console_parse_ ##y ##x #define CP_CMD_LENGTH 20 + +enum CONSOLE_PARSE_ENTRY_TYPE { + CPET_UNKNOWN, + CPET_FUNCTION, + CPET_CATEGORY, +}; + struct CParseEntry { char cmd[CP_CMD_LENGTH]; + int type; ///< Entry type (@see enum CONSOLE_PARSE_ENTRY_TYPE) union { CParseFunc func; - struct CParseEntry **next; + VECTOR_DECL(struct CParseEntry *) children; } u; - unsigned short next_count; }; #ifdef CONSOLE_INPUT -- cgit v1.2.3-70-g09d2 From aa6b8fd27b3c9b7c75f584434cc994ae9f9b044a Mon Sep 17 00:00:00 2001 From: Haru Date: Tue, 15 Sep 2015 17:52:21 +0200 Subject: Fixed an issue preventing correct nesting of console commands into subcategories - The issue prevented the creation of multiple commands in the same subcategory through console->input->addCommand (i.e. "foo:bar:baz" and "foo:bar:quux" would instead create "foo:bar:baz" and "foo:quux") Signed-off-by: Haru --- src/common/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/common/console.c') diff --git a/src/common/console.c b/src/common/console.c index 7633471c0..c8ca4ae87 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -319,7 +319,7 @@ void console_parse_create(char *name, CParseFunc func) cmd = entry; continue; } - // FIXME: This should advance cmd to VECTOR_INDEX(cmd->u.children, i) + cmd = VECTOR_INDEX(cmd->u.children, i); } Assert_retv(cmd->type != CPET_CATEGORY); cmd->type = CPET_FUNCTION; -- cgit v1.2.3-70-g09d2