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

core: add command /print

This commit is contained in:
Sebastien Helleu
2014-01-19 23:29:00 +01:00
parent 49f4c8e9ef
commit 4da8fcf34d
23 changed files with 1145 additions and 67 deletions
+229
View File
@@ -20,12 +20,18 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/* this define is needed for strptime() (not on OpenBSD) */
#if !defined(__OpenBSD__)
#define _XOPEN_SOURCE 700
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
@@ -4171,6 +4177,182 @@ COMMAND_CALLBACK(plugin)
return WEECHAT_RC_OK;
}
/*
* Callback for command "/print": display text on a buffer.
*/
COMMAND_CALLBACK(print)
{
struct t_gui_buffer *ptr_buffer;
int i, escape, to_stdout, to_stderr;
time_t date, date_now;
struct tm tm_date;
char *tags, *pos, *text, *text2, *error;
const char *prefix;
long value;
/* make C compiler happy */
(void) data;
if (argc < 2)
return WEECHAT_RC_OK;
ptr_buffer = buffer;
date = 0;
tags = NULL;
prefix = NULL;
escape = 0;
to_stdout = 0;
to_stderr = 0;
for (i = 1; i < argc; i++)
{
if (string_strcasecmp (argv[i], "-buffer") == 0)
{
if (i + 1 >= argc)
return WEECHAT_RC_ERROR;
i++;
ptr_buffer = gui_buffer_search_by_number_or_name (argv[i]);
if (!ptr_buffer)
return WEECHAT_RC_ERROR;
}
else if (string_strcasecmp (argv[i], "-core") == 0)
{
ptr_buffer = NULL;
}
else if (string_strcasecmp (argv[i], "-escape") == 0)
{
escape = 1;
}
else if (string_strcasecmp (argv[i], "-date") == 0)
{
if (i + 1 >= argc)
return WEECHAT_RC_ERROR;
i++;
if ((argv[i][0] == '-') || (argv[i][0] == '+'))
{
error = NULL;
value = strtol (argv[i] + 1, &error, 10);
if (!error || error[0])
return WEECHAT_RC_ERROR;
date = (argv[i][0] == '-') ?
time (NULL) - value : time (NULL) + value;
}
else
{
error = NULL;
value = strtol (argv[i], &error, 10);
if (error && !error[0])
{
date = value;
}
else
{
memset (&tm_date, 0, sizeof (struct tm));
if (strchr (argv[i], '-'))
{
/* ISO 8601 (date/time) */
if (strptime (argv[i], "%Y-%m-%dT%H:%M:%S", &tm_date))
{
if (tm_date.tm_year > 0)
date = mktime (&tm_date);
}
}
else
{
/* time only (use current date) */
date_now = time (NULL);
localtime_r (&date_now, &tm_date);
if (strptime (argv[i], "%H:%M:%S", &tm_date))
date = mktime (&tm_date);
}
}
}
}
else if (string_strcasecmp (argv[i], "-tags") == 0)
{
if (i + 1 >= argc)
return WEECHAT_RC_ERROR;
i++;
tags = argv[i];
}
else if (string_strcasecmp (argv[i], "-action") == 0)
{
prefix = gui_chat_prefix[GUI_CHAT_PREFIX_ACTION];
}
else if (string_strcasecmp (argv[i], "-error") == 0)
{
prefix = gui_chat_prefix[GUI_CHAT_PREFIX_ERROR];
}
else if (string_strcasecmp (argv[i], "-join") == 0)
{
prefix = gui_chat_prefix[GUI_CHAT_PREFIX_JOIN];
}
else if (string_strcasecmp (argv[i], "-network") == 0)
{
prefix = gui_chat_prefix[GUI_CHAT_PREFIX_NETWORK];
}
else if (string_strcasecmp (argv[i], "-quit") == 0)
{
prefix = gui_chat_prefix[GUI_CHAT_PREFIX_QUIT];
}
else if (string_strcasecmp (argv[i], "-stdout") == 0)
{
to_stdout = 1;
}
else if (string_strcasecmp (argv[i], "-stderr") == 0)
{
to_stderr = 1;
}
else
break;
}
if (i >= argc)
return WEECHAT_RC_OK;
if (to_stdout || to_stderr)
{
text = string_convert_escaped_chars (argv_eol[i]);
if (text)
{
fprintf ((to_stdout) ? stdout : stderr, "%s", text);
free (text);
}
}
else
{
text = strdup (argv_eol[i]);
if (text)
{
pos = NULL;
if (!prefix)
{
pos = strstr (text, "\\t");
if (pos)
{
pos[0] = '\t';
memmove (pos + 1, pos + 2, strlen (pos + 2) + 1);
}
}
text2 = (escape) ?
string_convert_escaped_chars (text) : strdup (text);
if (text2)
{
gui_chat_printf_date_tags (
ptr_buffer, date, tags,
"%s%s",
(prefix) ? prefix : ((!prefix && !pos) ? "\t" : ""),
text2);
free (text2);
}
free (text);
}
}
return WEECHAT_RC_OK;
}
/*
* Displays a list of proxies.
*/
@@ -6912,6 +7094,53 @@ command_init ()
" || reload %(plugins_names)"
" || unload %(plugins_names)",
&command_plugin, NULL);
hook_command (
NULL, "print",
N_("display text on a buffer"),
N_("[-buffer <number>|<name>] [-core] [-escape] [-date <date>] "
"[-tags <tags>] [-action|-error|-join|-network|-quit] <text>"
" || -stdout|-stderr <text>"),
N_("-buffer: the buffer where text is displayed (default: current "
"buffer)\n"
" -core: alias of \"-buffer core.weechat\"\n"
"-escape: interpret escaped chars (for example \\a, \\07, \\x07)\n"
" -date: message date, format can be:\n"
" -n: 'n' seconds before now\n"
" +n: 'n' seconds in the future\n"
" n: 'n' seconds since the Epoch (see man time)\n"
" date/time (ISO 8601): yyyy-mm-ddThh:mm:ss, example: "
"2014-01-19T04:32:55\n"
" time: hh:mm:ss (example: 04:32:55)\n"
" -tags: comma-separated list of tags (see /help filter for a list "
"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"
"\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"
"\n"
"Examples:\n"
" display a reminder on core buffer with a highlight:\n"
" /print -core -tags notify_highlight Reminder: buy milk\n"
" display an error on core buffer:\n"
" /print -core -error Some error here\n"
" display message on core buffer with prefix \"abc\":\n"
" /print -core abc\tThe message\n"
" display a message on channel #weechat:\n"
" /print -buffer irc.freenode.#weechat Message on #weechat\n"
" send alert (BEL):\n"
" /print -stderr \\a"),
"-buffer %(buffers_numbers)|%(buffers_plugins_names)"
" || -core|-escape|-date|-tags|-action|-error|-join|-network|-quit"
" || -prefix"
" || -stdout"
" || -stderr",
&command_print, NULL);
hook_command (
NULL, "proxy",
N_("manage proxies"),
+110 -52
View File
@@ -54,6 +54,11 @@
#include "../plugins/plugin.h"
#define IS_OCTAL_DIGIT(c) ((c >= '0') && (c <= '7'))
#define HEX2DEC(c) (((c >= 'a') && (c <= 'f')) ? c - 'a' + 10 : \
((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : \
c - '0')
typedef uint32_t string_shared_count_t;
struct t_hashtable *string_hashtable_shared = NULL;
@@ -623,74 +628,127 @@ string_strip (const char *string, int left, int right, const char *chars)
}
/*
* Converts hex chars (\x??) to value.
* 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)
*
* Note: result must be freed after use.
*/
char *
string_convert_hex_chars (const char *string)
string_convert_escaped_chars (const char *string)
{
char *output, hex_str[8], *error;
int pos_output;
long number;
const unsigned char *ptr_string;
char *output;
int pos_output, i, value;
/* the output length is always <= to string length */
output = malloc (strlen (string) + 1);
if (output)
if (!output)
return NULL;
pos_output = 0;
ptr_string = (const unsigned char *)string;
while (ptr_string && ptr_string[0])
{
pos_output = 0;
while (string && string[0])
if (ptr_string[0] == '\\')
{
if (string[0] == '\\')
ptr_string++;
switch (ptr_string[0])
{
string++;
switch (string[0])
{
case '\\':
output[pos_output++] = '\\';
string++;
break;
case 'x':
case 'X':
if (isxdigit ((unsigned char)string[1])
&& isxdigit ((unsigned char)string[2]))
case '"':
output[pos_output++] = '"';
ptr_string++;
break;
case '\\':
output[pos_output++] = '\\';
ptr_string++;
break;
case 'a': /* alert */
output[pos_output++] = 7;
ptr_string++;
break;
case 'b': /* backspace */
output[pos_output++] = 8;
ptr_string++;
break;
case 'e': /* escape */
output[pos_output++] = 27;
ptr_string++;
break;
case 'f': /* form feed */
output[pos_output++] = 12;
ptr_string++;
break;
case 'n': /* new line */
output[pos_output++] = 10;
ptr_string++;
break;
case 'r': /* carriage return */
output[pos_output++] = 13;
ptr_string++;
break;
case 't': /* horizontal tab */
output[pos_output++] = 9;
ptr_string++;
break;
case 'v': /* vertical tab */
output[pos_output++] = 11;
ptr_string++;
break;
case '0': /* octal value (0 to 3 digits expected) */
value = 0;
for (i = 0; (i < 3) && IS_OCTAL_DIGIT(ptr_string[i + 1]); i++)
{
value = (value * 8) + (ptr_string[i + 1] - '0');
}
output[pos_output++] = value;
ptr_string += 1 + i;
break;
case 'x': /* hexadecimal value (1 to 2 digits expected) */
case 'X':
if (isxdigit (ptr_string[1]))
{
value = 0;
for (i = 0; (i < 2) && isxdigit (ptr_string[i + 1]); i++)
{
snprintf (hex_str, sizeof (hex_str),
"0x%c%c", string[1], string[2]);
number = strtol (hex_str, &error, 16);
if (error && !error[0])
{
output[pos_output++] = number;
string += 3;
}
else
{
output[pos_output++] = '\\';
output[pos_output++] = string[0];
string++;
}
value = (value * 16) + HEX2DEC(ptr_string[i + 1]);
}
else
{
output[pos_output++] = string[0];
string++;
}
break;
default:
output[pos_output++] = '\\';
output[pos_output++] = string[0];
string++;
break;
}
}
else
{
output[pos_output++] = string[0];
string++;
output[pos_output++] = value;
ptr_string += 1 + i;
}
else
{
output[pos_output++] = ptr_string[0];
ptr_string++;
}
break;
default:
output[pos_output++] = '\\';
output[pos_output++] = ptr_string[0];
ptr_string++;
break;
}
}
output[pos_output] = '\0';
else
{
output[pos_output++] = ptr_string[0];
ptr_string++;
}
}
output[pos_output] = '\0';
return output;
}
+1 -1
View File
@@ -47,7 +47,7 @@ extern char *string_expand_home (const char *path);
extern char *string_remove_quotes (const char *string, const char *quotes);
extern char *string_strip (const char *string, int left, int right,
const char *chars);
extern char *string_convert_hex_chars (const char *string);
extern char *string_convert_escaped_chars (const char *string);
extern char *string_mask_to_regex (const char *mask);
extern const char *string_regex_flags (const char *regex, int default_flags,
int *flags);
+1 -1
View File
@@ -1666,7 +1666,7 @@ gui_input_insert (struct t_gui_buffer *buffer, const char *args)
if (args)
{
gui_buffer_undo_snap (buffer);
args2 = string_convert_hex_chars (args);
args2 = string_convert_escaped_chars (args);
gui_input_insert_string (buffer, (args2) ? args2 : args, -1);
gui_input_text_changed_modifier_and_signal (buffer,
1, /* save undo */