Post by George on Jun 9, 2022 14:06:45 GMT -5
I'm glad you have faith, 'cus I'm at the end of the rope.
I tried your suggestion to log all the MEntry stuff. It produces a lovely list of all the entry's being made, but it has been no help. It points at crash time to routines that have nothing to do with (SWAP), which seems to be the only trigger for all these various crashes. These routines are the innocent victims of the memory corruption.
If there are no X'd lines, I cannot get the thing to fail at all. If there is an x'd block, it fails about 30-50% of the time. And the only difference in the logic is that the processing loop skips processing the X marker line.
I am totally and completely lost here, I'm chasing ghosts with my hands tied behind behind my back.
Right now, I give up.
Here's the SWAP code, maybe some new eyes can see something. I can understand maybe the logic doesn't do the swap correctly, that's fixable, but there's no direct memory access there, so how is something being corrupted? The dxxx variables are the text, the cxxx variables are the attribute bytes. The me.CRPFwd(%mOData, swapLnum, 1) routine increments the line number, returning ONLY data lines.
George
I tried your suggestion to log all the MEntry stuff. It produces a lovely list of all the entry's being made, but it has been no help. It points at crash time to routines that have nothing to do with (SWAP), which seems to be the only trigger for all these various crashes. These routines are the innocent victims of the memory corruption.
If there are no X'd lines, I cannot get the thing to fail at all. If there is an x'd block, it fails about 30-50% of the time. And the only difference in the logic is that the processing loop skips processing the X marker line.
I am totally and completely lost here, I'm chasing ghosts with my hands tied behind behind my back.
Right now, I give up.
Here's the SWAP code, maybe some new eyes can see something. I can understand maybe the logic doesn't do the swap correctly, that's fixable, but there's no direct memory access there, so how is something being corrupted? The dxxx variables are the text, the cxxx variables are the attribute bytes. The me.CRPFwd(%mOData, swapLnum, 1) routine increments the line number, returning ONLY data lines.
George
METHOD krSwap()
'---------- Swap command
LOCAL i, j, swapLnum, markLnum, SNum AS LONG
LOCAL dSwapLine, dMarkLine, dSwapText, dMarkText, dPart1, dPart2, dPart3, dPart4 AS STRING
LOCAL cSwapLine, cMarkLine, cSwapText, cMarkText, cPart1, cPart2, cPart3, cPart4 AS WSTRING
LOCAL MaxECol, WorkECol AS LONG
MEntry
me.AttrInvClearFind ' Clear any Find HiLite
MaxECol = MAX(SwapECol, MarkECol)
'----- If both areas marked, we can do the Swap
IF IsMarkActive AND IsSwapActive THEN ' We have two marked areas ready
'----- Init for line loop
me.SwapKill ' To remove UL so they don't get copied
swapLnum = SwapSLin: markLnum = MarkSLin ' Point at the 1st two lines
FOR SNum = 1 TO SwapLines ' Loop for the number of lines
'----- Extract the two strings
WorkECol = MAX(MaxECol, LTxtGLen(swapLNum))
dSwapLine = LSET$(LTxtG(swapLnum), WorkECol USING " ") ' Get the data text from the Swap line
cSwapLine = LSET$(LAttrG(swapLnum), WorkECol USING CHR$$(0)) ' Get the attr text from the Swap line
dSwapText = MID$(dSwapLine, SwapSCol TO SwapECol) ' Extract the data columns
cSwapText = MID$(cSwapLine, SwapSCol TO SwapECol) ' Extract the attr columns
me.ModSet(swapLnum) ' Remember we changed something
dMarkLine = LSET$(LTxtG(markLNum), WorkECol USING " ") ' Get the data text from the Mark line
cMarkLine = LSET$(LAttrG(markLnum), WorkECol USING CHR$$(0)) ' Get the attr text from the Mark line
dMarkText = MID$(dMarkLine, MarkSCol TO MarkECol) ' Extract the data columns
cMarkText = MID$(cMarkLine, MarkSCol TO MarkECol) ' Extract the attr columns
me.ModSet(markLnum) ' Remember we changed something
IF swapLnum <> markLnum THEN ' We're dealing with two different lines
'----- Handle the two different line combination
IF SwapSCol = 1 THEN ' If old Swap text is at LH end
dSwapLine = dMarkText + MID$(dSwapLine, SwapECol + 1) ' Just replace with the Mark text
cSwapLine = cMarkText + MID$(cSwapLine, SwapECol + 1) ' Just replace with the Mark text
ELSE '
'----- Insert dMarkText to replace dSwapText text
dSwapLine = LEFT$(dSwapLine, SwapSCol - 1) + dMarkText + MID$(dSwapLine, SwapECol + 1)
cSwapLine = LEFT$(cSwapLine, SwapSCol - 1) + cMarkText + MID$(cSwapLine, SwapECol + 1)
END IF '
me.LTxtSet(swapLnum, dSwapLine) ' Save the Swap line back
me.LAttrSet(swapLnum,cSwapLine) '
me.AttrScan(swapLnum) ' Recolorize
IF MarkSCol = 1 THEN ' If old Mark text is at LH end
dMarkLine = dSwapText + MID$(dMarkLine, MarkECol + 1) ' Just replace with the Swap text
cMarkLine = cSwapText + MID$(cMarkLine, MarkECol + 1) ' Just replace with the Swap text
ELSE '
'----- Insert dMarkText to replace dSwapText text
dMarkLine = LEFT$(dMarkLine, MarkSCol - 1) + dSwapText + MID$(dMarkLine, MarkECol + 1)
cMarkLine = LEFT$(cMarkLine, MarkSCol - 1) + cSwapText + MID$(cMarkLine, MarkECol + 1)
END IF '
me.LTxtSet (markLnum, dMarkLine) ' Save the Swap line back
me.LAttrSet(markLnum, cMarkLine) ' Save the Swap line back
me.AttrScan(markLnum) ' Recolorize
ELSE ' The Mark and Swap are on the same line
'----- Swap on a single line
IF SwapSCol < MarkSCol THEN ' Swap is left of Mark
'----- Swap area is Left of the Mark area
dPart1 = LEFT$(dSwapLine, SwapSCol - 1) ' Get part 1, the left of Swap string
cPart1 = LEFT$(cSwapLine, SwapSCol - 1) ' Get part 1, the left of Swap string
'----- Get part 2, between the strings
dPart2 = IIF$(SwapEcol + 1 = MarkSCol, "", MID$(dSwapLine, SwapECol + 1, MarkSCol - SwapECol - 1))
cPart2 = IIF$(SwapEcol + 1 = MarkSCol, "", MID$(cSwapLine, SwapECol + 1, MarkSCol - SwapECol - 1))
'----- Get part3, after the strings
dPart3 = MID$(dSwapLine, MarkECol + 1) ' Get part 3, After the strings
cPart3 = MID$(cSwapLine, MarkECol + 1) ' Get part 3, After the strings
'----- Rebuild the line
dSwapLine = BUILD$(dPart1, dMarkText, dPart2, dSwapText, dPart3) ' Rebuild the line
cSwapLine = BUILD$(cPart1, cMarkText, cPart2, cSwapText, cPart3) ' Rebuild the line
ELSE ' Mark is left of swap
'----- Swap area is Right of the Mark area
dPart1 = LEFT$(dSwapLine, MarkSCol - 1) ' Get part 1, the left of Mark string
cPart1 = LEFT$(cSwapLine, MarkSCol - 1) ' Get part 1, the left of Mark string
'----- Get part 2, between the strings
dPart2 = IIF$(MarkEcol + 1 = SwapSCol, "", MID$(dSwapLine, MarkECol + 1, SwapSCol - MarkECol - 1))
cPart2 = IIF$(MarkEcol + 1 = SwapSCol, "", MID$(cSwapLine, MarkECol + 1, SwapSCol - MarkECol - 1))
'----- Get part 3, after the strings
dPart3 = MID$(dSwapLine, SwapECol + 1) ' Get part 3, After the strings
cPart3 = MID$(cSwapLine, SwapECol + 1) ' Get part 3, After the strings
'----- Rebuild the line
dSwapLine = BUILD$(dPart1, dSwapText, dPart2, dMarkText, dPart3) ' Rebuild the line
cSwapLine = BUILD$(cPart1, cSwapText, cPart2, cMarkText, cPart3) ' Rebuild the line
END IF '
me.LTxtSet (swapLnum, dSwapLine) ' Save the Swap line back
me.LAttrSet(swapLnum, cSwapLine) '
me.AttrScan(swapLnum) ' Recolorize
END IF '
swapLnum = me.CRPFwd(%mOData, swapLnum, 1) ' Move to next line
markLnum = me.CRPFwd(%mOData, markLnum, 1) ' Move to next line
NEXT SNum ' Loop till all lines in block done
me.MarkKill ' Kill the mark area
me.CurSetReq(%Position, IIF(SwapSLin < MarkSLin, SwapSLin, MarkSLin), 1, %True) ' Set cursor set attempt
DoSet(%Refresh) ' Have it looked at
'----- Only Mark area active, start a Swap activity
ELSEIF IsMarkActive AND ISFALSE IsSwapActive THEN ' We have a MARK but no SWAP, start a Swap
SwapSCol = MarkSCol ' Copy marked area as a swap area
SwapECol = MarkECol '
SwapSLin = MarkSLin '
SwapELin = MarkELin '
SwapLines = 0 ' Clear counter
FOR i = SwapSLin TO SwapELin ' Count data lines
IF IsLData(i) THEN INCR SwapLines '
NEXT i '
me.MarkKill ' Kill the mark area
OnSwapActive ' Make Swap active
me.SwapScr ' Draw the underline
'----- No Mark area, See if Move mode, or Kill time
ELSEIF ISFALSE IsMarkActive AND IsSwapActive THEN ' We have swap and no Mark, See if maybe Move mode
IF IsCData THEN ' Cursor In the Data Area?
j = GetIX(CRow) ' Get line number of the cursor
IF j < 0 THEN j = GetIX(CRow - ABS(j)) ' Convert to real line index
IF j = 0 THEN GOSUB KillSwap: MExitMeth ' Bail out if below last line
i = CCol - gLNPadCol + Offset ' Calc column index into line
IF j >= SwapSLin AND j <= SwapELin AND _ ' Cursor within the SWAP area?
i >= SwapSCol AND i <= SwapECol THEN GOSUB KillSwap: MExitMeth ' Kill if
'----- This looks like a SWAP Move mode request
'----- Init for line loop
me.SwapKill ' Remove UL so it doesn't get copied
swapLnum = SwapSLin: markLnum = j ' Point at the 1st two lines
FOR SNum = 1 TO SwapLines ' Loop for the number of lines in Swap area
'----- Extract the two lines
dSwapLine = LTxtG(swapLnum) ' Get the text from the Swap line
cSwapLine = LAttrG(swapLnum) ' Get the text from the Swap line
dMarkLine = LTxtG(markLnum) ' Get the text from the Mark line
cMarkLine = LAttrG(markLnum) ' Get the text from the Mark line
IF LEN(dSwapLine) < j THEN dSwapLine = LSET$(dSwapLine, j) ' Make sure lines are as long as the mark point
IF LEN(cSwapLine) < j THEN cSwapLine = LSET$(cSwapLine, j USING CHR$$(0)) '
IF LEN(dMarkLine) < j THEN dMarkLine = LSET$(dMarkLine, j) '
IF LEN(cMarkLine) < j THEN cMarkLine = LSET$(cMarkLine, j USING CHR$$(0)) '
IF swapLnum <> markLnum THEN ' We're dealing with two different lines
dSwapText = MID$(dSwapLine, SwapSCol TO SwapECol) ' Extract the swap data
cSwapText = MID$(cSwapLine, SwapSCol TO SwapECol) ' Extract the swap data
dSwapLine = LEFT$(dSwapLine, SwapSCol - 1) + MID$(dSwapLine, SwapECol + 1) ' Remove if from the line
cSwapLine = LEFT$(cSwapLine, SwapSCol - 1) + MID$(cSwapLine, SwapECol + 1) ' Remove if from the line
me.LTxtSet (swapLnum, dSwapLine) ' Save the Swap line back
me.LAttrSet(swapLnum, cSwapLine) ' Save the Swap line back
me.AttrScan(swapLnum) ' Recolorize
me.ModSet(swapLnum) ' Remember we changed something
'----- Handle the two different line combination
IF i = 1 THEN ' If insert point is at LH end
dMarkLine = dSwapText + dMarkLine ' Just insert it
cMarkLine = cSwapText + cMarkLine ' Just insert it
ELSE '
dMarkLine = LEFT$(dMarkLine, i - 1) + dSwapText + MID$(dMarkLine, i) ' Insert dMarkText at the cursor column
cMarkLine = LEFT$(cMarkLine, i - 1) + cSwapText + MID$(cMarkLine, i) ' Insert dMarkText at the cursor column
END IF '
me.LTxtSet (markLnum, dMarkLine) ' Save the Swap line back
me.LAttrSet(markLnum, cMarkLine) ' Save the Swap line back
me.AttrScan(markLnum) ' Recolorize
me.ModSet(markLnum) ' Remember we changed something
ELSE ' The Mark and Swap are on the same line
'----- Swap on a single line
IF SwapSCol < i THEN ' Swap is left of Mark
'----- Swap area is Left of the Mark area
dPart1 = LEFT$(dSwapLine, SwapSCol - 1) ' Get part 1, the left of Swap string
cPart1 = LEFT$(cSwapLine, SwapSCol - 1) ' Get part 1, the left of Swap string
dPart2 = MID$(dSwapLine, SwapECol + 1 TO i - 1) ' Get part 2, between the strings
cPart2 = MID$(cSwapLine, SwapECol + 1 TO i - 1) ' Get part 2, between the strings
dPart3 = MID$(dSwapLine, SwapSCol TO SwapECol) ' Get part 3, The swap string
cPart3 = MID$(cSwapLine, SwapSCol TO SwapECol) ' Get part 3, The swap string
dPart4 = MID$(dSwapLine, i) ' Get part 4, remainder of line
cPart4 = MID$(cSwapLine, i) ' Get part 4, remainder of line
dSwapLine = BUILD$(dPart1, dPart2, dPart3, dPart4) ' Rebuild the line
cSwapLine = BUILD$(cPart1, cPart2, cPart3, cPart4) ' Rebuild the line
ELSE ' Mark is left of swap
'----- Swap area is Right of the Mark point
dPart1 = LEFT$(dSwapLine, i - 1) ' Get part 1, the left of Mark string
cPart1 = LEFT$(cSwapLine, i - 1) ' Get part 1, the left of Mark string
dPart2 = MID$(dSwapLine, SwapSCol TO SwapECol) ' Get part 2, the swap string
cPart2 = MID$(cSwapLine, SwapSCol TO SwapECol) ' Get part 2, the swap string
dPart3 = MID$(dSwapLine, i TO SwapSCol - 1) ' Get part 3, Between mark and swap string
cPart3 = MID$(cSwapLine, i TO SwapSCol - 1) ' Get part 3, Between mark and swap string
dPart4 = MID$(dSwapLine, SwapECol + 1) ' Get part 4, After the Swap string
cPart4 = MID$(cSwapLine, SwapECol + 1) ' Get part 4, After the Swap string
dSwapLine = BUILD$(dPart1, dPart2, dPart3, dPart4) ' Rebuild the line
cSwapLine = BUILD$(cPart1, cPart2, cPart3, cPart4) ' Rebuild the line
END IF '
me.LTxtSet (swapLnum, dSwapLine) ' Save the Swap line back
me.LAttrSet(swapLnum, cSwapLine) ' Save the Swap line back
me.AttrScan(swapLnum) ' Recolorize
me.ModSet(swapLnum) ' Remember we changed something
END IF '
swapLnum = me.CRPFwd(%mOData, swapLnum, 1) ' Move to next line
markLnum = me.CRPFwd(%mOData, markLnum, 1) ' Move to next line
NEXT SNum ' Loop till all lines in block done
me.MarkKill ' Kill the mark area
me.SwapKill ' Kill the Swap area
me.CurSetReq(%Position, j, i, %True) ' Set cursor set attempt
DoSet(%Refresh) ' Have it looked at
ELSE ' Not even in data area
GOSUB KillSwap ' Kill things
END IF '
END IF '
MExitMeth
KillSwap:
IF IsSwapDrawn THEN me.SwapKill ' Kill underline if drawn
OffSwapActive ' Now kill Swap
RETURN
END METHOD