Index: plug-ins/script-fu/script-fu-text-console.c =================================================================== --- plug-ins/script-fu/script-fu-text-console.c (revision 23274) +++ plug-ins/script-fu/script-fu-text-console.c (working copy) @@ -42,7 +42,8 @@ script_fu_text_console_run (const gchar static GimpParam values[1]; /* Enable Script-Fu output */ - ts_set_output_file (stdout); + ts_register_output_func (ts_stdout_output_func, NULL); + ts_print_welcome (); /* Run the interface */ Index: plug-ins/script-fu/script-fu-scripts.c =================================================================== --- plug-ins/script-fu/script-fu-scripts.c (revision 23274) +++ plug-ins/script-fu/script-fu-scripts.c (working copy) @@ -41,6 +41,7 @@ #include "script-fu-intl.h" +#undef cons typedef struct { @@ -128,10 +129,9 @@ script_fu_find_scripts (const gchar *pat #if 1 /* ~~~~~ */ static pointer -my_err(scheme *sc, char *msg) +my_err (scheme *sc, char *msg) { - g_printerr (msg); - return sc->F; + return scheme_apply1 (sc, "throw", sc->vptr->cons (sc, sc->vptr->mk_string (sc, msg), sc->NIL)); } #endif @@ -663,10 +663,10 @@ script_fu_add_menu (scheme *sc, pointer } void -script_fu_error_msg (const gchar *command) +script_fu_error_msg (const gchar *command, const gchar *msg) { g_message (_("Error while executing\n%s\n\n%s"), - command, ts_get_error_msg ()); + command, msg); } @@ -680,12 +680,16 @@ script_fu_load_script (const GimpDatafil { gchar *command; gchar *escaped = g_strescape (file_data->filename, NULL); + GString *output; command = g_strdup_printf ("(load \"%s\")", escaped); g_free (escaped); + output = g_string_new (""); + ts_register_output_func (ts_gstring_output_func, output); if (ts_interpret_string (command)) - script_fu_error_msg (command); + script_fu_error_msg (command, output->str); + g_string_free (output, TRUE); #ifdef G_OS_WIN32 /* No, I don't know why, but this is @@ -844,6 +848,7 @@ script_fu_script_proc (const gchar GimpRunMode run_mode; SFScript *script; gint min_args = 0; + GString *output; run_mode = params[0].data.d_int32; @@ -1001,8 +1006,11 @@ script_fu_script_proc (const gchar command = g_string_free (s, FALSE); /* run the command through the interpreter */ + output = g_string_new (""); + ts_register_output_func (ts_gstring_output_func, output); if (ts_interpret_string (command)) - script_fu_error_msg (command); + script_fu_error_msg (command, output->str); + g_string_free (output, TRUE); g_free (command); } Index: plug-ins/script-fu/script-fu-scripts.h =================================================================== --- plug-ins/script-fu/script-fu-scripts.h (revision 23274) +++ plug-ins/script-fu/script-fu-scripts.h (working copy) @@ -22,6 +22,7 @@ void script_fu_find_scripts (const gchar *path); pointer script_fu_add_script (scheme *sc, pointer a); pointer script_fu_add_menu (scheme *sc, pointer a); -void script_fu_error_msg (const gchar *command); +void script_fu_error_msg (const gchar *command, + const gchar *msg); #endif /* __SCRIPT_FU_SCRIPTS__ */ Index: plug-ins/script-fu/script-fu-interface.c =================================================================== --- plug-ins/script-fu/script-fu-interface.c (revision 23274) +++ plug-ins/script-fu/script-fu-interface.c (working copy) @@ -762,7 +762,7 @@ static void script_fu_ok (SFScript *script) { gchar *escaped; - GString *s; + GString *s, *output; gchar *command; gchar buffer[G_ASCII_DTOSTR_BUF_SIZE]; gint i; @@ -897,9 +897,11 @@ script_fu_ok (SFScript *script) command = g_string_free (s, FALSE); - /* run the command through the interpreter */ + output = g_string_new (""); + ts_register_output_func (ts_gstring_output_func, output); if (ts_interpret_string (command)) - script_fu_error_msg (command); + script_fu_error_msg (command, output->str); + g_string_free (output, TRUE); g_free (command); } Index: plug-ins/script-fu/servertest.py =================================================================== --- plug-ins/script-fu/servertest.py (revision 0) +++ plug-ins/script-fu/servertest.py (revision 0) @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +import readline, socket, sys + +if len (sys.argv) == 1: + HOST = 'localhost' + PORT = 10008 +elif len (sys.argv) == 3: + HOST = sys.argv[1] + PORT = int (sys.argv[2]) +else: + print >> sys.stderr, "Usage: %s " % sys.argv[0] + print >> sys.stderr, " (if omitted connect to localhost, port 10008)" + sys.exit () + + +sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM) +sock.connect ((HOST, PORT)) + +try: + cmd = raw_input ("Script-Fu-Remote - Testclient\n> ") + + while len (cmd) > 0: + sock.send ('G%c%c%s' % (len (cmd) / 256, len (cmd) % 256, cmd)) + + data = "" + while len (data) < 4: + data += sock.recv (4 - len (data)) + + if len (data) >= 4: + if data[0] == 'G': + l = ord (data[2]) * 256 + ord (data[3]) + msg = "" + while len (msg) < l: + msg += sock.recv (l - len (msg)) + if ord (data[1]): + print "(ERR):", msg + else: + print " (OK):", msg + else: + print "invalid magic: %s\n" % data + else: + print "short response: %s\n" % data + cmd = raw_input ("> ") + +except EOFError: + print + +sock.close Index: plug-ins/script-fu/script-fu.c =================================================================== --- plug-ins/script-fu/script-fu.c (revision 23274) +++ plug-ins/script-fu/script-fu.c (working copy) @@ -178,8 +178,6 @@ script_fu_run (const gchar *name, path = script_fu_search_path (); - ts_set_console_mode (0); - /* Determine before we allow scripts to register themselves * whether this is the base, automatically installed script-fu extension */ Index: plug-ins/script-fu/script-fu-console.c =================================================================== --- plug-ins/script-fu/script-fu-console.c (revision 23274) +++ plug-ins/script-fu/script-fu-console.c (working copy) @@ -88,16 +88,10 @@ static gboolean script_fu_cc_key_functi GdkEventKey *event, ConsoleInterface *console); -static void script_fu_open_ts_console (void); -static void script_fu_close_ts_console (void); - - -/* - * Local variables - */ - -static GtkWidget *output = NULL; - +static void script_fu_output_to_console (TsOutputType type, + const gchar *text, + gint len, + gpointer user_data); /* * Function definitions @@ -112,12 +106,9 @@ script_fu_console_run (const gchar { static GimpParam values[1]; - script_fu_open_ts_console (); - + ts_set_print_flag (1); script_fu_console_interface (); - script_fu_close_ts_console (); - *nreturn_vals = 1; *return_vals = values; @@ -184,8 +175,6 @@ script_fu_console_interface (void) console->text_view = gtk_text_view_new_with_buffer (console->console); g_object_unref (console->console); - output = console->text_view; - gtk_text_view_set_editable (GTK_TEXT_VIEW (console->text_view), FALSE); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (console->text_view), GTK_WRAP_WORD); @@ -261,14 +250,14 @@ script_fu_console_interface (void) console->history = g_list_append (console->history, NULL); console->history_len = 1; + ts_register_output_func (script_fu_output_to_console, console); + gtk_widget_show (console->dialog); gtk_main (); g_source_remove (console->input_id); - output = NULL; - if (console->save_dialog) gtk_widget_destroy (console->save_dialog); @@ -521,21 +510,23 @@ script_fu_console_scroll_end (GtkWidget g_idle_add ((GSourceFunc) script_fu_console_idle_scroll_end, view); } -void -script_fu_output_to_console (const gchar *text, - gint len) +static void +script_fu_output_to_console (TsOutputType type, + const gchar *text, + gint len, + gpointer user_data) { - /* FIXME: This function needs to be passed a pointer to the console. - */ - if (output) + ConsoleInterface *console = user_data; + + if (console && console->text_view) { - GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (output)); + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (console->text_view)); GtkTextIter cursor; gtk_text_buffer_get_end_iter (buffer, &cursor); gtk_text_buffer_insert (buffer, &cursor, text, len); - script_fu_console_scroll_end (output); + script_fu_console_scroll_end (console->text_view); } } @@ -598,10 +589,15 @@ script_fu_cc_key_function (GtkWidget gtk_entry_set_text (GTK_ENTRY (console->cc), ""); if (ts_interpret_string (list->data) != 0) - gtk_text_buffer_insert_with_tags_by_name (console->console, &cursor, - ts_get_error_msg (), -1, - "emphasis", - NULL); + { + gtk_text_buffer_get_end_iter (console->console, &cursor); + /* + gtk_text_buffer_insert_with_tags_by_name (console->console, &cursor, + ts_get_error_msg (), -1, + "emphasis", + NULL); + */ + } gimp_displays_flush (); @@ -681,27 +677,6 @@ script_fu_cc_key_function (GtkWidget return FALSE; } -static void -script_fu_open_ts_console (void) -{ - ts_set_print_flag (1); - ts_set_console_mode (1); -} - -static void -script_fu_close_ts_console (void) -{ - FILE *output_file; - - ts_set_print_flag (0); - output_file = ts_get_output_file (); - - if (output_file != stdout) - fclose (output_file); - - ts_set_console_mode (0); -} - void script_fu_eval_run (const gchar *name, gint nparams, @@ -719,7 +694,7 @@ script_fu_eval_run (const gchar *na { case GIMP_RUN_NONINTERACTIVE: /* Disable Script-Fu output */ - ts_set_output_file (stdout); + /* FIXME - need a print handler here? */ if (ts_interpret_string (params[1].data.d_string) != 0) status = GIMP_PDB_EXECUTION_ERROR; break; Index: plug-ins/script-fu/script-fu-server.c =================================================================== --- plug-ins/script-fu/script-fu-server.c (revision 23274) +++ plug-ins/script-fu/script-fu-server.c (working copy) @@ -159,6 +159,7 @@ static FILE *server_log_file = NU static GHashTable *clients = NULL; static gboolean script_fu_done = FALSE; static gboolean server_mode = FALSE; +static GString *output = NULL; static ServerInterface sint = { @@ -417,6 +418,9 @@ server_start (gint port, progress = server_progress_install (); + output = g_string_new (""); + ts_register_output_func (ts_gstring_output_func, output); + server_log ("Script-Fu server initialized and listening...\n"); /* Loop until the server is finished */ @@ -441,6 +445,9 @@ server_start (gint port, } } + g_string_free (output, TRUE); + output = NULL; + server_progress_uninstall (progress); server_quit (); @@ -460,14 +467,15 @@ execute_command (SFCommand *cmd) server_log ("Processing request #%d\n", cmd->request_no); time (&clock1); + g_string_truncate (output, 0); + /* run the command */ if (ts_interpret_string (cmd->command) != 0) { error = TRUE; - response = ts_get_error_msg (); - response_len = strlen (response); - - server_log ("%s\n", response); + response = output->str; + response_len = strlen (output->str); + server_log ("%s\n", output->str); } else { Index: plug-ins/script-fu/script-fu-console.h =================================================================== --- plug-ins/script-fu/script-fu-console.h (revision 23274) +++ plug-ins/script-fu/script-fu-console.h (working copy) @@ -31,8 +31,5 @@ void script_fu_eval_run (cons gint *nreturn_vals, GimpParam **return_vals); -void script_fu_output_to_console (const gchar *text, - gint len); - #endif /* __SCRIPT_FU_CONSOLE__ */ Index: plug-ins/script-fu/scheme-wrapper.c =================================================================== --- plug-ins/script-fu/scheme-wrapper.c (revision 23274) +++ plug-ins/script-fu/scheme-wrapper.c (working copy) @@ -47,7 +47,8 @@ #include "scheme-wrapper.h" -static int ts_console_mode; +static ts_output_func ts_output_handler = NULL; +static gpointer ts_output_data = NULL; #undef cons @@ -188,27 +189,36 @@ struct named_constant const old_constant static scheme sc; -static FILE *ts_output; -/* wrapper functions */ -FILE * -ts_get_output_file (void) +void +ts_register_output_func (ts_output_func func, + gpointer user_data) { - return ts_output; + ts_output_handler = func; + ts_output_data = user_data; } void -ts_set_output_file (FILE *file) -{ - scheme_set_output_port_file (&sc, file); - ts_output = file; +ts_stdout_output_func (TsOutputType type, + const char *string, + int len, + gpointer user_data) +{ + if (len < 0) + len = strlen (string); + fprintf (stdout, "%*s", len, string); } void -ts_set_console_mode (int flag) +ts_gstring_output_func (TsOutputType type, + const char *string, + int len, + gpointer user_data) { - ts_console_mode = flag; + GString *gstr = (GString *) user_data; + + g_string_append (gstr, string); } void @@ -220,8 +230,8 @@ ts_set_print_flag (gint print_flag) void ts_print_welcome (void) { - fprintf (ts_output, "Welcome to TinyScheme, Version 1.38\n"); - fprintf (ts_output, "Copyright (c) Dimitrios Souflis\n"); + ts_output_string ("Welcome to TinyScheme, Version 1.38\n", -1); + ts_output_string ("Copyright (c) Dimitrios Souflis\n", -1); } void @@ -233,13 +243,6 @@ ts_interpret_stdin (void) gint ts_interpret_string (const gchar *expr) { - port *pt = sc.outport->_object._port; - - memset (sc.linebuff, '\0', LINESIZE); - pt->rep.string.curr = sc.linebuff; - /* Somewhere 'past_the_end' gets altered so it needs to be reset ~~~~~ */ - pt->rep.string.past_the_end = &sc.linebuff[LINESIZE-1]; - #if DEBUG_SCRIPTS sc.print_output = 1; sc.tracing = 1; @@ -250,12 +253,6 @@ ts_interpret_string (const gchar *expr) return sc.retcode; } -const char * -ts_get_error_msg (void) -{ - return sc.linebuff; -} - const gchar * ts_get_success_msg (void) { @@ -265,14 +262,15 @@ ts_get_success_msg (void) return "Success"; } -/* len is length of 'string' in bytes */ +/* len is length of 'string' in bytes or -1 for null terminated strings */ void ts_output_string (const char *string, int len) { - g_return_if_fail (len >= 0); + if (len < 0) + len = strlen (string); - if (len > 0 && ts_console_mode) - script_fu_output_to_console (string, len); + if (ts_output_handler && len > 0) + (* ts_output_handler) (TS_OUTPUT_NORMAL, string, len, ts_output_data); } @@ -296,11 +294,12 @@ tinyscheme_init (const gchar *path, } scheme_set_input_port_file (&sc, stdin); - ts_set_output_file (stdout); + scheme_set_output_port_file (&sc, stdout); + ts_register_output_func (ts_stdout_output_func, NULL); /* Initialize the TinyScheme extensions */ - init_ftx(&sc); - init_re(&sc); + init_ftx (&sc); + init_re (&sc); /* register in the interpreter the gimp functions and types. */ init_constants (); @@ -590,20 +589,8 @@ convert_string (gchar *str) static pointer my_err (char *msg, pointer a) { - if (ts_console_mode) - { - gchar *tmp = g_strdup_printf ("Error: %s\n", msg); - - script_fu_output_to_console (tmp, -1); - - g_free (tmp); - } - else - { - g_message (msg); - } - - return sc.NIL; + return scheme_apply1 (&sc, "throw", + sc.vptr->cons (&sc, sc.vptr->mk_string (&sc, msg), a)); } Index: plug-ins/script-fu/tinyscheme/scheme.c =================================================================== --- plug-ins/script-fu/tinyscheme/scheme.c (revision 23274) +++ plug-ins/script-fu/tinyscheme/scheme.c (working copy) @@ -1544,7 +1544,6 @@ static void backchar(scheme *sc, gunicha static void putchars(scheme *sc, const char *chars, int char_cnt) { int free_bytes; /* Space remaining in buffer (in bytes) */ int l; - char *s; port *pt=sc->outport->_object._port; if (char_cnt <= 0) @@ -1553,13 +1552,6 @@ static void putchars(scheme *sc, const c /* Get length of 'chars' in bytes */ char_cnt = g_utf8_offset_to_pointer(chars, (long)char_cnt) - chars; - if (sc->print_error) { - l = strlen(sc->linebuff); - s = &sc->linebuff[l]; - memcpy(s, chars, min(char_cnt, LINESIZE-l-1)); - return; - } - if(pt->kind&port_file) { #if STANDALONE fwrite(chars,1,char_cnt,pt->rep.stdio.file); @@ -3647,8 +3639,6 @@ static pointer opexe_4(scheme *sc, enum sc->args=cons(sc,mk_string(sc," -- "),sc->args); setimmutable(car(sc->args)); } - if (sc->print_error == 0) /* Reset buffer if not already */ - sc->linebuff[0] = '\0'; /* in error message output mode*/ sc->print_error = 1; putstr(sc, "Error: "); putstr(sc, strvalue(car(sc->args))); @@ -3964,8 +3954,7 @@ static pointer opexe_5(scheme *sc, enum s_return(sc,x); } default: - sprintf(sc->linebuff, "syntax error: illegal token %d", sc->tok); - Error_0(sc,sc->linebuff); + Error_0 (sc,"syntax error: illegal token"); } break; @@ -4695,6 +4684,19 @@ void scheme_apply0(scheme *sc, const cha Eval_Cycle(sc,OP_EVAL); } +pointer scheme_apply1(scheme *sc, const char *procname, pointer args) { + pointer carx=mk_symbol(sc,procname); + pointer cdrx=args; + + dump_stack_reset(sc); + sc->envir = sc->global_env; + sc->code = cons(sc,carx,cdrx); + sc->interactive_repl=0; + sc->retcode=0; + Eval_Cycle(sc,OP_EVAL); + return sc->NIL; + } + void scheme_call(scheme *sc, pointer func, pointer args) { dump_stack_reset(sc); sc->envir = sc->global_env; Index: plug-ins/script-fu/tinyscheme/scheme.h =================================================================== --- plug-ins/script-fu/tinyscheme/scheme.h (revision 23274) +++ plug-ins/script-fu/tinyscheme/scheme.h (working copy) @@ -129,6 +129,7 @@ SCHEME_EXPORT void scheme_set_output_por void scheme_set_output_port_string(scheme *sc, char *start, char *past_the_end); SCHEME_EXPORT void scheme_load_file(scheme *sc, FILE *fin); SCHEME_EXPORT void scheme_load_string(scheme *sc, const char *cmd); +void scheme_apply (scheme *sc, pointer code); void scheme_apply0(scheme *sc, const char *procname); SCHEME_EXPORT pointer scheme_apply1(scheme *sc, const char *procname, pointer); void scheme_set_external_data(scheme *sc, void *p); Index: plug-ins/script-fu/tinyscheme/scheme-private.h =================================================================== --- plug-ins/script-fu/tinyscheme/scheme-private.h (revision 23274) +++ plug-ins/script-fu/tinyscheme/scheme-private.h (working copy) @@ -117,7 +117,6 @@ char gc_verbose; /* if gc_verbos char no_memory; /* Whether mem. alloc. has failed */ #define LINESIZE 1024 -char linebuff[LINESIZE]; char strbuff[LINESIZE]; FILE *tmpfp; Index: plug-ins/script-fu/scheme-wrapper.h =================================================================== --- plug-ins/script-fu/scheme-wrapper.h (revision 23274) +++ plug-ins/script-fu/scheme-wrapper.h (working copy) @@ -19,15 +19,29 @@ #ifndef SCHEME_WRAPPER_H #define SCHEME_WRAPPER_H -FILE * ts_get_output_file (void); -void ts_set_output_file (FILE *file); +typedef enum { TS_OUTPUT_NORMAL, TS_OUTPUT_ERROR } TsOutputType; -void ts_set_console_mode (int flag); +typedef void (* ts_output_func) (TsOutputType type, + const char *string, + int len, + gpointer data); + +void ts_register_output_func (ts_output_func func, + gpointer user_data); + +void ts_stdout_output_func (TsOutputType type, + const char *string, + int len, + gpointer user_data); + +void ts_gstring_output_func (TsOutputType type, + const char *string, + int len, + gpointer user_data); void ts_set_print_flag (gint); void ts_print_welcome (void); -const gchar * ts_get_error_msg (void); const gchar * ts_get_success_msg (void); void tinyscheme_init (const gchar *path,