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@1390: #include "string.h" darkvater@135: #include "hal.h" darkvater@135: #include darkvater@289: #include signde@274: #include "console.h" truelight@543: #include "network.h" truelight@1026: #include "network_data.h" truelight@1026: #include "network_server.h" signde@274: 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@1397: static Window *_iconsole_win; // Pointer to console window 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@1390: static Textbuf _iconsole_cmdline; darkvater@135: static byte _iconsole_scroll; 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: /* *************** */ darkvater@135: /* end of header */ signde@274: /* *************** */ signde@274: darkvater@289: static void IConsoleClearCommand(void) darkvater@135: { Darkvater@1390: memset(_iconsole_cmdline.buf, 0, ICON_CMDLN_SIZE); Darkvater@1390: _iconsole_cmdline.length = 0; Darkvater@1390: _iconsole_cmdline.width = 0; Darkvater@1390: _iconsole_cmdline.caretpos = 0; Darkvater@1390: _iconsole_cmdline.caretxoffs = 0; darkvater@289: SetWindowDirty(_iconsole_win); darkvater@135: } darkvater@135: Darkvater@1390: // ** console window ** // darkvater@289: static void IConsoleWndProc(Window* w, WindowEvent* e) darkvater@135: { darkvater@135: switch(e->event) { Darkvater@1390: case WE_PAINT: { 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@986: while ((i > 0) && (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: } Darkvater@1390: /* If the text is longer than the window, don't show the starting ']' */ Darkvater@1390: delta = w->width - 10 - _iconsole_cmdline.width - 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: Darkvater@1390: DoDrawString(_iconsole_cmdline.buf, 10 + delta, w->height - ICON_LINE_HEIGHT, _iconsole_color_commands); Darkvater@1390: Darkvater@1390: if (_iconsole_cmdline.caret) Darkvater@1390: DoDrawString("_", 10 + delta + _iconsole_cmdline.caretxoffs, w->height - ICON_LINE_HEIGHT, 12); darkvater@289: break; darkvater@135: } Darkvater@1390: case WE_MOUSELOOP: Darkvater@1390: if (HandleCaret(&_iconsole_cmdline)) Darkvater@1390: SetWindowDirty(w); 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: e->keypress.cont = false; darkvater@289: switch (e->keypress.keycode) { 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@1390: case WKC_RETURN: case WKC_NUM_ENTER: Darkvater@1390: IConsolePrintF(_iconsole_color_commands, "] %s", _iconsole_cmdline.buf); Darkvater@1390: _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; Darkvater@1390: IConsoleCmdBufferAdd(_iconsole_cmdline.buf); darkvater@672: Darkvater@1390: IConsoleCmdExec(_iconsole_cmdline.buf); darkvater@289: IConsoleClearCommand(); darkvater@289: break; truelight@543: case WKC_CTRL | WKC_RETURN: Darkvater@1390: _iconsole_mode = (_iconsole_mode == ICONSOLE_FULL) ? ICONSOLE_OPENED : ICONSOLE_FULL; truelight@543: IConsoleResize(); truelight@543: MarkWholeScreenDirty(); truelight@543: break; Darkvater@1390: case (WKC_CTRL | 'V'): Darkvater@1390: if (InsertTextBufferClipboard(&_iconsole_cmdline)) Darkvater@1390: SetWindowDirty(w); Darkvater@1390: break; Darkvater@1390: case WKC_BACKSPACE: case WKC_DELETE: Darkvater@1390: if (DeleteTextBufferChar(&_iconsole_cmdline, e->keypress.keycode)) Darkvater@1390: SetWindowDirty(w); Darkvater@1390: _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; Darkvater@1390: break; Darkvater@1390: case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME: Darkvater@1390: if (MoveTextBufferPos(&_iconsole_cmdline, e->keypress.keycode)) Darkvater@1390: SetWindowDirty(w); darkvater@289: break; darkvater@289: default: Darkvater@1390: if (IsValidAsciiChar(e->keypress.ascii)) { darkvater@301: _iconsole_scroll = ICON_BUFFER; Darkvater@1390: InsertTextBufferChar(&_iconsole_cmdline, e->keypress.ascii); Darkvater@1390: _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; darkvater@289: SetWindowDirty(w); Darkvater@1390: } else darkvater@289: e->keypress.cont = true; darkvater@289: break; darkvater@289: } darkvater@135: } darkvater@135: } darkvater@135: Darkvater@1390: static const Widget _iconsole_window_widgets[] = { Darkvater@1390: {WIDGETS_END} Darkvater@1390: }; Darkvater@1390: Darkvater@1390: static const WindowDesc _iconsole_window_desc = { Darkvater@1390: 0, 0, 2, 2, Darkvater@1390: WC_CONSOLE, 0, Darkvater@1390: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, Darkvater@1390: _iconsole_window_widgets, Darkvater@1390: IConsoleWndProc, Darkvater@1390: }; Darkvater@1390: darkvater@659: extern const char _openttd_revision[]; darkvater@659: darkvater@289: void IConsoleInit(void) darkvater@135: { 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@1243: darkvater@1243: #ifdef ENABLE_NETWORK /* Initialize network only variables */ darkvater@1243: _redirect_console_to_client = 0; darkvater@1243: #endif darkvater@1243: darkvater@1243: memset(_iconsole_cmdbuffer, 0, sizeof(_iconsole_cmdbuffer)); darkvater@1243: memset(_iconsole_buffer, 0, sizeof(_iconsole_buffer)); darkvater@1243: memset(_iconsole_cbuffer, 0, sizeof(_iconsole_cbuffer)); Darkvater@1390: _iconsole_cmdline.buf = calloc(ICON_CMDLN_SIZE, sizeof(*_iconsole_cmdline.buf)); // create buffer and zero it Darkvater@1390: _iconsole_cmdline.maxlength = ICON_CMDLN_SIZE - 1; darkvater@1243: 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@1390: Darkvater@1390: free(_iconsole_cmdline.buf); darkvater@135: } darkvater@135: darkvater@1046: static void IConsoleWriteToLogFile(const char* string) darkvater@1046: { darkvater@1046: if (_iconsole_output_file != NULL) { darkvater@1046: // if there is an console output file ... also print it there darkvater@1046: fwrite(string, strlen(string), 1, _iconsole_output_file); darkvater@1046: fwrite("\n", 1, 1, _iconsole_output_file); darkvater@1046: } darkvater@1046: } darkvater@1046: darkvater@1046: bool CloseConsoleLogIfActive(void) darkvater@1046: { darkvater@1046: if (_iconsole_output_file != NULL) { darkvater@1046: IConsolePrintF(_iconsole_color_default, "file output complete"); darkvater@1046: fclose(_iconsole_output_file); darkvater@1127: _iconsole_output_file = NULL; darkvater@1046: return true; darkvater@1046: } darkvater@1046: darkvater@1046: return false; darkvater@1046: } darkvater@1046: darkvater@289: void IConsoleFree(void) darkvater@135: { darkvater@289: _iconsole_inited = false; signde@220: IConsoleClear(); darkvater@1046: CloseConsoleLogIfActive(); darkvater@135: } darkvater@135: darkvater@289: void IConsoleResize(void) signde@220: { darkvater@986: darkvater@986: _iconsole_win = FindWindowById(WC_CONSOLE, 0); darkvater@986: 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@986: darkvater@986: MarkWholeScreenDirty(); 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@1397: SETBIT(_no_scroll, SCROLL_CON); darkvater@289: break; Darkvater@1397: case ICONSOLE_OPENED: case ICONSOLE_FULL: darkvater@289: DeleteWindowById(WC_CONSOLE, 0); darkvater@289: _iconsole_win = NULL; darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; Darkvater@1397: CLRBIT(_no_scroll, SCROLL_CON); truelight@543: break; darkvater@289: } darkvater@986: darkvater@986: MarkWholeScreenDirty(); 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; Darkvater@1390: if (_iconsole_cmdbufferpos != (ICON_CMDBUF_SIZE - 1)) return; Darkvater@1390: free(_iconsole_cmdbuffer[ICON_CMDBUF_SIZE - 2]); Darkvater@1390: for (i = (ICON_CMDBUF_SIZE - 2); 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@1390: if (i < 0) i = ICON_CMDBUF_SIZE - 1; Darkvater@1390: if (i >= ICON_CMDBUF_SIZE) i = 0; darkvater@289: if (direction > 0) darkvater@289: while (_iconsole_cmdbuffer[i] == NULL) { Darkvater@1390: i++; Darkvater@1390: if (i >= ICON_CMDBUF_SIZE) i = 0; signde@220: } darkvater@289: if (direction < 0) darkvater@289: while (_iconsole_cmdbuffer[i] == NULL) { darkvater@289: --i; Darkvater@1390: if (i < 0) i = ICON_CMDBUF_SIZE - 1; signde@220: } signde@220: _iconsole_cmdbufferpos = i; signde@220: IConsoleClearCommand(); Darkvater@1390: ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_cmdbuffer[i], _iconsole_cmdline.maxlength); Darkvater@1390: UpdateTextBufferSize(&_iconsole_cmdline); darkvater@141: } darkvater@141: Darkvater@1588: /** Darkvater@1588: * Handle the printing of text entered into the console or redirected there Darkvater@1588: * by any other means. Text can be redirected to other players in a network game Darkvater@1588: * as well as to a logfile. If the network server is a dedicated server, all activities Darkvater@1588: * are also logged. All lines to print are added to a temporary buffer which can be Darkvater@1588: * used as a history to print them onscreen Darkvater@1588: * @param color_code the colour of the command. Red in case of errors, etc. Darkvater@1588: * @param string the message entered or output on the console (notice, error, etc.) Darkvater@1588: */ truelight@543: void IConsolePrint(uint16 color_code, const char* string) darkvater@135: { Darkvater@1588: char *i; darkvater@135: darkvater@1243: #ifdef ENABLE_NETWORK truelight@1026: if (_redirect_console_to_client != 0) { truelight@1026: /* Redirect the string to the client */ truelight@1026: SEND_COMMAND(PACKET_SERVER_RCON)(NetworkFindClientStateFromIndex(_redirect_console_to_client), color_code, string); truelight@1026: return; truelight@1026: } darkvater@1243: #endif truelight@1026: truelight@543: if (_network_dedicated) { truelight@543: printf("%s\n", string); darkvater@1046: IConsoleWriteToLogFile(string); truelight@543: return; truelight@543: } truelight@543: signde@220: if (!_iconsole_inited) return; darkvater@135: Darkvater@1588: /* move up all the strings in the buffer one place and do the same for colour Darkvater@1588: * to accomodate for the new command/message */ Darkvater@1588: free(_iconsole_buffer[0]); Darkvater@1588: memmove(&_iconsole_buffer[0], &_iconsole_buffer[1], sizeof(_iconsole_buffer[0]) * ICON_BUFFER); Darkvater@1588: _iconsole_buffer[ICON_BUFFER] = strdup(string); signde@220: Darkvater@1588: // filter out unprintable characters Darkvater@1588: for (i = _iconsole_buffer[ICON_BUFFER]; *i != '\0'; i++) Darkvater@1588: if (!IsValidAsciiChar((byte)*i)) *i = ' '; Darkvater@1588: Darkvater@1588: memmove(&_iconsole_cbuffer[0], &_iconsole_cbuffer[1], sizeof(_iconsole_cbuffer[0]) * ICON_BUFFER); Darkvater@1588: _iconsole_cbuffer[ICON_BUFFER] = color_code; darkvater@289: darkvater@1046: IConsoleWriteToLogFile(string); 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: tron@1095: static void IConsoleAliasExec(const char* cmdline, char* tokens[20], byte tokentypes[20]) tron@1095: { 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@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: tron@959: uint c; tron@959: uint i; tron@959: uint l; tron@1109: tron@1379: for (; strchr("\n\r \t", *cmdstr) != NULL; ++cmdstr) { tron@1379: switch (*cmdstr) { tron@1379: case '\0': tron@1379: case '#': tron@1379: return; tron@1379: tron@1379: default: tron@1379: break; tron@1379: } tron@1379: } 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: }