1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-10 11:43:13 +02:00

core: add support of escaped unicode chars in commands /print and "/input insert"

This commit is contained in:
Sebastien Helleu
2014-01-24 12:53:23 +01:00
parent d49c3eaac6
commit 97cede06b5
23 changed files with 459 additions and 285 deletions
+9 -5
View File
@@ -6899,7 +6899,8 @@ command_init ()
" switch_active_buffer: switch to next merged buffer\n"
" switch_active_buffer_previous: switch to previous merged buffer\n"
" zoom_merged_buffer: zoom on merged buffer\n"
" insert: insert text in command line\n"
" insert: insert text in command line (escaped chars are allowed, "
"see /help print)\n"
" paste_start: start paste (bracketed paste mode)\n"
" paste_stop: stop paste (bracketed paste mode)\n"
"\n"
@@ -7116,14 +7117,15 @@ command_init ()
"of tags most commonly used)\n"
" text: text to display (prefix and message must be separated by "
"\\t)\n"
"-stdout: display text on stdout (not in a buffer)\n"
"-stderr: display text on stderr (not in a buffer)\n"
"-stdout: display text on stdout (escaped chars are interpreted)\n"
"-stderr: display text on stderr (escaped chars are interpreted)\n"
"\n"
"The options -action ... -quit use the prefix defined in options "
"\"weechat.look.prefix_*\".\n"
"\n"
"With options -stdout and -stderr, escaped chars are always "
"interpreted.\n"
"Following escaped chars are supported:\n"
" \\\" \\\\ \\a \\b \\e \\f \\n \\r \\t \\v \\0ooo \\xhh \\uhhhh "
"\\Uhhhhhhhh\n"
"\n"
"Examples:\n"
" display a reminder on core buffer with a highlight:\n"
@@ -7134,6 +7136,8 @@ command_init ()
" /print -core abc\\tThe message\n"
" display a message on channel #weechat:\n"
" /print -buffer irc.freenode.#weechat Message on #weechat\n"
" display a snowman (U+2603):\n"
" /print -escape \\u2603\n"
" send alert (BEL):\n"
" /print -stderr \\a"),
"-buffer %(buffers_numbers)|%(buffers_plugins_names)"
+48 -18
View File
@@ -631,18 +631,20 @@ string_strip (const char *string, int left, int right, const char *chars)
* Converts escaped chars to their value.
*
* Following escaped chars are supported:
* \" double quote
* \\ backslash
* \a alert (BEL)
* \b backspace
* \e escape
* \f form feed
* \n new line
* \r carriage return
* \t horizontal tab
* \v vertical tab
* \0ooo octal value (ooo is 0 to 3 digits)
* \xhh hexadecimal value (hh is 1 to 2 digits)
* \" double quote
* \\ backslash
* \a alert (BEL)
* \b backspace
* \e escape
* \f form feed
* \n new line
* \r carriage return
* \t horizontal tab
* \v vertical tab
* \0ooo char as octal value (ooo is 0 to 3 digits)
* \xhh char as hexadecimal value (hh is 1 to 2 digits)
* \uhhhh unicode char as hexadecimal value (hhhh is 1 to 4 digits)
* \Uhhhhhhhh unicode char as hexadecimal value (hhhhhhhh is 1 to 8 digits)
*
* Note: result must be freed after use.
*/
@@ -651,8 +653,9 @@ char *
string_convert_escaped_chars (const char *string)
{
const unsigned char *ptr_string;
char *output;
int pos_output, i, value;
char *output, utf_char[16];
int pos_output, i, length;
unsigned int value;
/* the output length is always <= to string length */
output = malloc (strlen (string) + 1);
@@ -668,11 +671,11 @@ string_convert_escaped_chars (const char *string)
ptr_string++;
switch (ptr_string[0])
{
case '"':
case '"': /* double quote */
output[pos_output++] = '"';
ptr_string++;
break;
case '\\':
case '\\': /* backslash */
output[pos_output++] = '\\';
ptr_string++;
break;
@@ -708,7 +711,7 @@ string_convert_escaped_chars (const char *string)
output[pos_output++] = 11;
ptr_string++;
break;
case '0': /* octal value (0 to 3 digits expected) */
case '0': /* char as octal value (0 to 3 digits) */
value = 0;
for (i = 0; (i < 3) && IS_OCTAL_DIGIT(ptr_string[i + 1]); i++)
{
@@ -717,7 +720,7 @@ string_convert_escaped_chars (const char *string)
output[pos_output++] = value;
ptr_string += 1 + i;
break;
case 'x': /* hexadecimal value (1 to 2 digits expected) */
case 'x': /* char as hexadecimal value (1 to 2 digits) */
case 'X':
if (isxdigit (ptr_string[1]))
{
@@ -735,6 +738,33 @@ string_convert_escaped_chars (const char *string)
ptr_string++;
}
break;
case 'u': /* unicode char as hexadecimal (1 to 4 digits) */
case 'U': /* unicode char as hexadecimal (1 to 8 digits) */
if (isxdigit (ptr_string[1]))
{
value = 0;
for (i = 0;
(i < ((ptr_string[0] == 'u') ? 4 : 8))
&& isxdigit (ptr_string[i + 1]);
i++)
{
value = (value * 16) + HEX2DEC(ptr_string[i + 1]);
}
utf8_int_string (value, utf_char);
if (utf_char[0])
{
length = strlen (utf_char);
memcpy (output + pos_output, utf_char, length);
pos_output += length;
}
ptr_string += 1 + i;
}
else
{
output[pos_output++] = ptr_string[0];
ptr_string++;
}
break;
default:
output[pos_output++] = '\\';
output[pos_output++] = ptr_string[0];
+50
View File
@@ -297,6 +297,56 @@ utf8_char_int (const char *string)
return (int)ptr_string[0];
}
/*
* Converts a unicode char (as unsigned integer) to a string.
*
* The string must have a size >= 5
* (4 bytes for the UTF-8 char + the final '\0').
*
* In case of error (if unicode value is > 0x1FFFFF), the string is set to an
* empty string (string[0] == '\0').
*/
void
utf8_int_string (unsigned int unicode_value, char *string)
{
if (!string)
return;
string[0] = '\0';
if (unicode_value <= 0x007F)
{
/* UTF-8, 1 byte: 0vvvvvvv */
string[0] = unicode_value;
string[1] = '\0';
}
else if (unicode_value <= 0x07FF)
{
/* UTF-8, 2 bytes: 110vvvvv 10vvvvvv */
string[0] = 0xC0 | ((unicode_value >> 6) & 0x1F);
string[1] = 0x80 | (unicode_value & 0x3F);
string[2] = '\0';
}
else if (unicode_value <= 0xFFFF)
{
/* UTF-8, 3 bytes: 1110vvvv 10vvvvvv 10vvvvvv */
string[0] = 0xE0 | ((unicode_value >> 12) & 0x0F);
string[1] = 0x80 | ((unicode_value >> 6) & 0x3F);
string[2] = 0x80 | (unicode_value & 0x3F);
string[3] = '\0';
}
else if (unicode_value <= 0x1FFFFF)
{
/* UTF-8, 4 bytes: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */
string[0] = 0xF0 | ((unicode_value >> 18) & 0x07);
string[1] = 0x80 | ((unicode_value >> 12) & 0x3F);
string[2] = 0x80 | ((unicode_value >> 6) & 0x3F);
string[3] = 0x80 | (unicode_value & 0x3F);
string[4] = '\0';
}
}
/*
* Gets wide char from string (first char).
*
+1
View File
@@ -35,6 +35,7 @@ extern void utf8_normalize (char *string, char replacement);
extern char *utf8_prev_char (const char *string_start, const char *string);
extern char *utf8_next_char (const char *string);
extern int utf8_char_int (const char *string);
extern void utf8_int_string (unsigned int unicode_value, char *string);
extern wint_t utf8_wide_char (const char *string);
extern int utf8_char_size (const char *string);
extern int utf8_strlen (const char *string);