Tcl Source Code

Artifact [3caa747fcb]
Login

Artifact 3caa747fcb5da4f37772aab09f570c9078e60fde:

Attachment "1775878.patch" to ticket [1775878fff] added by dgp 2007-08-22 03:25:24.
Index: generic/tclMain.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclMain.c,v
retrieving revision 1.42
diff -u -r1.42 tclMain.c
--- generic/tclMain.c	24 Apr 2007 16:03:51 -0000	1.42
+++ generic/tclMain.c	21 Aug 2007 20:23:01 -0000
@@ -527,22 +527,30 @@
 		break;
 	    }
 
+	    /*
+	     * Add the newline removed by Tcl_GetsObj back to the string.
+	     * Have to add it back before testing completeness, because
+	     * it can make a difference.  [Bug 1775878].
+	     */
+
+	    if (Tcl_IsShared(commandPtr)) {
+		Tcl_DecrRefCount(commandPtr);
+		commandPtr = Tcl_DuplicateObj(commandPtr);
+		Tcl_IncrRefCount(commandPtr);
+	    }
+	    Tcl_AppendToObj(commandPtr, "\n", 1);
 	    if (!TclObjCommandComplete(commandPtr)) {
-		/*
-		 * Add the newline removed by Tcl_GetsObj back to the string.
-		 */
-
-		if (Tcl_IsShared(commandPtr)) {
-		    Tcl_DecrRefCount(commandPtr);
-		    commandPtr = Tcl_DuplicateObj(commandPtr);
-		    Tcl_IncrRefCount(commandPtr);
-		}
-		Tcl_AppendToObj(commandPtr, "\n", 1);
 		prompt = PROMPT_CONTINUE;
 		continue;
 	    }
 
 	    prompt = PROMPT_START;
+	    /*
+	     * The final newline is syntactically redundant, and causes
+	     * some error messages troubles deeper in, so lop it back off.
+	     */
+	    Tcl_GetStringFromObj(commandPtr, &length);
+	    Tcl_SetObjLength(commandPtr, --length);
 	    code = Tcl_RecordAndEvalObj(interp, commandPtr, TCL_EVAL_GLOBAL);
 	    inChannel = Tcl_GetStdChannel(TCL_STDIN);
 	    outChannel = Tcl_GetStdChannel(TCL_STDOUT);
@@ -758,17 +766,19 @@
 	return;
     }
 
+    if (Tcl_IsShared(commandPtr)) {
+	Tcl_DecrRefCount(commandPtr);
+	commandPtr = Tcl_DuplicateObj(commandPtr);
+	Tcl_IncrRefCount(commandPtr);
+    }
+    Tcl_AppendToObj(commandPtr, "\n", 1);
     if (!TclObjCommandComplete(commandPtr)) {
-	if (Tcl_IsShared(commandPtr)) {
-	    Tcl_DecrRefCount(commandPtr);
-	    commandPtr = Tcl_DuplicateObj(commandPtr);
-	    Tcl_IncrRefCount(commandPtr);
-	}
-	Tcl_AppendToObj(commandPtr, "\n", 1);
 	isPtr->prompt = PROMPT_CONTINUE;
 	goto prompt;
     }
     isPtr->prompt = PROMPT_START;
+    Tcl_GetStringFromObj(commandPtr, &length);
+    Tcl_SetObjLength(commandPtr, --length);
 
     /*
      * Disable the stdin channel handler while evaluating the command;
Index: tests/main.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/main.test,v
retrieving revision 1.20
diff -u -r1.20 main.test
--- tests/main.test	4 Sep 2006 21:34:58 -0000	1.20
+++ tests/main.test	21 Aug 2007 20:23:03 -0000
@@ -819,6 +819,20 @@
 	file delete result
     } -result "Exit MainLoop\nIn exit\neven 0\n"
 
+    test Tcl_Main-5.13 {
+	Bug 1775878
+    } -constraints {
+	exec
+    } -setup {
+	catch {set f [open "|[list [interpreter]]" w+]}
+    } -body {
+	type $f "puts \\"
+	type $f return
+	list [catch {gets $f} line] $line
+    } -cleanup {
+	close $f
+    } -result [list 0 return]
+
     # Tests Tcl_Main-6.*: interactive operations with prompts
 
     test Tcl_Main-6.1 {
@@ -1202,6 +1216,21 @@
 	file delete result
     } -result "1\nExit MainLoop\n"
 
+    test Tcl_Main-8.13 {
+	Bug 1775878
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	catch {set f [open "|[list [interpreter]]" w+]}
+    } -body {
+	exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "pwd\nExit MainLoop\n"
+
     # Tests Tcl_Main-9.*: Prompt operations
 
     test Tcl_Main-9.1 {