From 265cd64510efa5e44ea4e1bcc2e431f2deaae0c6 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 3 Jun 2005 15:24:49 +0000 Subject: Backported [console] rename fix. [Bug 1016385] --- ChangeLog | 6 ++++ generic/tkConsole.c | 80 +++++++++++++++++++++++++---------------------------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index e78a5cd..aa989d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-06-03 Donal K. Fellows + + * generic/tkConsole.c (Tk_CreateConsoleWindow, TkConsolePrint): + Transmit the ConsoleInfo through AssocData, so renaming [console] + won't make things break. [Bug 1016385] + 2005-06-03 Daniel Steffen *** 8.4.10 TAGGED FOR RELEASE *** diff --git a/generic/tkConsole.c b/generic/tkConsole.c index c8e2c8a..cfb9219 100644 --- a/generic/tkConsole.c +++ b/generic/tkConsole.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkConsole.c,v 1.18 2002/08/05 04:30:38 dgp Exp $ + * RCS: @(#) $Id: tkConsole.c,v 1.18.2.1 2005/06/03 15:25:01 dkf Exp $ */ #include "tk.h" @@ -29,6 +29,15 @@ typedef struct ConsoleInfo { Tcl_Interp *interp; /* Interpreter to send console commands. */ } ConsoleInfo; +/* + * Each interpreter with a console attached stores a reference to the + * interpreter's ConsoleInfo in the interpreter's AssocData store. The + * alternative is to look the values up by examining the "console" + * command and that is fragile. [Bug 1016385] + */ + +#define TK_CONSOLE_INFO_KEY "tk::ConsoleInfo" + typedef struct ThreadSpecificData { Tcl_Interp *gStdoutInterp; } ThreadSpecificData; @@ -333,9 +342,9 @@ Tk_CreateConsoleWindow(interp) ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); #ifdef MAC_TCL - static char initCmd[] = "if {[catch {source $tk_library:console.tcl}]} {source -rsrc console}"; + static const char *initCmd = "if {[catch {source $tk_library:console.tcl}]} {source -rsrc console}"; #else - static char initCmd[] = "source $tk_library/console.tcl"; + static const char *initCmd = "source $tk_library/console.tcl"; #endif consoleInterp = Tcl_CreateInterp(); @@ -365,6 +374,7 @@ Tk_CreateConsoleWindow(interp) (Tcl_CmdDeleteProc *) ConsoleDeleteProc); Tcl_CreateCommand(consoleInterp, "consoleinterp", InterpreterCmd, (ClientData) info, (Tcl_CmdDeleteProc *) NULL); + Tcl_SetAssocData(interp, TK_CONSOLE_INFO_KEY, NULL, (ClientData) info); Tk_CreateEventHandler(mainWindow, StructureNotifyMask, ConsoleEventProc, (ClientData) info); @@ -567,7 +577,6 @@ ConsoleCmd(clientData, interp, argc, argv) size_t length; int result; Tcl_Interp *consoleInterp; - Tcl_DString dString; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -580,20 +589,21 @@ ConsoleCmd(clientData, interp, argc, argv) result = TCL_OK; consoleInterp = info->consoleInterp; Tcl_Preserve((ClientData) consoleInterp); - Tcl_DStringInit(&dString); if ((c == 't') && (strncmp(argv[1], "title", length)) == 0) { + Tcl_DString dString; + + Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, "wm title . ", -1); if (argc == 3) { Tcl_DStringAppendElement(&dString, argv[2]); } Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); + Tcl_DStringFree(&dString); } else if ((c == 'h') && (strncmp(argv[1], "hide", length)) == 0) { - Tcl_DStringAppend(&dString, "wm withdraw . ", -1); - Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); + Tcl_Eval(consoleInterp, "wm withdraw . "); } else if ((c == 's') && (strncmp(argv[1], "show", length)) == 0) { - Tcl_DStringAppend(&dString, "wm deiconify . ", -1); - Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); + Tcl_Eval(consoleInterp, "wm deiconify . "); } else if ((c == 'e') && (strncmp(argv[1], "eval", length)) == 0) { if (argc == 3) { result = Tcl_Eval(consoleInterp, argv[2]); @@ -610,7 +620,6 @@ ConsoleCmd(clientData, interp, argc, argv) (char *) NULL); result = TCL_ERROR; } - Tcl_DStringFree(&dString); Tcl_Release((ClientData) consoleInterp); return result; } @@ -726,12 +735,8 @@ ConsoleEventProc(clientData, eventPtr) { ConsoleInfo *info = (ConsoleInfo *) clientData; Tcl_Interp *consoleInterp; - Tcl_DString dString; if (eventPtr->type == DestroyNotify) { - - Tcl_DStringInit(&dString); - consoleInterp = info->consoleInterp; /* @@ -741,14 +746,11 @@ ConsoleEventProc(clientData, eventPtr) * gone, we do not have to do any work here. */ - if (consoleInterp == (Tcl_Interp *) NULL) { - return; - } - Tcl_Preserve((ClientData) consoleInterp); - Tcl_DStringAppend(&dString, "::tk::ConsoleExit", -1); - Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); - Tcl_DStringFree(&dString); - Tcl_Release((ClientData) consoleInterp); + if (consoleInterp != (Tcl_Interp *) NULL) { + Tcl_Preserve((ClientData) consoleInterp); + Tcl_Eval(consoleInterp, "::tk::ConsoleExit"); + Tcl_Release((ClientData) consoleInterp); + } } } @@ -779,40 +781,34 @@ TkConsolePrint(interp, devId, buffer, size) long size; /* Size of text buffer. */ { Tcl_DString command, output; - Tcl_CmdInfo cmdInfo; - char *cmd; ConsoleInfo *info; Tcl_Interp *consoleInterp; - int result; if (interp == NULL) { return; } - + + info = (ConsoleInfo *) Tcl_GetAssocData(interp, TK_CONSOLE_INFO_KEY, NULL); + if (info->consoleInterp == NULL) { + return; + } + + Tcl_DStringInit(&command); if (devId == TCL_STDERR) { - cmd = "::tk::ConsoleOutput stderr "; + Tcl_DStringAppend(&command, "::tk::ConsoleOutput stderr ", -1); } else { - cmd = "::tk::ConsoleOutput stdout "; - } - - result = Tcl_GetCommandInfo(interp, "console", &cmdInfo); - if (result == 0) { - return; + Tcl_DStringAppend(&command, "::tk::ConsoleOutput stdout ", -1); } - info = (ConsoleInfo *) cmdInfo.clientData; - + Tcl_DStringInit(&output); Tcl_DStringAppend(&output, buffer, size); - - Tcl_DStringInit(&command); - Tcl_DStringAppend(&command, cmd, (int) strlen(cmd)); - Tcl_DStringAppendElement(&command, output.string); + Tcl_DStringAppendElement(&command, Tcl_DStringValue(&output)); + Tcl_DStringFree(&output); consoleInterp = info->consoleInterp; Tcl_Preserve((ClientData) consoleInterp); - Tcl_Eval(consoleInterp, command.string); + Tcl_Eval(consoleInterp, Tcl_DStringValue(&command)); Tcl_Release((ClientData) consoleInterp); - + Tcl_DStringFree(&command); - Tcl_DStringFree(&output); } -- cgit v0.12