Beispiel #1
0
globle intBool ExecuteIfCommandComplete(
  void *theEnv)
  {
   if ((CompleteCommand(CommandLineData(theEnv)->CommandString) == 0) || 
       (RouterData(theEnv)->CommandBufferInputCount <= 0))
     { return FALSE; }
      
   FlushPPBuffer(theEnv);
   SetPPBufferStatus(theEnv,OFF);
   RouterData(theEnv)->CommandBufferInputCount = -1;
   RouteCommand(theEnv,CommandLineData(theEnv)->CommandString,TRUE);
   FlushPPBuffer(theEnv);
   SetHaltExecution(theEnv,FALSE);
   SetEvaluationError(theEnv,FALSE);
   FlushCommandString(theEnv);
   FlushBindList(theEnv);
   PeriodicCleanup(theEnv,TRUE,FALSE);
   PrintPrompt(theEnv);
         
   return TRUE;
  }
LONG WINAPI InputLineWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	char inputBuffer[1024];

	switch ( uMsg )
	{
		case WM_KILLFOCUS:
			if ( ( HWND ) wParam == s_wcd.hWnd ||
				 ( HWND ) wParam == s_wcd.hwndErrorBox )
			{
				SetFocus( hWnd );
				return 0;
			}
			break;

		case WM_CHAR:
			if ( wParam == 13 )
			{
				GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) );
				strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 );
				strcat( s_wcd.consoleText, "\n" );
				SetWindowText( s_wcd.hwndInputLine, "" );

				Sys_Print( va( "]%s\n", inputBuffer ) );

				strcpy(kg.g_consoleField.buffer, inputBuffer);
				kg.historyEditLines[kg.nextHistoryLine % COMMAND_HISTORY] = kg.g_consoleField;
				kg.nextHistoryLine++;
				kg.historyLine = kg.nextHistoryLine;

				return 0;
			}
			else if (wParam == 9 )
			{
				GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) );
				strcpy(kg.g_consoleField.buffer, inputBuffer);
				CompleteCommand();
				SetWindowText( s_wcd.hwndInputLine, kg.g_consoleField.buffer);
				SendMessage(s_wcd.hwndInputLine, EM_SETSEL, strlen(kg.g_consoleField.buffer) , MAKELONG(0xffff, 0xffff) );
			}

		case WM_KEYDOWN:
			if (wParam == VK_UP)
			{
				if ( kg.nextHistoryLine - kg.historyLine < COMMAND_HISTORY && kg.historyLine > 0 ) 
				{
					kg.historyLine--;
				}
				kg.g_consoleField = kg.historyEditLines[ kg.historyLine % COMMAND_HISTORY ];
				SetWindowText( s_wcd.hwndInputLine, kg.g_consoleField.buffer);
				SendMessage(s_wcd.hwndInputLine, EM_SETSEL, strlen(kg.g_consoleField.buffer) , MAKELONG(0xffff, 0xffff) );
				return 0;
			}
			else if (wParam == VK_DOWN)
			{
				if (kg.historyLine == kg.nextHistoryLine)
				{
					return 0;
				}
				kg.historyLine++;
				kg.g_consoleField = kg.historyEditLines[ kg.historyLine % COMMAND_HISTORY ];
				SetWindowText( s_wcd.hwndInputLine, kg.g_consoleField.buffer);
				SendMessage(s_wcd.hwndInputLine, EM_SETSEL, strlen(kg.g_consoleField.buffer) , MAKELONG(0xffff, 0xffff) );
				return 0;
			}
			break;
	}

	return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam );
}
Beispiel #3
0
// The Simple Query Protocol
// Fix mis-split bug: Previously, this function assumes there are multiple
// queries in the string and split it by ';', which would cause one containing
// ';' being split into multiple queries.
// However, the multi-statement queries has been split by the psql client and
// there is no need to split the query again.
void PacketManager::ExecQueryMessage(InputPacket *pkt, const size_t thread_id) {
  std::string query;
  PacketGetString(pkt, pkt->len, query);

  // pop out the last character if it is ';'
  if (query.back() == ';') {
    query.pop_back();
  }
  boost::trim(query);

  if (!query.empty()) {
    std::vector<StatementResult> result;
    std::vector<FieldInfo> tuple_descriptor;
    std::string error_message;
    int rows_affected = 0;

    std::string query_type_string_;
    Statement::ParseQueryTypeString(query, query_type_string_);

    QueryType query_type;
    Statement::MapToQueryType(query_type_string_, query_type);
    std::stringstream stream(query_type_string_);

    switch (query_type) {
      case QueryType::QUERY_PREPARE:
      {
        std::string statement_name;
        stream >> statement_name;
        std::size_t pos = query.find("AS");
        std::string statement_query = query.substr(pos + 3);
        boost::trim(statement_query);

        // Prepare statement
        std::shared_ptr<Statement> statement(nullptr);

        LOG_DEBUG("PrepareStatement[%s] => %s", statement_name.c_str(),
                statement_query.c_str());

        statement = traffic_cop_->PrepareStatement(statement_name, statement_query,
                                                 error_message);
        if (statement.get() == nullptr) {
          skipped_stmt_ = true;
          SendErrorResponse(
              {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          LOG_TRACE("ExecQuery Error");
          return;
        }

        auto entry = std::make_pair(statement_name, statement);
        statement_cache_.insert(entry);
        for (auto table_id : statement->GetReferencedTables()) {
          table_statement_cache_[table_id].push_back(statement.get());
        }
        break;
      }
      case QueryType::QUERY_EXECUTE:
      {
        std::string statement_name;
        std::shared_ptr<Statement> statement;
        std::vector<type::Value> param_values;
        bool unnamed = false;
        std::vector<std::string> tokens;

        boost::split(tokens, query, boost::is_any_of("(), "));

        statement_name = tokens.at(1);
        auto statement_cache_itr = statement_cache_.find(statement_name);
        if (statement_cache_itr != statement_cache_.end()) {
          statement = *statement_cache_itr;
        }
        // Did not find statement with same name
        else {
          std::string error_message = "The prepared statement does not exist";
          LOG_ERROR("%s", error_message.c_str());
          SendErrorResponse(
              {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          SendReadyForQuery(NetworkTransactionStateType::IDLE);
          return;
        }

        std::vector<int> result_format(statement->GetTupleDescriptor().size(), 0);

        for (std::size_t idx = 2; idx < tokens.size(); idx++) {
          std::string param_str = tokens.at(idx);
          boost::trim(param_str);
          if (param_str.empty()) {
            continue;
          }
          param_values.push_back(type::ValueFactory::GetVarcharValue(param_str));
        }

        if (param_values.size() > 0) {
          statement->GetPlanTree()->SetParameterValues(&param_values);
        }

        auto status =
                traffic_cop_->ExecuteStatement(statement, param_values, unnamed, nullptr, result_format,
                             result, rows_affected, error_message, thread_id);

        if (status == ResultType::SUCCESS) {
          tuple_descriptor = statement->GetTupleDescriptor();
        } else {
          SendErrorResponse(
                {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          SendReadyForQuery(NetworkTransactionStateType::IDLE);
          return;
        }
      	break;
      }
      default:
      {
        // execute the query using tcop
        auto status = traffic_cop_->ExecuteStatement(
            query, result, tuple_descriptor, rows_affected, error_message,
            thread_id);

      // check status
        if (status == ResultType::FAILURE) {
          SendErrorResponse(
            {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          SendReadyForQuery(NetworkTransactionStateType::IDLE);
          return;
        }
      }
    }

    // send the attribute names
    PutTupleDescriptor(tuple_descriptor);

    // send the result rows
    SendDataRows(result, tuple_descriptor.size(), rows_affected);

    // The response to the SimpleQueryCommand is the query string.
    CompleteCommand(query, query_type, rows_affected);
  } else {
Beispiel #4
0
bool BatchStar(
  Environment *theEnv,
  const char *fileName)
  {
   int inchar;
   bool done = false;
   FILE *theFile;
   char *theString = NULL;
   size_t position = 0;
   size_t maxChars = 0;
#if (! RUN_TIME) && (! BLOAD_ONLY)
   char *oldParsingFileName;
   long oldLineCountValue;
#endif
   /*======================*/
   /* Open the batch file. */
   /*======================*/

   theFile = GenOpen(theEnv,fileName,"r");

   if (theFile == NULL)
     {
      OpenErrorMessage(theEnv,"batch",fileName);
      return false;
     }

   /*======================================*/
   /* Setup for capturing errors/warnings. */
   /*======================================*/

#if (! RUN_TIME) && (! BLOAD_ONLY)
   oldParsingFileName = CopyString(theEnv,GetParsingFileName(theEnv));
   SetParsingFileName(theEnv,fileName);

   CreateErrorCaptureRouter(theEnv);

   oldLineCountValue = SetLineCount(theEnv,1);
#endif

   /*=====================================*/
   /* If embedded, clear the error flags. */
   /*=====================================*/
   
   if (EvaluationData(theEnv)->CurrentExpression == NULL)
     { ResetErrorFlags(theEnv); }

   /*=============================================*/
   /* Evaluate commands from the file one by one. */
   /*=============================================*/

   while (! done)
     {
      inchar = getc(theFile);
      if (inchar == EOF)
        {
         inchar = '\n';
         done = true;
        }
        
      theString = ExpandStringWithChar(theEnv,inchar,theString,&position,
                                       &maxChars,maxChars+80);

      if (CompleteCommand(theString) != 0)
        {
         FlushPPBuffer(theEnv);
         SetPPBufferStatus(theEnv,false);
         RouteCommand(theEnv,theString,false);
         FlushPPBuffer(theEnv);
         SetHaltExecution(theEnv,false);
         SetEvaluationError(theEnv,false);
         FlushBindList(theEnv,NULL);
         genfree(theEnv,theString,maxChars);
         theString = NULL;
         maxChars = 0;
         position = 0;
#if (! RUN_TIME) && (! BLOAD_ONLY)
         FlushParsingMessages(theEnv);
#endif
        }

      if ((inchar == '\r') || (inchar == '\n'))
        { IncrementLineCount(theEnv); }
     }

   if (theString != NULL)
     { genfree(theEnv,theString,maxChars); }

   /*=======================*/
   /* Close the batch file. */
   /*=======================*/

   GenClose(theEnv,theFile);

   /*========================================*/
   /* Cleanup for capturing errors/warnings. */
   /*========================================*/

#if (! RUN_TIME) && (! BLOAD_ONLY)
   FlushParsingMessages(theEnv);
   DeleteErrorCaptureRouter(theEnv);

   SetLineCount(theEnv,oldLineCountValue);

   SetParsingFileName(theEnv,oldParsingFileName);
   DeleteString(theEnv,oldParsingFileName);
#endif

   return true;
  }
Beispiel #5
0
globle int EnvBatchStar(
  void *theEnv,
  char *fileName)
  {
   int inchar;
   FILE *theFile;
   char *theString = NULL;
   size_t position = 0;
   size_t maxChars = 0;

   /*======================*/
   /* Open the batch file. */
   /*======================*/

   theFile = GenOpen(theEnv,fileName,"r");

   if (theFile == NULL)
     {
      OpenErrorMessage(theEnv,"batch",fileName);
      return(FALSE);
     }

   /*========================*/
   /* Reset the error state. */
   /*========================*/

   SetHaltExecution(theEnv,FALSE);
   SetEvaluationError(theEnv,FALSE);

   /*=============================================*/
   /* Evaluate commands from the file one by one. */
   /*=============================================*/

   while ((inchar = getc(theFile)) != EOF)
     {
      theString = ExpandStringWithChar(theEnv,inchar,theString,&position,
                                       &maxChars,maxChars+80);

      if (CompleteCommand(theString) != 0)
        {
         FlushPPBuffer(theEnv);
         SetPPBufferStatus(theEnv,OFF);
         RouteCommand(theEnv,theString,FALSE);
         FlushPPBuffer(theEnv);
         SetHaltExecution(theEnv,FALSE);
         SetEvaluationError(theEnv,FALSE);
         FlushBindList(theEnv);      
         genfree(theEnv,theString,(unsigned) maxChars);
         theString = NULL;
         maxChars = 0;
         position = 0;
        }      
     }

   if (theString != NULL)
     { genfree(theEnv,theString,(unsigned) maxChars); }
     
   /*=======================*/
   /* Close the batch file. */
   /*=======================*/

   GenClose(theEnv,theFile);
   return(TRUE);
  }
Beispiel #6
0
/*
====================
Key_Console

Interactive line editing and console scrollback
====================
*/
static void Key_Console (int key)
{
	int	history_line_last;
	size_t		len;
	char	*workline = key_lines[edit_line];

	switch (key)
	{
	case K_ENTER:
	// backslash text are commands, else chat
		if (workline[1] == '\\' || workline[1] == '/')
			Cbuf_AddText (workline + 2);	// skip the >
		else if (CheckForCommand())
			Cbuf_AddText (workline + 1);	// valid command
		else
		{	// convert to a chat message
			if (cls.state >= ca_connected)
				Cbuf_AddText ("say ");
			Cbuf_AddText (workline + 1);	// skip the >
		}

		Cbuf_AddText ("\n");
		Con_Printf ("%s\n", workline);
		edit_line = (edit_line + 1) & 31;
		history_line = edit_line;
		key_lines[edit_line][0] = ']';
		key_lines[edit_line][1] = 0;
		key_linepos = 1;
		if (cls.state == ca_disconnected)
			SCR_UpdateScreen ();	// force an update, because the command
								// may take some time
		return;

	case K_TAB:
		CompleteCommand ();
		return;

	case K_LEFTARROW:
		if (key_linepos < 2)
			return;
		if (keydown[K_CTRL])
		{
		/* ctrl - left, word processor style: first,
		 * move to the ending of previous word, then
		 * move to its beginning
		 */
			char *p = workline + key_linepos - 1;
			while (p != workline && *p == ' ')
				--p;
			while (p != workline)
			{
				if (*--p == ' ')
					break;
			}
			key_linepos = (int)(p - workline) + 1;
		}
		else	/* simple cursor-to-left, only. */
		{
			--key_linepos;
		}
		return;

	case K_RIGHTARROW:
		if (!workline[key_linepos])
			return;
		if (keydown[K_CTRL])
		{
		/* ctrl - right, word processor style: if
		 * we are on a text move to its end, then
		 * move to the beginning of the next word
		 */
			char *p = workline + key_linepos;
			while (*p && *p != ' ')
				++p;
			while (*p && *p == ' ')
				++p;
			key_linepos = (int)(p - workline);
		}
		else	/* simple cursor-to-right only. */
		{
			++key_linepos;
		}
		return;

	case K_BACKSPACE:
		if (key_linepos > 1)
		{
			workline += key_linepos - 1;
			if (workline[1])
			{
				len = strlen(workline);
				memmove (workline, workline + 1, len);
			}
			else	*workline = 0;

			key_linepos--;
		}
		return;

	case K_DEL:
		workline += key_linepos;
		if (*workline)
		{
			if (workline[1])
			{
				len = strlen(workline);
				memmove (workline, workline + 1, len);
			}
			else	*workline = 0;
		}
		return;

	case K_UPARROW:
		history_line_last = history_line;
		do
		{
			history_line = (history_line - 1) & 31;
		} while (history_line != edit_line && !key_lines[history_line][1]);

		if (history_line == edit_line)
			history_line = history_line_last;

		strcpy(workline, key_lines[history_line]);
		key_linepos = strlen(workline);
		return;

	case K_DOWNARROW:
		if (history_line == edit_line)
			return;
		do
		{
			history_line = (history_line + 1) & 31;
		} while (history_line != edit_line && !key_lines[history_line][1]);

		if (history_line == edit_line)
		{
			workline[0] = ']';
			workline[1] = 0;
			key_linepos = 1;
		}
		else
		{
			strcpy(workline, key_lines[history_line]);
			key_linepos = strlen(workline);
		}
		return;

	case K_PGUP:
	case K_MWHEELUP:
		con->display -= 2;
		return;

	case K_PGDN:
	case K_MWHEELDOWN:
		con->display += 2;
		if (con->display > con->current)
			con->display = con->current;
		return;

	case K_HOME:
		if (keydown[K_CTRL])
			con->display = con->current - con_totallines + 10;
		else	key_linepos = 1;
		return;

	case K_END:
		if (keydown[K_CTRL])
			con->display = con->current;
		else	key_linepos = strlen(workline);
		return;

	case K_INS:
		if (keydown[K_SHIFT])		/* Shift+Ins paste */
			PasteToConsole();
		else	key_insert ^= 1;
		return;

	case 'v':
	case 'V':
#if defined(PLATFORM_OSX) || defined(PLATFORM_MAC)
		if (keydown[K_COMMAND]) {	/* Cmd+V paste (Mac-only) */
			PasteToConsole();
			return;
		}
#endif
		if (keydown[K_CTRL]) {		/* Ctrl+v paste */
			PasteToConsole();
			return;
		}
		break;

	case 'c':
	case 'C':
		if (keydown[K_CTRL]) {		/* Ctrl+C: abort the line -- S.A */
			Con_Printf ("%s\n", workline);
			workline[0] = ']';
			workline[1] = 0;
			key_linepos = 1;
			history_line= edit_line;
			return;
		}
		break;
	}

	if (key < 32 || key > 127)
		return;	// non printable

	if (key_linepos < MAXCMDLINE - 1)
	{
		qboolean endpos = !workline[key_linepos];
		// if inserting, move the text to the right
		if (key_insert && !endpos)
		{
			workline[MAXCMDLINE - 2] = 0;
			workline += key_linepos;
			len = strlen(workline) + 1;
			memmove (workline + 1, workline, len);
			*workline = key;
		}
		else
		{
			workline += key_linepos;
			*workline = key;
			// null terminate if at the end
			if (endpos)
				workline[1] = 0;
		}
		key_linepos++;
	}
}
Beispiel #7
0
// check input for console window ---------------------------------------------
//
PRIVATE
bool_t CheckConsoleInput()
{
	// scan keyboardbuffer and process key-presses sequentially
	dword *pos;
	bool_t console_input_done = false;
	while ( *( pos = &KeybBuffer->Data + KeybBuffer->ReadPos ) ) {

		int curlinelen = strlen( con_lines[ con_bottom ] + PROMPT_SIZE );

		if ( await_keypress && com_cont_func ) {

			// <space> or <enter> continues listing
			if ( ( *pos == CKC_SPACE ) || ( *pos == CKC_ENTER ) ) {

				EraseConLine( con_bottom );
				strcpy( con_lines[ con_bottom ], con_prompt );
				// ensure wait prompt gets overwritten
			    con_bottom  = last_con_bottom;
			    con_content = last_con_content;
				cursor_x    = 0;
				com_cont_func();

			// <escape> returns to command prompt immediately
			} else if ( *pos == CKC_ESCAPE ) {

				await_keypress = FALSE;
				com_cont_func  = NULL;
				if ( con_in_talk_mode ) {
					// restore talkmode prompt
					CreateSeparatorLine( con_bottom );
					CON_AddLineFeed();
					con_talk_line = con_bottom;
				} else {
					// restore standard prompt
					EraseConLine( con_bottom );
					strcpy( con_lines[ con_bottom ], con_prompt );
				}
				cursor_x = 0;
			}

		} else if ( *pos & CKC_CTRL_MASK ) {

			// control keys (CKC_xx)
			switch ( *pos ) {

			// <escape>: erase entire command line
			case CKC_ESCAPE:
				EraseConLine( con_bottom );
				strcpy( con_lines[ con_bottom ], con_prompt );
				history_scan  = history_add;
				cursor_x      = 0;
				con_back_view = 0;
				break;

			// <cursor-up>: scroll one line up in history buffer
			case CKC_CURSORUP:
				if ( !con_logged_in )
					break;
				if ( *( history_list[ ( history_scan - 1 ) & NUM_HISTORY_LINES_MASK ] ) != 0 ) {
					history_scan = ( history_scan - 1 ) & NUM_HISTORY_LINES_MASK;
					FetchHistoryEntry( history_scan );
				}
				break;

			// <cursor-down>: scroll one line down in history buffer
			case CKC_CURSORDOWN:
				if ( !con_logged_in )
					break;
				if ( *( history_list[ ( history_scan + 1 ) & NUM_HISTORY_LINES_MASK ] ) != 0 ) {
					history_scan = ( history_scan + 1 ) & NUM_HISTORY_LINES_MASK;
					FetchHistoryEntry( history_scan );
				}
				break;

			// <cursor-left>: set cursor one position left
			case CKC_CURSORLEFT:
				if ( cursor_x > 0 )
					cursor_x--;
				break;

			// <cursor-right>: set cursor one position right
			case CKC_CURSORRIGHT:
				if ( cursor_x < curlinelen )
					cursor_x++;
				break;

			// <shift + cursor-up>: view one line backward
			case CKC_CURSORUP_SHIFTED:
				if ( !con_logged_in || con_in_talk_mode )
					break;
				if ( con_back_view < CONSOLE_MAX_BACK_LINES )
					con_back_view++;
				break;

			// <shift + cursor-down>: view one line forward
			case CKC_CURSORDOWN_SHIFTED:
				if ( !con_logged_in || con_in_talk_mode )
					break;
				if ( con_back_view > 0 )
					con_back_view--;
				break;

			// <shift + cursor-left>: set cursor one word to the left
			case CKC_CURSORLEFT_SHIFTED:
				while ( ( cursor_x > 0 ) &&
						!isalnum( con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x - 1 ] ) )
					cursor_x--;
				while ( ( cursor_x > 0 ) &&
						isalnum( con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x - 1 ] ) )
					cursor_x--;
				break;

			// <shift + cursor-right>: set cursor one word to the right
			case CKC_CURSORRIGHT_SHIFTED:
				while ( ( cursor_x < curlinelen ) &&
						isalnum( con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x ] ) )
					cursor_x++;
				while ( ( cursor_x < curlinelen ) &&
						!isalnum( con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x ] ) )
					cursor_x++;
				break;

			// <home>: set cursor to first column
			case CKC_HOME:
				cursor_x = 0;
				break;

			// <end>: set cursor behind last column
			case CKC_END:
				cursor_x = curlinelen;
				break;

			// <page-up>: view one page backward
			case CKC_PAGEUP:
				if ( !con_logged_in || con_in_talk_mode )
					break;
				if ( cur_vis_conlines <= 0 )
					break;
				if ( con_back_view < CONSOLE_MAX_BACK_LINES )
					con_back_view += cur_vis_conlines;
				if ( con_back_view > CONSOLE_MAX_BACK_LINES )
					con_back_view = CONSOLE_MAX_BACK_LINES;
				break;

			// <page-down>: view one page forward
			case CKC_PAGEDOWN:
				if ( !con_logged_in || con_in_talk_mode )
					break;
				if ( cur_vis_conlines <= 0 )
					break;
				if ( con_back_view > 0 )
					con_back_view -= cur_vis_conlines;
				if ( con_back_view < 0 )
					con_back_view = 0;
				break;

			// <insert>: toggle insert mode
			case CKC_INSERT:
				insert_mode = !insert_mode;
				break;

			// <del>: delete and shift left
			case CKC_DELETE:
				if ( cursor_x < curlinelen ) {
					strcpy( paste_str, con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x + 1 );
					strcpy( con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x, paste_str );
				}
				break;

			// <tab>: find completion for current input
			case CKC_TAB:
				if ( !con_logged_in )
					break;
				CompleteCommand();
				break;

			// <enter>: execute current line
			case CKC_ENTER:
				EnterConsoleCommand();
				break;

			// <backspace>: step left and shift righthand side left
			case CKC_BACKSPACE:
				if ( cursor_x > 0 ) {
					if ( cursor_x == curlinelen ) {
						cursor_x--;
						con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x ] = 0;
					} else {
						cursor_x--;
						strcpy( paste_str, con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x + 1 );
						strcpy( con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x, paste_str );
					}
				}
				break;
			}

		} else {

			// typeable characters
			if ( ( ConsoleASCIIValid[ *pos & CON_ASCII_MASK ] ) &&
				 ( cursor_x < edit_max_x ) ) {
				if ( insert_mode && ( cursor_x < curlinelen ) ) {
					if ( curlinelen < edit_max_x ) {
						strcpy( paste_str, con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x );
						strcpy( con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x + 1, paste_str );
						con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x++ ] = (byte)*pos;
					}
				} else {
					con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x++ ] = (byte)*pos;
				}
			}
		}

		// advance one position in circular keybuffer
		KeybBuffer->ReadPos = ( KeybBuffer->ReadPos + 1 ) % KEYB_BUFF_SIZ;
		*pos = 0;

		console_input_done = true;
	}

	return console_input_done;
}
Beispiel #8
0
/**
 * \brief Interactive line editing and console scrollback.
 * \param[in] key Key that has been pressed.
 */
PRIVATE void Key_Console( int key )
{
	switch( key )
	{
		case K_KP_SLASH:
			key = '/';
			break;

		case K_KP_MINUS:
			key = '-';
			break;

		case K_KP_PLUS:
			key = '+';
			break;

		case K_KP_HOME:
			key = '7';
			break;

		case K_KP_UPARROW:
			key = '8';
			break;

		case K_KP_PGUP:
			key = '9';
			break;

		case K_KP_LEFTARROW:
			key = '4';
			break;

		case K_KP_5:
			key = '5';
			break;

		case K_KP_RIGHTARROW:
			key = '6';
			break;

		case K_KP_END:
			key = '1';
			break;

		case K_KP_DOWNARROW:
			key = '2';
			break;

		case K_KP_PGDN:
			key = '3';
			break;

		case K_KP_INS:
			key = '0';
			break;

		case K_KP_DEL:
			key = '.';
			break;
	}

	if( ( TOUPPER( key ) == 'V' && keydown[K_CTRL] ) ||
		 ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && keydown[K_SHIFT] ) )
	{
		char *cbd;

		if( ( cbd = Sys_GetClipboardData() ) != 0 )
		{
			int iStringLength;

			strtok( cbd, "\n\r\b" );

			iStringLength = strlen( cbd );
			if( iStringLength + key_linepos >= MAXCMDLINE )
			{
				iStringLength = MAXCMDLINE - key_linepos;
			}

			if( iStringLength > 0 )
			{
				cbd[ iStringLength ] = '\0';
				com_strlcat( key_lines[ edit_line ], cbd, sizeof( key_lines[ edit_line ] ) );
				key_linepos += iStringLength;
			}
			MM_FREE( cbd );
		}

		return;
	}

	// ctrl-L clears screen
	if ( key == 'l' && keydown[ K_CTRL ]  )
	{
		Cbuf_AddText( "clear\n" );
		return;
	}

	// enter finishes the line
	if( key == K_ENTER || key == K_KP_ENTER )
	{
		// backslash text are commands, else chat
		if( key_lines[ edit_line ][ 1 ] == '\\' || key_lines[ edit_line ][ 1 ] == '/' )
		{
			Cbuf_AddText( key_lines[ edit_line ] + 2 );	// skip the >
		}
		else
		{
			Cbuf_AddText( key_lines[ edit_line ] + 1 );	// valid command
		}

		Cbuf_AddText( "\n" );
		Com_Printf( "%s\n",key_lines[ edit_line ] );
		edit_line = (edit_line + 1) & 31;
		history_line = edit_line;
		key_lines[ edit_line ][ 0 ] = ']';
		key_linepos = 1;
		if( ClientStatic.state == ca_disconnected )
		{
			Client_Screen_UpdateScreen();	// force an update, because the command
											// may take some time
		}
		return;
	}

	if( key == K_TAB )
	{	// command completion
		CompleteCommand();
		return;
	}

	if( ( key == K_BACKSPACE ) || ( key == K_LEFTARROW ) || ( key == K_KP_LEFTARROW ) || ( ( key == 'h' ) && ( keydown[ K_CTRL ] ) ) )
	{
		if( key_linepos > 1 )
		{
			key_linepos--;
		}
		return;
	}

	if( ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) ||
		 ( ( key == 'p' ) && keydown[K_CTRL] ) )
	{
		do
		{
			history_line = (history_line - 1) & 31;

		} while( history_line != edit_line
				&& ! key_lines[ history_line ][ 1 ] );

		if( history_line == edit_line )
		{
			history_line = (edit_line + 1) & 31;
		}
		com_strlcpy( key_lines[ edit_line ], key_lines[ history_line ], sizeof( key_lines[ edit_line ] )  );
		key_linepos = strlen(key_lines[edit_line]);
		return;
	}

	if ( ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) ||
		 ( ( key == 'n' ) && keydown[K_CTRL] ) )
	{
		if( history_line == edit_line )
		{
			return;
		}

		do
		{
			history_line = (history_line + 1) & 31;
		}
		while (history_line != edit_line
			&& !key_lines[history_line][1]);

		if (history_line == edit_line)
		{
			key_lines[edit_line][0] = ']';
			key_linepos = 1;
		}
		else
		{
			com_strlcpy( key_lines[ edit_line ], key_lines[ history_line ], sizeof( key_lines[ edit_line ] ) );
			key_linepos = strlen(key_lines[edit_line]);
		}
		return;
	}


	// console scrolling
	if( key == K_PGUP || key == K_KP_PGUP )
	{
		Con_PageUp();
		return;
	}

	if( key == K_PGDN || key == K_KP_PGDN )
	{
		Con_PageDown();
		return;
	}

	if ( key == K_MWHEELUP)
	{
		Con_PageUp();
		if(keys[K_CTRL].down) {	// hold <ctrl> to accelerate scrolling
			Con_PageUp();
			Con_PageUp();
		}
		return;
	}

	if ( key == K_MWHEELDOWN)
	{
		Con_PageDown();
		if(keys[K_CTRL].down) {	// hold <ctrl> to accelerate scrolling
			Con_PageDown();
			Con_PageDown();
		}
		return;
	}

	// ctrl-home = top of console
	if( key == K_HOME || key == K_KP_HOME )
	{
		Con_Top();
		return;
	}

	// ctrl-end = bottom of console
	if( key == K_END || key == K_KP_END )
	{
		Con_Bottom();
		return;
	}

	if( key < 32 || key > 127 )
	{
		return;	// non printable
	}

	if (key_linepos < MAXCMDLINE-1)
	{
		key_lines[ edit_line ][ key_linepos ] = key;
		key_linepos++;
		key_lines[ edit_line ][ key_linepos ] = 0;
	}

}
Beispiel #9
0
char *Sys_ConsoleInput()
{
	guard(Sys_ConsoleInput);

#if !NO_DEDICATED
	if (console_drawInput)
	{
		// display input line
		Win32Log.WriteChar(']');
		if (console_textlen)
		{
			console_text[console_textlen] = 0;
			Win32Log.WriteStr(console_text);
		}
		console_drawInput = false;
	}

	while (true)
	{
		DWORD	numevents, numread;
		GetNumberOfConsoleInputEvents(hConInput, &numevents);
		if (numevents <= 0) break;

		INPUT_RECORD rec;
		ReadConsoleInput(hConInput, &rec, 1, &numread);
		if (rec.EventType == KEY_EVENT && rec.Event.KeyEvent.bKeyDown)
		{
			int ch = rec.Event.KeyEvent.uChar.AsciiChar;
			switch (ch)
			{
				case '\r':		// ENTER
					Win32Log.WriteStr("\r\n");
					console_drawInput = true;
					if (console_textlen)
					{
						console_textlen = 0;
						return console_text;
					}
					break;

				case '\b':		// BACKSPACE
					if (console_textlen)
					{
						console_text[--console_textlen] = 0;
						Win32Log.WriteStr("\b \b");
					}
					break;

				case '\t':		// TAB
					{
						appSprintf(ARRAY_ARG(editLine), "]%s", console_text);
						CompleteCommand();
						const char *s = editLine;
						if (s[0] == ']') s++;
						if (s[0] == '/') s++;
						int len = strlen(s);
						if (len > 0)
						{
							console_textlen = min(len, sizeof(console_text)-2);
							appStrncpyz(console_text, s, console_textlen+1);
							Win32Log.EraseInput();
							console_drawInput = true;	// next time ...
						}
					}
					break;

				case '\x1B':	// ESC
					Win32Log.EraseInput();
					console_textlen = 0;
					console_text[0] = 0;
					break;

				default:
					if (ch >= ' ')
					{
						if (console_textlen < sizeof(console_text)-2)
						{
							Win32Log.WriteChar(ch);
							console_text[console_textlen++] = ch;
							console_text[console_textlen] = 0;
						}
					}
//					else
//						appPrintf("%2X\n",ch);
					break;
			}
		}
	}
#endif
	return NULL;

	unguard;
}