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:
@@ -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
@@ -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];
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user