src/console.cpp
changeset 6123 04eb770ec17e
parent 5893 7e431a4abebb
child 6247 7d81e3a5d803
equal deleted inserted replaced
6122:3359af5a1f54 6123:04eb770ec17e
     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(Window *w, WindowEvent *e)
    66 static void IConsoleWndProc(Window *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 
   338  */
   340  */
   339 static void IConsoleHistoryNavigate(int direction)
   341 static void IConsoleHistoryNavigate(int direction)
   340 {
   342 {
   341 	int i = _iconsole_historypos + direction;
   343 	int i = _iconsole_historypos + direction;
   342 
   344 
   343 	// watch out for overflows, just wrap around
   345 	/* watch out for overflows, just wrap around */
   344 	if (i < 0) i = ICON_HISTORY_SIZE - 1;
   346 	if (i < 0) i = ICON_HISTORY_SIZE - 1;
   345 	if (i >= ICON_HISTORY_SIZE) i = 0;
   347 	if (i >= ICON_HISTORY_SIZE) i = 0;
   346 
   348 
   347 	if (direction > 0)
   349 	if (direction > 0)
   348 		if (_iconsole_history[i] == NULL) i = 0;
   350 		if (_iconsole_history[i] == NULL) i = 0;
   351 		while (i > 0 && _iconsole_history[i] == NULL) i--;
   353 		while (i > 0 && _iconsole_history[i] == NULL) i--;
   352 	}
   354 	}
   353 
   355 
   354 	_iconsole_historypos = i;
   356 	_iconsole_historypos = i;
   355 	IConsoleClearCommand();
   357 	IConsoleClearCommand();
   356 	// copy history to 'command prompt / bash'
   358 	/* copy history to 'command prompt / bash' */
   357 	assert(_iconsole_history[i] != NULL && IS_INT_INSIDE(i, 0, ICON_HISTORY_SIZE));
   359 	assert(_iconsole_history[i] != NULL && IS_INT_INSIDE(i, 0, ICON_HISTORY_SIZE));
   358 	ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_history[i], _iconsole_cmdline.maxlength);
   360 	ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_history[i], _iconsole_cmdline.maxlength);
   359 	UpdateTextBufferSize(&_iconsole_cmdline);
   361 	UpdateTextBufferSize(&_iconsole_cmdline);
   360 }
   362 }
   361 
   363 
   479 
   481 
   480 	*value = strtoul(arg, &endptr, 0);
   482 	*value = strtoul(arg, &endptr, 0);
   481 	return arg != endptr;
   483 	return arg != endptr;
   482 }
   484 }
   483 
   485 
   484 // * ************************* * //
   486 /*  * *************************
   485 // * hooking code              * //
   487     * hooking code            *
   486 // * ************************* * //
   488     * *************************/
       
   489 
   487 /**
   490 /**
   488  * General internal hooking code that is the same for both commands and variables
   491  * General internal hooking code that is the same for both commands and variables
   489  * @param hooks @IConsoleHooks structure that will be set according to
   492  * @param hooks @IConsoleHooks structure that will be set according to
   490  * @param type type access trigger
   493  * @param type type access trigger
   491  * @param proc function called when the hook criteria is met
   494  * @param proc function called when the hook criteria is met
   707 	aliases[0] = aliasstream;
   710 	aliases[0] = aliasstream;
   708 	for (cmdptr = alias->cmdline, a_index = 0, astream_i = 0; *cmdptr != '\0'; cmdptr++) {
   711 	for (cmdptr = alias->cmdline, a_index = 0, astream_i = 0; *cmdptr != '\0'; cmdptr++) {
   709 		if (a_index >= lengthof(aliases) || astream_i >= lengthof(aliasstream)) break;
   712 		if (a_index >= lengthof(aliases) || astream_i >= lengthof(aliasstream)) break;
   710 
   713 
   711 		switch (*cmdptr) {
   714 		switch (*cmdptr) {
   712 		case '\'': /* ' will double for "" */
   715 		case '\'': // ' will double for ""
   713 			aliasstream[astream_i++] = '"';
   716 			aliasstream[astream_i++] = '"';
   714 			break;
   717 			break;
   715 		case ';': /* Cmd seperator, start new command */
   718 		case ';': // Cmd seperator, start new command
   716 			aliasstream[astream_i] = '\0';
   719 			aliasstream[astream_i] = '\0';
   717 			aliases[++a_index] = &aliasstream[++astream_i];
   720 			aliases[++a_index] = &aliasstream[++astream_i];
   718 			cmdptr++;
   721 			cmdptr++;
   719 			break;
   722 			break;
   720 		case '%': /* Some or all parameters */
   723 		case '%': // Some or all parameters
   721 			cmdptr++;
   724 			cmdptr++;
   722 			switch (*cmdptr) {
   725 			switch (*cmdptr) {
   723 			case '+': { /* All parameters seperated: "[param 1]" "[param 2]" */
   726 			case '+': { // All parameters seperated: "[param 1]" "[param 2]"
   724 				for (i = 0; i != tokencount; i++) {
   727 				for (i = 0; i != tokencount; i++) {
   725 					aliasstream[astream_i++] = '"';
   728 					aliasstream[astream_i++] = '"';
   726 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   729 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   727 					aliasstream[astream_i++] = '"';
   730 					aliasstream[astream_i++] = '"';
   728 					aliasstream[astream_i++] = ' ';
   731 					aliasstream[astream_i++] = ' ';
   729 				}
   732 				}
   730 			} break;
   733 			} break;
   731 			case '!': { /* Merge the parameters to one: "[param 1] [param 2] [param 3...]" */
   734 			case '!': { // Merge the parameters to one: "[param 1] [param 2] [param 3...]"
   732 				aliasstream[astream_i++] = '"';
   735 				aliasstream[astream_i++] = '"';
   733 				for (i = 0; i != tokencount; i++) {
   736 				for (i = 0; i != tokencount; i++) {
   734 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   737 					astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
   735 					aliasstream[astream_i++] = ' ';
   738 					aliasstream[astream_i++] = ' ';
   736 				}
   739 				}
   737 				aliasstream[astream_i++] = '"';
   740 				aliasstream[astream_i++] = '"';
   738 
   741 
   739 			} break;
   742 			} break;
   740 				default: { /* One specific parameter: %A = [param 1] %B = [param 2] ... */
   743 				default: { // One specific parameter: %A = [param 1] %B = [param 2] ...
   741 				int param = *cmdptr - 'A';
   744 				int param = *cmdptr - 'A';
   742 
   745 
   743 				if (param < 0 || param >= tokencount) {
   746 				if (param < 0 || param >= tokencount) {
   744 					IConsoleError("too many or wrong amount of parameters passed to alias, aborting");
   747 					IConsoleError("too many or wrong amount of parameters passed to alias, aborting");
   745 					IConsolePrintF(_icolour_warn, "Usage of alias '%s': %s", alias->name, alias->cmdline);
   748 					IConsolePrintF(_icolour_warn, "Usage of alias '%s': %s", alias->name, alias->cmdline);
  1084 				foundtoken = false;
  1087 				foundtoken = false;
  1085 			}
  1088 			}
  1086 
  1089 
  1087 			tstream_i++;
  1090 			tstream_i++;
  1088 			break;
  1091 			break;
  1089 		case '"': /* Tokens enclosed in "" are one token */
  1092 		case '"': // Tokens enclosed in "" are one token
  1090 			longtoken = !longtoken;
  1093 			longtoken = !longtoken;
  1091 			break;
  1094 			break;
  1092 		case '\\': /* Escape character for "" */
  1095 		case '\\': // Escape character for ""
  1093 			if (cmdptr[1] == '"' && tstream_i + 1 < lengthof(tokenstream)) {
  1096 			if (cmdptr[1] == '"' && tstream_i + 1 < lengthof(tokenstream)) {
  1094 				tokenstream[tstream_i++] = *++cmdptr;
  1097 				tokenstream[tstream_i++] = *++cmdptr;
  1095 				break;
  1098 				break;
  1096 			}
  1099 			}
  1097 			/* fallthrough */
  1100 			/* fallthrough */
  1098 		default: /* Normal character */
  1101 		default: // Normal character
  1099 			tokenstream[tstream_i++] = *cmdptr;
  1102 			tokenstream[tstream_i++] = *cmdptr;
  1100 
  1103 
  1101 			if (!foundtoken) {
  1104 			if (!foundtoken) {
  1102 				tokens[t_index++] = &tokenstream[tstream_i - 1];
  1105 				tokens[t_index++] = &tokenstream[tstream_i - 1];
  1103 				foundtoken = true;
  1106 				foundtoken = true;