mirror of
https://github.com/weechat/weechat.git
synced 2026-06-27 13:26:38 +02:00
scripts: add "eval" option in script commands and info "xxx_eval" (issue #128)
For now this works only in python, perl, ruby and guile.
This commit is contained in:
@@ -46,7 +46,23 @@ WEECHAT_PLUGIN_PRIORITY(4000);
|
||||
|
||||
struct t_weechat_plugin *weechat_guile_plugin = NULL;
|
||||
|
||||
int guile_quiet;
|
||||
int guile_quiet = 0;
|
||||
|
||||
struct t_plugin_script *guile_script_eval = NULL;
|
||||
int guile_eval_mode = 0;
|
||||
int guile_eval_send_input = 0;
|
||||
int guile_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *guile_eval_buffer = NULL;
|
||||
char *guile_eval_output = NULL;
|
||||
#define GUILE_EVAL_SCRIPT \
|
||||
"(weechat:register \"" WEECHAT_SCRIPT_EVAL_NAME "\" \"\" \"1.0\" " \
|
||||
"\"" WEECHAT_LICENSE "\" \"Evaluation of script code\" " \
|
||||
"\"\" \"\")\n" \
|
||||
"\n" \
|
||||
"(define (script_guile_eval code)\n" \
|
||||
" (eval-string code)\n" \
|
||||
")\n"
|
||||
|
||||
struct t_plugin_script *guile_scripts = NULL;
|
||||
struct t_plugin_script *last_guile_script = NULL;
|
||||
struct t_plugin_script *guile_current_script = NULL;
|
||||
@@ -54,7 +70,7 @@ struct t_plugin_script *guile_registered_script = NULL;
|
||||
const char *guile_current_script_filename = NULL;
|
||||
SCM guile_module_weechat;
|
||||
SCM guile_port;
|
||||
char *guile_stdout = NULL;
|
||||
char **guile_buffer_output = NULL;
|
||||
|
||||
struct t_guile_function
|
||||
{
|
||||
@@ -89,20 +105,63 @@ char *guile_action_autoload_list = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* Flushes stdout.
|
||||
* Flushes output.
|
||||
*/
|
||||
|
||||
void
|
||||
weechat_guile_stdout_flush ()
|
||||
weechat_guile_output_flush ()
|
||||
{
|
||||
if (guile_stdout)
|
||||
const char *ptr_command;
|
||||
char *command;
|
||||
int length;
|
||||
|
||||
if (!*guile_buffer_output[0])
|
||||
return;
|
||||
|
||||
if (guile_eval_mode)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s%s"),
|
||||
GUILE_PLUGIN_NAME, guile_stdout, "");
|
||||
free (guile_stdout);
|
||||
guile_stdout = NULL;
|
||||
/* if there's no buffer, we catch the output, so there's no flush */
|
||||
if (!guile_eval_buffer)
|
||||
return;
|
||||
|
||||
if (guile_eval_send_input)
|
||||
{
|
||||
if (guile_eval_exec_commands)
|
||||
ptr_command = *guile_buffer_output;
|
||||
else
|
||||
ptr_command = weechat_string_input_for_buffer (*guile_buffer_output);
|
||||
if (ptr_command)
|
||||
{
|
||||
weechat_command (guile_eval_buffer, *guile_buffer_output);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = 1 + strlen (*guile_buffer_output) + 1;
|
||||
command = malloc (length);
|
||||
if (command)
|
||||
{
|
||||
snprintf (command, length, "%c%s",
|
||||
*guile_buffer_output[0], *guile_buffer_output);
|
||||
weechat_command (guile_eval_buffer,
|
||||
(command[0]) ? command : " ");
|
||||
free (command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (guile_eval_buffer, "%s", *guile_buffer_output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* script (no eval mode) */
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s"),
|
||||
GUILE_PLUGIN_NAME, *guile_buffer_output);
|
||||
}
|
||||
|
||||
weechat_string_dyn_copy (guile_buffer_output, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -272,6 +331,8 @@ weechat_guile_exec (struct t_plugin_script *script,
|
||||
void *argv2[17], *ret_value;
|
||||
int i, argc, *ret_int;
|
||||
|
||||
ret_value = NULL;
|
||||
|
||||
old_guile_current_script = guile_current_script;
|
||||
old_current_module = NULL;
|
||||
if (script->interpreter)
|
||||
@@ -310,7 +371,7 @@ weechat_guile_exec (struct t_plugin_script *script,
|
||||
rc = weechat_guile_exec_function (function, NULL, 0);
|
||||
}
|
||||
|
||||
ret_value = NULL;
|
||||
weechat_guile_output_flush ();
|
||||
|
||||
if ((ret_type == WEECHAT_SCRIPT_EXEC_STRING) && (scm_is_string (rc)))
|
||||
{
|
||||
@@ -332,13 +393,17 @@ weechat_guile_exec (struct t_plugin_script *script,
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must return "
|
||||
"a valid value"),
|
||||
weechat_prefix ("error"), GUILE_PLUGIN_NAME, function);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), GUILE_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret_value == NULL)
|
||||
if ((ret_type != WEECHAT_SCRIPT_EXEC_IGNORE) && !ret_value)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: error in function \"%s\""),
|
||||
@@ -354,16 +419,43 @@ weechat_guile_exec (struct t_plugin_script *script,
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes guile module for script.
|
||||
* Initializes guile module for a script file.
|
||||
*/
|
||||
|
||||
void
|
||||
weechat_guile_module_init_script (void *data)
|
||||
weechat_guile_module_init_file (void *filename)
|
||||
{
|
||||
SCM rc;
|
||||
|
||||
weechat_guile_catch (scm_c_eval_string, "(use-modules (weechat))");
|
||||
rc = weechat_guile_catch (scm_c_primitive_load, data);
|
||||
rc = weechat_guile_catch (scm_c_primitive_load, filename);
|
||||
|
||||
/* error loading script? */
|
||||
if (rc == SCM_BOOL_F)
|
||||
{
|
||||
/* if script was registered, remove it from list */
|
||||
if (guile_current_script)
|
||||
{
|
||||
plugin_script_remove (weechat_guile_plugin,
|
||||
&guile_scripts, &last_guile_script,
|
||||
guile_current_script);
|
||||
}
|
||||
guile_current_script = NULL;
|
||||
guile_registered_script = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes guile module for a string with guile code.
|
||||
*/
|
||||
|
||||
void
|
||||
weechat_guile_module_init_code (void *code)
|
||||
{
|
||||
SCM rc;
|
||||
|
||||
weechat_guile_catch (scm_c_eval_string, "(use-modules (weechat))");
|
||||
rc = weechat_guile_catch (scm_c_eval_string, code);
|
||||
|
||||
/* error loading script? */
|
||||
if (rc == SCM_BOOL_F)
|
||||
@@ -383,16 +475,30 @@ weechat_guile_module_init_script (void *data)
|
||||
/*
|
||||
* Loads a guile script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_guile_load (const char *filename)
|
||||
struct t_plugin_script *
|
||||
weechat_guile_load (const char *filename, const char *code)
|
||||
{
|
||||
char *filename2, *ptr_base_name, *base_name;
|
||||
SCM module;
|
||||
struct stat buf;
|
||||
|
||||
if (!code)
|
||||
{
|
||||
if (stat (filename, &buf) != 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), GUILE_PLUGIN_NAME,
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((weechat_guile_plugin->debug >= 2) || !guile_quiet)
|
||||
{
|
||||
@@ -405,15 +511,24 @@ weechat_guile_load (const char *filename)
|
||||
guile_registered_script = NULL;
|
||||
guile_current_script_filename = filename;
|
||||
|
||||
filename2 = strdup (filename);
|
||||
if (!filename2)
|
||||
return 0;
|
||||
|
||||
ptr_base_name = basename (filename2);
|
||||
base_name = strdup (ptr_base_name);
|
||||
module = scm_c_define_module (base_name,
|
||||
&weechat_guile_module_init_script, filename2);
|
||||
free (filename2);
|
||||
if (code)
|
||||
{
|
||||
module = scm_c_define_module (filename,
|
||||
&weechat_guile_module_init_code,
|
||||
(char *)code);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename2 = strdup (filename);
|
||||
if (!filename2)
|
||||
return NULL;
|
||||
ptr_base_name = basename (filename2);
|
||||
base_name = strdup (ptr_base_name);
|
||||
module = scm_c_define_module (base_name,
|
||||
&weechat_guile_module_init_file,
|
||||
filename2);
|
||||
free (filename2);
|
||||
}
|
||||
|
||||
if (!guile_registered_script)
|
||||
{
|
||||
@@ -421,7 +536,7 @@ weechat_guile_load (const char *filename)
|
||||
weechat_gettext ("%s%s: function \"register\" not "
|
||||
"found (or failed) in file \"%s\""),
|
||||
weechat_prefix ("error"), GUILE_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
weechat_guile_catch (scm_gc_protect_object, (void *)module);
|
||||
@@ -442,7 +557,7 @@ weechat_guile_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
guile_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return guile_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -455,7 +570,7 @@ weechat_guile_load_cb (void *data, const char *filename)
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_guile_load (filename);
|
||||
weechat_guile_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -570,7 +685,7 @@ weechat_guile_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
GUILE_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_guile_load (filename);
|
||||
weechat_guile_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -582,6 +697,56 @@ weechat_guile_reload_name (const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates guile code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_guile_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
void *func_argv[1], *result;
|
||||
|
||||
if (!guile_script_eval)
|
||||
{
|
||||
guile_quiet = 1;
|
||||
guile_script_eval = weechat_guile_load (WEECHAT_SCRIPT_EVAL_NAME,
|
||||
GUILE_EVAL_SCRIPT);
|
||||
guile_quiet = 0;
|
||||
if (!guile_script_eval)
|
||||
return 0;
|
||||
}
|
||||
|
||||
weechat_guile_output_flush ();
|
||||
|
||||
guile_eval_mode = 1;
|
||||
guile_eval_send_input = send_to_buffer_as_input;
|
||||
guile_eval_exec_commands = exec_commands;
|
||||
guile_eval_buffer = buffer;
|
||||
|
||||
func_argv[0] = (char *)code;
|
||||
result = weechat_guile_exec (guile_script_eval,
|
||||
WEECHAT_SCRIPT_EXEC_IGNORE,
|
||||
"script_guile_eval",
|
||||
"s", func_argv);
|
||||
/* result is ignored */
|
||||
if (result)
|
||||
free (result);
|
||||
|
||||
weechat_guile_output_flush ();
|
||||
|
||||
guile_eval_mode = 0;
|
||||
guile_eval_send_input = 0;
|
||||
guile_eval_exec_commands = 0;
|
||||
guile_eval_buffer = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/guile".
|
||||
*/
|
||||
@@ -591,13 +756,12 @@ weechat_guile_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
SCM value;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -667,7 +831,8 @@ weechat_guile_command_cb (const void *pointer, void *data,
|
||||
/* load guile script */
|
||||
path_script = plugin_script_search_path (weechat_guile_plugin,
|
||||
ptr_name);
|
||||
weechat_guile_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_guile_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -685,14 +850,36 @@ weechat_guile_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
/* eval guile code */
|
||||
value = weechat_guile_catch (scm_c_eval_string, argv_eol[2]);
|
||||
if (!SCM_EQ_P (value, SCM_UNDEFINED)
|
||||
&& !SCM_EQ_P (value, SCM_UNSPECIFIED))
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
scm_display (value, guile_port);
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
weechat_guile_stdout_flush ();
|
||||
if (!weechat_guile_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
@@ -739,6 +926,29 @@ weechat_guile_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns guile info "guile_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_guile_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
weechat_guile_eval (NULL, 0, 0, (arguments) ? arguments : "");
|
||||
if (guile_eval_output)
|
||||
free (guile_eval_output);
|
||||
guile_eval_output = strdup (*guile_buffer_output);
|
||||
weechat_string_dyn_copy (guile_buffer_output, NULL);
|
||||
|
||||
return guile_eval_output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with guile scripts.
|
||||
*/
|
||||
@@ -896,39 +1106,28 @@ weechat_guile_port_fill_input (SCM port)
|
||||
void
|
||||
weechat_guile_port_write (SCM port, const void *data, size_t size)
|
||||
{
|
||||
char *new_stdout;
|
||||
int length_stdout;
|
||||
char *data2, *ptr_data, *ptr_newline;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) port;
|
||||
|
||||
/* concatenate str to guile_stdout */
|
||||
if (guile_stdout)
|
||||
{
|
||||
length_stdout = strlen (guile_stdout);
|
||||
new_stdout = realloc (guile_stdout, length_stdout + size + 1);
|
||||
if (!new_stdout)
|
||||
{
|
||||
free (guile_stdout);
|
||||
return;
|
||||
}
|
||||
guile_stdout = new_stdout;
|
||||
memcpy (guile_stdout + length_stdout, data, size);
|
||||
guile_stdout[length_stdout + size] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
guile_stdout = malloc (size + 1);
|
||||
if (guile_stdout)
|
||||
{
|
||||
memcpy (guile_stdout, data, size);
|
||||
guile_stdout[size] = '\0';
|
||||
}
|
||||
}
|
||||
data2 = malloc (size + 1);
|
||||
if (!data2)
|
||||
return;
|
||||
|
||||
/* flush stdout if at least "\n" is in string */
|
||||
if (guile_stdout && (strchr (guile_stdout, '\n')))
|
||||
weechat_guile_stdout_flush ();
|
||||
memcpy (data2, data, size);
|
||||
data2[size] = '\0';
|
||||
|
||||
ptr_data = data2;
|
||||
while ((ptr_newline = strchr (ptr_data, '\n')) != NULL)
|
||||
{
|
||||
ptr_newline[0] = '\0';
|
||||
weechat_string_dyn_concat (guile_buffer_output, ptr_data);
|
||||
weechat_guile_output_flush ();
|
||||
ptr_newline[0] = '\n';
|
||||
ptr_data = ++ptr_newline;
|
||||
}
|
||||
weechat_string_dyn_concat (guile_buffer_output, ptr_data);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -960,7 +1159,10 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
"");
|
||||
#endif /* defined(SCM_MAJOR_VERSION) && defined(SCM_MINOR_VERSION) && defined(SCM_MICRO_VERSION) */
|
||||
|
||||
guile_stdout = NULL;
|
||||
/* init stdout/stderr buffer */
|
||||
guile_buffer_output = weechat_string_dyn_alloc (256);
|
||||
if (!guile_buffer_output)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
#ifdef HAVE_GUILE_GMP_MEMORY_FUNCTIONS
|
||||
/*
|
||||
@@ -982,6 +1184,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
init.callback_command = &weechat_guile_command_cb;
|
||||
init.callback_completion = &weechat_guile_completion_cb;
|
||||
init.callback_hdata = &weechat_guile_hdata_cb;
|
||||
init.callback_info_eval = &weechat_guile_info_eval_cb;
|
||||
init.callback_infolist = &weechat_guile_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_guile_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_guile_signal_script_action_cb;
|
||||
@@ -1008,6 +1211,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
/* unload all scripts */
|
||||
guile_quiet = 1;
|
||||
plugin_script_end (plugin, &guile_scripts, &weechat_guile_unload_all);
|
||||
if (guile_script_eval)
|
||||
{
|
||||
weechat_guile_unload (guile_script_eval);
|
||||
guile_script_eval = NULL;
|
||||
}
|
||||
guile_quiet = 0;
|
||||
|
||||
/* unprotect module */
|
||||
@@ -1020,6 +1228,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (guile_action_remove_list);
|
||||
if (guile_action_autoload_list)
|
||||
free (guile_action_autoload_list);
|
||||
weechat_string_dyn_free (guile_buffer_output, 1);
|
||||
if (guile_eval_output)
|
||||
free (guile_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,14 @@ WEECHAT_PLUGIN_PRIORITY(4000);
|
||||
struct t_weechat_plugin *weechat_js_plugin;
|
||||
|
||||
int js_quiet = 0;
|
||||
|
||||
struct t_plugin_script *js_script_eval = NULL;
|
||||
int js_eval_mode = 0;
|
||||
int js_eval_send_input = 0;
|
||||
int js_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *js_eval_buffer = NULL;
|
||||
char *js_eval_output = NULL;
|
||||
|
||||
struct t_plugin_script *js_scripts = NULL;
|
||||
struct t_plugin_script *last_js_script = NULL;
|
||||
struct t_plugin_script *js_current_script = NULL;
|
||||
@@ -235,15 +243,18 @@ weechat_js_exec (struct t_plugin_script *script,
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), JS_PLUGIN_NAME,
|
||||
function);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), JS_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret_value)
|
||||
if ((ret_type != WEECHAT_SCRIPT_EXEC_IGNORE) && !ret_value)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: error in function \"%s\""),
|
||||
@@ -259,13 +270,14 @@ end:
|
||||
/*
|
||||
* Loads a javascript script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_js_load (const char *filename)
|
||||
struct t_plugin_script *
|
||||
weechat_js_load (const char *filename, const char *code)
|
||||
{
|
||||
char *source;
|
||||
|
||||
@@ -275,7 +287,7 @@ weechat_js_load (const char *filename)
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), JS_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((weechat_js_plugin->debug >= 2) || !js_quiet)
|
||||
@@ -297,7 +309,7 @@ weechat_js_load (const char *filename)
|
||||
"sub-interpreter"),
|
||||
weechat_prefix ("error"), JS_PLUGIN_NAME);
|
||||
free (source);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* load libs */
|
||||
@@ -322,7 +334,7 @@ weechat_js_load (const char *filename)
|
||||
js_current_script = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free (source);
|
||||
@@ -343,7 +355,7 @@ weechat_js_load (const char *filename)
|
||||
js_current_script);
|
||||
js_current_script = NULL;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!js_registered_script)
|
||||
@@ -353,7 +365,7 @@ weechat_js_load (const char *filename)
|
||||
"found (or failed) in file \"%s\""),
|
||||
weechat_prefix ("error"), JS_PLUGIN_NAME, filename);
|
||||
delete js_current_interpreter;
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js_current_script = js_registered_script;
|
||||
@@ -372,7 +384,7 @@ weechat_js_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
js_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return js_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -385,7 +397,7 @@ weechat_js_load_cb (void *data, const char *filename)
|
||||
/* make C++ compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_js_load (filename);
|
||||
weechat_js_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -499,7 +511,7 @@ weechat_js_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
JS_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_js_load (filename);
|
||||
weechat_js_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -511,6 +523,27 @@ weechat_js_reload_name (const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates javascript code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_js_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
/* TODO: implement javascript eval */
|
||||
(void) buffer;
|
||||
(void) send_to_buffer_as_input;
|
||||
(void) exec_commands;
|
||||
(void) code;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/javascript".
|
||||
*/
|
||||
@@ -520,12 +553,12 @@ weechat_js_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C++ compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -595,7 +628,8 @@ weechat_js_command_cb (const void *pointer, void *data,
|
||||
/* load javascript script */
|
||||
path_script = plugin_script_search_path (weechat_js_plugin,
|
||||
ptr_name);
|
||||
weechat_js_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_js_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -611,6 +645,43 @@ weechat_js_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
js_quiet = 0;
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!weechat_js_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
/* TODO: implement /javascript eval */
|
||||
weechat_printf (NULL,
|
||||
"%sCommand \"/javascript eval\" is not yet implemented",
|
||||
weechat_prefix ("error"));
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
@@ -656,6 +727,28 @@ weechat_js_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns javascript info "javascript_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_js_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
static const char *not_implemented = "not yet implemented";
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
(void) arguments;
|
||||
return not_implemented;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with javascript scripts.
|
||||
*/
|
||||
@@ -817,6 +910,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
init.callback_command = &weechat_js_command_cb;
|
||||
init.callback_completion = &weechat_js_completion_cb;
|
||||
init.callback_hdata = &weechat_js_hdata_cb;
|
||||
init.callback_info_eval = &weechat_js_info_eval_cb;
|
||||
init.callback_infolist = &weechat_js_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_js_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_js_signal_script_action_cb;
|
||||
@@ -840,6 +934,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
{
|
||||
js_quiet = 1;
|
||||
plugin_script_end (plugin, &js_scripts, &weechat_js_unload_all);
|
||||
if (js_script_eval)
|
||||
{
|
||||
weechat_js_unload (js_script_eval);
|
||||
js_script_eval = NULL;
|
||||
}
|
||||
js_quiet = 0;
|
||||
|
||||
/* free some data */
|
||||
@@ -849,6 +948,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (js_action_remove_list);
|
||||
if (js_action_autoload_list)
|
||||
free (js_action_autoload_list);
|
||||
/* weechat_string_dyn_free (js_buffer_output, 1); */
|
||||
if (js_eval_output)
|
||||
free (js_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
+130
-17
@@ -45,6 +45,14 @@ WEECHAT_PLUGIN_PRIORITY(4000);
|
||||
struct t_weechat_plugin *weechat_lua_plugin;
|
||||
|
||||
int lua_quiet = 0;
|
||||
|
||||
struct t_plugin_script *lua_script_eval = NULL;
|
||||
int lua_eval_mode = 0;
|
||||
int lua_eval_send_input = 0;
|
||||
int lua_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *lua_eval_buffer = NULL;
|
||||
char *lua_eval_output = NULL;
|
||||
|
||||
struct t_plugin_script *lua_scripts = NULL;
|
||||
struct t_plugin_script *last_lua_script = NULL;
|
||||
struct t_plugin_script *lua_current_script = NULL;
|
||||
@@ -239,7 +247,14 @@ weechat_lua_exec (struct t_plugin_script *script, int ret_type,
|
||||
}
|
||||
else
|
||||
{
|
||||
WEECHAT_SCRIPT_MSG_WRONG_ARGS(LUA_CURRENT_SCRIPT_NAME, function);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), LUA_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -253,6 +268,13 @@ weechat_lua_exec (struct t_plugin_script *script, int ret_type,
|
||||
lua_tostring (lua_current_interpreter, -1));
|
||||
}
|
||||
|
||||
if ((ret_type != WEECHAT_SCRIPT_EXEC_IGNORE) && !ret_value)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: error in function \"%s\""),
|
||||
weechat_prefix ("error"), LUA_PLUGIN_NAME, function);
|
||||
}
|
||||
|
||||
lua_pop (lua_current_interpreter, 1);
|
||||
|
||||
lua_current_script = old_lua_current_script;
|
||||
@@ -338,13 +360,14 @@ weechat_lua_register_lib (lua_State *L, const char *libname,
|
||||
/*
|
||||
* Loads a lua script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_lua_load (const char *filename)
|
||||
struct t_plugin_script *
|
||||
weechat_lua_load (const char *filename, const char *code)
|
||||
{
|
||||
FILE *fp;
|
||||
char *weechat_lua_code = {
|
||||
@@ -362,7 +385,7 @@ weechat_lua_load (const char *filename)
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), LUA_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((weechat_lua_plugin->debug >= 2) || !lua_quiet)
|
||||
@@ -384,7 +407,7 @@ weechat_lua_load (const char *filename)
|
||||
"sub-interpreter"),
|
||||
weechat_prefix ("error"), LUA_PLUGIN_NAME);
|
||||
fclose (fp);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef LUA_VERSION_NUM /* LUA_VERSION_NUM is defined only in lua >= 5.1.0 */
|
||||
@@ -427,7 +450,7 @@ weechat_lua_load (const char *filename)
|
||||
lua_tostring (lua_current_interpreter, -1));
|
||||
lua_close (lua_current_interpreter);
|
||||
fclose (fp);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lua_pcall (lua_current_interpreter, 0, 0, 0) != 0)
|
||||
@@ -452,7 +475,7 @@ weechat_lua_load (const char *filename)
|
||||
lua_current_script = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
@@ -463,7 +486,7 @@ weechat_lua_load (const char *filename)
|
||||
"found (or failed) in file \"%s\""),
|
||||
weechat_prefix ("error"), LUA_PLUGIN_NAME, filename);
|
||||
lua_close (lua_current_interpreter);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
lua_current_script = lua_registered_script;
|
||||
|
||||
@@ -481,7 +504,7 @@ weechat_lua_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
lua_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return lua_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -494,7 +517,7 @@ weechat_lua_load_cb (void *data, const char *filename)
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_lua_load (filename);
|
||||
weechat_lua_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -597,7 +620,7 @@ weechat_lua_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
LUA_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_lua_load (filename);
|
||||
weechat_lua_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -622,6 +645,27 @@ weechat_lua_unload_all ()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates lua code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_lua_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
/* TODO: implement lua eval */
|
||||
(void) buffer;
|
||||
(void) send_to_buffer_as_input;
|
||||
(void) exec_commands;
|
||||
(void) code;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/lua".
|
||||
*/
|
||||
@@ -631,12 +675,12 @@ weechat_lua_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -706,7 +750,8 @@ weechat_lua_command_cb (const void *pointer, void *data,
|
||||
/* load lua script */
|
||||
path_script = plugin_script_search_path (weechat_lua_plugin,
|
||||
ptr_name);
|
||||
weechat_lua_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_lua_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -722,6 +767,43 @@ weechat_lua_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
lua_quiet = 0;
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!weechat_lua_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
/* TODO: implement /lua eval */
|
||||
weechat_printf (NULL,
|
||||
"%sCommand \"/lua eval\" is not yet implemented",
|
||||
weechat_prefix ("error"));
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
@@ -767,6 +849,28 @@ weechat_lua_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns lua info "lua_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_lua_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
static const char *not_implemented = "not yet implemented";
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
(void) arguments;
|
||||
return not_implemented;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with lua scripts.
|
||||
*/
|
||||
@@ -929,6 +1033,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
init.callback_command = &weechat_lua_command_cb;
|
||||
init.callback_completion = &weechat_lua_completion_cb;
|
||||
init.callback_hdata = &weechat_lua_hdata_cb;
|
||||
init.callback_info_eval = &weechat_lua_info_eval_cb;
|
||||
init.callback_infolist = &weechat_lua_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_lua_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_lua_signal_script_action_cb;
|
||||
@@ -955,6 +1060,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
/* unload all scripts */
|
||||
lua_quiet = 1;
|
||||
plugin_script_end (plugin, &lua_scripts, &weechat_lua_unload_all);
|
||||
if (lua_script_eval)
|
||||
{
|
||||
weechat_lua_unload (lua_script_eval);
|
||||
lua_script_eval = NULL;
|
||||
}
|
||||
lua_quiet = 0;
|
||||
|
||||
/* free some data */
|
||||
@@ -964,6 +1074,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (lua_action_remove_list);
|
||||
if (lua_action_autoload_list)
|
||||
free (lua_action_autoload_list);
|
||||
/* weechat_string_dyn_free (lua_buffer_output, 1); */
|
||||
if (lua_eval_output)
|
||||
free (lua_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
@@ -108,9 +108,6 @@ API_FUNC(register)
|
||||
char *charset;
|
||||
dXSARGS;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) items;
|
||||
|
||||
API_INIT_FUNC(0, "register", API_RETURN_ERROR);
|
||||
if (perl_registered_script)
|
||||
{
|
||||
@@ -5063,6 +5060,7 @@ weechat_perl_api_init (pTHX)
|
||||
HV *stash;
|
||||
|
||||
newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__);
|
||||
newXS ("weechat::__output__", weechat_perl_output, "weechat");
|
||||
|
||||
/* interface functions */
|
||||
API_DEF_FUNC(register);
|
||||
|
||||
+316
-39
@@ -42,6 +42,20 @@ WEECHAT_PLUGIN_PRIORITY(4000);
|
||||
struct t_weechat_plugin *weechat_perl_plugin = NULL;
|
||||
|
||||
int perl_quiet = 0;
|
||||
|
||||
struct t_plugin_script *perl_script_eval = NULL;
|
||||
int perl_eval_mode = 0;
|
||||
int perl_eval_send_input = 0;
|
||||
int perl_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *perl_eval_buffer = NULL;
|
||||
char *perl_eval_output = NULL;
|
||||
#define PERL_EVAL_SCRIPT \
|
||||
"sub script_perl_eval {\n" \
|
||||
" eval \"$_[0]\";\n" \
|
||||
"}\n" \
|
||||
"weechat::register('" WEECHAT_SCRIPT_EVAL_NAME "', '', '1.0', " \
|
||||
"'" WEECHAT_LICENSE "', 'Evaluation of script code', '', '');\n"
|
||||
|
||||
struct t_plugin_script *perl_scripts = NULL;
|
||||
struct t_plugin_script *last_perl_script = NULL;
|
||||
struct t_plugin_script *perl_current_script = NULL;
|
||||
@@ -51,6 +65,7 @@ const char *perl_current_script_filename = NULL;
|
||||
PerlInterpreter *perl_current_interpreter = NULL;
|
||||
#endif /* MULTIPLICITY */
|
||||
int perl_quit_or_upgrade = 0;
|
||||
char **perl_buffer_output = NULL;
|
||||
|
||||
/*
|
||||
* string used to execute action "install":
|
||||
@@ -94,9 +109,21 @@ char *perl_weechat_code =
|
||||
#ifndef MULTIPLICITY
|
||||
"package %s;"
|
||||
#endif /* MULTIPLICITY */
|
||||
"$SIG{__WARN__} = sub { weechat::print('', 'perl\twarning: '.$_[0]) };"
|
||||
"$SIG{__DIE__} = sub { weechat::print('', 'perl\terror: '.$_[0]) };"
|
||||
"do '%s';"
|
||||
"$SIG{__WARN__} = sub { weechat::print('', '%s '.$_[0]); };"
|
||||
"$SIG{__DIE__} = sub { weechat::print('', '%s '.$_[0]); };"
|
||||
"tie(*STDOUT, 'weechat_output');"
|
||||
"tie(*STDERR, 'weechat_output');"
|
||||
"do %s%s%s"
|
||||
"package weechat_output;"
|
||||
"sub TIEHANDLE { bless {}; }"
|
||||
"sub PRINT {"
|
||||
" weechat::__output__($_[1]);"
|
||||
"}"
|
||||
"sub PRINTF {"
|
||||
" my $self = shift;"
|
||||
" my $fmt = shift;"
|
||||
" weechat::__output__(sprintf($fmt, @_));"
|
||||
"}"
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -185,6 +212,91 @@ weechat_perl_hash_to_hashtable (SV *hash, int size, const char *type_keys,
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flushes output.
|
||||
*/
|
||||
|
||||
void
|
||||
weechat_perl_output_flush ()
|
||||
{
|
||||
const char *ptr_command;
|
||||
char *command;
|
||||
int length;
|
||||
|
||||
if (!*perl_buffer_output[0])
|
||||
return;
|
||||
|
||||
if (perl_eval_mode)
|
||||
{
|
||||
/* if there's no buffer, we catch the output, so there's no flush */
|
||||
if (!perl_eval_buffer)
|
||||
return;
|
||||
|
||||
if (perl_eval_send_input)
|
||||
{
|
||||
if (perl_eval_exec_commands)
|
||||
ptr_command = *perl_buffer_output;
|
||||
else
|
||||
ptr_command = weechat_string_input_for_buffer (*perl_buffer_output);
|
||||
if (ptr_command)
|
||||
{
|
||||
weechat_command (perl_eval_buffer, *perl_buffer_output);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = 1 + strlen (*perl_buffer_output) + 1;
|
||||
command = malloc (length);
|
||||
if (command)
|
||||
{
|
||||
snprintf (command, length, "%c%s",
|
||||
*perl_buffer_output[0], *perl_buffer_output);
|
||||
weechat_command (perl_eval_buffer,
|
||||
(command[0]) ? command : " ");
|
||||
free (command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (perl_eval_buffer, "%s", *perl_buffer_output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* script (no eval mode) */
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s"),
|
||||
PERL_PLUGIN_NAME, *perl_buffer_output);
|
||||
}
|
||||
|
||||
weechat_string_dyn_copy (perl_buffer_output, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirection for stdout and stderr.
|
||||
*/
|
||||
|
||||
XS (weechat_perl_output)
|
||||
{
|
||||
char *msg, *ptr_msg, *ptr_newline;
|
||||
dXSARGS;
|
||||
|
||||
if (items < 1)
|
||||
return;
|
||||
|
||||
msg = SvPV_nolen (ST (0));
|
||||
ptr_msg = msg;
|
||||
while ((ptr_newline = strchr (ptr_msg, '\n')) != NULL)
|
||||
{
|
||||
ptr_newline[0] = '\0';
|
||||
weechat_string_dyn_concat (perl_buffer_output, ptr_msg);
|
||||
weechat_perl_output_flush ();
|
||||
ptr_newline[0] = '\n';
|
||||
ptr_msg = ++ptr_newline;
|
||||
}
|
||||
weechat_string_dyn_concat (perl_buffer_output, ptr_msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes a perl function.
|
||||
*/
|
||||
@@ -258,24 +370,29 @@ weechat_perl_exec (struct t_plugin_script *script,
|
||||
|
||||
SPAGAIN;
|
||||
|
||||
weechat_perl_output_flush ();
|
||||
|
||||
if (SvTRUE (ERRSV))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: error: %s"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME,
|
||||
SvPV_nolen (ERRSV));
|
||||
(void) POPs; /* poping the 'undef' */
|
||||
(void) POPs; /* pop the "undef" */
|
||||
mem_err = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count != 1)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return one valid value (%d)"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME,
|
||||
function, count);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
mem_err = 0;
|
||||
}
|
||||
else
|
||||
@@ -302,16 +419,27 @@ weechat_perl_exec (struct t_plugin_script *script,
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" is "
|
||||
"internally misused"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME,
|
||||
function);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (
|
||||
NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must return "
|
||||
"a valid value"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
mem_err = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret_type != WEECHAT_SCRIPT_EXEC_IGNORE) && !ret_value)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: error in function \"%s\""),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME, function);
|
||||
}
|
||||
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
@@ -338,14 +466,17 @@ weechat_perl_exec (struct t_plugin_script *script,
|
||||
/*
|
||||
* Loads a perl script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_perl_load (const char *filename)
|
||||
struct t_plugin_script *
|
||||
weechat_perl_load (const char *filename, const char *code)
|
||||
{
|
||||
char str_warning[512], str_error[512];
|
||||
|
||||
struct t_plugin_script temp_script;
|
||||
struct stat buf;
|
||||
char *perl_code;
|
||||
@@ -364,12 +495,16 @@ weechat_perl_load (const char *filename)
|
||||
temp_script.shutdown_func = NULL;
|
||||
temp_script.charset = NULL;
|
||||
|
||||
if (stat (filename, &buf) != 0)
|
||||
if (!code)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
if (stat (filename, &buf) != 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME,
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((weechat_perl_plugin->debug >= 2) || !perl_quiet)
|
||||
@@ -392,27 +527,48 @@ weechat_perl_load (const char *filename)
|
||||
weechat_gettext ("%s%s: unable to create new "
|
||||
"sub-interpreter"),
|
||||
weechat_prefix ("error"), PERL_PLUGIN_NAME);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf (str_warning, sizeof (str_warning),
|
||||
weechat_gettext ("%s: warning:"),
|
||||
PERL_PLUGIN_NAME);
|
||||
snprintf (str_error, sizeof (str_error),
|
||||
weechat_gettext ("%s: error:"),
|
||||
PERL_PLUGIN_NAME);
|
||||
|
||||
PERL_SET_CONTEXT (perl_current_interpreter);
|
||||
perl_construct (perl_current_interpreter);
|
||||
temp_script.interpreter = (PerlInterpreter *) perl_current_interpreter;
|
||||
perl_parse (perl_current_interpreter, weechat_perl_api_init,
|
||||
perl_args_count, perl_args, NULL);
|
||||
length = strlen (perl_weechat_code) - 2 + strlen (filename) + 1;
|
||||
length = strlen (perl_weechat_code) + strlen (str_warning) +
|
||||
strlen (str_error) - 2 + 4 + strlen ((code) ? code : filename) + 4 + 1;
|
||||
perl_code = malloc (length);
|
||||
if (!perl_code)
|
||||
return 0;
|
||||
snprintf (perl_code, length, perl_weechat_code, filename);
|
||||
return NULL;
|
||||
snprintf (perl_code, length, perl_weechat_code,
|
||||
str_warning,
|
||||
str_error,
|
||||
(code) ? "{\n" : "'",
|
||||
(code) ? code : filename,
|
||||
(code) ? "\n};\n" : "';");
|
||||
#else
|
||||
snprintf (pkgname, sizeof (pkgname), "%s%d", PKG_NAME_PREFIX, perl_num);
|
||||
perl_num++;
|
||||
length = strlen (perl_weechat_code) - 4 + strlen (pkgname) + strlen (filename) + 1;
|
||||
length = strlen (perl_weechat_code) + strlen (str_warning) +
|
||||
strlen (str_error) - 4 + strlen (pkgname) + 4 +
|
||||
strlen ((code) ? code : filename) + 4 + 1;
|
||||
perl_code = malloc (length);
|
||||
if (!perl_code)
|
||||
return 0;
|
||||
snprintf (perl_code, length, perl_weechat_code, pkgname, filename);
|
||||
return NULL;
|
||||
snprintf (perl_code, length, perl_weechat_code,
|
||||
pkgname,
|
||||
str_warning,
|
||||
str_error,
|
||||
(code) ? "{\n" : "'",
|
||||
(code) ? code : filename,
|
||||
(code) ? "\n};\n" : "';");
|
||||
#endif /* MULTIPLICITY */
|
||||
eval_pv (perl_code, TRUE);
|
||||
free (perl_code);
|
||||
@@ -440,7 +596,7 @@ weechat_perl_load (const char *filename)
|
||||
perl_current_script = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!perl_registered_script)
|
||||
@@ -453,7 +609,7 @@ weechat_perl_load (const char *filename)
|
||||
perl_destruct (perl_current_interpreter);
|
||||
perl_free (perl_current_interpreter);
|
||||
#endif /* MULTIPLICITY */
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
perl_current_script = perl_registered_script;
|
||||
|
||||
@@ -475,7 +631,7 @@ weechat_perl_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
perl_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return perl_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -488,7 +644,7 @@ weechat_perl_load_cb (void *data, const char *filename)
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_perl_load (filename);
|
||||
weechat_perl_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -620,7 +776,7 @@ weechat_perl_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
PERL_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_perl_load (filename);
|
||||
weechat_perl_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -632,6 +788,56 @@ weechat_perl_reload_name (const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates perl code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_perl_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
void *func_argv[1], *result;
|
||||
|
||||
if (!perl_script_eval)
|
||||
{
|
||||
perl_quiet = 1;
|
||||
perl_script_eval = weechat_perl_load (WEECHAT_SCRIPT_EVAL_NAME,
|
||||
PERL_EVAL_SCRIPT);
|
||||
perl_quiet = 0;
|
||||
if (!perl_script_eval)
|
||||
return 0;
|
||||
}
|
||||
|
||||
weechat_perl_output_flush ();
|
||||
|
||||
perl_eval_mode = 1;
|
||||
perl_eval_send_input = send_to_buffer_as_input;
|
||||
perl_eval_exec_commands = exec_commands;
|
||||
perl_eval_buffer = buffer;
|
||||
|
||||
func_argv[0] = (char *)code;
|
||||
result = weechat_perl_exec (perl_script_eval,
|
||||
WEECHAT_SCRIPT_EXEC_IGNORE,
|
||||
"script_perl_eval",
|
||||
"s", func_argv);
|
||||
/* result is ignored */
|
||||
if (result)
|
||||
free (result);
|
||||
|
||||
weechat_perl_output_flush ();
|
||||
|
||||
perl_eval_mode = 0;
|
||||
perl_eval_send_input = 0;
|
||||
perl_eval_exec_commands = 0;
|
||||
perl_eval_buffer = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/perl".
|
||||
*/
|
||||
@@ -641,12 +847,12 @@ weechat_perl_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -716,7 +922,8 @@ weechat_perl_command_cb (const void *pointer, void *data,
|
||||
/* load perl script */
|
||||
path_script = plugin_script_search_path (weechat_perl_plugin,
|
||||
ptr_name);
|
||||
weechat_perl_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_perl_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -732,6 +939,39 @@ weechat_perl_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
perl_quiet = 0;
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!weechat_perl_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
@@ -777,6 +1017,29 @@ weechat_perl_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns perl info "perl_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_perl_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
weechat_perl_eval (NULL, 0, 0, (arguments) ? arguments : "");
|
||||
if (perl_eval_output)
|
||||
free (perl_eval_output);
|
||||
perl_eval_output = strdup (*perl_buffer_output);
|
||||
weechat_string_dyn_copy (perl_buffer_output, NULL);
|
||||
|
||||
return perl_eval_output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with perl scripts.
|
||||
*/
|
||||
@@ -967,6 +1230,11 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
"");
|
||||
#endif /* PERL_VERSION_STRING */
|
||||
|
||||
/* init stdout/stderr buffer */
|
||||
perl_buffer_output = weechat_string_dyn_alloc (256);
|
||||
if (!perl_buffer_output)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
#ifndef MULTIPLICITY
|
||||
perl_main = perl_alloc ();
|
||||
|
||||
@@ -987,6 +1255,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
init.callback_command = &weechat_perl_command_cb;
|
||||
init.callback_completion = &weechat_perl_completion_cb;
|
||||
init.callback_hdata = &weechat_perl_hdata_cb;
|
||||
init.callback_info_eval = &weechat_perl_info_eval_cb;
|
||||
init.callback_infolist = &weechat_perl_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_perl_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_perl_signal_script_action_cb;
|
||||
@@ -1018,6 +1287,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
/* unload all scripts */
|
||||
perl_quiet = 1;
|
||||
plugin_script_end (plugin, &perl_scripts, &weechat_perl_unload_all);
|
||||
if (perl_script_eval)
|
||||
{
|
||||
weechat_perl_unload (perl_script_eval);
|
||||
perl_script_eval = NULL;
|
||||
}
|
||||
perl_quiet = 0;
|
||||
|
||||
#ifndef MULTIPLICITY
|
||||
@@ -1046,6 +1320,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (perl_action_remove_list);
|
||||
if (perl_action_autoload_list)
|
||||
free (perl_action_autoload_list);
|
||||
weechat_string_dyn_free (perl_buffer_output, 1);
|
||||
if (perl_eval_output)
|
||||
free (perl_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ extern HV *weechat_perl_hashtable_to_hash (struct t_hashtable *hashtable);
|
||||
extern struct t_hashtable *weechat_perl_hash_to_hashtable (SV *hash, int size,
|
||||
const char *type_keys,
|
||||
const char *type_values);
|
||||
extern XS (weechat_perl_output);
|
||||
extern void *weechat_perl_exec (struct t_plugin_script *script,
|
||||
int ret_type, const char *function,
|
||||
const char *format, void **argv);
|
||||
|
||||
+128
-14
@@ -39,7 +39,15 @@ WEECHAT_PLUGIN_PRIORITY(4000);
|
||||
|
||||
struct t_weechat_plugin *weechat_php_plugin;
|
||||
|
||||
int php_quiet;
|
||||
int php_quiet = 0;
|
||||
|
||||
struct t_plugin_script *php_script_eval = NULL;
|
||||
int php_eval_mode = 0;
|
||||
int php_eval_send_input = 0;
|
||||
int php_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *php_eval_buffer = NULL;
|
||||
char *php_eval_output = NULL;
|
||||
|
||||
struct t_plugin_script *php_scripts = NULL;
|
||||
struct t_plugin_script *last_php_script = NULL;
|
||||
struct t_plugin_script *php_current_script = NULL;
|
||||
@@ -577,7 +585,15 @@ weechat_php_exec (struct t_plugin_script *script, int ret_type,
|
||||
}
|
||||
else
|
||||
{
|
||||
WEECHAT_SCRIPT_MSG_WRONG_ARGS(PHP_CURRENT_SCRIPT_NAME, function);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" "
|
||||
"must return a valid "
|
||||
"value"),
|
||||
weechat_prefix ("error"), PHP_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -589,6 +605,13 @@ weechat_php_exec (struct t_plugin_script *script, int ret_type,
|
||||
}
|
||||
zend_end_try ();
|
||||
|
||||
if ((ret_type != WEECHAT_SCRIPT_EXEC_IGNORE) && !ret_value)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: error in function \"%s\""),
|
||||
weechat_prefix ("error"), PHP_PLUGIN_NAME, function);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
if (params)
|
||||
{
|
||||
@@ -608,13 +631,14 @@ weechat_php_exec (struct t_plugin_script *script, int ret_type,
|
||||
/*
|
||||
* Loads a PHP script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_php_load (const char *filename)
|
||||
struct t_plugin_script *
|
||||
weechat_php_load (const char *filename, const char *code)
|
||||
{
|
||||
zend_file_handle file_handle;
|
||||
|
||||
@@ -647,7 +671,7 @@ weechat_php_load (const char *filename)
|
||||
weechat_gettext ("%s%s: function \"register\" not "
|
||||
"found (or failed) in file \"%s\""),
|
||||
weechat_prefix ("error"), PHP_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
php_current_script = php_registered_script;
|
||||
|
||||
@@ -661,7 +685,7 @@ weechat_php_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
php_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return php_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -674,7 +698,7 @@ weechat_php_load_cb (void *data, const char *filename)
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_php_load (filename);
|
||||
weechat_php_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -782,7 +806,7 @@ weechat_php_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
PHP_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_php_load (filename);
|
||||
weechat_php_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -794,6 +818,27 @@ weechat_php_reload_name (const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates PHP code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_php_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
/* TODO: implement PHP eval */
|
||||
(void) buffer;
|
||||
(void) send_to_buffer_as_input;
|
||||
(void) exec_commands;
|
||||
(void) code;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/php".
|
||||
*/
|
||||
@@ -803,12 +848,12 @@ weechat_php_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -878,7 +923,8 @@ weechat_php_command_cb (const void *pointer, void *data,
|
||||
/* load PHP script */
|
||||
path_script = plugin_script_search_path (weechat_php_plugin,
|
||||
ptr_name);
|
||||
weechat_php_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_php_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -894,6 +940,43 @@ weechat_php_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
php_quiet = 0;
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!weechat_php_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
/* TODO: implement /php eval */
|
||||
weechat_printf (NULL,
|
||||
"%sCommand \"/php eval\" is not yet implemented",
|
||||
weechat_prefix ("error"));
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
@@ -939,6 +1022,28 @@ weechat_php_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns PHP info "php_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_php_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
static const char *not_implemented = "not yet implemented";
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
(void) arguments;
|
||||
return not_implemented;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with PHP scripts.
|
||||
*/
|
||||
@@ -1142,6 +1247,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
init.callback_command = &weechat_php_command_cb;
|
||||
init.callback_completion = &weechat_php_completion_cb;
|
||||
init.callback_hdata = &weechat_php_hdata_cb;
|
||||
init.callback_info_eval = &weechat_php_info_eval_cb;
|
||||
init.callback_infolist = &weechat_php_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_php_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_php_signal_script_action_cb;
|
||||
@@ -1178,6 +1284,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
/* unload all scripts */
|
||||
php_quiet = 1;
|
||||
plugin_script_end (plugin, &php_scripts, &weechat_php_unload_all);
|
||||
if (php_script_eval)
|
||||
{
|
||||
weechat_php_unload (php_script_eval);
|
||||
php_script_eval = NULL;
|
||||
}
|
||||
php_quiet = 0;
|
||||
|
||||
if (weechat_php_func_map)
|
||||
@@ -1195,6 +1306,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (php_action_remove_list);
|
||||
if (php_action_autoload_list)
|
||||
free (php_action_autoload_list);
|
||||
/* weechat_string_dyn_free (php_buffer_output, 1); */
|
||||
if (php_eval_output)
|
||||
free (php_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
+97
-46
@@ -241,6 +241,7 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin,
|
||||
" || autoload"
|
||||
" || reload %s"
|
||||
" || unload %s"
|
||||
" || eval"
|
||||
" || version",
|
||||
"%s",
|
||||
string);
|
||||
@@ -251,6 +252,7 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin,
|
||||
" || load [-q] <filename>"
|
||||
" || autoload"
|
||||
" || reload|unload [-q] [<name>]"
|
||||
" || eval [-o|-oc] <code>"
|
||||
" || version"),
|
||||
N_(" list: list loaded scripts\n"
|
||||
"listfull: list loaded scripts (verbose)\n"
|
||||
@@ -260,9 +262,16 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin,
|
||||
"then load all scripts in \"autoload\" directory)\n"
|
||||
" unload: unload a script (if no name given, unload all scripts)\n"
|
||||
"filename: script (file) to load\n"
|
||||
" -q: quiet mode: do not display messages\n"
|
||||
" name: a script name (name used in call to \"register\" "
|
||||
"function)\n"
|
||||
" -q: quiet mode: do not display messages\n"
|
||||
" eval: evaluate script code and display result on current "
|
||||
"buffer\n"
|
||||
" -o: send evaluation result to the buffer without executing "
|
||||
"commands\n"
|
||||
" -oc: send evaluation result to the buffer and execute "
|
||||
"commands\n"
|
||||
" code: the script code to evaluate\n"
|
||||
" version: display the version of interpreter used\n"
|
||||
"\n"
|
||||
"Without argument, this command lists all loaded scripts."),
|
||||
@@ -282,6 +291,10 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin,
|
||||
N_("script name (wildcard \"*\" is allowed) "
|
||||
"(optional)"),
|
||||
init->callback_infolist, NULL, NULL);
|
||||
snprintf (string, sizeof (string), "%s_eval", weechat_plugin->name);
|
||||
weechat_hook_info (string, N_("evaluation of script code"),
|
||||
N_("code to execute"),
|
||||
init->callback_info_eval, NULL, NULL);
|
||||
|
||||
/* add signal for "debug_dump" */
|
||||
weechat_hook_signal ("debug_dump",
|
||||
@@ -316,7 +329,7 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin,
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if ((strcmp (argv[i], "-s") == 0)
|
||||
|| (strcmp (argv[i], "--no-script") == 0))
|
||||
|| (strcmp (argv[i], "--no-script") == 0))
|
||||
{
|
||||
auto_load_scripts = 0;
|
||||
}
|
||||
@@ -706,6 +719,41 @@ plugin_script_insert_sorted (struct t_weechat_plugin *weechat_plugin,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates a new script.
|
||||
*
|
||||
* Returns pointer to new script, NULL if error.
|
||||
*/
|
||||
|
||||
struct t_plugin_script *
|
||||
plugin_script_alloc (const char *filename, const char *name,
|
||||
const char *author, const char *version,
|
||||
const char *license, const char *description,
|
||||
const char *shutdown_func, const char *charset)
|
||||
{
|
||||
struct t_plugin_script *new_script;
|
||||
|
||||
new_script = malloc (sizeof (*new_script));
|
||||
if (!new_script)
|
||||
return NULL;
|
||||
|
||||
new_script->filename = strdup (filename);
|
||||
new_script->interpreter = NULL;
|
||||
new_script->name = strdup (name);
|
||||
new_script->author = strdup (author);
|
||||
new_script->version = strdup (version);
|
||||
new_script->license = strdup (license);
|
||||
new_script->description = strdup (description);
|
||||
new_script->shutdown_func = (shutdown_func) ?
|
||||
strdup (shutdown_func) : NULL;
|
||||
new_script->charset = (charset) ? strdup (charset) : NULL;
|
||||
new_script->unloading = 0;
|
||||
new_script->prev_script = NULL;
|
||||
new_script->next_script = NULL;
|
||||
|
||||
return new_script;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a script to list of scripts.
|
||||
*
|
||||
@@ -743,32 +791,25 @@ plugin_script_add (struct t_weechat_plugin *weechat_plugin,
|
||||
license, name, weechat_plugin->license);
|
||||
}
|
||||
|
||||
new_script = malloc (sizeof (*new_script));
|
||||
if (new_script)
|
||||
new_script = plugin_script_alloc (filename, name, author, version, license,
|
||||
description, shutdown_func, charset);
|
||||
if (!new_script)
|
||||
{
|
||||
new_script->filename = strdup (filename);
|
||||
new_script->interpreter = NULL;
|
||||
new_script->name = strdup (name);
|
||||
new_script->author = strdup (author);
|
||||
new_script->version = strdup (version);
|
||||
new_script->license = strdup (license);
|
||||
new_script->description = strdup (description);
|
||||
new_script->shutdown_func = (shutdown_func) ?
|
||||
strdup (shutdown_func) : NULL;
|
||||
new_script->charset = (charset) ? strdup (charset) : NULL;
|
||||
new_script->unloading = 0;
|
||||
|
||||
plugin_script_insert_sorted (weechat_plugin, scripts, last_script,
|
||||
new_script);
|
||||
|
||||
return new_script;
|
||||
weechat_printf (NULL,
|
||||
_("%s: error loading script \"%s\" "
|
||||
"(not enough memory)"),
|
||||
weechat_plugin->name, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
weechat_printf (NULL,
|
||||
_("%s: error loading script \"%s\" (not enough memory)"),
|
||||
weechat_plugin->name, name);
|
||||
/* add script to the list (except the internal "eval" fake script) */
|
||||
if (strcmp (new_script->name, WEECHAT_SCRIPT_EVAL_NAME) != 0)
|
||||
{
|
||||
plugin_script_insert_sorted (weechat_plugin, scripts, last_script,
|
||||
new_script);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return new_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -997,6 +1038,33 @@ plugin_script_remove_configs (struct t_weechat_plugin *weechat_plugin,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees a script.
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_script_free (struct t_plugin_script *script)
|
||||
{
|
||||
if (script->filename)
|
||||
free (script->filename);
|
||||
if (script->name)
|
||||
free (script->name);
|
||||
if (script->author)
|
||||
free (script->author);
|
||||
if (script->version)
|
||||
free (script->version);
|
||||
if (script->license)
|
||||
free (script->license);
|
||||
if (script->description)
|
||||
free (script->description);
|
||||
if (script->shutdown_func)
|
||||
free (script->shutdown_func);
|
||||
if (script->charset)
|
||||
free (script->charset);
|
||||
|
||||
free (script);
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes a script from list of scripts.
|
||||
*/
|
||||
@@ -1018,24 +1086,6 @@ plugin_script_remove (struct t_weechat_plugin *weechat_plugin,
|
||||
/* remove all hooks created by this script */
|
||||
weechat_unhook_all (script->name);
|
||||
|
||||
/* free data */
|
||||
if (script->filename)
|
||||
free (script->filename);
|
||||
if (script->name)
|
||||
free (script->name);
|
||||
if (script->author)
|
||||
free (script->author);
|
||||
if (script->version)
|
||||
free (script->version);
|
||||
if (script->license)
|
||||
free (script->license);
|
||||
if (script->description)
|
||||
free (script->description);
|
||||
if (script->shutdown_func)
|
||||
free (script->shutdown_func);
|
||||
if (script->charset)
|
||||
free (script->charset);
|
||||
|
||||
/* remove script from list */
|
||||
if (script->prev_script)
|
||||
(script->prev_script)->next_script = script->next_script;
|
||||
@@ -1046,8 +1096,8 @@ plugin_script_remove (struct t_weechat_plugin *weechat_plugin,
|
||||
if (*last_script == script)
|
||||
*last_script = script->prev_script;
|
||||
|
||||
/* free script */
|
||||
free (script);
|
||||
/* free data and script */
|
||||
plugin_script_free (script);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1189,7 +1239,8 @@ void
|
||||
plugin_script_action_install (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *scripts,
|
||||
void (*script_unload)(struct t_plugin_script *script),
|
||||
int (*script_load)(const char *filename),
|
||||
struct t_plugin_script *(*script_load)(const char *filename,
|
||||
const char *code),
|
||||
int *quiet,
|
||||
char **list)
|
||||
{
|
||||
@@ -1302,7 +1353,7 @@ plugin_script_action_install (struct t_weechat_plugin *weechat_plugin,
|
||||
* - script was loaded
|
||||
*/
|
||||
if ((!existing_script && autoload) || script_loaded)
|
||||
(*script_load) (new_path);
|
||||
(*script_load) (new_path, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -27,10 +27,13 @@ enum t_weechat_script_exec_type
|
||||
WEECHAT_SCRIPT_EXEC_INT = 0,
|
||||
WEECHAT_SCRIPT_EXEC_STRING,
|
||||
WEECHAT_SCRIPT_EXEC_HASHTABLE,
|
||||
WEECHAT_SCRIPT_EXEC_IGNORE,
|
||||
};
|
||||
|
||||
#define WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE 16
|
||||
|
||||
#define WEECHAT_SCRIPT_EVAL_NAME "__eval__"
|
||||
|
||||
#define WEECHAT_SCRIPT_MSG_NOT_INIT(__current_script, \
|
||||
__function) \
|
||||
weechat_printf (NULL, \
|
||||
@@ -78,6 +81,10 @@ struct t_plugin_script_init
|
||||
struct t_hdata *(*callback_hdata)(const void *pointer,
|
||||
void *data,
|
||||
const char *hdata_name);
|
||||
const char *(*callback_info_eval)(const void *pointer,
|
||||
void *data,
|
||||
const char *info_name,
|
||||
const char *arguments);
|
||||
struct t_infolist *(*callback_infolist)(const void *pointer,
|
||||
void *data,
|
||||
const char *infolist_name,
|
||||
@@ -119,13 +126,25 @@ extern struct t_plugin_script *plugin_script_search (struct t_weechat_plugin *we
|
||||
const char *name);
|
||||
extern char *plugin_script_search_path (struct t_weechat_plugin *weechat_plugin,
|
||||
const char *filename);
|
||||
extern struct t_plugin_script *plugin_script_alloc (const char *filename,
|
||||
const char *name,
|
||||
const char *author,
|
||||
const char *version,
|
||||
const char *license,
|
||||
const char *description,
|
||||
const char *shutdown_func,
|
||||
const char *charset);
|
||||
extern struct t_plugin_script *plugin_script_add (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script **scripts,
|
||||
struct t_plugin_script **last_script,
|
||||
const char *filename, const char *name,
|
||||
const char *author, const char *version,
|
||||
const char *license, const char *description,
|
||||
const char *shutdown_func, const char *charset);
|
||||
const char *filename,
|
||||
const char *name,
|
||||
const char *author,
|
||||
const char *version,
|
||||
const char *license,
|
||||
const char *description,
|
||||
const char *shutdown_func,
|
||||
const char *charset);
|
||||
extern void plugin_script_set_buffer_callbacks (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *scripts,
|
||||
struct t_plugin_script *script,
|
||||
@@ -136,6 +155,7 @@ extern void plugin_script_set_buffer_callbacks (struct t_weechat_plugin *weechat
|
||||
int (*callback_buffer_close) (const void *pointer,
|
||||
void *data,
|
||||
struct t_gui_buffer *buffer));
|
||||
extern void plugin_script_free (struct t_plugin_script *script);
|
||||
extern void plugin_script_remove (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script **scripts,
|
||||
struct t_plugin_script **last_script,
|
||||
@@ -147,7 +167,8 @@ extern void plugin_script_action_add (char **action_list, const char *name);
|
||||
extern void plugin_script_action_install (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *scripts,
|
||||
void (*script_unload)(struct t_plugin_script *script),
|
||||
int (*script_load)(const char *filename),
|
||||
struct t_plugin_script *(*script_load)(const char *filename,
|
||||
const char *code),
|
||||
int *quiet,
|
||||
char **list);
|
||||
extern void plugin_script_action_remove (struct t_weechat_plugin *weechat_plugin,
|
||||
|
||||
+411
-175
@@ -44,7 +44,23 @@ WEECHAT_PLUGIN_PRIORITY(4000);
|
||||
|
||||
struct t_weechat_plugin *weechat_python_plugin = NULL;
|
||||
|
||||
int python_quiet;
|
||||
int python_quiet = 0;
|
||||
|
||||
struct t_plugin_script *python_script_eval = NULL;
|
||||
int python_eval_mode = 0;
|
||||
int python_eval_send_input = 0;
|
||||
int python_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *python_eval_buffer = NULL;
|
||||
char *python_eval_output = NULL;
|
||||
#define PYTHON_EVAL_SCRIPT \
|
||||
"import weechat\n" \
|
||||
"\n" \
|
||||
"def script_python_eval(code):\n" \
|
||||
" exec(code)\n" \
|
||||
"\n" \
|
||||
"weechat.register('" WEECHAT_SCRIPT_EVAL_NAME "', '', '1.0', " \
|
||||
"'" WEECHAT_LICENSE "', 'Evaluation of script code', '', '')\n"
|
||||
|
||||
struct t_plugin_script *python_scripts = NULL;
|
||||
struct t_plugin_script *last_python_script = NULL;
|
||||
struct t_plugin_script *python_current_script = NULL;
|
||||
@@ -53,6 +69,7 @@ const char *python_current_script_filename = NULL;
|
||||
PyThreadState *python_mainThreadState = NULL;
|
||||
PyThreadState *python_current_interpreter = NULL;
|
||||
char *python2_bin = NULL;
|
||||
char **python_buffer_output = NULL;
|
||||
|
||||
/* outputs subroutines */
|
||||
static PyObject *weechat_python_output (PyObject *self, PyObject *args);
|
||||
@@ -111,8 +128,6 @@ char *python_action_remove_list = NULL;
|
||||
*/
|
||||
char *python_action_autoload_list = NULL;
|
||||
|
||||
char python_buffer_output[128];
|
||||
|
||||
|
||||
/*
|
||||
* Gets path to python 2.x interpreter.
|
||||
@@ -308,6 +323,102 @@ weechat_python_dict_to_hashtable (PyObject *dict, int size,
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flushes output.
|
||||
*/
|
||||
|
||||
void
|
||||
weechat_python_output_flush ()
|
||||
{
|
||||
const char *ptr_command;
|
||||
char *command;
|
||||
int length;
|
||||
|
||||
if (!*python_buffer_output[0])
|
||||
return;
|
||||
|
||||
if (python_eval_mode)
|
||||
{
|
||||
/* if there's no buffer, we catch the output, so there's no flush */
|
||||
if (!python_eval_buffer)
|
||||
return;
|
||||
|
||||
if (python_eval_send_input)
|
||||
{
|
||||
if (python_eval_exec_commands)
|
||||
ptr_command = *python_buffer_output;
|
||||
else
|
||||
ptr_command = weechat_string_input_for_buffer (*python_buffer_output);
|
||||
if (ptr_command)
|
||||
{
|
||||
weechat_command (python_eval_buffer, *python_buffer_output);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = 1 + strlen (*python_buffer_output) + 1;
|
||||
command = malloc (length);
|
||||
if (command)
|
||||
{
|
||||
snprintf (command, length, "%c%s",
|
||||
*python_buffer_output[0], *python_buffer_output);
|
||||
weechat_command (python_eval_buffer,
|
||||
(command[0]) ? command : " ");
|
||||
free (command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (python_eval_buffer, "%s", *python_buffer_output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* script (no eval mode) */
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s"),
|
||||
PYTHON_PLUGIN_NAME, *python_buffer_output);
|
||||
}
|
||||
|
||||
weechat_string_dyn_copy (python_buffer_output, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirection for stdout and stderr.
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
weechat_python_output (PyObject *self, PyObject *args)
|
||||
{
|
||||
char *msg, *ptr_msg, *ptr_newline;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) self;
|
||||
|
||||
msg = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple (args, "s", &msg))
|
||||
{
|
||||
weechat_python_output_flush ();
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_msg = msg;
|
||||
while ((ptr_newline = strchr (ptr_msg, '\n')) != NULL)
|
||||
{
|
||||
ptr_newline[0] = '\0';
|
||||
weechat_string_dyn_concat (python_buffer_output, ptr_msg);
|
||||
weechat_python_output_flush ();
|
||||
ptr_newline[0] = '\n';
|
||||
ptr_msg = ++ptr_newline;
|
||||
}
|
||||
weechat_string_dyn_concat (python_buffer_output, ptr_msg);
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes a python function.
|
||||
*/
|
||||
@@ -371,6 +482,8 @@ weechat_python_exec (struct t_plugin_script *script,
|
||||
rc = PyObject_CallFunction (evFunc, NULL);
|
||||
}
|
||||
|
||||
weechat_python_output_flush ();
|
||||
|
||||
/*
|
||||
* ugly hack : rc = NULL while 'return weechat.WEECHAT_RC_OK ....
|
||||
* because of '#define WEECHAT_RC_OK 0'
|
||||
@@ -414,17 +527,23 @@ weechat_python_exec (struct t_plugin_script *script,
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must return "
|
||||
"a valid value"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME, function);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
Py_XDECREF(rc);
|
||||
}
|
||||
|
||||
if (!ret_value)
|
||||
if ((ret_type != WEECHAT_SCRIPT_EXEC_IGNORE) && !ret_value)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: error in function \"%s\""),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME, function);
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
|
||||
/* PyEval_ReleaseThread (python_current_script->interpreter); */
|
||||
@@ -438,62 +557,6 @@ end:
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirection for stdout and stderr.
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
weechat_python_output (PyObject *self, PyObject *args)
|
||||
{
|
||||
char *msg, *m, *p;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) self;
|
||||
|
||||
msg = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple (args, "s", &msg))
|
||||
{
|
||||
if (strlen(python_buffer_output) > 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s%s"),
|
||||
PYTHON_PLUGIN_NAME, python_buffer_output, "");
|
||||
python_buffer_output[0] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m = msg;
|
||||
while ((p = strchr (m, '\n')) != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
if (strlen (m) + strlen (python_buffer_output) > 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s%s"),
|
||||
PYTHON_PLUGIN_NAME, python_buffer_output, m);
|
||||
}
|
||||
*p = '\n';
|
||||
python_buffer_output[0] = '\0';
|
||||
m = ++p;
|
||||
}
|
||||
|
||||
if (strlen(m) + strlen(python_buffer_output) > sizeof(python_buffer_output))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s%s"),
|
||||
PYTHON_PLUGIN_NAME, python_buffer_output, m);
|
||||
python_buffer_output[0] = '\0';
|
||||
}
|
||||
else
|
||||
strcat (python_buffer_output, m);
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the "weechat" module.
|
||||
*/
|
||||
@@ -582,32 +645,82 @@ void weechat_python_init_module_weechat ()
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a python script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* Sets weechat output (to redirect stdout/stderr to WeeChat buffer).
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_python_load (const char *filename)
|
||||
void
|
||||
weechat_python_set_output ()
|
||||
{
|
||||
PyObject *weechat_outputs;
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
/* python >= 3.x */
|
||||
weechat_outputs = PyModule_Create (&moduleDefOutputs);
|
||||
#else
|
||||
/* python <= 2.x */
|
||||
weechat_outputs = Py_InitModule("weechatOutputs",
|
||||
weechat_python_output_funcs);
|
||||
#endif /* PY_MAJOR_VERSION >= 3 */
|
||||
|
||||
if (weechat_outputs)
|
||||
{
|
||||
if (PySys_SetObject("stdout", weechat_outputs) == -1)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to redirect stdout"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
}
|
||||
if (PySys_SetObject("stderr", weechat_outputs) == -1)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to redirect stderr"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to redirect stdout and "
|
||||
"stderr"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a python script.
|
||||
*
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
struct t_plugin_script *
|
||||
weechat_python_load (const char *filename, const char *code)
|
||||
{
|
||||
char *argv[] = { "__weechat_plugin__" , NULL };
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
wchar_t *wargv[] = { NULL, NULL };
|
||||
#endif /* PY_MAJOR_VERSION >= 3 */
|
||||
FILE *fp;
|
||||
PyObject *weechat_outputs, *python_path, *path;
|
||||
PyObject *python_path, *path, *module_main, *globals, *rc;
|
||||
const char *weechat_home;
|
||||
char *str_home;
|
||||
int len;
|
||||
|
||||
if ((fp = fopen (filename, "r")) == NULL)
|
||||
fp = NULL;
|
||||
|
||||
if (!code)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
fp = fopen (filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME,
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((weechat_python_plugin->debug >= 2) || !python_quiet)
|
||||
@@ -648,9 +761,10 @@ weechat_python_load (const char *filename)
|
||||
weechat_gettext ("%s%s: unable to create new "
|
||||
"sub-interpreter"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
fclose (fp);
|
||||
if (fp)
|
||||
fclose (fp);
|
||||
/* PyEval_ReleaseLock (); */
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyThreadState_Swap (python_current_interpreter);
|
||||
@@ -681,70 +795,76 @@ weechat_python_load (const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
/* python >= 3.x */
|
||||
weechat_outputs = PyModule_Create (&moduleDefOutputs);
|
||||
#else
|
||||
/* python <= 2.x */
|
||||
weechat_outputs = Py_InitModule("weechatOutputs",
|
||||
weechat_python_output_funcs);
|
||||
#endif /* PY_MAJOR_VERSION >= 3 */
|
||||
|
||||
if (!weechat_outputs)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to redirect stdout and "
|
||||
"stderr"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PySys_SetObject("stdout", weechat_outputs) == -1)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to redirect stdout"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
}
|
||||
if (PySys_SetObject("stderr", weechat_outputs) == -1)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to redirect stderr"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
}
|
||||
}
|
||||
weechat_python_set_output ();
|
||||
|
||||
python_current_script_filename = filename;
|
||||
|
||||
if (PyRun_SimpleFile (fp, filename) != 0)
|
||||
if (code)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to parse file \"%s\""),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME, filename);
|
||||
fclose (fp);
|
||||
|
||||
/* execute code without reading file */
|
||||
module_main = PyImport_AddModule ("__main__");
|
||||
globals = PyModule_GetDict (module_main);
|
||||
rc = PyRun_String (code, Py_file_input, globals, NULL);
|
||||
if (PyErr_Occurred ())
|
||||
PyErr_Print ();
|
||||
|
||||
/* if script was registered, remove it from list */
|
||||
if (python_current_script)
|
||||
{
|
||||
plugin_script_remove (weechat_python_plugin,
|
||||
&python_scripts, &last_python_script,
|
||||
python_current_script);
|
||||
python_current_script = NULL;
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to create eval script"),
|
||||
weechat_prefix ("error"),
|
||||
PYTHON_PLUGIN_NAME);
|
||||
PyErr_Print ();
|
||||
if (rc)
|
||||
Py_XDECREF(rc);
|
||||
|
||||
/* if script was registered, remove it from list */
|
||||
if (python_current_script)
|
||||
{
|
||||
plugin_script_remove (weechat_python_plugin,
|
||||
&python_scripts, &last_python_script,
|
||||
python_current_script);
|
||||
python_current_script = NULL;
|
||||
}
|
||||
|
||||
Py_EndInterpreter (python_current_interpreter);
|
||||
/* PyEval_ReleaseLock (); */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
if (rc)
|
||||
Py_XDECREF(rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read and execute code from file */
|
||||
if (PyRun_SimpleFile (fp, filename) != 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to parse file \"%s\""),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME, filename);
|
||||
fclose (fp);
|
||||
|
||||
Py_EndInterpreter (python_current_interpreter);
|
||||
/* PyEval_ReleaseLock (); */
|
||||
if (PyErr_Occurred ())
|
||||
PyErr_Print ();
|
||||
|
||||
return 0;
|
||||
/* if script was registered, remove it from list */
|
||||
if (python_current_script)
|
||||
{
|
||||
plugin_script_remove (weechat_python_plugin,
|
||||
&python_scripts, &last_python_script,
|
||||
python_current_script);
|
||||
python_current_script = NULL;
|
||||
}
|
||||
|
||||
Py_EndInterpreter (python_current_interpreter);
|
||||
/* PyEval_ReleaseLock (); */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
if (PyErr_Occurred ())
|
||||
PyErr_Print ();
|
||||
|
||||
fclose (fp);
|
||||
|
||||
if (!python_registered_script)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
@@ -757,7 +877,7 @@ weechat_python_load (const char *filename)
|
||||
Py_EndInterpreter (python_current_interpreter);
|
||||
/* PyEval_ReleaseLock (); */
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
python_current_script = python_registered_script;
|
||||
|
||||
@@ -777,7 +897,7 @@ weechat_python_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
python_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return python_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -790,7 +910,7 @@ weechat_python_load_cb (void *data, const char *filename)
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_python_load (filename);
|
||||
weechat_python_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -910,7 +1030,7 @@ weechat_python_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
PYTHON_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_python_load (filename);
|
||||
weechat_python_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -922,6 +1042,56 @@ weechat_python_reload_name (const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates python code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_python_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
void *func_argv[1], *result;
|
||||
|
||||
if (!python_script_eval)
|
||||
{
|
||||
python_quiet = 1;
|
||||
python_script_eval = weechat_python_load (WEECHAT_SCRIPT_EVAL_NAME,
|
||||
PYTHON_EVAL_SCRIPT);
|
||||
python_quiet = 0;
|
||||
if (!python_script_eval)
|
||||
return 0;
|
||||
}
|
||||
|
||||
weechat_python_output_flush ();
|
||||
|
||||
python_eval_mode = 1;
|
||||
python_eval_send_input = send_to_buffer_as_input;
|
||||
python_eval_exec_commands = exec_commands;
|
||||
python_eval_buffer = buffer;
|
||||
|
||||
func_argv[0] = (char *)code;
|
||||
result = weechat_python_exec (python_script_eval,
|
||||
WEECHAT_SCRIPT_EXEC_IGNORE,
|
||||
"script_python_eval",
|
||||
"s", func_argv);
|
||||
/* result is ignored */
|
||||
if (result)
|
||||
free (result);
|
||||
|
||||
weechat_python_output_flush ();
|
||||
|
||||
python_eval_mode = 0;
|
||||
python_eval_send_input = 0;
|
||||
python_eval_exec_commands = 0;
|
||||
python_eval_buffer = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/python".
|
||||
*/
|
||||
@@ -931,12 +1101,12 @@ weechat_python_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -1006,7 +1176,8 @@ weechat_python_command_cb (const void *pointer, void *data,
|
||||
/* load python script */
|
||||
path_script = plugin_script_search_path (weechat_python_plugin,
|
||||
ptr_name);
|
||||
weechat_python_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_python_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -1022,6 +1193,39 @@ weechat_python_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
python_quiet = 0;
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!weechat_python_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
@@ -1050,40 +1254,6 @@ weechat_python_completion_cb (const void *pointer, void *data,
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns python info.
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_python_info_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
int rc;
|
||||
struct stat stat_buf;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) arguments;
|
||||
|
||||
if (weechat_strcasecmp (info_name, "python2_bin") == 0)
|
||||
{
|
||||
if (python2_bin && (strcmp (python2_bin, "python") != 0))
|
||||
{
|
||||
rc = stat (python2_bin, &stat_buf);
|
||||
if ((rc != 0) || (!S_ISREG(stat_buf.st_mode)))
|
||||
{
|
||||
free (python2_bin);
|
||||
python2_bin = weechat_python_get_python2_bin ();
|
||||
}
|
||||
}
|
||||
return python2_bin;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns hdata for python scripts.
|
||||
*/
|
||||
@@ -1101,6 +1271,59 @@ weechat_python_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns python info "python2_bin".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_python_info_python2_bin_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
int rc;
|
||||
struct stat stat_buf;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
(void) arguments;
|
||||
|
||||
if (python2_bin && (strcmp (python2_bin, "python") != 0))
|
||||
{
|
||||
rc = stat (python2_bin, &stat_buf);
|
||||
if ((rc != 0) || (!S_ISREG(stat_buf.st_mode)))
|
||||
{
|
||||
free (python2_bin);
|
||||
python2_bin = weechat_python_get_python2_bin ();
|
||||
}
|
||||
}
|
||||
return python2_bin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns python info "python_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_python_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
weechat_python_eval (NULL, 0, 0, (arguments) ? arguments : "");
|
||||
if (python_eval_output)
|
||||
free (python_eval_output);
|
||||
python_eval_output = strdup (*python_buffer_output);
|
||||
weechat_string_dyn_copy (python_buffer_output, NULL);
|
||||
|
||||
return python_eval_output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with python scripts.
|
||||
*/
|
||||
@@ -1262,6 +1485,11 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
"");
|
||||
#endif /* PY_VERSION */
|
||||
|
||||
/* init stdout/stderr buffer */
|
||||
python_buffer_output = weechat_string_dyn_alloc (256);
|
||||
if (!python_buffer_output)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
/*
|
||||
* hook info to get path to python 2.x interpreter
|
||||
* (some scripts using hook_process need that)
|
||||
@@ -1270,10 +1498,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
weechat_hook_info ("python2_bin",
|
||||
N_("path to python 2.x interpreter"),
|
||||
NULL,
|
||||
&weechat_python_info_cb, NULL, NULL);
|
||||
|
||||
/* init stdout/stderr buffer */
|
||||
python_buffer_output[0] = '\0';
|
||||
&weechat_python_info_python2_bin_cb, NULL, NULL);
|
||||
|
||||
PyImport_AppendInittab("weechat",
|
||||
&weechat_python_init_module_weechat);
|
||||
@@ -1285,6 +1510,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
weechat_gettext ("%s%s: unable to launch global "
|
||||
"interpreter"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
weechat_string_dyn_free (python_buffer_output, 1);
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
@@ -1299,12 +1525,14 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
weechat_gettext ("%s%s: unable to get current "
|
||||
"interpreter state"),
|
||||
weechat_prefix ("error"), PYTHON_PLUGIN_NAME);
|
||||
weechat_string_dyn_free (python_buffer_output, 1);
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
init.callback_command = &weechat_python_command_cb;
|
||||
init.callback_completion = &weechat_python_completion_cb;
|
||||
init.callback_hdata = &weechat_python_hdata_cb;
|
||||
init.callback_info_eval = &weechat_python_info_eval_cb;
|
||||
init.callback_infolist = &weechat_python_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_python_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_python_signal_script_action_cb;
|
||||
@@ -1331,6 +1559,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
/* unload all scripts */
|
||||
python_quiet = 1;
|
||||
plugin_script_end (plugin, &python_scripts, &weechat_python_unload_all);
|
||||
if (python_script_eval)
|
||||
{
|
||||
weechat_python_unload (python_script_eval);
|
||||
python_script_eval = NULL;
|
||||
}
|
||||
python_quiet = 0;
|
||||
|
||||
/* free python interpreter */
|
||||
@@ -1359,6 +1592,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (python_action_remove_list);
|
||||
if (python_action_autoload_list)
|
||||
free (python_action_autoload_list);
|
||||
weechat_string_dyn_free (python_buffer_output, 1);
|
||||
if (python_eval_output)
|
||||
free (python_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
+306
-106
@@ -67,12 +67,31 @@ struct t_weechat_plugin *weechat_ruby_plugin = NULL;
|
||||
|
||||
int ruby_quiet = 0;
|
||||
int ruby_hide_errors = 0;
|
||||
|
||||
struct t_plugin_script *ruby_script_eval = NULL;
|
||||
int ruby_eval_mode = 0;
|
||||
int ruby_eval_send_input = 0;
|
||||
int ruby_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *ruby_eval_buffer = NULL;
|
||||
char *ruby_eval_output = NULL;
|
||||
#define RUBY_EVAL_SCRIPT \
|
||||
"def weechat_init\n" \
|
||||
" Weechat.register('" WEECHAT_SCRIPT_EVAL_NAME "', '', '1.0', " \
|
||||
"'" WEECHAT_LICENSE "', 'Evaluation of script code', '', '')\n" \
|
||||
" return Weechat::WEECHAT_RC_OK\n" \
|
||||
"end\n" \
|
||||
"\n" \
|
||||
"def script_ruby_eval(code)\n" \
|
||||
" module_eval(code)\n" \
|
||||
"end\n"
|
||||
|
||||
struct t_plugin_script *ruby_scripts = NULL;
|
||||
struct t_plugin_script *last_ruby_script = NULL;
|
||||
struct t_plugin_script *ruby_current_script = NULL;
|
||||
struct t_plugin_script *ruby_registered_script = NULL;
|
||||
const char *ruby_current_script_filename = NULL;
|
||||
VALUE ruby_current_module;
|
||||
char **ruby_buffer_output = NULL;
|
||||
|
||||
/*
|
||||
* string used to execute action "install":
|
||||
@@ -103,8 +122,6 @@ VALUE ruby_mWeechat, ruby_mWeechatOutputs;
|
||||
#define MOD_NAME_PREFIX "WeechatRubyModule"
|
||||
int ruby_num = 0;
|
||||
|
||||
char ruby_buffer_output[128];
|
||||
|
||||
typedef struct protect_call_arg {
|
||||
VALUE recv;
|
||||
ID mid;
|
||||
@@ -318,6 +335,114 @@ weechat_ruby_print_exception (VALUE err)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function used for compatibility.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
weechat_ruby_output_flush_ruby (VALUE self)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) self;
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flushes output.
|
||||
*/
|
||||
|
||||
void
|
||||
weechat_ruby_output_flush ()
|
||||
{
|
||||
const char *ptr_command;
|
||||
char *command;
|
||||
int length;
|
||||
|
||||
if (!*ruby_buffer_output[0])
|
||||
return;
|
||||
|
||||
if (ruby_eval_mode)
|
||||
{
|
||||
/* if there's no buffer, we catch the output, so there's no flush */
|
||||
if (!ruby_eval_buffer)
|
||||
return;
|
||||
|
||||
if (ruby_eval_send_input)
|
||||
{
|
||||
if (ruby_eval_exec_commands)
|
||||
ptr_command = *ruby_buffer_output;
|
||||
else
|
||||
ptr_command = weechat_string_input_for_buffer (*ruby_buffer_output);
|
||||
if (ptr_command)
|
||||
{
|
||||
weechat_command (ruby_eval_buffer, *ruby_buffer_output);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = 1 + strlen (*ruby_buffer_output) + 1;
|
||||
command = malloc (length);
|
||||
if (command)
|
||||
{
|
||||
snprintf (command, length, "%c%s",
|
||||
*ruby_buffer_output[0], *ruby_buffer_output);
|
||||
weechat_command (ruby_eval_buffer,
|
||||
(command[0]) ? command : " ");
|
||||
free (command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (ruby_eval_buffer, "%s", *ruby_buffer_output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* script (no eval mode) */
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s: stdout/stderr: %s"),
|
||||
RUBY_PLUGIN_NAME, *ruby_buffer_output);
|
||||
}
|
||||
|
||||
weechat_string_dyn_copy (ruby_buffer_output, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirection for stdout and stderr.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
weechat_ruby_output (VALUE self, VALUE str)
|
||||
{
|
||||
char *msg, *m, *p;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) self;
|
||||
|
||||
if (ruby_hide_errors)
|
||||
return Qnil;
|
||||
|
||||
msg = strdup (StringValuePtr (str));
|
||||
|
||||
m = msg;
|
||||
while ((p = strchr (m, '\n')) != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
weechat_string_dyn_concat (ruby_buffer_output, m);
|
||||
weechat_ruby_output_flush ();
|
||||
*p = '\n';
|
||||
m = ++p;
|
||||
}
|
||||
|
||||
weechat_string_dyn_concat (ruby_buffer_output, m);
|
||||
|
||||
if (msg)
|
||||
free (msg);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes a ruby function.
|
||||
*/
|
||||
@@ -333,6 +458,8 @@ weechat_ruby_exec (struct t_plugin_script *script,
|
||||
void *ret_value;
|
||||
struct t_plugin_script *old_ruby_current_script;
|
||||
|
||||
ret_value = NULL;
|
||||
|
||||
old_ruby_current_script = ruby_current_script;
|
||||
ruby_current_script = script;
|
||||
|
||||
@@ -370,6 +497,8 @@ weechat_ruby_exec (struct t_plugin_script *script,
|
||||
&ruby_error, 0, NULL);
|
||||
}
|
||||
|
||||
weechat_ruby_output_flush ();
|
||||
|
||||
if (ruby_error)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
@@ -405,22 +534,21 @@ weechat_ruby_exec (struct t_plugin_script *script,
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must return a "
|
||||
"valid value"),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME, function);
|
||||
ruby_current_script = old_ruby_current_script;
|
||||
return WEECHAT_RC_OK;
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret_value == NULL)
|
||||
if ((ret_type != WEECHAT_SCRIPT_EXEC_IGNORE) && !ret_value)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: not enough memory in function "
|
||||
"\"%s\""),
|
||||
weechat_gettext ("%s%s: error in function \"%s\""),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME, function);
|
||||
ruby_current_script = old_ruby_current_script;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ruby_current_script = old_ruby_current_script;
|
||||
@@ -428,91 +556,33 @@ weechat_ruby_exec (struct t_plugin_script *script,
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirection for stdout and stderr.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
weechat_ruby_output (VALUE self, VALUE str)
|
||||
{
|
||||
char *msg, *p, *m;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) self;
|
||||
|
||||
if (ruby_hide_errors)
|
||||
return Qnil;
|
||||
|
||||
msg = strdup(StringValuePtr(str));
|
||||
|
||||
m = msg;
|
||||
while ((p = strchr (m, '\n')) != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
if (strlen (m) + strlen (ruby_buffer_output) > 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: stdout/stderr: %s%s"),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME,
|
||||
ruby_buffer_output, m);
|
||||
}
|
||||
*p = '\n';
|
||||
ruby_buffer_output[0] = '\0';
|
||||
m = ++p;
|
||||
}
|
||||
|
||||
if (strlen(m) + strlen(ruby_buffer_output) > sizeof(ruby_buffer_output))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: stdout/stderr: %s%s"),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME,
|
||||
ruby_buffer_output, m);
|
||||
ruby_buffer_output[0] = '\0';
|
||||
}
|
||||
else
|
||||
strcat (ruby_buffer_output, m);
|
||||
|
||||
if (msg)
|
||||
free (msg);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function used for compatibility.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
weechat_ruby_output_flush (VALUE self)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) self;
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a ruby script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_ruby_load (const char *filename)
|
||||
struct t_plugin_script *
|
||||
weechat_ruby_load (const char *filename, const char *code)
|
||||
{
|
||||
char modname[64];
|
||||
VALUE ruby_retcode, err, argv[1];
|
||||
int ruby_error;
|
||||
struct stat buf;
|
||||
|
||||
if (stat (filename, &buf) != 0)
|
||||
if (!code)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
if (stat (filename, &buf) != 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME,
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((weechat_ruby_plugin->debug >= 2) || !ruby_quiet)
|
||||
@@ -533,15 +603,16 @@ weechat_ruby_load (const char *filename)
|
||||
ruby_current_script_filename = filename;
|
||||
|
||||
argv[0] = rb_str_new2 (filename);
|
||||
argv[1] = rb_str_new2 ((code) ? code : "");
|
||||
ruby_retcode = rb_protect_funcall (ruby_current_module,
|
||||
rb_intern ("load_eval_file"),
|
||||
&ruby_error, 1, argv);
|
||||
&ruby_error, 2, argv);
|
||||
|
||||
if (ruby_retcode == Qnil)
|
||||
{
|
||||
err = rb_gv_get("$!");
|
||||
weechat_ruby_print_exception(err);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (NUM2INT(ruby_retcode) != 0)
|
||||
@@ -578,7 +649,7 @@ weechat_ruby_load (const char *filename)
|
||||
"@load_eval_file_error"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void) rb_protect_funcall (ruby_current_module, rb_intern ("weechat_init"),
|
||||
@@ -602,7 +673,7 @@ weechat_ruby_load (const char *filename)
|
||||
ruby_current_script = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ruby_registered_script)
|
||||
@@ -611,7 +682,7 @@ weechat_ruby_load (const char *filename)
|
||||
weechat_gettext ("%s%s: function \"register\" not "
|
||||
"found (or failed) in file \"%s\""),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
ruby_current_script = ruby_registered_script;
|
||||
|
||||
@@ -631,7 +702,7 @@ weechat_ruby_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
ruby_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return ruby_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -644,7 +715,7 @@ weechat_ruby_load_cb (void *data, const char *filename)
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_ruby_load (filename);
|
||||
weechat_ruby_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -745,7 +816,7 @@ weechat_ruby_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
RUBY_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_ruby_load (filename);
|
||||
weechat_ruby_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -770,6 +841,57 @@ weechat_ruby_unload_all ()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates ruby code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_ruby_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
void *func_argv[1], *result;
|
||||
char empty_arg[1] = { '\0' };
|
||||
|
||||
if (!ruby_script_eval)
|
||||
{
|
||||
ruby_quiet = 1;
|
||||
ruby_script_eval = weechat_ruby_load (WEECHAT_SCRIPT_EVAL_NAME,
|
||||
RUBY_EVAL_SCRIPT);
|
||||
ruby_quiet = 0;
|
||||
if (!ruby_script_eval)
|
||||
return 0;
|
||||
}
|
||||
|
||||
weechat_ruby_output_flush ();
|
||||
|
||||
ruby_eval_mode = 1;
|
||||
ruby_eval_send_input = send_to_buffer_as_input;
|
||||
ruby_eval_exec_commands = exec_commands;
|
||||
ruby_eval_buffer = buffer;
|
||||
|
||||
func_argv[0] = (code) ? (char *)code : empty_arg;
|
||||
result = weechat_ruby_exec (ruby_script_eval,
|
||||
WEECHAT_SCRIPT_EXEC_IGNORE,
|
||||
"script_ruby_eval",
|
||||
"s", func_argv);
|
||||
/* result is ignored */
|
||||
if (result)
|
||||
free (result);
|
||||
|
||||
weechat_ruby_output_flush ();
|
||||
|
||||
ruby_eval_mode = 0;
|
||||
ruby_eval_send_input = 0;
|
||||
ruby_eval_exec_commands = 0;
|
||||
ruby_eval_buffer = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/ruby".
|
||||
*/
|
||||
@@ -779,12 +901,12 @@ weechat_ruby_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -854,7 +976,8 @@ weechat_ruby_command_cb (const void *pointer, void *data,
|
||||
/* load ruby script */
|
||||
path_script = plugin_script_search_path (weechat_ruby_plugin,
|
||||
ptr_name);
|
||||
weechat_ruby_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_ruby_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -870,6 +993,39 @@ weechat_ruby_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
ruby_quiet = 0;
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!weechat_ruby_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
@@ -915,6 +1071,29 @@ weechat_ruby_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns ruby info "ruby_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_ruby_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
weechat_ruby_eval (NULL, 0, 0, (arguments) ? arguments : "");
|
||||
if (ruby_eval_output)
|
||||
free (ruby_eval_output);
|
||||
ruby_eval_output = strdup (*ruby_buffer_output);
|
||||
weechat_string_dyn_copy (ruby_buffer_output, NULL);
|
||||
|
||||
return ruby_eval_output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with ruby scripts.
|
||||
*/
|
||||
@@ -1061,6 +1240,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
{
|
||||
struct t_plugin_script_init init;
|
||||
int ruby_error;
|
||||
VALUE err;
|
||||
char *weechat_ruby_code = {
|
||||
"$stdout = WeechatOutputs\n"
|
||||
"$stderr = WeechatOutputs\n"
|
||||
@@ -1081,12 +1261,16 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
"\n"
|
||||
"class Module\n"
|
||||
"\n"
|
||||
" def load_eval_file (file)\n"
|
||||
" lines = ''\n"
|
||||
" begin\n"
|
||||
" lines = File.read(file)\n"
|
||||
" rescue => e\n"
|
||||
" return 1\n"
|
||||
" def load_eval_file (file, code)\n"
|
||||
" if !code.empty?\n"
|
||||
" lines = code\n"
|
||||
" else\n"
|
||||
" lines = ''\n"
|
||||
" begin\n"
|
||||
" lines = File.read(file)\n"
|
||||
" rescue => e\n"
|
||||
" return 1\n"
|
||||
" end\n"
|
||||
" end\n"
|
||||
"\n"
|
||||
" begin\n"
|
||||
@@ -1113,6 +1297,10 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
"\n"
|
||||
" return 0\n"
|
||||
" end\n"
|
||||
"\n"
|
||||
" def eval_code (code)\n"
|
||||
" module_eval(code)\n"
|
||||
" end\n"
|
||||
"end\n"
|
||||
};
|
||||
|
||||
@@ -1132,7 +1320,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
ruby_error = 0;
|
||||
|
||||
/* init stdout/stderr buffer */
|
||||
ruby_buffer_output[0] = '\0';
|
||||
ruby_buffer_output = weechat_string_dyn_alloc (256);
|
||||
if (!ruby_buffer_output)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
#if (defined(RUBY_API_VERSION_MAJOR) && defined(RUBY_API_VERSION_MINOR)) && (RUBY_API_VERSION_MAJOR >= 2 || (RUBY_API_VERSION_MAJOR == 1 && RUBY_API_VERSION_MINOR >= 9))
|
||||
RUBY_INIT_STACK;
|
||||
@@ -1149,7 +1339,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
rb_define_singleton_method (ruby_mWeechatOutputs, "p",
|
||||
weechat_ruby_output, 1);
|
||||
rb_define_singleton_method (ruby_mWeechatOutputs, "flush",
|
||||
weechat_ruby_output_flush, 0);
|
||||
weechat_ruby_output_flush_ruby, 0);
|
||||
|
||||
ruby_script ("__weechat_plugin__");
|
||||
|
||||
@@ -1163,8 +1353,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
weechat_gettext ("%s%s: unable to eval WeeChat ruby "
|
||||
"internal code"),
|
||||
weechat_prefix ("error"), RUBY_PLUGIN_NAME);
|
||||
VALUE err = rb_gv_get ("$!");
|
||||
err = rb_gv_get ("$!");
|
||||
weechat_ruby_print_exception (err);
|
||||
weechat_string_dyn_free (ruby_buffer_output, 1);
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
@@ -1173,6 +1364,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
init.callback_command = &weechat_ruby_command_cb;
|
||||
init.callback_completion = &weechat_ruby_completion_cb;
|
||||
init.callback_hdata = &weechat_ruby_hdata_cb;
|
||||
init.callback_info_eval = &weechat_ruby_info_eval_cb;
|
||||
init.callback_infolist = &weechat_ruby_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_ruby_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_ruby_signal_script_action_cb;
|
||||
@@ -1199,6 +1391,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
/* unload all scripts */
|
||||
ruby_quiet = 1;
|
||||
plugin_script_end (plugin, &ruby_scripts, &weechat_ruby_unload_all);
|
||||
if (ruby_script_eval)
|
||||
{
|
||||
weechat_ruby_unload (ruby_script_eval);
|
||||
ruby_script_eval = NULL;
|
||||
}
|
||||
ruby_quiet = 0;
|
||||
|
||||
ruby_cleanup (0);
|
||||
@@ -1210,6 +1407,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (ruby_action_remove_list);
|
||||
if (ruby_action_autoload_list)
|
||||
free (ruby_action_autoload_list);
|
||||
weechat_string_dyn_free (ruby_buffer_output, 1);
|
||||
if (ruby_eval_output)
|
||||
free (ruby_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
+129
-23
@@ -45,6 +45,14 @@ WEECHAT_PLUGIN_PRIORITY(4000);
|
||||
struct t_weechat_plugin *weechat_tcl_plugin = NULL;
|
||||
|
||||
int tcl_quiet = 0;
|
||||
|
||||
struct t_plugin_script *tcl_script_eval = NULL;
|
||||
int tcl_eval_mode = 0;
|
||||
int tcl_eval_send_input = 0;
|
||||
int tcl_eval_exec_commands = 0;
|
||||
struct t_gui_buffer *tcl_eval_buffer = NULL;
|
||||
char *tcl_eval_output = NULL;
|
||||
|
||||
struct t_plugin_script *tcl_scripts = NULL;
|
||||
struct t_plugin_script *last_tcl_script = NULL;
|
||||
struct t_plugin_script *tcl_current_script = NULL;
|
||||
@@ -237,8 +245,9 @@ weechat_tcl_exec (struct t_plugin_script *script,
|
||||
|
||||
if (Tcl_EvalObjEx (interp, cmdlist, TCL_EVAL_DIRECT) == TCL_OK)
|
||||
{
|
||||
Tcl_ListObjReplace (interp, cmdlist, 0, llength, 0, NULL); /* remove elements, decrement their ref count */
|
||||
Tcl_DecrRefCount (cmdlist); /* -1 */
|
||||
/* remove elements, decrement their ref count */
|
||||
Tcl_ListObjReplace (interp, cmdlist, 0, llength, 0, NULL);
|
||||
Tcl_DecrRefCount (cmdlist); /* -1 */
|
||||
ret_val = NULL;
|
||||
if (ret_type == WEECHAT_SCRIPT_EXEC_STRING)
|
||||
{
|
||||
@@ -269,15 +278,21 @@ weechat_tcl_exec (struct t_plugin_script *script,
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must return a "
|
||||
"valid value"),
|
||||
weechat_prefix ("error"), TCL_PLUGIN_NAME, function);
|
||||
if (ret_type != WEECHAT_SCRIPT_EXEC_IGNORE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: function \"%s\" must "
|
||||
"return a valid value"),
|
||||
weechat_prefix ("error"), TCL_PLUGIN_NAME,
|
||||
function);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Tcl_ListObjReplace (interp, cmdlist, 0, llength, 0, NULL); /* remove elements, decrement their ref count */
|
||||
Tcl_DecrRefCount (cmdlist); /* -1 */
|
||||
/* remove elements, decrement their ref count */
|
||||
Tcl_ListObjReplace (interp, cmdlist, 0, llength, 0, NULL);
|
||||
Tcl_DecrRefCount (cmdlist); /* -1 */
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: unable to run function \"%s\": %s"),
|
||||
weechat_prefix ("error"), TCL_PLUGIN_NAME, function,
|
||||
@@ -290,13 +305,14 @@ weechat_tcl_exec (struct t_plugin_script *script,
|
||||
/*
|
||||
* Loads a tcl script.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* If code is NULL, the content of filename is read and executed.
|
||||
* If code is not NULL, it is executed (the file is not read).
|
||||
*
|
||||
* Returns pointer to new registered script, NULL if error.
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_tcl_load (const char *filename)
|
||||
struct t_plugin_script *
|
||||
weechat_tcl_load (const char *filename, const char *code)
|
||||
{
|
||||
int i;
|
||||
Tcl_Interp *interp;
|
||||
@@ -307,7 +323,7 @@ weechat_tcl_load (const char *filename)
|
||||
weechat_printf (NULL,
|
||||
weechat_gettext ("%s%s: script \"%s\" not found"),
|
||||
weechat_prefix ("error"), TCL_PLUGIN_NAME, filename);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((weechat_tcl_plugin->debug >= 2) || !tcl_quiet)
|
||||
@@ -325,7 +341,7 @@ weechat_tcl_load (const char *filename)
|
||||
weechat_gettext ("%s%s: unable to create new "
|
||||
"interpreter"),
|
||||
weechat_prefix ("error"), TCL_PLUGIN_NAME);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
tcl_current_script_filename = filename;
|
||||
|
||||
@@ -348,7 +364,7 @@ weechat_tcl_load (const char *filename)
|
||||
tcl_current_script = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!tcl_registered_script)
|
||||
@@ -358,7 +374,7 @@ weechat_tcl_load (const char *filename)
|
||||
"found (or failed) in file \"%s\""),
|
||||
weechat_prefix ("error"), TCL_PLUGIN_NAME, filename);
|
||||
Tcl_DeleteInterp (interp);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
tcl_current_script = tcl_registered_script;
|
||||
|
||||
@@ -376,7 +392,7 @@ weechat_tcl_load (const char *filename)
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
tcl_current_script->filename);
|
||||
|
||||
return 1;
|
||||
return tcl_current_script;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -389,7 +405,7 @@ weechat_tcl_load_cb (void *data, const char *filename)
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
weechat_tcl_load (filename);
|
||||
weechat_tcl_load (filename, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -501,7 +517,7 @@ weechat_tcl_reload_name (const char *name)
|
||||
weechat_gettext ("%s: script \"%s\" unloaded"),
|
||||
TCL_PLUGIN_NAME, name);
|
||||
}
|
||||
weechat_tcl_load (filename);
|
||||
weechat_tcl_load (filename, NULL);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
@@ -513,6 +529,27 @@ weechat_tcl_reload_name (const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates tcl code.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
weechat_tcl_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input,
|
||||
int exec_commands, const char *code)
|
||||
{
|
||||
/* TODO: implement tcl eval */
|
||||
(void) buffer;
|
||||
(void) send_to_buffer_as_input;
|
||||
(void) exec_commands;
|
||||
(void) code;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for command "/tcl".
|
||||
*/
|
||||
@@ -522,12 +559,12 @@ weechat_tcl_command_cb (const void *pointer, void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
char *ptr_name, *path_script;
|
||||
char *ptr_name, *ptr_code, *path_script;
|
||||
int i, send_to_buffer_as_input, exec_commands;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
@@ -597,7 +634,8 @@ weechat_tcl_command_cb (const void *pointer, void *data,
|
||||
/* load tcl script */
|
||||
path_script = plugin_script_search_path (weechat_tcl_plugin,
|
||||
ptr_name);
|
||||
weechat_tcl_load ((path_script) ? path_script : ptr_name);
|
||||
weechat_tcl_load ((path_script) ? path_script : ptr_name,
|
||||
NULL);
|
||||
if (path_script)
|
||||
free (path_script);
|
||||
}
|
||||
@@ -613,6 +651,43 @@ weechat_tcl_command_cb (const void *pointer, void *data,
|
||||
}
|
||||
tcl_quiet = 0;
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[1], "eval") == 0)
|
||||
{
|
||||
send_to_buffer_as_input = 0;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[2];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 0;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
else if (strcmp (argv[i], "-oc") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
send_to_buffer_as_input = 1;
|
||||
exec_commands = 1;
|
||||
ptr_code = argv_eol[i + 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!weechat_tcl_eval (buffer, send_to_buffer_as_input,
|
||||
exec_commands, ptr_code))
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
/* TODO: implement /tcl eval */
|
||||
weechat_printf (NULL,
|
||||
"%sCommand \"/tcl eval\" is not yet implemented",
|
||||
weechat_prefix ("error"));
|
||||
}
|
||||
else
|
||||
WEECHAT_COMMAND_ERROR;
|
||||
}
|
||||
@@ -658,6 +733,28 @@ weechat_tcl_hdata_cb (const void *pointer, void *data,
|
||||
hdata_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns tcl info "tcl_eval".
|
||||
*/
|
||||
|
||||
const char *
|
||||
weechat_tcl_info_eval_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
static const char *not_implemented = "not yet implemented";
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) info_name;
|
||||
|
||||
(void) arguments;
|
||||
return not_implemented;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns infolist with tcl scripts.
|
||||
*/
|
||||
@@ -820,6 +917,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
init.callback_command = &weechat_tcl_command_cb;
|
||||
init.callback_completion = &weechat_tcl_completion_cb;
|
||||
init.callback_hdata = &weechat_tcl_hdata_cb;
|
||||
init.callback_info_eval = &weechat_tcl_info_eval_cb;
|
||||
init.callback_infolist = &weechat_tcl_infolist_cb;
|
||||
init.callback_signal_debug_dump = &weechat_tcl_signal_debug_dump_cb;
|
||||
init.callback_signal_script_action = &weechat_tcl_signal_script_action_cb;
|
||||
@@ -846,6 +944,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
/* unload all scripts */
|
||||
tcl_quiet = 1;
|
||||
plugin_script_end (plugin, &tcl_scripts, &weechat_tcl_unload_all);
|
||||
if (tcl_script_eval)
|
||||
{
|
||||
weechat_tcl_unload (tcl_script_eval);
|
||||
tcl_script_eval = NULL;
|
||||
}
|
||||
tcl_quiet = 0;
|
||||
|
||||
/* free some data */
|
||||
@@ -855,6 +958,9 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
free (tcl_action_remove_list);
|
||||
if (tcl_action_autoload_list)
|
||||
free (tcl_action_autoload_list);
|
||||
/* weechat_string_dyn_free (tcl_buffer_output, 1); */
|
||||
if (tcl_eval_output)
|
||||
free (tcl_eval_output);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user