From f68f95ac0fcee0b75243b53bc18e21d9ddcfa7bd Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 19 Jan 2012 20:33:10 +0000 Subject: [Bug-3288113,3288121]: Missing marks/endless loop in text mark prev/next --- ChangeLog | 5 ++++ generic/tkTextMark.c | 41 +++++++++++++++++++++++++-------- tests/textMark.test | 65 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 85 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6b35ca..8ed5d1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012-??-?? Francois Vogel + + * generic/tkTextMark.c: [Bug-3288113,3288121]: Missing marks/endless + * tests/textMark.test: loop in text mark prev/next + 2012-01-19 Francois Vogel * generic/tkText.c: [Bug-3021557]: Moving the cursor in diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c index 281baf1..55edb46 100644 --- a/generic/tkTextMark.c +++ b/generic/tkTextMark.c @@ -781,11 +781,17 @@ MarkFindNext( Tcl_SetResult(interp, "current", TCL_STATIC); } else if (segPtr == textPtr->insertMarkPtr) { Tcl_SetResult(interp, "insert", TCL_STATIC); - } else if (segPtr->body.mark.textPtr != textPtr) { + } else if (segPtr->body.mark.hPtr == NULL) { /* * Ignore widget-specific marks for the other widgets. - */ - + * This is either an insert or a current mark + * (markPtr->body.mark.hPtr actually receives NULL + * for these marks in TkTextSetMark). + * The insert and current marks for textPtr having + * already been tested above, the current segment is + * an insert or current mark from a peer of textPtr, + * which we don't want to return. + */ continue; } else { Tcl_SetResult(interp, @@ -868,7 +874,7 @@ MarkFindPrev( while (1) { /* * segPtr points just past the first possible candidate, or at the - * begining of the line. + * beginning of the line. */ for (prevPtr = NULL, seg2Ptr = index.linePtr->segPtr; @@ -876,26 +882,43 @@ MarkFindPrev( seg2Ptr = seg2Ptr->nextPtr) { if (seg2Ptr->typePtr == &tkTextRightMarkType || seg2Ptr->typePtr == &tkTextLeftMarkType) { + if (seg2Ptr->body.mark.hPtr == NULL) { + if (seg2Ptr != textPtr->currentMarkPtr && + seg2Ptr != textPtr->insertMarkPtr) { + /* + * This is an insert or current mark from a + * peer of textPtr. + */ + continue; + } + } prevPtr = seg2Ptr; } } if (prevPtr != NULL) { if (prevPtr == textPtr->currentMarkPtr) { Tcl_SetResult(interp, "current", TCL_STATIC); + return TCL_OK; } else if (prevPtr == textPtr->insertMarkPtr) { Tcl_SetResult(interp, "insert", TCL_STATIC); - } else if (prevPtr->body.mark.textPtr != textPtr) { + return TCL_OK; + } else if (prevPtr->body.mark.hPtr == NULL) { /* * Ignore widget-specific marks for the other widgets. - */ - - continue; + * This is either an insert or a current mark + * (markPtr->body.mark.hPtr actually receives NULL + * for these marks in TkTextSetMark). + * The insert and current marks for textPtr having + * already been tested above, the current segment is + * an insert or current mark from a peer of textPtr, + * which we don't want to return. + */ } else { Tcl_SetResult(interp, Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, prevPtr->body.mark.hPtr), TCL_STATIC); + return TCL_OK; } - return TCL_OK; } index.linePtr = TkBTreePreviousLine(textPtr, index.linePtr); if (index.linePtr == NULL) { diff --git a/tests/textMark.test b/tests/textMark.test index c2810cc..174f674 100644 --- a/tests/textMark.test +++ b/tests/textMark.test @@ -19,7 +19,8 @@ pack append . .t {top expand fill} update .t debug on wm geometry . {} - +.t peer create .pt + # The statements below reset the main window; it's needed if the window # manager is mwm to make mwm forget about a previous minimum size setting. @@ -175,47 +176,77 @@ test textMark-7.8 {MarkFindNext - no next mark} haveCourier12 { .t mark set insert 3.0 .t mark next insert } {} -test textMark-8.1 {MarkFindPrev - invalid mark name} haveCourier12 { +test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a peer} -setup { + .t mark unset {*}[.t mark names] +} -body { + .t mark set mymark 1.0 + set res [list [.pt mark next 1.0] [.pt mark next mymark] [.pt mark next insert]] +} -result {mymark insert current} + +test textMark-8.1 {MarkFindPrev - invalid mark name} -constraints haveCourier12 -setup { + .t mark unset {*}[.t mark names] +} -body { catch {.t mark prev bogus} x set x -} {bad text index "bogus"} -test textMark-8.2 {MarkFindPrev - marks at same location} haveCourier12 { +} -result {bad text index "bogus"} +test textMark-8.2 {MarkFindPrev - marks at same location} -constraints haveCourier12 -setup { + .t mark unset {*}[.t mark names] +} -body { .t mark set insert 2.0 .t mark set current 2.0 .t mark prev insert -} {current} -test textMark-8.3 {MarkFindPrev - numerical starting mark} haveCourier12 { +} -result {current} +test textMark-8.3 {MarkFindPrev - numerical starting mark} -constraints haveCourier12 -setup { + .t mark unset {*}[.t mark names] +} -body { .t mark set current 1.0 .t mark set insert 1.0 .t mark prev 1.1 -} {current} -test textMark-8.4 {MarkFindPrev - mark on the same line} haveCourier12 { +} -result {current} +test textMark-8.4 {MarkFindPrev - mark on the same line} -setup { + .t mark unset {*}[.t mark names] +} -body { .t mark set current 1.0 .t mark set insert 1.1 .t mark prev insert -} {current} -test textMark-8.5 {MarkFindPrev - mark on the previous line} haveCourier12 { +} -result {current} +test textMark-8.5 {MarkFindPrev - mark on the previous line} -setup { + .t mark unset {*}[.t mark names] +} -body { .t mark set current 1.end .t mark set insert 2.0 .t mark prev insert -} {current} -test textMark-8.6 {MarkFindPrev - mark far away} haveCourier12 { +} -result {current} +test textMark-8.6 {MarkFindPrev - mark far away} -constraints haveCourier12 -setup { + .t mark unset {*}[.t mark names] +} -body { .t mark set current 1.2 .t mark set insert 7.0 .t mark prev insert -} {current} -test textMark-8.7 {MarkFindPrev - mark on top of end} haveCourier12 { +} -result {current} +test textMark-8.7 {MarkFindPrev - mark on top of end} -constraints haveCourier12 -setup { + .t mark unset {*}[.t mark names] +} -body { .t mark set insert 3.0 .t mark set current end .t mark prev end -} {insert} -test textMark-8.8 {MarkFindPrev - no previous mark} haveCourier12 { +} -result {insert} +test textMark-8.8 {MarkFindPrev - no previous mark} -constraints haveCourier12 -setup { + .t mark unset {*}[.t mark names] +} -body { .t mark set current 1.0 .t mark set insert 3.0 .t mark prev current -} {} +} -result {} +test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a peer} -setup { + .t mark unset {*}[.t mark names] +} -body { + .t mark set mymark 1.0 + set res [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]] +} -result {current insert mymark} catch {destroy .t} +catch {destroy .pt} # cleanup cleanupTests -- cgit v0.12