Exemple #1
0
U8_EXPORT
/* u8_string_subst:
    Arguments: returns a copy of its argument with all occurrences of one string replaced with another
    Returns: the concatenation of the strings
*/
u8_string u8_string_subst(u8_string input,u8_string key,u8_string replace)
{
  const u8_byte *scan=input, *next=strstr(scan,key);
  if (next==NULL) return u8_strdup(input);
  else {
    struct U8_OUTPUT out;
    int key_len=u8_bytelen(key), replace_len=u8_bytelen(replace);
    U8_INIT_STATIC_OUTPUT(out,u8_bytelen(input)+(replace_len*4)+2);
    while (next) {
      u8_putn(&out,scan,next-scan);
      u8_putn(&out,replace,replace_len);
      scan=next+key_len;
      next=strstr(scan,key);}
    u8_puts(&out,scan);
    return (u8_string) out.u8_outbuf;}
}
Exemple #2
0
/*
====================
Interactive line editing and console scrollback
====================
*/
static void
Key_Console (int key, int unicode)
{
	// LordHavoc: copied most of this from Q2 to improve keyboard handling
	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 ((key == 'v' && keydown[K_CTRL]) || ((key == K_INS || key == K_KP_INS) && keydown[K_SHIFT]))
	{
		char *cbd, *p;
		if ((cbd = Sys_GetClipboardData()) != 0)
		{
			int i;
#if 1
			p = cbd;
			while (*p)
			{
				if (*p == '\r' && *(p+1) == '\n')
				{
					*p++ = ';';
					*p++ = ' ';
				}
				else if (*p == '\n' || *p == '\r' || *p == '\b')
					*p++ = ';';
				p++;
			}
#else
			strtok(cbd, "\n\r\b");
#endif
			i = (int)strlen(cbd);
			if (i + key_linepos >= MAX_INPUTLINE)
				i= MAX_INPUTLINE - key_linepos - 1;
			if (i > 0)
			{
				// terencehill: insert the clipboard text between the characters of the line
				/*
				char *temp = (char *) Z_Malloc(MAX_INPUTLINE);
				cbd[i]=0;
				temp[0]=0;
				if ( key_linepos < (int)strlen(key_line) )
					strlcpy(temp, key_line + key_linepos, (int)strlen(key_line) - key_linepos +1);
				key_line[key_linepos] = 0;
				strlcat(key_line, cbd, sizeof(key_line));
				if (temp[0])
					strlcat(key_line, temp, sizeof(key_line));
				Z_Free(temp);
				key_linepos += i;
				*/
				// blub: I'm changing this to use memmove() like the rest of the code does.
				cbd[i] = 0;
				memmove(key_line + key_linepos + i, key_line + key_linepos, sizeof(key_line) - key_linepos - i);
				memcpy(key_line + key_linepos, cbd, i);
				key_linepos += i;
			}
			Z_Free(cbd);
		}
		return;
	}

	if (key == 'l' && keydown[K_CTRL])
	{
		Cbuf_AddText ("clear\n");
		return;
	}

	if (key == 'u' && keydown[K_CTRL]) // like vi/readline ^u: delete currently edited line
	{
		// clear line
		key_line[0] = ']';
		key_line[1] = 0;
		key_linepos = 1;
		return;
	}

	if (key == 'q' && keydown[K_CTRL]) // like zsh ^q: push line to history, don't execute, and clear
	{
		// clear line
		Key_History_Push();
		key_line[0] = ']';
		key_line[1] = 0;
		key_linepos = 1;
		return;
	}

	if (key == K_ENTER || key == K_KP_ENTER)
	{
		Cbuf_AddText (key_line+1);	// skip the ]
		Cbuf_AddText ("\n");
		Key_History_Push();
		key_line[0] = ']';
		key_line[1] = 0;	// EvilTypeGuy: null terminate
		key_linepos = 1;
		// force an update, because the command may take some time
		if (cls.state == ca_disconnected)
			CL_UpdateScreen ();
		return;
	}

	if (key == K_TAB)
	{
		if(keydown[K_CTRL]) // append to the cvar its value
		{
			int		cvar_len, cvar_str_len, chars_to_move;
			char	k;
			char	cvar[MAX_INPUTLINE];
			const char *cvar_str;
			
			// go to the start of the variable
			while(--key_linepos)
			{
				k = key_line[key_linepos];
				if(k == '\"' || k == ';' || k == ' ' || k == '\'')
					break;
			}
			key_linepos++;
			
			// save the variable name in cvar
			for(cvar_len=0; (k = key_line[key_linepos + cvar_len]) != 0; cvar_len++)
			{
				if(k == '\"' || k == ';' || k == ' ' || k == '\'')
					break;
				cvar[cvar_len] = k;
			}
			if (cvar_len==0)
				return;
			cvar[cvar_len] = 0;
			
			// go to the end of the cvar
			key_linepos += cvar_len;
			
			// save the content of the variable in cvar_str
			cvar_str = Cvar_VariableString(cvar);
			cvar_str_len = strlen(cvar_str);
			if (cvar_str_len==0)
				return;
			
			// insert space and cvar_str in key_line
			chars_to_move = strlen(&key_line[key_linepos]);
			if (key_linepos + 1 + cvar_str_len + chars_to_move < MAX_INPUTLINE)
			{
				if (chars_to_move)
					memmove(&key_line[key_linepos + 1 + cvar_str_len], &key_line[key_linepos], chars_to_move);
				key_line[key_linepos++] = ' ';
				memcpy(&key_line[key_linepos], cvar_str, cvar_str_len);
				key_linepos += cvar_str_len;
				key_line[key_linepos + chars_to_move] = 0;
			}
			else
				Con_Printf("Couldn't append cvar value, edit line too long.\n");
			return;
		}
		// Enhanced command completion
		// by EvilTypeGuy [email protected]
		// Thanks to Fett, Taniwha
		Con_CompleteCommandLine();
		return;
	}

	// Advanced Console Editing by Radix [email protected]
	// Added/Modified by EvilTypeGuy [email protected]
	// Enhanced by [515]
	// Enhanced by terencehill

	// move cursor to the previous character
	if (key == K_LEFTARROW || key == K_KP_LEFTARROW)
	{
		if (key_linepos < 2)
			return;
		if(keydown[K_CTRL]) // move cursor to the previous word
		{
			int		pos;
			char	k;
			pos = key_linepos-1;

			if(pos) // skip all "; ' after the word
				while(--pos)
				{
					k = key_line[pos];
					if (!(k == '\"' || k == ';' || k == ' ' || k == '\''))
						break;
				}

			if(pos)
				while(--pos)
				{
					k = key_line[pos];
					if(k == '\"' || k == ';' || k == ' ' || k == '\'')
						break;
				}
			key_linepos = pos + 1;
		}
		else if(keydown[K_SHIFT]) // move cursor to the previous character ignoring colors
		{
			int		pos;
			size_t          inchar = 0;
			pos = u8_prevbyte(key_line, key_linepos);
			while (pos)
				if(pos-1 > 0 && key_line[pos-1] == STRING_COLOR_TAG && isdigit(key_line[pos]))
					pos-=2;
				else if(pos-4 > 0 && key_line[pos-4] == STRING_COLOR_TAG && key_line[pos-3] == STRING_COLOR_RGB_TAG_CHAR
						&& isxdigit(key_line[pos-2]) && isxdigit(key_line[pos-1]) && isxdigit(key_line[pos]))
					pos-=5;
				else
				{
					if(pos-1 > 0 && key_line[pos-1] == STRING_COLOR_TAG && key_line[pos] == STRING_COLOR_TAG) // consider ^^ as a character
						pos--;
					pos--;
					break;
				}
			// we need to move to the beginning of the character when in a wide character:
			u8_charidx(key_line, pos + 1, &inchar);
			key_linepos = pos + 1 - inchar;
		}
		else
		{
			key_linepos = u8_prevbyte(key_line, key_linepos);
		}
		return;
	}

	// delete char before cursor
	if (key == K_BACKSPACE || (key == 'h' && keydown[K_CTRL]))
	{
		if (key_linepos > 1)
		{
			int newpos = u8_prevbyte(key_line, key_linepos);
			strlcpy(key_line + newpos, key_line + key_linepos, sizeof(key_line) + 1 - key_linepos);
			key_linepos = newpos;
		}
		return;
	}

	// delete char on cursor
	if (key == K_DEL || key == K_KP_DEL)
	{
		size_t linelen;
		linelen = strlen(key_line);
		if (key_linepos < (int)linelen)
			memmove(key_line + key_linepos, key_line + key_linepos + u8_bytelen(key_line + key_linepos, 1), linelen - key_linepos);
		return;
	}


	// move cursor to the next character
	if (key == K_RIGHTARROW || key == K_KP_RIGHTARROW)
	{
		if (key_linepos >= (int)strlen(key_line))
			return;
		if(keydown[K_CTRL]) // move cursor to the next word
		{
			int		pos, len;
			char	k;
			len = (int)strlen(key_line);
			pos = key_linepos;

			while(++pos < len)
			{
				k = key_line[pos];
				if(k == '\"' || k == ';' || k == ' ' || k == '\'')
					break;
			}
			
			if (pos < len) // skip all "; ' after the word
				while(++pos < len)
				{
					k = key_line[pos];
					if (!(k == '\"' || k == ';' || k == ' ' || k == '\''))
						break;
				}
			key_linepos = pos;
		}
		else if(keydown[K_SHIFT]) // move cursor to the next character ignoring colors
		{
			int		pos, len;
			len = (int)strlen(key_line);
			pos = key_linepos;
			
			// go beyond all initial consecutive color tags, if any
			if(pos < len)
				while (key_line[pos] == STRING_COLOR_TAG)
				{
					if(isdigit(key_line[pos+1]))
						pos+=2;
					else if(key_line[pos+1] == STRING_COLOR_RGB_TAG_CHAR && isxdigit(key_line[pos+2]) && isxdigit(key_line[pos+3]) && isxdigit(key_line[pos+4]))
						pos+=5;
					else
						break;
				}
			
			// skip the char
			if (key_line[pos] == STRING_COLOR_TAG && key_line[pos+1] == STRING_COLOR_TAG) // consider ^^ as a character
				pos++;
			pos += u8_bytelen(key_line + pos, 1);
			
			// now go beyond all next consecutive color tags, if any
			if(pos < len)
				while (key_line[pos] == STRING_COLOR_TAG)
				{
					if(isdigit(key_line[pos+1]))
						pos+=2;
					else if(key_line[pos+1] == STRING_COLOR_RGB_TAG_CHAR && isxdigit(key_line[pos+2]) && isxdigit(key_line[pos+3]) && isxdigit(key_line[pos+4]))
						pos+=5;
					else
						break;
				}
			key_linepos = pos;
		}
		else
			key_linepos += u8_bytelen(key_line + key_linepos, 1);
		return;
	}

	if (key == K_INS || key == K_KP_INS) // toggle insert mode
	{
		key_insert ^= 1;
		return;
	}

	// End Advanced Console Editing

	if (key == K_UPARROW || key == K_KP_UPARROW || (key == 'p' && keydown[K_CTRL]))
	{
		Key_History_Up();
		return;
	}

	if (key == K_DOWNARROW || key == K_KP_DOWNARROW || (key == 'n' && keydown[K_CTRL]))
	{
		Key_History_Down();
		return;
	}
	// ~1.0795 = 82/76  using con_textsize 64 76 is height of the char, 6 is the distance between 2 lines
	if (key == K_PGUP || key == K_KP_PGUP)
	{
		if(keydown[K_CTRL])
		{
			con_backscroll += ((vid_conheight.integer >> 2) / con_textsize.integer)-1;
		}
		else
			con_backscroll += ((vid_conheight.integer >> 1) / con_textsize.integer)-3;
		return;
	}