src/console.cpp
branchcpp_gui
changeset 6268 4b5241e5dd10
parent 6263 19dab6a68886
child 6298 c30fe89622df
equal deleted inserted replaced
6267:7c8ec33959b1 6268:4b5241e5dd10
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file console.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 #include "table/strings.h"
     7 #include "table/strings.h"
     6 #include "functions.h"
     8 #include "functions.h"
    24 #define ICON_RIGHT_BORDERWIDTH 10
    26 #define ICON_RIGHT_BORDERWIDTH 10
    25 #define ICON_BOTTOM_BORDERWIDTH 12
    27 #define ICON_BOTTOM_BORDERWIDTH 12
    26 #define ICON_MAX_ALIAS_LINES 40
    28 #define ICON_MAX_ALIAS_LINES 40
    27 #define ICON_TOKEN_COUNT 20
    29 #define ICON_TOKEN_COUNT 20
    28 
    30 
    29 // ** main console ** //
    31 /* ** main console ** */
    30 static char *_iconsole_buffer[ICON_BUFFER + 1];
    32 static char *_iconsole_buffer[ICON_BUFFER + 1];
    31 static uint16 _iconsole_cbuffer[ICON_BUFFER + 1];
    33 static uint16 _iconsole_cbuffer[ICON_BUFFER + 1];
    32 static Textbuf _iconsole_cmdline;
    34 static Textbuf _iconsole_cmdline;
    33 
    35 
    34 // ** stdlib ** //
    36 /* ** stdlib ** */
    35 byte _stdlib_developer = 1;
    37 byte _stdlib_developer = 1;
    36 bool _stdlib_con_developer = false;
    38 bool _stdlib_con_developer = false;
    37 FILE *_iconsole_output_file;
    39 FILE *_iconsole_output_file;
    38 
    40 
    39 // ** main console cmd buffer
    41 /* ** main console cmd buffer ** */
    40 static char *_iconsole_history[ICON_HISTORY_SIZE];
    42 static char *_iconsole_history[ICON_HISTORY_SIZE];
    41 static byte _iconsole_historypos;
    43 static byte _iconsole_historypos;
    42 
    44 
    43 /* *************** */
    45 /* *************** *
    44 /*  end of header  */
    46  *  end of header  *
    45 /* *************** */
    47  * *************** */
    46 
    48 
    47 static void IConsoleClearCommand(void)
    49 static void IConsoleClearCommand(void)
    48 {
    50 {
    49 	memset(_iconsole_cmdline.buf, 0, ICON_CMDLN_SIZE);
    51 	memset(_iconsole_cmdline.buf, 0, ICON_CMDLN_SIZE);
    50 	_iconsole_cmdline.length = 0;
    52 	_iconsole_cmdline.length = 0;
    58 
    60 
    59 
    61 
    60 static void IConsoleHistoryAdd(const char *cmd);
    62 static void IConsoleHistoryAdd(const char *cmd);
    61 static void IConsoleHistoryNavigate(int direction);
    63 static void IConsoleHistoryNavigate(int direction);
    62 
    64 
    63 // ** console window ** //
    65 /* ** console window ** */
    64 static void IConsoleWndProc(BaseWindow *w, WindowEvent *e)
    66 static void IConsoleWndProc(BaseWindow *w, WindowEvent *e)
    65 {
    67 {
    66 	static byte iconsole_scroll = ICON_BUFFER;
    68 	static byte iconsole_scroll = ICON_BUFFER;
    67 
    69 
    68 	switch (e->event) {
    70 	switch (e->event) {
   252 }
   254 }
   253 
   255 
   254 static void IConsoleWriteToLogFile(const char *string)
   256 static void IConsoleWriteToLogFile(const char *string)
   255 {
   257 {
   256 	if (_iconsole_output_file != NULL) {
   258 	if (_iconsole_output_file != NULL) {
   257 		// if there is an console output file ... also print it there
   259 		/* if there is an console output file ... also print it there */
   258 		fwrite(string, strlen(string), 1, _iconsole_output_file);
   260 		fwrite(string, strlen(string), 1, _iconsole_output_file);
   259 		fwrite("\n", 1, 1, _iconsole_output_file);
   261 		fwrite("\n", 1, 1, _iconsole_output_file);
   260 	}
   262 	}
   261 }
   263 }
   262 
   264 
   335  */
   337  */
   336 static void IConsoleHistoryNavigate(int direction)
   338 static void IConsoleHistoryNavigate(int direction)
   337 {
   339 {
   338 	int i = _iconsole_historypos + direction;
   340 	int i = _iconsole_historypos + direction;
   339 
   341 
   340 	// watch out for overflows, just wrap around
   342 	/* watch out for overflows, just wrap around */
   341 	if (i < 0) i = ICON_HISTORY_SIZE - 1;
   343 	if (i < 0) i = ICON_HISTORY_SIZE - 1;
   342 	if (i >= ICON_HISTORY_SIZE) i = 0;
   344 	if (i >= ICON_HISTORY_SIZE) i = 0;
   343 
   345 
   344 	if (direction > 0)
   346 	if (direction > 0)
   345 		if (_iconsole_history[i] == NULL) i = 0;
   347 		if (_iconsole_history[i] == NULL) i = 0;
   348 		while (i > 0 && _iconsole_history[i] == NULL) i--;
   350 		while (i > 0 && _iconsole_history[i] == NULL) i--;
   349 	}
   351 	}
   350 
   352 
   351 	_iconsole_historypos = i;
   353 	_iconsole_historypos = i;
   352 	IConsoleClearCommand();
   354 	IConsoleClearCommand();
   353 	// copy history to 'command prompt / bash'
   355 	/* copy history to 'command prompt / bash' */
   354 	assert(_iconsole_history[i] != NULL && IS_INT_INSIDE(i, 0, ICON_HISTORY_SIZE));
   356 	assert(_iconsole_history[i] != NULL && IS_INT_INSIDE(i, 0, ICON_HISTORY_SIZE));
   355 	ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_history[i], _iconsole_cmdline.maxlength);
   357 	ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_history[i], _iconsole_cmdline.maxlength);
   356 	UpdateTextBufferSize(&_iconsole_cmdline);
   358 	UpdateTextBufferSize(&_iconsole_cmdline);
   357 }
   359 }
   358 
   360 
   476 
   478 
   477 	*value = strtoul(arg, &endptr, 0);
   479 	*value = strtoul(arg, &endptr, 0);
   478 	return arg != endptr;
   480 	return arg != endptr;
   479 }
   481 }
   480 
   482 
   481 // * ************************* * //
   483 /*  * *************************
   482 // * hooking code              * //
   484     * hooking code            *
   483 // * ************************* * //
   485     * *************************/
       
   486 
   484 /**
   487 /**
   485  * General internal hooking code that is the same for both commands and variables
   488  * General internal hooking code that is the same for both commands and variables
   486  * @param hooks @IConsoleHooks structure that will be set according to
   489  * @param hooks @IConsoleHooks structure that will be set according to
   487  * @param type type access trigger
   490  * @param type type access trigger
   488  * @param proc function called when the hook criteria is met
   491  * @param proc function called when the hook criteria is met
   704 	aliases[0] = aliasstream;
   707 	aliases[0] = aliasstream;
   705 	for (cmdptr = alias->cmdline, a_index = 0, astream_i = 0; *cmdptr != '\0'; cmdptr++) {
   708 	for (cmdptr = alias->cmdline, a_index = 0, astream_i = 0; *cmdptr != '\0'; cmdptr++) {
   706 		if (a_index >= lengthof(aliases) || astream_i >= lengthof(aliasstream)) break;
   709 		if (a_index >= lengthof(aliases) || astream_i >= lengthof(aliasstream)) break;
   707 
   710 
   708 		switch (*cmdptr) {
   711 		switch (*cmdptr) {
   709 		case '\'': /* ' will double for "" */
   712 		case '\'': // ' will double for ""
   710 			aliasstream[astream_i++] = '"';
   713 			aliasstream[astream_i++] = '"';
   711 			break;
   714 			break;
   712 		case ';': /* Cmd seperator, start new command */
   715 		case ';': // Cmd seperator, start new command
   713 			aliasstream[astream_i] = '\0';
   716 			aliasstream[astream_i] = '\0';
   714 			aliases[++a_index] = &aliasstream[++astream_i];
   717 			aliases[++a_index] = &aliasstream[++astream_i];
   715 			cmdptr++;
   718 			cmdptr++;
   716 			break;
   719 			break;
   717 		case '%': /* Some or all parameters */
   720 		case '%': // Some or all parameters
   718 			cmdptr++;
   721 			cmdptr++;
   719 			switch (*cmdptr) {
   722 			switch (*cmdptr) {
   720 			case '+': { /* All parameters seperated: "[param 1]" "[param 2]" */
   723 			case '+': { // All parameters seperated: "[param 1]" "[param 2]"
   721 				for (i = 0; i != tokencount; i++) {
   724 				for (i = 0; i != tokencount; i++) {
   722 					aliasstream[astream_i++] = '"';
   725 					aliasstream[astream_i++] = '"';
   723 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   726 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   724 					aliasstream[astream_i++] = '"';
   727 					aliasstream[astream_i++] = '"';
   725 					aliasstream[astream_i++] = ' ';
   728 					aliasstream[astream_i++] = ' ';
   726 				}
   729 				}
   727 			} break;
   730 			} break;
   728 			case '!': { /* Merge the parameters to one: "[param 1] [param 2] [param 3...]" */
   731 			case '!': { // Merge the parameters to one: "[param 1] [param 2] [param 3...]"
   729 				aliasstream[astream_i++] = '"';
   732 				aliasstream[astream_i++] = '"';
   730 				for (i = 0; i != tokencount; i++) {
   733 				for (i = 0; i != tokencount; i++) {
   731 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   734 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   732 					aliasstream[astream_i++] = ' ';
   735 					aliasstream[astream_i++] = ' ';
   733 				}
   736 				}
   734 				aliasstream[astream_i++] = '"';
   737 				aliasstream[astream_i++] = '"';
   735 
   738 
   736 			} break;
   739 			} break;
   737 				default: { /* One specific parameter: %A = [param 1] %B = [param 2] ... */
   740 				default: { // One specific parameter: %A = [param 1] %B = [param 2] ...
   738 				int param = *cmdptr - 'A';
   741 				int param = *cmdptr - 'A';
   739 
   742 
   740 				if (param < 0 || param >= tokencount) {
   743 				if (param < 0 || param >= tokencount) {
   741 					IConsoleError("too many or wrong amount of parameters passed to alias, aborting");
   744 					IConsoleError("too many or wrong amount of parameters passed to alias, aborting");
   742 					IConsolePrintF(_icolour_warn, "Usage of alias '%s': %s", alias->name, alias->cmdline);
   745 					IConsolePrintF(_icolour_warn, "Usage of alias '%s': %s", alias->name, alias->cmdline);
  1081 				foundtoken = false;
  1084 				foundtoken = false;
  1082 			}
  1085 			}
  1083 
  1086 
  1084 			tstream_i++;
  1087 			tstream_i++;
  1085 			break;
  1088 			break;
  1086 		case '"': /* Tokens enclosed in "" are one token */
  1089 		case '"': // Tokens enclosed in "" are one token
  1087 			longtoken = !longtoken;
  1090 			longtoken = !longtoken;
  1088 			break;
  1091 			break;
  1089 		case '\\': /* Escape character for "" */
  1092 		case '\\': // Escape character for ""
  1090 			if (cmdptr[1] == '"' && tstream_i + 1 < lengthof(tokenstream)) {
  1093 			if (cmdptr[1] == '"' && tstream_i + 1 < lengthof(tokenstream)) {
  1091 				tokenstream[tstream_i++] = *++cmdptr;
  1094 				tokenstream[tstream_i++] = *++cmdptr;
  1092 				break;
  1095 				break;
  1093 			}
  1096 			}
  1094 			/* fallthrough */
  1097 			/* fallthrough */
  1095 		default: /* Normal character */
  1098 		default: // Normal character
  1096 			tokenstream[tstream_i++] = *cmdptr;
  1099 			tokenstream[tstream_i++] = *cmdptr;
  1097 
  1100 
  1098 			if (!foundtoken) {
  1101 			if (!foundtoken) {
  1099 				tokens[t_index++] = &tokenstream[tstream_i - 1];
  1102 				tokens[t_index++] = &tokenstream[tstream_i - 1];
  1100 				foundtoken = true;
  1103 				foundtoken = true;