1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-06-26 17:10:38 +00:00

Adds support to watching arrays with multiple dimensions.

This commit is contained in:
FellippeHeitor 2021-09-08 22:47:31 -03:00
parent a02243455b
commit a37e3801d8
2 changed files with 163 additions and 51 deletions

View file

@ -2,18 +2,19 @@ $CHECKING:OFF
SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
STATIC AS LONG vw_ideHost, vw_breakpointCount, vw_skipCount, vw_timeout, vw_startLevel, vw_lastLine
STATIC AS LONG vw_runToLine, vw_arrayIndex, vw_originalVarLineNumber
STATIC AS LONG vw_runToLine, vw_originalVarLineNumber
STATIC AS _BYTE vw_pauseMode, vw_stepOver, vw_bypass, vw_setNextLine, vw_hwndSent
STATIC AS _OFFSET vw_ideHwnd
STATIC vw_buffer$
DIM AS LONG vw_i, vw_tempIndex, vw_localIndex, vw_varSize, vw_cmdSize
DIM AS LONG vw_arrayElementSize, vw_element, vw_elementOffset, vw_storage
DIM AS LONG vw_arrayDimension, vw_arrayTotalDimensions
DIM AS LONG vw_arrayElementSize, vw_element, vw_elementOffset, vw_storage, vw_blockSize
DIM AS LONG vw_arrayDimension, vw_arrayTotalDimensions, vw_arrayIndex, vw_realArrayIndex
DIM AS _OFFSET vw_address, vw_lBound, vw_uBound
DIM AS _MEM vw_m, vw_m2
DIM AS _BYTE vw_isArray, vw_isUDT
DIM vw_start!, vw_temp$, vw_cmd$, vw_value$, vw_k&, vw_buf$, vw_scope$, vw_varType$
DIM vw_prevValue$, vw_getBytes&, vw_getBytesPosition&, vw_valueBytes$, vw_dummy%&
DIM vw_arrayIndexes$
DECLARE LIBRARY
SUB vwatch_stoptimers ALIAS stop_timers
@ -261,7 +262,9 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
vw_getBytes& = 1: GOSUB GetBytes: vw_isArray = _CV(_BYTE, vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_originalVarLineNumber = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_localIndex = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayIndex = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayTotalDimensions = CVL(vw_valueBytes$)
vw_getBytes& = vw_arrayTotalDimensions: GOSUB GetBytes: vw_arrayIndexes$ = vw_valueBytes$
vw_arrayTotalDimensions = vw_arrayTotalDimensions \ 4
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayElementSize = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_element = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_elementOffset = CVL(vw_valueBytes$)
@ -293,12 +296,22 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
'prevent fetching array data before DIM line
IF vwatch_linenumber <= vw_originalVarLineNumber THEN GOTO cmdProcessingDone
END IF
vw_lBound = check_lbound%&(vw_address, vw_arrayDimension, vw_arrayTotalDimensions)
vw_uBound = check_ubound%&(vw_address, vw_arrayDimension, vw_arrayTotalDimensions)
IF vw_arrayIndex < vw_lBound OR vw_arrayIndex > vw_uBound THEN
GOTO cmdProcessingDone
END IF
vw_realArrayIndex = 0
vw_blockSize = 1
FOR vw_arrayDimension = 1 TO vw_arrayTotalDimensions
vw_lBound = check_lbound%&(vw_address, vw_arrayDimension, vw_arrayTotalDimensions)
vw_uBound = check_ubound%&(vw_address, vw_arrayDimension, vw_arrayTotalDimensions)
vw_arrayIndex = CVL(MID$(vw_arrayIndexes$, vw_arrayDimension * 4 - 3, 4))
IF vw_arrayIndex < vw_lBound OR vw_arrayIndex > vw_uBound THEN
GOTO cmdProcessingDone
END IF
vw_arrayIndex = (vw_arrayIndex - VAL(STR$(vw_lBound))) * vw_blockSize
vw_realArrayIndex = vw_realArrayIndex + vw_arrayIndex
vw_blockSize = vw_blockSize * VAL(STR$(vw_uBound - vw_lBound + 1))
NEXT
'get the address of where this array's data is stored
vw_buf$ = SPACE$(LEN(vw_dummy%&))
@ -321,9 +334,9 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
END IF
'this is where we calculate the actual array index position in memory
IF vw_arrayElementSize = 0 THEN
vw_address = vw_address + ((vw_arrayIndex - vw_lBound) * vw_varSize)
vw_address = vw_address + (vw_realArrayIndex * vw_varSize)
ELSE
vw_address = vw_address + ((vw_arrayIndex - vw_lBound) * vw_arrayElementSize)
vw_address = vw_address + (vw_realArrayIndex * vw_arrayElementSize)
END IF
END IF
@ -538,6 +551,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
ELSE
vw_cmd$ = "": vw_value$ = ""
END IF
vw_prevValue$ = ""
RETURN
SendCallStack:
@ -566,6 +580,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
vw_prevValue$ = vw_value$
vw_getBytesPosition& = 1
END IF
IF vw_getBytes& = 0 THEN vw_valueBytes$ = "": RETURN
vw_valueBytes$ = MID$(vw_value$, vw_getBytesPosition&, vw_getBytes&)
vw_getBytesPosition& = vw_getBytesPosition& + vw_getBytes&
RETURN

View file

@ -7399,14 +7399,20 @@ SUB DebugMode
'request variables addresses
IF LEN(variableWatchList$) THEN
requestVariableValues:
temp$ = MID$(variableWatchList$, 9)
DO WHILE LEN(temp$)
tempIndex& = CVL(LEFT$(temp$, 4))
tempArrayIndex& = CVL(MID$(temp$, 5, 4))
tempElement& = CVL(MID$(temp$, 9, 4))
tempElementOffset& = CVL(MID$(temp$, 13, 4))
tempStorage& = CVL(MID$(temp$, 17, 4))
temp$ = MID$(temp$, 25)
temp$ = GetBytes$("", 0) 'reset buffer
temp$ = MID$(variableWatchList$, 9) 'skip longest var name and total visible vars
DO
temp2$ = GetBytes$(temp$, 4)
IF temp2$ <> MKL$(-1) THEN EXIT DO 'no more variables in list
tempIndex& = CVL(GetBytes$(temp$, 4))
tempArrayIndexes$ = GetBytes$(temp$, 4)
i = CVL(tempArrayIndexes$)
IF i > 0 THEN
tempArrayIndexes$ = tempArrayIndexes$ + GetBytes$(temp$, i)
END IF
tempElement& = CVL(GetBytes$(temp$, 4))
tempElementOffset& = CVL(GetBytes$(temp$, 4))
tempStorage& = CVL(GetBytes$(temp$, 4))
IF LEN(usedVariableList(tempIndex&).subfunc) = 0 THEN
cmd$ = "get global var:"
ELSE
@ -7418,7 +7424,7 @@ SUB DebugMode
cmd$ = cmd$ + _MK$(_BYTE, usedVariableList(tempIndex&).isarray)
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).linenumber)
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).localIndex)
cmd$ = cmd$ + MKL$(tempArrayIndex&)
cmd$ = cmd$ + tempArrayIndexes$
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).arrayElementSize)
cmd$ = cmd$ + MKL$(tempElement&)
IF tempElement& THEN
@ -7662,7 +7668,7 @@ SUB showvWatchPanel (this AS vWatchPanelType, currentScope$, totalVisibleVariabl
'new setup
previousVariableWatchList$ = variableWatchList$
longestVarName = CVL(LEFT$(variableWatchList$, 4))
totalVisibleVariables = (LEN(variableWatchList$) - 4) \ 20
totalVisibleVariables = CVL(MID$(variableWatchList$, 5, 4))
this.h = totalVisibleVariables + 2
IF this.h > idewy - 10 THEN this.h = idewy - 10
IF this.h < 5 THEN this.h = 5
@ -7697,14 +7703,18 @@ SUB showvWatchPanel (this AS vWatchPanelType, currentScope$, totalVisibleVariabl
i = 0
this.contentWidth = 0
IF this.hPos = 0 THEN this.hPos = 1
temp$ = GetBytes$("", 0) 'reset buffer
temp$ = MID$(variableWatchList$, 9)
DO WHILE LEN(temp$)
tempIndex& = CVL(LEFT$(temp$, 4))
tempArrayIndex& = CVL(MID$(temp$, 5, 4))
tempElement& = CVL(MID$(temp$, 9, 4))
tempElementOffset& = CVL(MID$(temp$, 13, 4))
tempStorage& = CVL(MID$(temp$, 17, 4))
temp$ = MID$(temp$, 25)
DO
temp2$ = GetBytes$(temp$, 4)
IF temp2$ <> MKL$(-1) THEN EXIT DO 'no more variables in list
tempIndex& = CVL(GetBytes$(temp$, 4))
tempTotalArrayIndexes& = CVL(GetBytes$(temp$, 4))
tempArrayIndexes$ = GetBytes$(temp$, tempTotalArrayIndexes&)
tempElement& = CVL(GetBytes$(temp$, 4))
tempElementOffset& = CVL(GetBytes$(temp$, 4))
tempStorage& = CVL(GetBytes$(temp$, 4))
i = i + 1
IF this.firstVisible > i AND WatchListToConsole = 0 THEN _CONTINUE
y = y + 1
@ -7712,8 +7722,13 @@ SUB showvWatchPanel (this AS vWatchPanelType, currentScope$, totalVisibleVariabl
thisName$ = usedVariableList(tempIndex&).name
IF usedVariableList(tempIndex&).isarray THEN
thisName$ = LEFT$(thisName$, LEN(thisName$) - 1) + _
LTRIM$(STR$(tempArrayIndex&)) + ")"
thisName$ = LEFT$(thisName$, LEN(thisName$) - 1)
tempTotalArrayIndexes& = tempTotalArrayIndexes& \ 4
FOR j = 1 TO tempTotalArrayIndexes&
thisName$ = thisName$ + LTRIM$(STR$(CVL(MID$(tempArrayIndexes$, j * 4 - 3, 4))))
IF j < tempTotalArrayIndexes& THEN thisName$ = thisName$ + ", "
NEXT
thisName$ = thisName$ + ")"
END IF
IF tempElement& THEN
tempElementList$ = MID$(usedVariableList(tempIndex&).elements, 5)
@ -8199,12 +8214,13 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
variableWatchList$ = ""
longestVarName = 0
nextvWatchDataSlot = 0
totalVisibleVariables = 0
FOR y = 1 TO totalVariablesCreated
IF usedVariableList(y).includedLine THEN _CONTINUE 'don't deal with variables in $INCLUDEs
IF usedVariableList(y).watch THEN
thisLen = LEN(usedVariableList(y).name)
IF usedVariableList(y).isarray THEN
thisLen = thisLen + LEN(STR$(CVL(RIGHT$(usedVariableList(y).indexes, 4)))) - 1
thisLen = thisLen + LEN(usedVariableList(y).watchRange)
END IF
IF LEN(usedVariableList(y).elements) THEN
@ -8213,28 +8229,39 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
IF thisLen > longestVarName THEN
longestVarName = thisLen
IF variableWatchList$ = "" THEN variableWatchList$ = SPACE$(4)
IF variableWatchList$ = "" THEN variableWatchList$ = SPACE$(8)
MID$(variableWatchList$, 1, 4) = MKL$(longestVarName)
END IF
IF usedVariableList(y).isarray <> 0 AND LEN(usedVariableList(y).elements) = 0 THEN
'array of native data type
temp$ = usedVariableList(y).indexes
DO WHILE LEN(temp$)
temp$ = GetBytes$("", 0)
temp$ = expandArray$(usedVariableList(y).indexes, "")
DO
temp2$ = GetBytes$(temp$, 4)
IF LEN(temp2$) <> 4 THEN EXIT DO 'no more items
length = CVL(temp2$)
temp2$ = MKL$(length) + GetBytes$(temp$, length)
nextvWatchDataSlot = nextvWatchDataSlot + 1
WHILE nextvWatchDataSlot > UBOUND(vWatchReceivedData$)
REDIM _PRESERVE vWatchReceivedData$(1 TO UBOUND(vWatchReceivedData$) + 999)
WEND
variableWatchList$ = variableWatchList$ + MKL$(-1) + MKL$(y) + LEFT$(temp$, 4) + MKL$(0) + MKL$(0) + MKL$(nextvWatchDataSlot)
variableWatchList$ = variableWatchList$ + MKL$(-1) + MKL$(y) + temp2$ + MKL$(0) + MKL$(0) + MKL$(nextvWatchDataSlot)
totalVisibleVariables = totalVisibleVariables + 1
usedVariableList(y).storage = usedVariableList(y).storage + MKL$(nextvWatchDataSlot)
vWatchReceivedData$(nextvWatchDataSlot) = ""
temp$ = MID$(temp$, 5)
LOOP
ELSEIF usedVariableList(y).isarray <> 0 AND LEN(usedVariableList(y).elements) > 0 THEN
'array of UDT
temp$ = usedVariableList(y).indexes
DO WHILE LEN(temp$)
thisTempElement$ = MKL$(-1) + MKL$(y) + LEFT$(temp$, 4)
temp$ = GetBytes$("", 0)
temp$ = expandArray$(usedVariableList(y).indexes, "")
DO
temp2$ = GetBytes$(temp$, 4)
IF LEN(temp2$) <> 4 THEN EXIT DO 'no more items
length = CVL(temp2$)
temp2$ = MKL$(length) + GetBytes$(temp$, length)
thisTempElement$ = MKL$(-1) + MKL$(y) + temp2$
thisElementList$ = MID$(usedVariableList(y).elements, 5)
i = 0
DO
@ -8248,10 +8275,10 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
WEND
tempElementOffset& = CVL(MID$(usedVariableList(y).elementOffset, i * 4 - 3, 4))
variableWatchList$ = variableWatchList$ + thisTempElement$ + MKL$(i) + MKL$(tempElementOffset&) + MKL$(nextvWatchDataSlot)
totalVisibleVariables = totalVisibleVariables + 1
usedVariableList(y).storage = usedVariableList(y).storage + MKL$(nextvWatchDataSlot)
vWatchReceivedData$(nextvWatchDataSlot) = ""
LOOP
temp$ = MID$(temp$, 5)
LOOP
ELSEIF usedVariableList(y).isarray = 0 AND LEN(usedVariableList(y).elements) > 0 THEN
'single variable of UDT
@ -8269,6 +8296,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
WEND
tempElementOffset& = CVL(MID$(usedVariableList(y).elementOffset, i * 4 - 3, 4))
variableWatchList$ = variableWatchList$ + thisTempElement$ + MKL$(i) + MKL$(tempElementOffset&) + MKL$(nextvWatchDataSlot)
totalVisibleVariables = totalVisibleVariables + 1
usedVariableList(y).storage = usedVariableList(y).storage + MKL$(nextvWatchDataSlot)
vWatchReceivedData$(nextvWatchDataSlot) = ""
LOOP
@ -8279,10 +8307,12 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
REDIM _PRESERVE vWatchReceivedData$(1 TO UBOUND(vWatchReceivedData$) + 999)
WEND
variableWatchList$ = variableWatchList$ + MKL$(-1) + MKL$(y) + MKL$(0) + MKL$(0) + MKL$(0) + MKL$(nextvWatchDataSlot)
totalVisibleVariables = totalVisibleVariables + 1
usedVariableList(y).storage = MKL$(nextvWatchDataSlot)
END IF
END IF
NEXT
IF LEN(variableWatchList$) THEN MID$(variableWatchList$, 5, 4) = MKL$(totalVisibleVariables)
IF mousedown THEN
DO
GetInput
@ -8322,17 +8352,38 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
IF LEN(usedVariableList(varDlgList(y).index).indexes) THEN
temp$ = usedVariableList(varDlgList(y).index).watchRange
END IF
v$ = ideinputbox$("Watch Array", "#Indexes to watch", temp$, "01234567890,-", 45, 0, ok)
setArrayRange2:
v$ = ideinputbox$("Watch Array", "#Indexes" + tempPrompt$, temp$, "01234567890,-; TOto", 45, 0, ok)
IF ok THEN
IF LEN(v$) > 0 THEN
temp$ = parseRange$(v$)
usedVariableList(varDlgList(y).index).indexes = temp$
temp$ = formatRange$(temp$)
usedVariableList(varDlgList(y).index).watchRange = temp$
ELSE
v$ = UCASE$(v$)
v$ = StrReplace$(v$, " TO ", "-")
WHILE RIGHT$(v$, 1) = ",": v$ = LEFT$(v$, LEN(v$) - 1): WEND
temp$ = lineformat$(v$)
i = countelements(temp$)
IF i <> ABS(ids(usedVariableList(varDlgList(y).index).id).arrayelements) THEN
result = idemessagebox("Error", "Array has" + STR$(ABS(ids(usedVariableList(varDlgList(y).index).id).arrayelements)) + " dimension(s).", "#OK")
temp$ = v$
GOTO setArrayRange2
END IF
usedVariableList(varDlgList(y).index).indexes = ""
usedVariableList(varDlgList(y).index).watchRange = ""
WHILE i
foundComma = INSTR(v$, ",")
IF foundComma THEN
temp$ = LEFT$(v$, foundComma - 1)
v$ = MID$(v$, foundComma + 1)
ELSE
temp$ = v$
END IF
temp$ = parseRange$(temp$)
usedVariableList(varDlgList(y).index).indexes = usedVariableList(varDlgList(y).index).indexes + MKL$(LEN(temp$)) + temp$
temp$ = formatRange$(temp$)
usedVariableList(varDlgList(y).index).watchRange = usedVariableList(varDlgList(y).index).watchRange + temp$
i = i - 1
IF i THEN usedVariableList(varDlgList(y).index).watchRange = usedVariableList(varDlgList(y).index).watchRange + ","
WEND
ELSE
usedVariableList(varDlgList(y).index).watch = 0
GOSUB buildList
idetxt(o(varListBox).txt) = l$
@ -8344,6 +8395,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
usedVariableList(varDlgList(y).index).watch = 0
GOTO unWatch
END IF
END IF
varType$ = usedVariableList(varDlgList(y).index).varType
@ -9064,10 +9116,10 @@ FUNCTION formatRange$(__text$)
v2 = v
ELSE
IF v2 = -1 THEN
a2$ = a2$ + LTRIM$(STR$(v1)) + ","
a2$ = a2$ + LTRIM$(STR$(v1)) + ";"
v1 = v
ELSE
a2$ = a2$ + LTRIM$(STR$(v1)) + "-" + LTRIM$(STR$(v2)) + ","
a2$ = a2$ + LTRIM$(STR$(v1)) + "-" + LTRIM$(STR$(v2)) + ";"
v1 = v
v2 = -1
END IF
@ -9079,6 +9131,37 @@ FUNCTION formatRange$(__text$)
formatRange$ = a2$
END FUNCTION
FUNCTION expandArray$ (__indexes$, __path$)
STATIC thisLevel AS LONG, returnValue$
IF thisLevel = 0 THEN
returnValue$ = ""
END IF
thisLevel = thisLevel + 1
totalIndexes = CVL(LEFT$(__indexes$, 4))
indexes$ = MID$(__indexes$, 5, totalIndexes)
remainingIndexes$ = MID$(__indexes$, 5 + totalIndexes)
totalIndexes = totalIndexes \ 4
FOR i = 1 TO totalIndexes
temp$ = __path$ + MID$(indexes$, i * 4 - 3, 4)
IF LEN(remainingIndexes$) THEN
temp$ = expandArray$(remainingIndexes$, temp$)
END IF
IF LEN(temp$) THEN
returnValue$ = returnValue$ + MKL$(LEN(temp$)) + temp$
END IF
NEXT
thisLevel = thisLevel - 1
IF thisLevel = 0 THEN
expandArray$ = returnValue$
END IF
END FUNCTION
FUNCTION parseRange$(__text$)
'__text$ must contain a valid numeric string (####),
'a valid interval (####-####) or comma-separated values.
@ -9090,7 +9173,7 @@ FUNCTION parseRange$(__text$)
DIM zeroIncluded AS _BYTE
Filter$ = _TRIM$(__text$)
j = INSTR(Filter$, "-") + INSTR(Filter$, ",")
j = INSTR(Filter$, "-") + INSTR(Filter$, ";")
temp$ = SPACE$(1000)
IF j = 0 THEN 'Single number passed
@ -9102,7 +9185,7 @@ FUNCTION parseRange$(__text$)
FOR j = 1 TO LEN(Filter$)
v = ASC(Filter$, j)
SELECT CASE v
CASE 44 'comma
CASE 59 ';
Reading = 1
GOSUB parseIt
CASE 45 'hyphen
@ -18658,3 +18741,17 @@ SUB printWrapStatus (x AS INTEGER, y AS INTEGER, initialX AS INTEGER, __text$)
RETURN
END SUB
FUNCTION GetBytes$(__value$, numberOfBytes&)
STATIC prevValue$, getBytesPosition&
value$ = __value$
IF value$ <> prevValue$ THEN
prevValue$ = value$
getBytesPosition& = 1
END IF
IF numberOfBytes& = 0 THEN EXIT FUNCTION
GetBytes$ = MID$(value$, getBytesPosition&, numberOfBytes&)
getBytesPosition& = getBytesPosition& + numberOfBytes&
END FUNCTION