@@ -1,10 +1,10 @@ /* ================================================================== - FILE: "/home/joze/src/tclreadline/tclreadline.c" - LAST MODIFICATION: "Mon Sep 13 02:21:35 1999 (joze)" + FILE: "/diska/home/joze/src/tclreadline/tclreadline.c" + LAST MODIFICATION: "Mon Sep 13 18:04:01 1999 (joze)" (C) 1998, 1999 by Johannes Zellner, $Id$ --- tclreadline -- gnu readline for tcl @@ -25,10 +25,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. , http://www.zellner.org/tclreadline/ ================================================================== */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include #include #include #include @@ -39,10 +43,19 @@ /** * this prototype is missing * in readline.h */ void rl_extend_line_buffer(int len); + +#ifdef EXECUTING_MACRO_HACK +/** + * this prototype is private in readline's file `macro.c'. + * We need it here to decide, if we should read more + * characters from a macro. Dirty, but it should work. + */ +extern char* _rl_executing_macro; +#endif #include "tclreadline.h" #define MALLOC(size) Tcl_Alloc((int) size) #define FREE(ptr) if (ptr) { Tcl_Free((char*) ptr); ptr = 0; } @@ -69,18 +82,14 @@ char* stripright(char* in); char* stripwhite(char* in); char* TclReadlineQuote(char* text, char* quotechars); int TclReadlineCmd(ClientData clientData, Tcl_Interp* interp, int argc, char** argv); -int TclReadlineEventHook(void); void TclReadlineReadHandler(ClientData clientData, int mask); -void TclReadlineWriteHandler(ClientData clientData, int mask); void TclReadlineLineCompleteHandler(char* ptr); int Tclreadline_SafeInit(Tcl_Interp* interp); int Tclreadline_Init(Tcl_Interp* interp); -char *TclReadlineFilenameQuotingFunction( - char *text, int match_type, char* quote_ptr); int TclReadlineInitialize(Tcl_Interp* interp, char* historyfile); int blank_line(char* str); char** TclReadlineCompletion(char* text, int start, int end); char* TclReadline0generator(char* text, int state); char* TclReadlineKnownCommands(char* text, int state, int mode); @@ -174,22 +183,17 @@ if (c == 'r' && strncmp(argv[1], "read", length) == 0) { char* expansion = (char*) NULL; int status; -#if 1 tclrl_line_complete = LINE_PENDING; tclrl_state = TCL_OK; rl_callback_handler_install(argc == 3 ? argv[2] : "%", TclReadlineLineCompleteHandler); Tcl_CreateFileHandler(0, TCL_READABLE, TclReadlineReadHandler, (ClientData) NULL); - /* - Tcl_CreateFileHandler(1, TCL_WRITABLE, - TclReadlineWriteHandler, (ClientData) NULL); - */ /** * Main Loop. * XXX each modification of the global variables * which terminates the main loop must call @@ -197,29 +201,21 @@ * readline in a defined state. XXX */ while (LINE_PENDING == tclrl_line_complete && TCL_OK == tclrl_state && !rl_done) { Tcl_DoOneEvent(TCL_ALL_EVENTS); - /* - Tcl_DoOneEvent(0); - fprintf (stderr, "(TclReadlineCmd) \n"); - rl_inhibit_completion = 0; - */ } + Tcl_DeleteFileHandler(0); if (TCL_OK != tclrl_state) return tclrl_state; /* !! */ if ((LINE_EOF == tclrl_line_complete) && tclrl_eof_string) { Tcl_Eval(interp, tclrl_eof_string); return tclrl_state; } -#else - rl_event_hook = TclReadlineEventHook; - tclrl_line = readline(argc == 3 ? argv[2] : "%"); -#endif status = history_expand(tclrl_line, &expansion); if (status >= 1) { #if 0 Tcl_Channel channel = Tcl_MakeFileChannel(stdout, TCL_WRITABLE); @@ -325,52 +321,24 @@ (char*) NULL); return TCL_ERROR; } -int TclReadlineEventHook(void) -{ - Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); - /* - TCL_DONT_WAIT - TCL_WINDOW_EVENTS - TCL_FILE_EVENTS - TCL_TIMER_EVENTS - TCL_IDLE_EVENTS - TCL_ALL_EVENTS - */ - return TCL_OK; -} void TclReadlineReadHandler(ClientData clientData, int mask) { -#if 0 - fprintf(stderr, "(TclReadlineReadHandler) mask = %d\n", mask); -#endif - if (mask & TCL_READABLE) { - /* - fprintf(stderr, "(TclReadlineReadHandler) mask = readable\n"); - rl_event_hook = TclReadlineEventHook; - while (!rl_done) { - */ - rl_callback_read_char(); - /* - } - fflush(stdin); - */ - } -} - -void -TclReadlineWriteHandler(ClientData clientData, int mask) -{ - if (mask & TCL_WRITABLE) { - /* - fprintf(stderr, "(TclReadlineReadHandler) mask = writable\n"); - */ - fflush(stdout); - rl_redisplay(); + if (mask & TCL_READABLE) { + rl_callback_read_char(); +#ifdef EXECUTING_MACRO_HACK + /** + * check, if we're inside a macro and + * if so, read all macro characters. + */ + while (_rl_executing_macro) { + rl_callback_read_char(); + } +#endif } } void TclReadlineLineCompleteHandler(char* ptr) @@ -428,42 +396,10 @@ (char*) &TCLRL_PATCHLEVEL, TCL_LINK_STRING | TCL_LINK_READ_ONLY))) return status; return Tcl_PkgProvide(interp, "tclreadline", TCLRL_VERSION); } -#if 0 -char * -TclReadlineFilenameQuotingFunction -(char *filename, int match_type, char* quote_ptr) -{ - char *res = (char*) malloc(sizeof(char) * (strlen(filename) + 2)); - int i = 0; - fprintf (stderr, "(TclReadlineFilenameQuotingFunction) \n"); - if (quote_ptr && *quote_ptr) { - *res = *quote_ptr; /* leading quote */ - i++; - } - strcpy (res + i, filename); /* name */ -#if 0 - fprintf (stderr, "(Tclreadline_Init) filename=|%s|\n", filename); - fprintf (stderr, "(Tclreadline_Init) *quote_ptr=|%c|\n", *quote_ptr); -#endif - if (quote_ptr && '{' == *quote_ptr) { - *quote_ptr = '}'; - } - return res; - -#if 0 - switch (match_type) { - case SINGLE_MATCH: - break; - default: - } -#endif -} -#endif - int TclReadlineInitialize(Tcl_Interp* interp, char* historyfile) { rl_readline_name = "tclreadline"; // rl_special_prefixes = "${\"["; @@ -479,12 +415,14 @@ /* 11.Sep rl_basic_word_break_characters = " \t\n\"\\@$}=;|&[]"; */ /* besser (11. Sept) 2. (removed \") */ /* rl_basic_word_break_characters = " \t\n\\@$}=;|&[]"; */ /* besser (11. Sept) 3. (removed }) */ rl_basic_word_break_characters = " \t\n\\@$=;|&[]"; - // rl_basic_quote_characters = "\"{"; // XXX ??? XXX - // rl_completer_quote_characters = "\""; +#if 0 + rl_basic_quote_characters = "\"{"; // XXX ??? XXX + rl_completer_quote_characters = "\""; +#endif /* rl_filename_quote_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; rl_filename_quoting_function @@ -527,34 +465,12 @@ char** TclReadlineCompletion(char* text, int start, int end) { char** matches = (char**) NULL; int status; - // rl_attempted_completion_over = 0; rl_completion_append_character = ' '; /* reset, just in case ... */ -#if 0 - fprintf(stderr, "DEBUG> TclReadlineCompletion: text=|%s|\n", text); - fprintf(stderr, "DEBUG> TclReadlineCompletion: start=|%d|\n", start); - fprintf(stderr, "DEBUG> TclReadlineCompletion: end=|%d|\n", end); -#endif - -#if 0 - char* history_event = (char*) NULL; - if (text) { - if ('!' == text[0]) - history_event = strdup(text); - else if (start && rl_line_buffer[start - 1] == '!' /* for '$' */) { - int len = strlen(text); - history_event = strncpy((char*) malloc(sizeof(char) * (len + 1)), - rl_line_buffer[start - 1], len); - history_event[len] = '\0'; /* terminate */ - } - } - if (history_event) -#endif - if (text && ('!' == text[0] || (start && rl_line_buffer[start - 1] == '!' /* for '$' */))) { char* expansion = (char*) NULL; int oldlen = strlen(rl_line_buffer); status = history_expand(rl_line_buffer, &expansion); @@ -562,11 +478,10 @@ rl_extend_line_buffer(strlen(expansion) + 1); strcpy(rl_line_buffer, expansion); rl_end = strlen(expansion); rl_point += strlen(expansion) - oldlen; FREE(expansion); - /* rl_redisplay(); */ /* * TODO: * because we return 0 == matches, * the filename completer will still beep. rl_inhibit_completion = 1; @@ -582,19 +497,10 @@ Tcl_Obj** objv; int objc; char* quoted_text = TclReadlineQuote(text, "$[]{}\""); char* quoted_rl_line_buffer = TclReadlineQuote(rl_line_buffer, "$[]{}\""); -#if 0 - fprintf (stderr, "(TclReadlineCompletion) rl_line_buffer = |%s|\n", - rl_line_buffer); - fprintf (stderr, "(TclReadlineCompletion) quoted_rl_line_buffer = |%s|\n", - quoted_rl_line_buffer); - fprintf (stderr, "(TclReadlineCompletion) text = |%s|\n", text); - fprintf (stderr, "(TclReadlineCompletion) quoted_text = |%s|\n", - quoted_text); -#endif sprintf(start_s, "%d", start); sprintf(end_s, "%d", end); Tcl_ResetResult(tclrl_interp); /* clear result space */ tclrl_state = Tcl_VarEval(tclrl_interp, tclrl_custom_completer, " \"", quoted_text, "\" ", start_s, " ", end_s, @@ -606,34 +512,25 @@ Tcl_AppendResult (tclrl_interp, " `", tclrl_custom_completer, " \"", quoted_text, "\" ", start_s, " ", end_s, " \"", quoted_rl_line_buffer, "\"' failed.", (char*) NULL); return matches; } -#if 0 - fprintf(stderr, "\nscript returned |%s|\n", - Tcl_GetStringResult(tclrl_interp)); -#endif obj = Tcl_GetObjResult(tclrl_interp); status = Tcl_ListObjGetElements(tclrl_interp, obj, &objc, &objv); if (TCL_OK != status) return matches; - /* fprintf (stderr, "(TclReadlineCompletion) objc = %d\n", objc); */ + if (objc) { int i, length; matches = (char**) MALLOC(sizeof(char*) * (objc + 1)); for (i = 0; i < objc; i++) { matches[i] = strdup(Tcl_GetStringFromObj(objv[i], &length)); if (1 == objc && !strlen(matches[i])) { - // rl_attempted_completion_over = 1; FREE(matches[i]); FREE(matches); return (char**) NULL; } - /* - fprintf (stderr, "(TclReadlineCompletion) len[%s]=%d\n", - matches[i], strlen(matches[i])); - */ } /** * this is a special one: * if the script returns exactly two arguments @@ -653,17 +550,10 @@ } if (!matches && tclrl_use_builtin_completer) { matches = completion_matches(text, TclReadline0generator); } -#if 0 - { - char **ptr; - for (ptr = matches; ptr && *ptr; ptr++) - fprintf (stderr, "(TclReadlineCompletion) |%s|\n", *ptr); - } -#endif return matches; } char* @@ -718,14 +608,10 @@ case _CMD_GET: local_line = strdup(rl_line_buffer); sub = TclReadlineParse(args, sizeof(args), local_line); - /* - * fprintf (stderr, "(TclReadlineKnownCommands) state=%d\n", state); - * fprintf (stderr, "(TclReadlineKnownCommands) text = |%s|\n", text); - */ if (0 == sub || (1 == sub && '\0' != text[0])) { if (!state) { new = cmds; len = strlen(text);