Index: plug-ins/script-fu/script-fu-text-console.c =================================================================== --- plug-ins/script-fu/script-fu-text-console.c (revision 23397) +++ 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 23397) +++ plug-ins/script-fu/script-fu-scripts.c (working copy) @@ -41,7 +41,6 @@ #include "script-fu-intl.h" - typedef struct { SFScript *script; @@ -126,14 +125,12 @@ script_fu_find_scripts (const gchar *pat script_menu_list = NULL; } -#if 1 /* ~~~~~ */ static pointer -my_err(scheme *sc, char *msg) +my_err (scheme *sc, char *msg) { - g_printerr (msg); + ts_output_string (TS_OUTPUT_ERROR, msg, -1); return sc->F; } -#endif pointer script_fu_add_script (scheme *sc, pointer a) @@ -663,10 +660,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 +677,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 +845,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 +1003,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 23397) +++ 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 23397) +++ 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; @@ -898,8 +898,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/script-fu-console.c =================================================================== --- plug-ins/script-fu/script-fu-console.c (revision 23397) +++ 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); @@ -267,8 +256,6 @@ script_fu_console_interface (void) g_source_remove (console->input_id); - output = NULL; - if (console->save_dialog) gtk_widget_destroy (console->save_dialog); @@ -521,21 +508,31 @@ 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); + if (type == TS_OUTPUT_NORMAL) + { + gtk_text_buffer_insert (buffer, &cursor, text, len); + } + else + { + gtk_text_buffer_insert_with_tags_by_name (console->console, &cursor, + text, len, "emphasis", + NULL); + } + script_fu_console_scroll_end (console->text_view); } } @@ -566,6 +563,7 @@ script_fu_cc_key_function (GtkWidget GList *list; gint direction = 0; GtkTextIter cursor; + GString *output; switch (event->keyval) { @@ -597,11 +595,23 @@ script_fu_cc_key_function (GtkWidget gtk_entry_set_text (GTK_ENTRY (console->cc), ""); + output = g_string_new (""); + ts_register_output_func (ts_gstring_output_func, output); 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); + { + script_fu_output_to_console (TS_OUTPUT_ERROR, + output->str, + output->len, + console); + } + else + { + script_fu_output_to_console (TS_OUTPUT_NORMAL, + output->str, + output->len, + console); + } + g_string_free (output, TRUE); gimp_displays_flush (); @@ -681,27 +691,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 +708,7 @@ script_fu_eval_run (const gchar *na { case GIMP_RUN_NONINTERACTIVE: /* Disable Script-Fu output */ - ts_set_output_file (stdout); + ts_register_output_func (NULL, NULL); if (ts_interpret_string (params[1].data.d_string) != 0) status = GIMP_PDB_EXECUTION_ERROR; break; Index: plug-ins/script-fu/script-fu.c =================================================================== --- plug-ins/script-fu/script-fu.c (revision 23397) +++ 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 */ @@ -230,7 +228,6 @@ script_fu_run (const gchar *name, * The script-fu text console for interactive Scheme development */ - ts_output_routine = NULL; script_fu_text_console_run (name, nparams, param, nreturn_vals, return_vals); } 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-server.c =================================================================== --- plug-ins/script-fu/script-fu-server.c (revision 23397) +++ plug-ins/script-fu/script-fu-server.c (working copy) @@ -450,31 +450,29 @@ static gboolean execute_command (SFCommand *cmd) { guchar buffer[RESPONSE_HEADER]; - const gchar *response; + GString *response; time_t clock1; time_t clock2; - gint response_len; gboolean error; gint i; server_log ("Processing request #%d\n", cmd->request_no); time (&clock1); + response = g_string_new (""); + ts_register_output_func (ts_gstring_output_func, response); + /* 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); + server_log ("%s\n", response->str); } else { error = FALSE; - response = ts_get_success_msg (); - response_len = strlen (response); + g_string_assign (response, ts_get_success_msg ()); time (&clock2); server_log ("Request #%d processed in %f seconds, finishing on %s", @@ -483,8 +481,8 @@ execute_command (SFCommand *cmd) buffer[MAGIC_BYTE] = MAGIC; buffer[ERROR_BYTE] = error ? TRUE : FALSE; - buffer[RSP_LEN_H_BYTE] = (guchar) (response_len >> 8); - buffer[RSP_LEN_L_BYTE] = (guchar) (response_len & 0xFF); + buffer[RSP_LEN_H_BYTE] = (guchar) (response->len >> 8); + buffer[RSP_LEN_L_BYTE] = (guchar) (response->len & 0xFF); /* Write the response to the client */ for (i = 0; i < RESPONSE_HEADER; i++) @@ -495,14 +493,16 @@ execute_command (SFCommand *cmd) return FALSE; } - for (i = 0; i < response_len; i++) - if (cmd->filedes > 0 && send (cmd->filedes, response + i, 1, 0) < 0) + for (i = 0; i < response->len; i++) + if (cmd->filedes > 0 && send (cmd->filedes, response->str + i, 1, 0) < 0) { /* Write error */ print_socket_api_error ("send"); return FALSE; } + g_string_free (response, TRUE); + return FALSE; } Index: plug-ins/script-fu/script-fu-console.h =================================================================== --- plug-ins/script-fu/script-fu-console.h (revision 23397) +++ 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 23397) +++ 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_len (gstr, string, len); } void @@ -220,8 +230,10 @@ 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 (TS_OUTPUT_NORMAL, + "Welcome to TinyScheme, Version 1.38\n", -1); + ts_output_string (TS_OUTPUT_NORMAL, + "Copyright (c) Dimitrios Souflis\n", -1); } void @@ -233,13 +245,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 +255,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 +264,17 @@ 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) +ts_output_string (TsOutputType type, + 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) (type, string, len, ts_output_data); } @@ -286,7 +288,6 @@ tinyscheme_init (const gchar *path, gboolean local_register_scripts) { register_scripts = local_register_scripts; - ts_output_routine = ts_output_string; /* init the interpreter */ if (!scheme_init (&sc)) @@ -296,11 +297,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,19 +592,7 @@ 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); - } - + ts_output_string (TS_OUTPUT_ERROR, msg, -1); return sc.NIL; } Index: plug-ins/script-fu/tinyscheme/scheme.c =================================================================== --- plug-ins/script-fu/tinyscheme/scheme.c (revision 23397) +++ plug-ins/script-fu/tinyscheme/scheme.c (working copy) @@ -46,6 +46,10 @@ #include "scheme-private.h" +#if !STANDALONE +#include "../scheme-wrapper.h" +#endif + /* Used for documentation purposes, to signal functions in 'interface' */ #define INTERFACE @@ -92,7 +96,7 @@ static int utf8_stricmp(const char *s1, return result; } -#define min(a, b) ((a <= b) ? a : b) +#define min(a, b) ((a) <= (b) ? (a) : (b)) #if USE_STRLWR /* @@ -395,8 +399,6 @@ static void assign_proc(scheme *sc, enum scheme *scheme_init_new(void); #if !STANDALONE void scheme_call(scheme *sc, pointer func, pointer args); - -void (*ts_output_routine) (const char *, int) = NULL; #endif #define num_ivalue(n) (n.is_fixnum?(n).value.ivalue:(long)(n).value.rvalue) @@ -1544,7 +1546,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,22 +1554,15 @@ 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); fflush(pt->rep.stdio.file); #else /* If output is still directed to stdout (the default) it should be */ - /* safe to redirect it to the routine pointed to by ts_output_routine. */ - if (pt->rep.stdio.file == stdout && ts_output_routine != NULL) - (*ts_output_routine) (chars, char_cnt); + /* safe to redirect it to the registered output routine. */ + if (pt->rep.stdio.file == stdout) + ts_output_string (TS_OUTPUT_NORMAL, chars, char_cnt); else { fwrite(chars,1,char_cnt,pt->rep.stdio.file); fflush(pt->rep.stdio.file); @@ -3647,9 +3641,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))); sc->args = cdr(sc->args); @@ -3664,7 +3655,6 @@ static pointer opexe_4(scheme *sc, enum s_goto(sc,OP_P0LIST); } else { putstr(sc, "\n"); - sc->print_error = 0; if(sc->interactive_repl) { s_goto(sc,OP_T0LVL); } else { @@ -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_1(sc, "syntax error: illegal token", mk_integer (sc, sc->tok)); } break; @@ -4515,7 +4504,6 @@ int scheme_init_custom_alloc(scheme *sc, sc->nesting=0; sc->interactive_repl=0; sc->print_output=0; - sc->print_error=0; if (alloc_cellseg(sc,FIRST_CELLSEGS) != FIRST_CELLSEGS) { sc->no_memory=1; Index: plug-ins/script-fu/tinyscheme/scheme.h =================================================================== --- plug-ins/script-fu/tinyscheme/scheme.h (revision 23397) +++ plug-ins/script-fu/tinyscheme/scheme.h (working copy) @@ -114,10 +114,6 @@ typedef struct num { } value; } num; -#if !STANDALONE -SCHEME_EXPORT void (*ts_output_routine) (const char *, int); -#endif - SCHEME_EXPORT scheme *scheme_init_new(); SCHEME_EXPORT scheme *scheme_init_new_custom_alloc(func_alloc malloc, func_dealloc free); SCHEME_EXPORT int scheme_init(scheme *sc); Index: plug-ins/script-fu/tinyscheme/scheme-private.h =================================================================== --- plug-ins/script-fu/tinyscheme/scheme-private.h (revision 23397) +++ plug-ins/script-fu/tinyscheme/scheme-private.h (working copy) @@ -72,7 +72,6 @@ pointer safe_foreign; /* register to int interactive_repl; /* are we in an interactive REPL? */ int print_output; /* set to 1 to print results and error messages */ -int print_error; /* set to 1 while printing error messages */ struct cell _sink; pointer sink; /* when mem. alloc. fails */ @@ -117,7 +116,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 23397) +++ plug-ins/script-fu/scheme-wrapper.h (working copy) @@ -19,22 +19,38 @@ #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, - gboolean local_register_scripts); +void tinyscheme_init (const gchar *path, + gboolean local_register_scripts); void tinyscheme_deinit (void); -void ts_output_string (const char *string, int len); +void ts_output_string (TsOutputType type, + const char *string, + int len); void ts_interpret_stdin (void);