darkvater@135: #include "stdafx.h" darkvater@135: #include "ttd.h" tron@507: #include "table/strings.h" darkvater@135: #include "window.h" darkvater@135: #include "gui.h" darkvater@135: #include "gfx.h" darkvater@135: #include "player.h" darkvater@135: #include "variables.h" darkvater@135: #include "hal.h" darkvater@135: #include darkvater@289: #include signde@274: #include "console.h" truelight@543: #include "network.h" signde@274: signde@274: #ifdef WIN32 signde@274: #include signde@273: #endif darkvater@135: darkvater@301: #define ICON_BUFFER 79 darkvater@301: #define ICON_CMDBUF_SIZE 20 darkvater@301: #define ICON_CMDLN_SIZE 255 darkvater@301: #define ICON_LINE_HEIGHT 12 truelight@543: #define ICON_RIGHT_BORDERWIDTH 10 truelight@543: #define ICON_BOTTOM_BORDERWIDTH 12 truelight@634: #define ICON_MAX_ALIAS_LINES 40 darkvater@289: darkvater@135: // ** main console ** // darkvater@135: static bool _iconsole_inited; darkvater@301: static char* _iconsole_buffer[ICON_BUFFER + 1]; truelight@543: static uint16 _iconsole_cbuffer[ICON_BUFFER + 1]; darkvater@301: static char _iconsole_cmdline[ICON_CMDLN_SIZE]; darkvater@135: static byte _iconsole_cmdpos; darkvater@289: static Window* _iconsole_win = NULL; darkvater@135: static byte _iconsole_scroll; darkvater@135: darkvater@135: // ** console cursor ** // darkvater@135: static bool _icursor_state; darkvater@135: static byte _icursor_rate; darkvater@135: static byte _icursor_counter; darkvater@135: signde@220: // ** stdlib ** // darkvater@289: byte _stdlib_developer = 1; darkvater@289: bool _stdlib_con_developer = false; darkvater@289: FILE* _iconsole_output_file; signde@220: darkvater@301: // ** main console cmd buffer darkvater@301: static char* _iconsole_cmdbuffer[ICON_CMDBUF_SIZE]; signde@220: static byte _iconsole_cmdbufferpos; signde@220: darkvater@135: // ** console window ** // darkvater@289: static void IConsoleWndProc(Window* w, WindowEvent* e); darkvater@289: static const Widget _iconsole_window_widgets[] = { darkvater@289: {WIDGETS_END} darkvater@289: }; darkvater@135: static const WindowDesc _iconsole_window_desc = { darkvater@135: 0, 0, 2, 2, darkvater@289: WC_CONSOLE, 0, darkvater@135: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, darkvater@135: _iconsole_window_widgets, darkvater@135: IConsoleWndProc, darkvater@135: }; darkvater@135: darkvater@135: /* *************** */ darkvater@135: /* end of header */ signde@274: /* *************** */ signde@274: darkvater@289: static void IConsoleAppendClipboard(void) signde@274: { signde@274: #ifdef WIN32 signde@274: if (IsClipboardFormatAvailable(CF_TEXT)) { darkvater@289: const char* data; signde@274: HGLOBAL cbuf; signde@274: signde@274: OpenClipboard(NULL); signde@274: cbuf = GetClipboardData(CF_TEXT); darkvater@289: data = GlobalLock(cbuf); signde@274: darkvater@301: /* IS_INT_INSIDE = filter for ascii-function codes like BELL and so on [we need an special filter here later] */ darkvater@301: for (; (IS_INT_INSIDE(*data, ' ', 256)) && (_iconsole_cmdpos < lengthof(_iconsole_cmdline) - 1); ++data) darkvater@301: _iconsole_cmdline[_iconsole_cmdpos++] = *data; signde@274: signde@274: GlobalUnlock(cbuf); signde@274: CloseClipboard(); signde@274: } signde@274: #endif signde@273: } darkvater@135: darkvater@289: static void IConsoleClearCommand(void) darkvater@135: { darkvater@289: memset(_iconsole_cmdline, 0, sizeof(_iconsole_cmdline)); darkvater@289: _iconsole_cmdpos = 0; darkvater@289: SetWindowDirty(_iconsole_win); darkvater@135: } darkvater@135: darkvater@289: static void IConsoleWndProc(Window* w, WindowEvent* e) darkvater@135: { signde@209: // only do window events with the console signde@209: w = FindWindowById(WC_CONSOLE, 0); signde@209: darkvater@135: switch(e->event) { darkvater@289: case WE_PAINT: darkvater@135: { darkvater@289: int i = _iconsole_scroll; darkvater@301: int max = (w->height / ICON_LINE_HEIGHT) - 1; truelight@543: int delta = 0; darkvater@289: GfxFillRect(w->left, w->top, w->width, w->height - 1, 0); darkvater@289: while ((i > _iconsole_scroll - max) && (_iconsole_buffer[i] != NULL)) { darkvater@289: DoDrawString(_iconsole_buffer[i], 5, darkvater@301: w->height - (_iconsole_scroll + 2 - i) * ICON_LINE_HEIGHT, _iconsole_cbuffer[i]); darkvater@289: i--; darkvater@135: } truelight@543: delta = w->width - 10 - GetStringWidth(_iconsole_cmdline) - ICON_RIGHT_BORDERWIDTH; truelight@543: if (delta > 0) { truelight@543: DoDrawString("]", 5, w->height - ICON_LINE_HEIGHT, _iconsole_color_commands); truelight@543: delta = 0; truelight@543: } truelight@543: truelight@543: DoDrawString(_iconsole_cmdline, 10 + delta, w->height - ICON_LINE_HEIGHT, _iconsole_color_commands); darkvater@289: break; darkvater@135: } darkvater@289: case WE_TICK: darkvater@289: _icursor_counter++; darkvater@289: if (_icursor_counter > _icursor_rate) { darkvater@135: int posx; darkvater@135: int posy; truelight@543: int delta; darkvater@169: darkvater@289: _icursor_state = !_icursor_state; darkvater@135: darkvater@289: _cur_dpi = &_screen; truelight@543: delta = w->width - 10 - GetStringWidth(_iconsole_cmdline) - ICON_RIGHT_BORDERWIDTH; truelight@543: if (delta > 0) truelight@543: delta = 0; truelight@543: posx = 10 + GetStringWidth(_iconsole_cmdline) + delta; darkvater@289: posy = w->height - 3; darkvater@289: GfxFillRect(posx, posy, posx + 5, posy + 1, _icursor_state ? 14 : 0); darkvater@289: _video_driver->make_dirty(posx, posy, 5, 1); darkvater@289: _icursor_counter = 0; darkvater@289: } darkvater@289: break; darkvater@289: case WE_DESTROY: darkvater@289: _iconsole_win = NULL; darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; darkvater@289: break; darkvater@289: case WE_KEYPRESS: darkvater@289: { darkvater@289: e->keypress.cont = false; darkvater@289: switch (e->keypress.keycode) { darkvater@289: case WKC_CTRL | 'V': darkvater@289: IConsoleAppendClipboard(); darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_UP: darkvater@289: IConsoleCmdBufferNavigate(+1); darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_DOWN: darkvater@289: IConsoleCmdBufferNavigate(-1); darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_PAGEUP: darkvater@301: if (_iconsole_scroll - (w->height / ICON_LINE_HEIGHT) - 1 < 0) darkvater@289: _iconsole_scroll = 0; darkvater@289: else darkvater@301: _iconsole_scroll -= (w->height / ICON_LINE_HEIGHT) - 1; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_PAGEDOWN: darkvater@301: if (_iconsole_scroll + (w->height / ICON_LINE_HEIGHT) - 1 > ICON_BUFFER) darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@289: else darkvater@301: _iconsole_scroll += (w->height / ICON_LINE_HEIGHT) - 1; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_UP: darkvater@289: if (_iconsole_scroll <= 0) darkvater@289: _iconsole_scroll = 0; darkvater@289: else darkvater@289: --_iconsole_scroll; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_DOWN: darkvater@301: if (_iconsole_scroll >= ICON_BUFFER) darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@289: else darkvater@289: ++_iconsole_scroll; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_BACKQUOTE: darkvater@289: IConsoleSwitch(); darkvater@289: break; darkvater@289: case WKC_RETURN: darkvater@289: IConsolePrintF(_iconsole_color_commands, "] %s", _iconsole_cmdline); truelight@543: _iconsole_cmdbufferpos = 19; darkvater@289: IConsoleCmdBufferAdd(_iconsole_cmdline); darkvater@672: if (strlen(_iconsole_cmdline) != 0) // only execute if there is something typed obviously darkvater@672: IConsoleCmdExec(_iconsole_cmdline); darkvater@672: darkvater@289: IConsoleClearCommand(); darkvater@289: break; truelight@543: case WKC_CTRL | WKC_RETURN: truelight@543: if (_iconsole_mode == ICONSOLE_FULL) { truelight@543: _iconsole_mode = ICONSOLE_OPENED; truelight@543: } else { truelight@543: _iconsole_mode = ICONSOLE_FULL; truelight@543: } truelight@543: IConsoleResize(); truelight@543: MarkWholeScreenDirty(); truelight@543: break; darkvater@289: case WKC_BACKSPACE: darkvater@289: if (_iconsole_cmdpos != 0) _iconsole_cmdpos--; darkvater@289: _iconsole_cmdline[_iconsole_cmdpos] = 0; darkvater@289: SetWindowDirty(w); darkvater@289: _iconsole_cmdbufferpos = 19; darkvater@289: break; darkvater@289: default: darkvater@301: /* IS_INT_INSIDE = filter for ascii-function codes like BELL and so on [we need an special filter here later] */ darkvater@301: if (IS_INT_INSIDE(e->keypress.ascii, ' ', 256)) { darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@289: _iconsole_cmdline[_iconsole_cmdpos] = e->keypress.ascii; darkvater@301: if (_iconsole_cmdpos != lengthof(_iconsole_cmdline)) darkvater@289: _iconsole_cmdpos++; darkvater@289: SetWindowDirty(w); darkvater@301: _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; darkvater@289: } darkvater@289: else darkvater@289: e->keypress.cont = true; darkvater@289: } darkvater@289: break; darkvater@289: } darkvater@135: } darkvater@135: } darkvater@135: darkvater@659: extern const char _openttd_revision[]; darkvater@659: darkvater@289: void IConsoleInit(void) darkvater@135: { darkvater@289: uint i; darkvater@247: _iconsole_output_file = NULL; signde@220: _iconsole_color_default = 1; darkvater@247: _iconsole_color_error = 3; signde@229: _iconsole_color_warning = 13; signde@220: _iconsole_color_debug = 5; signde@220: _iconsole_color_commands = 2; darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@301: _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; darkvater@289: _iconsole_inited = true; darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; darkvater@289: _iconsole_win = NULL; darkvater@289: _icursor_state = false; darkvater@289: _icursor_rate = 5; darkvater@289: _icursor_counter = 0; darkvater@289: for (i = 0; i < lengthof(_iconsole_cmdbuffer); i++) darkvater@289: _iconsole_cmdbuffer[i] = NULL; darkvater@301: for (i = 0; i <= ICON_BUFFER; i++) { darkvater@289: _iconsole_buffer[i] = NULL; darkvater@289: _iconsole_cbuffer[i] = 0; darkvater@289: } signde@220: IConsoleStdLibRegister(); truelight@634: IConsolePrintF(13, "OpenTTD Game Console Revision 6 - %s", _openttd_revision); darkvater@289: IConsolePrint(12, "---------------------------------"); darkvater@289: IConsolePrint(12, "use \"help\" for more info"); darkvater@289: IConsolePrint(12, ""); signde@220: IConsoleClearCommand(); signde@220: IConsoleCmdBufferAdd(""); darkvater@135: } darkvater@135: darkvater@289: void IConsoleClear(void) darkvater@135: { darkvater@289: uint i; darkvater@301: for (i = 0; i <= ICON_BUFFER; i++) signde@220: free(_iconsole_buffer[i]); darkvater@135: } darkvater@135: darkvater@289: void IConsoleFree(void) darkvater@135: { darkvater@289: _iconsole_inited = false; signde@220: IConsoleClear(); darkvater@289: if (_iconsole_output_file != NULL) fclose(_iconsole_output_file); darkvater@135: } darkvater@135: darkvater@289: void IConsoleResize(void) signde@220: { truelight@543: switch (_iconsole_mode) { truelight@543: case ICONSOLE_OPENED: truelight@543: _iconsole_win->height = _screen.height / 3; truelight@543: _iconsole_win->width = _screen.width; truelight@543: break; truelight@543: case ICONSOLE_FULL: truelight@543: _iconsole_win->height = _screen.height - ICON_BOTTOM_BORDERWIDTH; truelight@543: _iconsole_win->width = _screen.width; truelight@543: break; truelight@543: default: truelight@543: break; darkvater@135: } darkvater@135: } darkvater@135: darkvater@289: void IConsoleSwitch(void) darkvater@135: { darkvater@289: switch (_iconsole_mode) { darkvater@289: case ICONSOLE_CLOSED: darkvater@289: _iconsole_win = AllocateWindowDesc(&_iconsole_window_desc); darkvater@289: _iconsole_win->height = _screen.height / 3; darkvater@289: _iconsole_win->width = _screen.width; darkvater@289: _iconsole_mode = ICONSOLE_OPENED; darkvater@289: break; darkvater@289: case ICONSOLE_OPENED: darkvater@289: DeleteWindowById(WC_CONSOLE, 0); darkvater@289: _iconsole_win = NULL; darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; darkvater@289: break; truelight@543: case ICONSOLE_FULL: truelight@543: DeleteWindowById(WC_CONSOLE, 0); truelight@543: _iconsole_win = NULL; truelight@543: _iconsole_mode = ICONSOLE_CLOSED; truelight@543: break; darkvater@289: } darkvater@135: } darkvater@135: darkvater@289: void IConsoleClose(void) signde@220: { darkvater@289: if (_iconsole_mode == ICONSOLE_OPENED) IConsoleSwitch(); darkvater@135: } darkvater@135: darkvater@289: void IConsoleOpen(void) signde@220: { darkvater@289: if (_iconsole_mode == ICONSOLE_CLOSED) IConsoleSwitch(); darkvater@141: } darkvater@141: darkvater@289: void IConsoleCmdBufferAdd(const char* cmd) signde@220: { signde@220: int i; signde@220: if (_iconsole_cmdbufferpos != 19) return; darkvater@289: free(_iconsole_cmdbuffer[18]); darkvater@289: for (i = 18; i > 0; i--) _iconsole_cmdbuffer[i] = _iconsole_cmdbuffer[i - 1]; darkvater@289: _iconsole_cmdbuffer[0] = strdup(cmd); signde@220: } signde@220: signde@220: void IConsoleCmdBufferNavigate(signed char direction) signde@220: { signde@220: int i; darkvater@289: i = _iconsole_cmdbufferpos + direction; darkvater@289: if (i < 0) i = 19; darkvater@289: if (i > 19) i = 0; darkvater@289: if (direction > 0) darkvater@289: while (_iconsole_cmdbuffer[i] == NULL) { darkvater@289: ++i; darkvater@289: if (i > 19) i = 0; signde@220: } darkvater@289: if (direction < 0) darkvater@289: while (_iconsole_cmdbuffer[i] == NULL) { darkvater@289: --i; darkvater@289: if (i < 0) i = 19; signde@220: } signde@220: _iconsole_cmdbufferpos = i; signde@220: IConsoleClearCommand(); darkvater@289: memcpy(_iconsole_cmdline, _iconsole_cmdbuffer[i], darkvater@289: strlen(_iconsole_cmdbuffer[i])); darkvater@289: _iconsole_cmdpos = strlen(_iconsole_cmdbuffer[i]); darkvater@141: } darkvater@141: truelight@543: void IConsolePrint(uint16 color_code, const char* string) darkvater@135: { darkvater@289: char* _ex; darkvater@289: char* _new; truelight@543: uint16 _exc; truelight@543: uint16 _newc; darkvater@289: char* i; darkvater@289: int j; darkvater@135: truelight@543: if (_network_dedicated) { truelight@543: printf("%s\n", string); truelight@543: return; truelight@543: } truelight@543: signde@220: if (!_iconsole_inited) return; darkvater@135: darkvater@289: _newc = color_code; darkvater@289: _new = strdup(string); signde@220: darkvater@289: for (i = _new; *i != '\0'; ++i) darkvater@301: if (*i < ' ') *i = ' '; /* filter for ascii-function codes like BELL and so on [we need an special filter here later] */ signde@220: darkvater@301: for (j = ICON_BUFFER; j >= 0; --j) { darkvater@289: _ex = _iconsole_buffer[j]; darkvater@289: _exc = _iconsole_cbuffer[j]; darkvater@289: _iconsole_buffer[j] = _new; darkvater@289: _iconsole_cbuffer[j] = _newc; darkvater@289: _new = _ex; darkvater@289: _newc = _exc; darkvater@289: } darkvater@289: free(_ex); darkvater@289: dominik@650: if (_iconsole_output_file != NULL) { dominik@650: // if there is an console output file ... also print it there dominik@650: fwrite(string, strlen(string), 1, _iconsole_output_file); dominik@650: fwrite("\n", 1, 1, _iconsole_output_file); dominik@650: } dominik@650: darkvater@289: if (_iconsole_win != NULL) SetWindowDirty(_iconsole_win); darkvater@135: } darkvater@135: darkvater@135: truelight@543: void CDECL IConsolePrintF(uint16 color_code, const char* s, ...) darkvater@135: { darkvater@135: va_list va; darkvater@135: char buf[1024]; darkvater@247: int len; darkvater@247: darkvater@135: va_start(va, s); darkvater@289: len = vsnprintf(buf, sizeof(buf), s, va); darkvater@135: va_end(va); darkvater@247: darkvater@289: IConsolePrint(color_code, buf); darkvater@135: } darkvater@135: darkvater@289: void IConsoleDebug(const char* string) signde@220: { darkvater@289: if (_stdlib_developer > 1) truelight@543: IConsolePrintF(_iconsole_color_debug, "dbg: %s", string); darkvater@247: } darkvater@135: darkvater@289: void IConsoleError(const char* string) signde@220: { darkvater@289: if (_stdlib_developer > 0) darkvater@289: IConsolePrintF(_iconsole_color_error, "ERROR: %s", string); darkvater@289: } darkvater@135: darkvater@289: void IConsoleWarning(const char* string) darkvater@289: { darkvater@289: if (_stdlib_developer > 0) darkvater@289: IConsolePrintF(_iconsole_color_warning, "WARNING: %s", string); darkvater@289: } darkvater@289: darkvater@289: void IConsoleCmdRegister(const char* name, _iconsole_cmd_addr addr) darkvater@289: { darkvater@289: char* _new; darkvater@289: _iconsole_cmd* item; darkvater@289: _iconsole_cmd* item_new; truelight@554: _iconsole_cmd* item_before; darkvater@289: darkvater@289: _new = strdup(name); darkvater@135: signde@220: item_new = malloc(sizeof(_iconsole_cmd)); darkvater@135: signde@220: item_new->_next = NULL; darkvater@289: item_new->addr = addr; darkvater@289: item_new->name = _new; signde@220: signde@220: item_new->hook_access = NULL; signde@220: item_new->hook_after_exec = NULL; signde@220: item_new->hook_before_exec = NULL; signde@220: truelight@554: item_before = NULL; signde@220: item = _iconsole_cmds; truelight@554: signde@220: if (item == NULL) { signde@220: _iconsole_cmds = item_new; darkvater@289: } else { truelight@554: while ((item->_next != NULL) && (strcmp(item->name,item_new->name)<=0)) { truelight@554: item_before = item; truelight@554: item = item->_next; truelight@554: } truelight@554: // insertion sort truelight@554: if (item_before==NULL) { truelight@554: if (strcmp(item->name,item_new->name)<=0) { truelight@554: // appending truelight@554: item ->_next = item_new; truelight@554: } else { truelight@554: // inserting as startitem truelight@554: _iconsole_cmds = item_new; truelight@554: item_new ->_next = item; truelight@554: } truelight@554: } else { truelight@554: if (strcmp(item->name,item_new->name)<=0) { truelight@554: // appending truelight@554: item ->_next = item_new; truelight@554: } else { truelight@554: // inserting truelight@554: item_new ->_next = item_before->_next; truelight@554: item_before ->_next = item_new; truelight@554: } truelight@554: } truelight@554: // insertion sort end darkvater@289: } truelight@554: signde@220: } signde@220: darkvater@289: _iconsole_cmd* IConsoleCmdGet(const char* name) signde@220: { darkvater@289: _iconsole_cmd* item; signde@220: signde@220: item = _iconsole_cmds; signde@220: while (item != NULL) { darkvater@289: if (strcmp(item->name, name) == 0) return item; signde@220: item = item->_next; darkvater@289: } signde@220: return NULL; signde@220: } signde@220: truelight@634: void IConsoleAliasRegister(const char* name, const char* cmdline) truelight@634: { truelight@634: char* _new; truelight@634: char* _newcmd; truelight@634: _iconsole_alias* item; truelight@634: _iconsole_alias* item_new; truelight@634: _iconsole_alias* item_before; truelight@634: truelight@634: _new = strdup(name); truelight@634: _newcmd = strdup(cmdline); truelight@634: truelight@634: item_new = malloc(sizeof(_iconsole_alias)); truelight@634: truelight@634: item_new->_next = NULL; truelight@634: item_new->cmdline = _newcmd; truelight@634: item_new->name = _new; truelight@634: truelight@634: item_before = NULL; truelight@634: item = _iconsole_aliases; truelight@634: truelight@634: if (item == NULL) { truelight@634: _iconsole_aliases = item_new; truelight@634: } else { truelight@634: while ((item->_next != NULL) && (strcmp(item->name,item_new->name)<=0)) { truelight@634: item_before = item; truelight@634: item = item->_next; truelight@634: } truelight@634: // insertion sort truelight@634: if (item_before==NULL) { truelight@634: if (strcmp(item->name,item_new->name)<=0) { truelight@634: // appending truelight@634: item ->_next = item_new; truelight@634: } else { truelight@634: // inserting as startitem truelight@634: _iconsole_aliases = item_new; truelight@634: item_new ->_next = item; truelight@634: } truelight@634: } else { truelight@634: if (strcmp(item->name,item_new->name)<=0) { truelight@634: // appending truelight@634: item ->_next = item_new; truelight@634: } else { truelight@634: // inserting truelight@634: item_new ->_next = item_before->_next; truelight@634: item_before ->_next = item_new; truelight@634: } truelight@634: } truelight@634: // insertion sort end truelight@634: } truelight@634: truelight@634: } truelight@634: truelight@634: _iconsole_alias* IConsoleAliasGet(const char* name) truelight@634: { truelight@634: _iconsole_alias* item; truelight@634: truelight@634: item = _iconsole_aliases; truelight@634: while (item != NULL) { truelight@634: if (strcmp(item->name, name) == 0) return item; truelight@634: item = item->_next; truelight@634: } truelight@634: return NULL; truelight@634: } truelight@634: truelight@634: void IConsoleAliasExec(const char* cmdline, char* tokens[20], byte tokentypes[20]) { truelight@634: char* lines[ICON_MAX_ALIAS_LINES]; truelight@634: char* linestream; truelight@634: char* linestream_s; truelight@634: truelight@634: int c; truelight@634: int i; truelight@634: int l; truelight@634: int x; truelight@634: byte t; truelight@634: truelight@634: //** clearing buffer **// truelight@634: truelight@634: for (i = 0; i < 40; i++) { truelight@634: lines[0] = NULL; truelight@634: } truelight@634: linestream_s = linestream = malloc(1024*ICON_MAX_ALIAS_LINES); truelight@634: memset(linestream, 0, 1024*ICON_MAX_ALIAS_LINES); truelight@634: truelight@634: //** parsing **// truelight@634: truelight@634: l = strlen(cmdline); truelight@634: i = 0; truelight@634: c = 0; truelight@634: x = 0; truelight@634: t = 0; truelight@634: lines[c] = linestream; truelight@634: truelight@634: while (i < l && c < ICON_MAX_ALIAS_LINES - 1) { truelight@634: if (cmdline[i] == '%') { truelight@634: i++; truelight@634: if (cmdline[i] == '+') { dominik@644: // all params seperated: "[param 1]" "[param 2]" truelight@634: t=1; truelight@656: while ((tokens[t]!=NULL) && (t<20) && dominik@640: ((tokentypes[t] == ICONSOLE_VAR_STRING) || (tokentypes[t] == ICONSOLE_VAR_UNKNOWN))) { truelight@634: int l2 = strlen(tokens[t]); truelight@634: *linestream = '"'; truelight@634: linestream++; truelight@634: memcpy(linestream,tokens[t],l2); truelight@634: linestream += l2; truelight@634: *linestream = '"'; truelight@634: linestream++; truelight@634: *linestream = ' '; truelight@634: linestream++; truelight@634: x += l2+3; truelight@634: t++; truelight@634: } dominik@644: } else if (cmdline[i] == '!') { dominik@644: // merge the params to one: "[param 1] [param 2] [param 3...]" dominik@644: t=1; dominik@644: *linestream = '"'; dominik@644: linestream++; truelight@656: while ((tokens[t]!=NULL) && (t<20) && dominik@644: ((tokentypes[t] == ICONSOLE_VAR_STRING) || (tokentypes[t] == ICONSOLE_VAR_UNKNOWN))) { dominik@644: int l2 = strlen(tokens[t]); dominik@644: memcpy(linestream,tokens[t],l2); dominik@644: linestream += l2; dominik@644: *linestream = ' '; dominik@644: linestream++; dominik@644: x += l2+1; dominik@644: t++; dominik@644: } darkvater@932: linestream--; dominik@644: *linestream = '"'; dominik@644: linestream++; darkvater@932: x += 1; truelight@634: } else { dominik@644: // one specific parameter: %A = [param 1] %B = [param 2] ... truelight@634: int l2; truelight@634: t = ((byte)cmdline[i]) - 64; truelight@656: if ((t<20) && (tokens[t]!=NULL) && dominik@644: ((tokentypes[t] == ICONSOLE_VAR_STRING) || (tokentypes[t] == ICONSOLE_VAR_UNKNOWN))) { truelight@634: l2 = strlen(tokens[t]); dominik@640: *linestream = '"'; dominik@640: linestream++; truelight@634: memcpy(linestream,tokens[t],l2); truelight@634: linestream += l2; dominik@640: *linestream = '"'; dominik@640: linestream++; dominik@640: x += l2+2; truelight@634: } truelight@634: } truelight@634: } else if (cmdline[i] == '\\') { dominik@644: // \\ = \ \' = ' \% = % truelight@634: i++; truelight@634: if (cmdline[i] == '\\') { truelight@634: *linestream = '\\'; truelight@634: linestream++; truelight@634: } else if (cmdline[i] == '\'') { truelight@634: *linestream = '\''; truelight@634: linestream++; dominik@644: } else if (cmdline[i] == '%') { dominik@644: *linestream = '%'; dominik@644: linestream++; truelight@634: } truelight@634: } else if (cmdline[i] == '\'') { dominik@644: // ' = " truelight@634: *linestream = '"'; truelight@634: linestream++; truelight@634: } else if (cmdline[i] == ';') { dominik@644: // ; = start a new line truelight@634: c++; truelight@634: *linestream = '\0'; truelight@634: linestream += 1024 - (x % 1024); truelight@634: x += 1024 - (x % 1024); truelight@634: lines[c] = linestream; truelight@634: } else { truelight@634: *linestream = cmdline[i]; truelight@634: linestream++; truelight@634: x++; truelight@634: } truelight@634: i++; truelight@634: } truelight@634: truelight@634: linestream--; truelight@634: if (*linestream != '\0') { truelight@634: c++; truelight@634: linestream++; truelight@634: *linestream = '\0'; truelight@634: } truelight@634: dominik@640: for (i=0; i_next = NULL; truelight@554: truelight@554: item_new->name = malloc(strlen(name) + 2); /* XXX unchecked malloc */ truelight@554: sprintf(item_new->name, "%s", name); truelight@554: truelight@554: item_before = NULL; truelight@554: item = _iconsole_vars; truelight@554: truelight@554: if (item == NULL) { truelight@554: _iconsole_vars = item_new; truelight@554: } else { truelight@554: while ((item->_next != NULL) && (strcmp(item->name,item_new->name)<=0)) { truelight@554: item_before = item; truelight@554: item = item->_next; truelight@554: } truelight@554: // insertion sort truelight@554: if (item_before==NULL) { truelight@554: if (strcmp(item->name,item_new->name)<=0) { truelight@554: // appending truelight@554: item ->_next = item_new; truelight@554: } else { truelight@554: // inserting as startitem truelight@554: _iconsole_vars = item_new; truelight@554: item_new ->_next = item; truelight@554: } truelight@554: } else { truelight@554: if (strcmp(item->name,item_new->name)<=0) { truelight@554: // appending truelight@554: item ->_next = item_new; truelight@554: } else { truelight@554: // inserting truelight@554: item_new ->_next = item_before->_next; truelight@554: item_before ->_next = item_new; truelight@554: } truelight@554: } truelight@554: // insertion sort end truelight@554: } truelight@554: } truelight@554: darkvater@289: void IConsoleVarRegister(const char* name, void* addr, _iconsole_var_types type) signde@220: { darkvater@289: _iconsole_var* item_new; signde@220: darkvater@289: item_new = malloc(sizeof(_iconsole_var)); /* XXX unchecked malloc */ signde@220: truelight@554: item_new->_next = NULL; signde@220: darkvater@289: switch (type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: item_new->data.bool_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: truelight@543: case ICONSOLE_VAR_UINT8: darkvater@289: item_new->data.byte_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: item_new->data.uint16_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: item_new->data.uint32_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: item_new->data.int16_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: item_new->data.int32_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_STRING: darkvater@289: item_new->data.string_ = addr; darkvater@289: break; darkvater@289: default: darkvater@301: error("unknown console variable type"); darkvater@289: break; darkvater@289: } truelight@554: truelight@554: IConsoleVarInsert(item_new, name); truelight@554: darkvater@289: item_new->type = type; signde@220: item_new->_malloc = false; signde@220: signde@220: item_new->hook_access = NULL; signde@220: item_new->hook_after_change = NULL; signde@220: item_new->hook_before_change = NULL; truelight@618: signde@220: } signde@220: darkvater@289: void IConsoleVarMemRegister(const char* name, _iconsole_var_types type) signde@220: { darkvater@289: _iconsole_var* item; signde@220: item = IConsoleVarAlloc(type); darkvater@289: IConsoleVarInsert(item, name); signde@220: } signde@220: darkvater@289: _iconsole_var* IConsoleVarGet(const char* name) signde@220: { darkvater@289: _iconsole_var* item; darkvater@289: for (item = _iconsole_vars; item != NULL; item = item->_next) darkvater@289: if (strcmp(item->name, name) == 0) return item; signde@220: return NULL; darkvater@135: } darkvater@135: darkvater@289: _iconsole_var* IConsoleVarAlloc(_iconsole_var_types type) signde@220: { darkvater@289: _iconsole_var* item = malloc(sizeof(_iconsole_var)); /* XXX unchecked malloc */ signde@220: item->_next = NULL; darkvater@289: item->name = NULL; darkvater@289: item->type = type; signde@220: switch (item->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: item->data.bool_ = malloc(sizeof(*item->data.bool_)); darkvater@289: *item->data.bool_ = false; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: truelight@543: case ICONSOLE_VAR_UINT8: darkvater@289: item->data.byte_ = malloc(sizeof(*item->data.byte_)); darkvater@289: *item->data.byte_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: item->data.uint16_ = malloc(sizeof(*item->data.uint16_)); darkvater@289: *item->data.uint16_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: item->data.uint32_ = malloc(sizeof(*item->data.uint32_)); darkvater@289: *item->data.uint32_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: item->data.int16_ = malloc(sizeof(*item->data.int16_)); darkvater@289: *item->data.int16_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: item->data.int32_ = malloc(sizeof(*item->data.int32_)); darkvater@289: *item->data.int32_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_POINTER: darkvater@301: case ICONSOLE_VAR_STRING: darkvater@301: // needs no memory ... it gets memory when it is set to an value darkvater@289: item->data.addr = NULL; darkvater@289: item->_malloc = false; darkvater@289: break; darkvater@289: default: darkvater@301: error("unknown console variable type"); darkvater@289: break; darkvater@289: } signde@220: signde@220: item->hook_access = NULL; signde@220: item->hook_after_change = NULL; signde@220: item->hook_before_change = NULL; signde@220: return item; darkvater@135: } darkvater@135: darkvater@135: darkvater@289: void IConsoleVarFree(_iconsole_var* var) signde@220: { darkvater@222: if (var->_malloc) darkvater@289: free(var->data.addr); darkvater@289: free(var->name); signde@220: free(var); darkvater@135: } darkvater@135: darkvater@289: void IConsoleVarSetString(_iconsole_var* var, const char* string) signde@220: { signde@220: if (string == NULL) return; signde@220: darkvater@289: if (var->_malloc) darkvater@289: free(var->data.string_); signde@220: darkvater@289: var->data.string_ = strdup(string); darkvater@289: var->_malloc = true; darkvater@222: } signde@220: darkvater@289: void IConsoleVarSetValue(_iconsole_var* var, int value) { signde@220: switch (var->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: *var->data.bool_ = (value != 0); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: truelight@543: case ICONSOLE_VAR_UINT8: darkvater@289: *var->data.byte_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: *var->data.uint16_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: *var->data.uint32_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: *var->data.int16_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: *var->data.int32_ = value; darkvater@289: break; darkvater@289: default: darkvater@289: assert(0); darkvater@289: break; darkvater@222: } darkvater@135: } darkvater@135: darkvater@289: void IConsoleVarDump(const _iconsole_var* var, const char* dump_desc) signde@220: { truelight@543: if (var == NULL) return; darkvater@289: if (dump_desc == NULL) dump_desc = var->name; darkvater@135: darkvater@135: switch (var->type) { darkvater@135: case ICONSOLE_VAR_BOOLEAN: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %s", darkvater@289: dump_desc, *var->data.bool_ ? "true" : "false"); darkvater@289: break; darkvater@289: break; darkvater@135: case ICONSOLE_VAR_BYTE: truelight@543: case ICONSOLE_VAR_UINT8: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %u", darkvater@289: dump_desc, *var->data.byte_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_UINT16: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %u", darkvater@289: dump_desc, *var->data.uint16_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_UINT32: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %u", darkvater@289: dump_desc, *var->data.uint32_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_INT16: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %i", darkvater@289: dump_desc, *var->data.int16_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_INT32: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %i", darkvater@289: dump_desc, *var->data.int32_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_STRING: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %s", darkvater@289: dump_desc, var->data.string_); darkvater@289: break; darkvater@141: case ICONSOLE_VAR_REFERENCE: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = @%s", darkvater@289: dump_desc, var->data.reference_); darkvater@135: case ICONSOLE_VAR_UNKNOWN: darkvater@135: case ICONSOLE_VAR_POINTER: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = @%p", darkvater@289: dump_desc, var->data.addr); darkvater@289: break; darkvater@301: case ICONSOLE_VAR_NONE: darkvater@301: IConsolePrintF(_iconsole_color_default, "%s = [nothing]", darkvater@301: dump_desc); darkvater@289: break; darkvater@289: } darkvater@135: } darkvater@135: signde@220: // * ************************* * // signde@220: // * hooking code * // signde@220: // * ************************* * // darkvater@135: darkvater@289: void IConsoleVarHook(const char* name, _iconsole_hook_types type, iconsole_var_hook proc) signde@220: { darkvater@289: _iconsole_var* hook_var = IConsoleVarGet(name); signde@220: if (hook_var == NULL) return; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: hook_var->hook_before_change = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: hook_var->hook_after_change = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: hook_var->hook_access = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: assert(0); darkvater@289: break; signde@220: } signde@220: } darkvater@135: darkvater@289: bool IConsoleVarHookHandle(_iconsole_var* hook_var, _iconsole_hook_types type) signde@220: { truelight@543: iconsole_var_hook proc; truelight@543: if (hook_var == NULL) return false; truelight@543: truelight@543: proc = NULL; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: proc = hook_var->hook_before_change; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: proc = hook_var->hook_after_change; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: proc = hook_var->hook_access; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: assert(0); darkvater@289: break; signde@220: } darkvater@289: return proc == NULL ? true : proc(hook_var); signde@220: } signde@220: darkvater@289: void IConsoleCmdHook(const char* name, _iconsole_hook_types type, iconsole_cmd_hook proc) signde@220: { darkvater@289: _iconsole_cmd* hook_cmd = IConsoleCmdGet(name); signde@220: if (hook_cmd == NULL) return; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: hook_cmd->hook_after_exec = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: hook_cmd->hook_before_exec = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: hook_cmd->hook_access = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: assert(0); darkvater@289: break; signde@220: } signde@220: } signde@220: darkvater@289: bool IConsoleCmdHookHandle(_iconsole_cmd* hook_cmd, _iconsole_hook_types type) signde@220: { darkvater@289: iconsole_cmd_hook proc = NULL; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: proc = hook_cmd->hook_after_exec; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: proc = hook_cmd->hook_before_exec; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: proc = hook_cmd->hook_access; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: assert(0); darkvater@289: break; signde@220: } darkvater@289: return proc == NULL ? true : proc(hook_cmd); signde@220: } signde@220: darkvater@289: void IConsoleCmdExec(const char* cmdstr) signde@220: { darkvater@289: _iconsole_cmd_addr function; darkvater@289: char* tokens[20]; darkvater@289: byte tokentypes[20]; darkvater@289: char* tokenstream; darkvater@289: char* tokenstream_s; darkvater@289: byte execution_mode; truelight@634: _iconsole_var* var = NULL; truelight@634: _iconsole_var* result = NULL; truelight@634: _iconsole_cmd* cmd = NULL; truelight@634: _iconsole_alias* alias = NULL; signde@220: signde@220: bool longtoken; signde@220: bool valid_token; signde@220: bool skip_lt_change; signde@220: signde@220: int c; signde@220: int i; signde@220: int l; signde@220: dominik@640: if (_stdlib_con_developer) dominik@640: IConsolePrintF(_iconsole_color_debug, "CONDEBUG: execution_cmdline: %s", cmdstr); dominik@640: signde@220: //** clearing buffer **// signde@220: darkvater@289: for (i = 0; i < 20; i++) { darkvater@289: tokens[i] = NULL; darkvater@289: tokentypes[i] = ICONSOLE_VAR_NONE; darkvater@289: } darkvater@289: tokenstream_s = tokenstream = malloc(1024); darkvater@289: memset(tokenstream, 0, 1024); signde@220: signde@220: //** parsing **// signde@220: darkvater@289: longtoken = false; darkvater@289: valid_token = false; darkvater@289: skip_lt_change = false; darkvater@289: l = strlen(cmdstr); darkvater@289: i = 0; darkvater@289: c = 0; signde@220: tokens[c] = tokenstream; truelight@543: tokentypes[c] = ICONSOLE_VAR_UNKNOWN; darkvater@301: while (i < l && c < lengthof(tokens) - 1) { darkvater@289: if (cmdstr[i] == '"') { signde@220: if (longtoken) { darkvater@289: if (cmdstr[i + 1] == '"') { signde@220: i++; signde@220: *tokenstream = '"'; signde@220: tokenstream++; darkvater@289: skip_lt_change = true; darkvater@135: } else { darkvater@289: longtoken = !longtoken; truelight@543: tokentypes[c] = ICONSOLE_VAR_STRING; darkvater@135: } truelight@543: } else { darkvater@289: longtoken = !longtoken; truelight@543: tokentypes[c] = ICONSOLE_VAR_STRING; truelight@543: } signde@220: if (!skip_lt_change) { signde@220: if (!longtoken) { signde@220: if (valid_token) { signde@220: c++; darkvater@289: *tokenstream = '\0'; signde@220: tokenstream++; signde@220: tokens[c] = tokenstream; truelight@543: tokentypes[c] = ICONSOLE_VAR_UNKNOWN; signde@220: valid_token = false; signde@220: } darkvater@289: } signde@220: skip_lt_change=false; darkvater@135: } darkvater@289: } else if (!longtoken && cmdstr[i] == ' ') { signde@220: if (valid_token) { signde@220: c++; darkvater@289: *tokenstream = '\0'; signde@220: tokenstream++; signde@220: tokens[c] = tokenstream; truelight@543: tokentypes[c] = ICONSOLE_VAR_UNKNOWN; signde@220: valid_token = false; signde@220: } darkvater@289: } else { darkvater@289: valid_token = true; signde@220: *tokenstream = cmdstr[i]; signde@220: tokenstream++; darkvater@289: } signde@220: i++; darkvater@289: } signde@220: signde@220: tokenstream--; darkvater@289: if (*tokenstream != '\0') { signde@220: c++; signde@220: tokenstream++; darkvater@289: *tokenstream = '\0'; darkvater@289: } signde@220: signde@220: //** interpreting **// signde@220: darkvater@289: for (i = 0; i < c; i++) { darkvater@289: if (tokens[i] != NULL && i > 0 && strlen(tokens[i]) > 0) { truelight@543: if (IConsoleVarGet((char *)tokens[i]) != NULL) { darkvater@301: // change the variable to an pointer if execution_mode != 4 is truelight@543: // being prepared. execution_mode 4 is used to assign darkvater@301: // one variables data to another one darkvater@301: // [token 0 and 2] darkvater@301: if (!((i == 2) && (tokentypes[1] == ICONSOLE_VAR_UNKNOWN) && darkvater@301: (strcmp(tokens[1], "<<") == 0))) { truelight@543: // only look for another variable if it isnt an longtoken == string with "" truelight@543: var = NULL; truelight@543: if (tokentypes[i]!=ICONSOLE_VAR_STRING) var = IConsoleVarGet(tokens[i]); darkvater@289: if (var != NULL) { darkvater@301: // pointer to the data --> token truelight@543: tokens[i] = (char *) var->data.addr; /* XXX: maybe someone finds an cleaner way to do this */ darkvater@289: tokentypes[i] = var->type; darkvater@141: } darkvater@135: } darkvater@135: } truelight@543: if (tokens[i] != NULL && tokens[i][0] == '@' && (IConsoleVarGet(tokens[i]+1) != NULL)) { truelight@543: var = IConsoleVarGet(tokens[i]+1); darkvater@289: if (var != NULL) { darkvater@301: // pointer to the _iconsole_var struct --> token truelight@543: tokens[i] = (char *) var; /* XXX: maybe someone finds an cleaner way to do this */ darkvater@289: tokentypes[i] = ICONSOLE_VAR_REFERENCE; darkvater@289: } darkvater@289: } darkvater@135: } darkvater@289: } darkvater@135: signde@220: execution_mode=0; signde@220: signde@220: function = NULL; signde@220: cmd = IConsoleCmdGet(tokens[0]); truelight@634: if (cmd != NULL) { truelight@634: function = cmd->addr; truelight@634: } else { truelight@634: alias = IConsoleAliasGet(tokens[0]); truelight@634: if (alias != NULL) execution_mode = 5; // alias handling truelight@634: } signde@220: signde@220: if (function != NULL) { darkvater@289: execution_mode = 1; // this is a command darkvater@289: } else { signde@220: var = IConsoleVarGet(tokens[0]); signde@220: if (var != NULL) { darkvater@289: execution_mode = 2; // this is a variable darkvater@289: if (c > 2 && strcmp(tokens[1], "<<") == 0) { signde@220: // this is command to variable mode [normal] darkvater@222: signde@220: function = NULL; signde@220: cmd = IConsoleCmdGet(tokens[2]); signde@220: if (cmd != NULL) function = cmd->addr; signde@220: signde@220: if (function != NULL) { darkvater@289: execution_mode = 3; darkvater@289: } else { signde@220: result = IConsoleVarGet(tokens[2]); darkvater@289: if (result != NULL) truelight@634: execution_mode = 4; darkvater@135: } signde@220: } signde@220: } darkvater@289: } signde@220: signde@220: //** executing **// darkvater@289: if (_stdlib_con_developer) darkvater@289: IConsolePrintF(_iconsole_color_debug, "CONDEBUG: execution_mode: %i", darkvater@289: execution_mode); signde@220: switch (execution_mode) { darkvater@289: case 0: darkvater@289: // not found darkvater@289: IConsoleError("command or variable not found"); darkvater@289: break; darkvater@289: case 1: darkvater@289: if (IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_ACCESS)) { darkvater@289: // execution with command syntax darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_BEFORE_EXEC); darkvater@289: result = function(c, tokens, tokentypes); darkvater@289: if (result != NULL) { darkvater@289: IConsoleVarDump(result, "result"); darkvater@289: IConsoleVarFree(result); darkvater@289: } darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_AFTER_EXEC); darkvater@289: break; signde@220: } darkvater@289: case 2: signde@220: { darkvater@289: // execution with variable syntax darkvater@289: if (IConsoleVarHookHandle(var, ICONSOLE_HOOK_ACCESS) && (c == 2 || c == 3)) { darkvater@289: // ** variable modifications ** // darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_BEFORE_CHANGE); darkvater@289: switch (var->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: signde@220: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) { darkvater@289: *var->data.bool_ = (atoi(tokens[2]) != 0); signde@220: } else { darkvater@289: *var->data.bool_ = false; signde@220: } darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@301: *var->data.bool_ = true; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@301: *var->data.bool_ = false; darkvater@289: IConsoleVarDump(var, NULL); signde@220: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; signde@220: } darkvater@289: case ICONSOLE_VAR_BYTE: truelight@543: case ICONSOLE_VAR_UINT8: signde@220: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.byte_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.byte_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.byte_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--")==0) { darkvater@289: --*var->data.byte_; darkvater@289: IConsoleVarDump(var, NULL); signde@220: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.uint16_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.uint16_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.uint16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.uint16_; darkvater@289: IConsoleVarDump(var, NULL); signde@220: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; signde@220: } darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.uint32_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.uint32_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.uint32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.uint32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.int16_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.int16_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.int16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.int16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.int32_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.int32_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.int32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.int32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else { IConsoleError("operation not supported"); } darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_STRING: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: IConsoleVarSetString(var, tokens[2]); darkvater@289: else darkvater@289: IConsoleVarSetString(var, ""); darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_POINTER: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) { darkvater@289: if (tokentypes[2] == ICONSOLE_VAR_UNKNOWN) darkvater@301: var->data.addr = (void*)atoi(tokens[2]); /* direct access on memory [by address] */ darkvater@289: else darkvater@301: var->data.addr = (void*)tokens[2]; /* direct acces on memory [by variable] */ darkvater@289: } else darkvater@289: var->data.addr = NULL; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@301: ++*(char*)&var->data.addr; /* change the address + 1 */ darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@301: --*(char*)&var->data.addr; /* change the address - 1 */ darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } truelight@543: case ICONSOLE_VAR_NONE: truelight@543: case ICONSOLE_VAR_REFERENCE: truelight@543: case ICONSOLE_VAR_UNKNOWN: darkvater@301: IConsoleError("operation not supported"); darkvater@289: break; signde@220: } darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_AFTER_CHANGE); darkvater@289: } darkvater@289: if (c == 1) // ** variable output ** // darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; signde@220: } darkvater@289: case 3: darkvater@289: case 4: signde@220: { darkvater@289: // execute command with result or assign a variable darkvater@289: if (execution_mode == 3) { darkvater@289: if (IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_ACCESS)) { darkvater@222: int i; darkvater@222: int diff; darkvater@289: void* temp; darkvater@222: byte temp2; signde@220: darkvater@222: // tokenshifting darkvater@289: for (diff = 0; diff < 2; diff++) { darkvater@289: temp = tokens[0]; darkvater@289: temp2 = tokentypes[0]; darkvater@289: for (i = 0; i < 19; i++) { darkvater@289: tokens[i] = tokens[i + 1]; darkvater@289: tokentypes[i] = tokentypes[i + 1]; darkvater@222: } darkvater@289: tokens[19] = temp; darkvater@289: tokentypes[19] = temp2; signde@220: } darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_BEFORE_EXEC); darkvater@289: result = function(c, tokens, tokentypes); darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_AFTER_EXEC); darkvater@222: } else darkvater@289: execution_mode = 255; signde@220: } signde@220: darkvater@289: if (IConsoleVarHookHandle(var, ICONSOLE_HOOK_ACCESS) && result != NULL) { darkvater@289: if (result->type != var->type) { darkvater@289: IConsoleError("variable type missmatch"); signde@220: } else { darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_BEFORE_CHANGE); darkvater@289: switch (result->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: *var->data.bool_ = *result->data.bool_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: truelight@543: case ICONSOLE_VAR_UINT8: darkvater@289: *var->data.byte_ = *result->data.byte_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: *var->data.uint16_ = *result->data.uint16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: *var->data.uint32_ = *result->data.uint32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: *var->data.int16_ = *result->data.int16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: *var->data.int32_ = *result->data.int32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_POINTER: darkvater@289: var->data.addr = result->data.addr; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_STRING: darkvater@289: IConsoleVarSetString(var, result->data.string_); darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: default: darkvater@289: IConsoleError("variable type missmatch"); darkvater@289: break; signde@220: } darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_AFTER_CHANGE); darkvater@135: } signde@220: darkvater@289: if (execution_mode == 3) { darkvater@289: IConsoleVarFree(result); darkvater@135: } darkvater@135: } darkvater@289: break; darkvater@135: } truelight@634: case 5: { truelight@634: // execute an alias truelight@634: IConsoleAliasExec(alias->cmdline, tokens,tokentypes); truelight@634: } truelight@634: break; darkvater@289: default: darkvater@289: // execution mode invalid darkvater@289: IConsoleError("invalid execution mode"); darkvater@289: break; darkvater@135: } darkvater@135: darkvater@301: //** freeing the tokenstream **// signde@220: free(tokenstream_s); darkvater@135: }