diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2010-05-29 07:25:38 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2010-05-29 07:25:38 +0000 |
| commit | 72c06a258940696093f255fb1061beb58e1cdd0b (patch) | |
| tree | 36b9a7712eec2d4f07837eab9c38ef1c5af85319 /src/engine/e_console.cpp | |
| parent | e56feb597bc743677633432f77513b02907fd169 (diff) | |
| download | zcatch-72c06a258940696093f255fb1061beb58e1cdd0b.tar.gz zcatch-72c06a258940696093f255fb1061beb58e1cdd0b.zip | |
copied refactor to trunk
Diffstat (limited to 'src/engine/e_console.cpp')
| -rw-r--r-- | src/engine/e_console.cpp | 464 |
1 files changed, 0 insertions, 464 deletions
diff --git a/src/engine/e_console.cpp b/src/engine/e_console.cpp deleted file mode 100644 index c641289d..00000000 --- a/src/engine/e_console.cpp +++ /dev/null @@ -1,464 +0,0 @@ -#include <base/system.h> -#include "e_if_other.h" -#include "e_console.h" -#include "e_config.h" -#include "e_engine.h" -#include "e_linereader.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - - -#define CONSOLE_MAX_STR_LENGTH 1024 -/* the maximum number of tokens occurs in a string of length CONSOLE_MAX_STR_LENGTH with tokens size 1 separated by single spaces */ -#define MAX_PARTS (CONSOLE_MAX_STR_LENGTH+1)/2 - -typedef struct -{ - char string_storage[CONSOLE_MAX_STR_LENGTH+1]; - char *args_start; - - const char *command; - const char *args[MAX_PARTS]; - unsigned int num_args; -} PARSE_RESULT; - -static char *str_skipblanks(char *str) -{ - while(*str && (*str == ' ' || *str == '\t' || *str == '\n')) - str++; - return str; -} - -static char *str_skiptoblank(char *str) -{ - while(*str && (*str != ' ' && *str != '\t' && *str != '\n')) - str++; - return str; -} - -/* static int digit(char c) { return '0' <= c && c <= '9'; } */ - -static int console_parse_start(PARSE_RESULT *result, const char *string, int length) -{ - char *str; - int len = sizeof(result->string_storage); - if(length < len) - len = length; - - str_copy(result->string_storage, string, length); - str = result->string_storage; - - /* get command */ - str = str_skipblanks(str); - result->command = str; - str = str_skiptoblank(str); - - if(*str) - { - str[0] = 0; - str++; - } - - result->args_start = str; - result->num_args = 0; - return 0; -} - -static int console_parse_args(PARSE_RESULT *result, const char *format) -{ - char command; - char *str; - int optional = 0; - int error = 0; - - str = result->args_start; - - while(1) - { - /* fetch command */ - command = *format; - format++; - - if(!command) - break; - - if(command == '?') - optional = 1; - else - { - str = str_skipblanks(str); - - if(!(*str)) /* error, non optional command needs value */ - { - if(!optional) - error = 1; - break; - } - - /* add token */ - if(*str == '"') - { - char *dst; - str++; - result->args[result->num_args++] = str; - - dst = str; /* we might have to process escape data */ - while(1) - { - if(str[0] == '"') - break; - else if(str[0] == '\\') - { - if(str[1] == '\\') - str++; /* skip due to escape */ - else if(str[1] == '"') - str++; /* skip due to escape */ - } - else if(str[0] == 0) - return 1; /* return error */ - - *dst = *str; - dst++; - str++; - } - - /* write null termination */ - *dst = 0; - } - else - { - result->args[result->num_args++] = str; - - if(command == 'r') /* rest of the string */ - break; - else if(command == 'i') /* validate int */ - str = str_skiptoblank(str); - else if(command == 'f') /* validate float */ - str = str_skiptoblank(str); - else if(command == 's') /* validate string */ - str = str_skiptoblank(str); - - if(str[0] != 0) /* check for end of string */ - { - str[0] = 0; - str++; - } - } - } - } - - return error; -} - -const char *console_arg_string(void *res, unsigned index) -{ - PARSE_RESULT *result = (PARSE_RESULT *)res; - if (index < 0 || index >= result->num_args) - return ""; - return result->args[index]; -} - -int console_arg_int(void *res, unsigned index) -{ - PARSE_RESULT *result = (PARSE_RESULT *)res; - if (index < 0 || index >= result->num_args) - return 0; - return atoi(result->args[index]); -} - -float console_arg_float(void *res, unsigned index) -{ - PARSE_RESULT *result = (PARSE_RESULT *)res; - if (index < 0 || index >= result->num_args) - return 0.0f; - return atof(result->args[index]); -} - -int console_arg_num(void *result) -{ - return ((PARSE_RESULT *)result)->num_args; -} - -static COMMAND *first_command = 0x0; - -COMMAND *console_find_command(const char *name) -{ - COMMAND *cmd; - for (cmd = first_command; cmd; cmd = cmd->next) - { - if (strcmp(cmd->name, name) == 0) - return cmd; - } - - return 0x0; -} - -void console_register(COMMAND *cmd) -{ - cmd->next = first_command; - first_command = cmd; -} - -static void (*print_callback)(const char *, void *) = 0x0; -static void *print_callback_userdata; - -void console_register_print_callback(void (*callback)(const char *, void *), void *user_data) -{ - print_callback = callback; - print_callback_userdata = user_data; -} - -void console_print(const char *str) -{ - if (print_callback) - print_callback(str, print_callback_userdata); -} - -void console_execute_line_stroked(int stroke, const char *str) -{ - PARSE_RESULT result; - COMMAND *command; - - char strokestr[2] = {'0', 0}; - if(stroke) - strokestr[0] = '1'; - - while(str) - { - const char *end = str; - const char *next_part = 0; - int in_string = 0; - - while(*end) - { - if(*end == '"') - in_string ^= 1; - else if(*end == '\\') /* escape sequences */ - { - if(end[1] == '"') - end++; - } - else if(!in_string) - { - if(*end == ';') /* command separator */ - { - next_part = end+1; - break; - } - else if(*end == '#') /* comment, no need to do anything more */ - break; - } - - end++; - } - - if(console_parse_start(&result, str, (end-str) + 1) != 0) - return; - - command = console_find_command(result.command); - - if(command) - { - int is_stroke_command = 0; - if(result.command[0] == '+') - { - /* insert the stroke direction token */ - result.args[result.num_args] = strokestr; - result.num_args++; - is_stroke_command = 1; - } - - if(stroke || is_stroke_command) - { - if(console_parse_args(&result, command->params)) - { - char buf[256]; - str_format(buf, sizeof(buf), "Invalid arguments... Usage: %s %s", command->name, command->params); - console_print(buf); - } - else - command->callback(&result, command->user_data); - } - } - else - { - char buf[256]; - str_format(buf, sizeof(buf), "No such command: %s.", result.command); - console_print(buf); - } - - str = next_part; - } -} - -void console_possible_commands(const char *str, int flagmask, void (*callback)(const char *cmd, void *user), void *user) -{ - COMMAND *cmd; - for (cmd = first_command; cmd; cmd = cmd->next) - { - if(cmd->flags&flagmask) - { - if(str_find_nocase(cmd->name, str)) - callback(cmd->name, user); - } - } -} - - -COMMAND *console_get_command(const char *str) -{ - COMMAND *cmd; - for (cmd = first_command; cmd; cmd = cmd->next) - { - if(str_comp_nocase(cmd->name, str) == 0) - return cmd; - } - - return 0x0; -} - -void console_execute_line(const char *str) -{ - console_execute_line_stroked(1, str); -} - -static void console_execute_file_real(const char *filename) -{ - IOHANDLE file; - file = engine_openfile(filename, IOFLAG_READ); - - if(file) - { - char *line; - LINEREADER lr; - - dbg_msg("console", "executing '%s'", filename); - linereader_init(&lr, file); - - while((line = linereader_get(&lr))) - console_execute_line(line); - - io_close(file); - } - else - dbg_msg("console", "failed to open '%s'", filename); -} - -struct EXECFILE -{ - const char *filename; - struct EXECFILE *next; -}; - -void console_execute_file(const char *filename) -{ - static struct EXECFILE *first = 0; - struct EXECFILE this_file; - struct EXECFILE *cur; - struct EXECFILE *prev; - - /* make sure that this isn't being executed already */ - for(cur = first; cur; cur = cur->next) - if(strcmp(filename, cur->filename) == 0) - return; - - /* push this one to the stack */ - prev = first; - this_file.filename = filename; - this_file.next = first; - first = &this_file; - - /* execute file */ - console_execute_file_real(filename); - - /* pop this one from the stack */ - first = prev; -} - -static void con_echo(void *result, void *user_data) -{ - console_print(console_arg_string(result, 0)); -} - -static void con_exec(void *result, void *user_data) -{ - console_execute_file(console_arg_string(result, 0)); - -} - - -typedef struct -{ - CONFIG_INT_GETTER getter; - CONFIG_INT_SETTER setter; -} INT_VARIABLE_DATA; - -typedef struct -{ - CONFIG_STR_GETTER getter; - CONFIG_STR_SETTER setter; -} STR_VARIABLE_DATA; - -static void int_variable_command(void *result, void *user_data) -{ - INT_VARIABLE_DATA *data = (INT_VARIABLE_DATA *)user_data; - - if(console_arg_num(result)) - data->setter(&config, console_arg_int(result, 0)); - else - { - char buf[1024]; - str_format(buf, sizeof(buf), "Value: %d", data->getter(&config)); - console_print(buf); - } -} - -static void str_variable_command(void *result, void *user_data) -{ - STR_VARIABLE_DATA *data = (STR_VARIABLE_DATA *)user_data; - - if(console_arg_num(result)) - data->setter(&config, console_arg_string(result, 0)); - else - { - char buf[1024]; - str_format(buf, sizeof(buf), "Value: %s", data->getter(&config)); - console_print(buf); - } -} - -static void console_chain(void *result, void *user_data) -{ - COMMANDCHAIN *info = (COMMANDCHAIN *)user_data; - info->chain_callback(result, info->user_data, info->callback, info->callback_user_data); -} - -void console_chain_command(const char *cmd, COMMANDCHAIN *chaininfo, CONSOLE_CHAIN_CALLBACK cb, void *user) -{ - COMMAND *command = console_get_command(cmd); - - /* store info */ - chaininfo->chain_callback = cb; - chaininfo->callback = command->callback; - chaininfo->callback_user_data = command->user_data; - chaininfo->user_data = user; - - /* chain */ - command->callback = console_chain; - command->user_data = chaininfo; -} - -void console_init() -{ - MACRO_REGISTER_COMMAND("echo", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, con_echo, 0x0, "Echo the text"); - MACRO_REGISTER_COMMAND("exec", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, con_exec, 0x0, "Execute the specified file"); - - #define MACRO_CONFIG_INT(name,def,min,max,flags,desc) { static INT_VARIABLE_DATA data = { &config_get_ ## name, &config_set_ ## name }; MACRO_REGISTER_COMMAND(#name, "?i", flags, int_variable_command, &data, desc) } - #define MACRO_CONFIG_STR(name,len,def,flags,desc) { static STR_VARIABLE_DATA data = { &config_get_ ## name, &config_set_ ## name }; MACRO_REGISTER_COMMAND(#name, "?r", flags, str_variable_command, &data, desc) } - - #include "e_config_variables.h" - - #undef MACRO_CONFIG_INT - #undef MACRO_CONFIG_STR -} |