mirror of
https://github.com/QB64Official/qb64.git
synced 2024-07-05 04:10:22 +00:00
Allows setting watchpoints regardless of scope.
Adds "Clear Watchpoint" functionality. Allows watching more than one array index/element.
This commit is contained in:
parent
833e28aaf3
commit
a67dccae5b
|
@ -5,7 +5,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
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$, vw_globalWatchpoints$, vw_localWatchpoints$
|
||||
STATIC vw_buffer$, vw_globalWatchpoints$, vw_localWatchpoints$, vw_lastWatchpoint$
|
||||
DIM AS LONG vw_i, vw_j, vw_tempIndex, vw_localIndex, vw_varSize, vw_cmdSize
|
||||
DIM AS LONG vw_arrayElementSize, vw_element, vw_elementOffset, vw_storage, vw_blockSize
|
||||
DIM AS LONG vw_arrayDimension, vw_arrayTotalDimensions, vw_arrayIndex, vw_realArrayIndex
|
||||
|
@ -304,7 +304,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
IF vw_scope$ = LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1) THEN
|
||||
vw_address = _OFFSET(localVariables) + LEN(vw_address) * vw_localIndex
|
||||
ELSE
|
||||
IF vw_checkingWatchpoints THEN RETURN
|
||||
IF vw_checkingWatchpoints THEN vw_varType$ = "": RETURN
|
||||
GOTO cmdProcessingDone
|
||||
END IF
|
||||
END IF
|
||||
|
@ -316,7 +316,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
IF vw_originalVarLineNumber > 0 THEN
|
||||
'prevent fetching array data before DIM line
|
||||
IF vwatch_linenumber <= vw_originalVarLineNumber THEN
|
||||
IF vw_checkingWatchpoints THEN RETURN
|
||||
IF vw_checkingWatchpoints THEN vw_varType$ = "": RETURN
|
||||
GOTO cmdProcessingDone
|
||||
END IF
|
||||
END IF
|
||||
|
@ -329,7 +329,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
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
|
||||
IF vw_checkingWatchpoints THEN RETURN
|
||||
IF vw_checkingWatchpoints THEN vw_varType$ = "": RETURN
|
||||
GOTO cmdProcessingDone
|
||||
END IF
|
||||
|
||||
|
@ -545,7 +545,17 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
'vw_address now points to the actual data
|
||||
vw_m = _MEM(vw_address, vw_varSize)
|
||||
_MEMPUT vw_m, vw_m.OFFSET, vw_value$
|
||||
CASE "clear last watchpoint"
|
||||
IF LEFT$(vw_lastWatchpoint$, 1) = "g" THEN
|
||||
vw_cmd$ = "clear global watchpoint"
|
||||
ELSE
|
||||
vw_cmd$ = "clear local watchpoint"
|
||||
END IF
|
||||
vw_value$ = MID$(vw_lastWatchpoint$, 2)
|
||||
vw_getBytesPosition& = 1
|
||||
GOTO WatchpointCommands
|
||||
CASE "set global watchpoint", "set local watchpoint", "clear global watchpoint", "clear local watchpoint"
|
||||
WatchpointCommands:
|
||||
vw_getBytes& = 4: GOSUB GetBytes: vw_tempIndex = CVL(vw_valueBytes$)
|
||||
vw_getBytes& = 1: GOSUB GetBytes: vw_isArray = _CV(_BYTE, vw_valueBytes$)
|
||||
vw_getBytes& = 4: GOSUB GetBytes: vw_originalVarLineNumber = CVL(vw_valueBytes$)
|
||||
|
@ -553,7 +563,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayTotalDimensions = CVL(vw_valueBytes$)
|
||||
vw_getBytes& = vw_arrayTotalDimensions: GOSUB GetBytes: vw_arrayIndexes$ = vw_valueBytes$
|
||||
|
||||
vw_temp$ = LEFT$(vw_value$, vw_arrayTotalDimensions + 37)
|
||||
vw_temp$ = LEFT$(vw_value$, vw_arrayTotalDimensions + 33)
|
||||
|
||||
vw_arrayTotalDimensions = vw_arrayTotalDimensions \ 4
|
||||
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayElementSize = CVL(vw_valueBytes$)
|
||||
|
@ -575,24 +585,29 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
IF INSTR(vw_cmd$, " global ") THEN
|
||||
vw_buf$ = vw_globalWatchpoints$
|
||||
ELSE
|
||||
vw_scope$ = LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1)
|
||||
vw_value$ = vw_value$ + MKI$(LEN(vw_scope$)) + vw_scope$
|
||||
vw_buf$ = vw_localWatchpoints$
|
||||
END IF
|
||||
|
||||
vw_i = INSTR(vw_buf$, vw_temp$)
|
||||
vw_i = 0
|
||||
vw_i = INSTR(vw_i + 1, vw_buf$, MKL$(-1))
|
||||
DO WHILE vw_i
|
||||
IF MID$(vw_buf$, vw_i + 8, LEN(vw_temp$)) = vw_temp$ THEN EXIT DO
|
||||
vw_i = INSTR(vw_i + 1, vw_buf$, MKL$(-1))
|
||||
LOOP
|
||||
|
||||
IF vw_i > 0 THEN
|
||||
'remove existing watchpoint for the same variable/index/element
|
||||
vw_j = CVL(MID$(vw_buf$, vw_i - 4, 4))
|
||||
vw_buf$ = LEFT$(vw_buf$, vw_i - 5) + MID$(vw_buf$, vw_i + vw_j)
|
||||
vw_j = CVL(MID$(vw_buf$, vw_i + 4, 4))
|
||||
templen = LEN(vw_buf$)
|
||||
vw_buf$ = LEFT$(vw_buf$, vw_i - 1) + MID$(vw_buf$, vw_i + vw_j + 8)
|
||||
END IF
|
||||
|
||||
IF LEFT$(vw_cmd$, 4) = "set " THEN
|
||||
vw_value$ = MKI$(LEN(vw_wpExpression$)) + vw_wpExpression$ + vw_value$
|
||||
vw_buf$ = vw_buf$ + MKL$(LEN(vw_value$)) + vw_value$
|
||||
vw_value$ = vw_value$ + MKL$(LEN(vw_wpExpression$))
|
||||
vw_buf$ = vw_buf$ + MKL$(-1) + MKL$(LEN(vw_value$)) + vw_value$
|
||||
END IF
|
||||
|
||||
IF vw_cmd$ = "set global watchpoint" THEN
|
||||
IF INSTR(vw_cmd$, " global ") THEN
|
||||
vw_globalWatchpoints$ = vw_buf$
|
||||
ELSE
|
||||
vw_localWatchpoints$ = vw_buf$
|
||||
|
@ -689,9 +704,9 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
DIM vw_wpTemp$, vw_v1$, vw_v2$
|
||||
FOR vw_wpi = 1 TO 2
|
||||
IF vw_wpi = 1 AND LEN(vw_globalWatchpoints$) > 0 THEN
|
||||
vw_wpTemp$ = vw_globalWatchpoints$
|
||||
vw_wpTemp$ = MID$(vw_globalWatchpoints$, 5)
|
||||
ELSEIF vw_wpi = 2 AND LEN(vw_localWatchpoints$) > 0 THEN
|
||||
vw_wpTemp$ = vw_localWatchpoints$
|
||||
vw_wpTemp$ = MID$(vw_localWatchpoints$, 5)
|
||||
ELSE
|
||||
_CONTINUE
|
||||
END IF
|
||||
|
@ -699,16 +714,15 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
DO WHILE LEN(vw_wpTemp$)
|
||||
vw_wpj = CVL(LEFT$(vw_wpTemp$, 4))
|
||||
vw_value$ = MID$(vw_wpTemp$, 5, vw_wpj)
|
||||
vw_wpTemp$ = MID$(vw_wpTemp$, 5 + vw_wpj)
|
||||
vw_wpTemp$ = MID$(vw_wpTemp$, 9 + vw_wpj)
|
||||
IF vw_wpi = 1 THEN vw_cmd$ = "get global var" ELSE vw_cmd$ = "get local var"
|
||||
|
||||
vw_getBytesPosition& = 1
|
||||
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
|
||||
vw_getBytes& = vw_i: GOSUB GetBytes: vw_wpExpression$ = vw_valueBytes$
|
||||
vw_value$ = MID$(vw_value$, 3 + LEN(vw_wpExpression$))
|
||||
vw_i = CVL(RIGHT$(vw_value$, 4))
|
||||
vw_wpExpression$ = MID$(vw_value$, LEN(vw_value$) - (4 + vw_i) + 1, vw_i)
|
||||
|
||||
vw_getBytesPosition& = 1
|
||||
GOSUB getGlobalLocal
|
||||
IF vw_varType$ = "" THEN _CONTINUE
|
||||
|
||||
IF INSTR(vw_varType$, "STRING") THEN
|
||||
IF LEFT$(vw_wpExpression$, 1) = "=" THEN
|
||||
|
@ -755,6 +769,11 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
|
|||
|
||||
WatchPointBreak:
|
||||
'send watchpoint info and pause
|
||||
IF INSTR(vw_cmd$, "global") THEN
|
||||
vw_lastWatchpoint$ = "g" + vw_value$
|
||||
ELSE
|
||||
vw_lastWatchpoint$ = "l" + vw_value$
|
||||
END IF
|
||||
vw_checkingWatchpoints = 2
|
||||
RETURN
|
||||
|
||||
|
|
|
@ -7156,6 +7156,7 @@ SUB DebugMode
|
|||
cmd$ = "set local address:"
|
||||
END IF
|
||||
|
||||
findVarSize:
|
||||
tempVarType$ = varType$
|
||||
fixedVarSize& = 0
|
||||
IF INSTR(varType$, "STRING *") THEN
|
||||
|
@ -7232,6 +7233,8 @@ SUB DebugMode
|
|||
END IF
|
||||
END SELECT
|
||||
|
||||
IF returnAction = 2 OR returnAction = 3 THEN RETURN
|
||||
|
||||
cmd$ = cmd$ + MKL$(tempIndex&)
|
||||
cmd$ = cmd$ + _MK$(_BYTE, tempIsArray& <> 0)
|
||||
cmd$ = cmd$ + MKL$(0)
|
||||
|
@ -7290,6 +7293,9 @@ SUB DebugMode
|
|||
cmd$ = temp$ + "local watchpoint:"
|
||||
END IF
|
||||
|
||||
temp$ = value$
|
||||
GOSUB findVarSize
|
||||
|
||||
cmd$ = cmd$ + MKL$(tempIndex&)
|
||||
cmd$ = cmd$ + _MK$(_BYTE, tempIsArray& <> 0)
|
||||
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).linenumber)
|
||||
|
@ -7303,7 +7309,7 @@ SUB DebugMode
|
|||
cmd$ = cmd$ + MKL$(tempStorage&)
|
||||
cmd$ = cmd$ + MKI$(LEN(tempScope$)) + tempScope$
|
||||
cmd$ = cmd$ + MKI$(LEN(varType$)) + varType$
|
||||
cmd$ = cmd$ + MKI$(LEN(value$)) + value$
|
||||
cmd$ = cmd$ + MKI$(LEN(temp$)) + temp$
|
||||
GOSUB SendCommand
|
||||
|
||||
PCOPY 3, 0: SCREEN , , 3, 0
|
||||
|
@ -7524,7 +7530,11 @@ SUB DebugMode
|
|||
tempIndex& = CVL(GetBytes$(value$, 4))
|
||||
i = CVI(GetBytes$(value$, 2))
|
||||
temp$ = usedVariableList(tempIndex&).name + GetBytes$(value$, i)
|
||||
result = idemessagebox("Watchpoint condition met", temp$, "#Continue;#Clear Watchpoint")
|
||||
result = idemessagebox("Watchpoint condition met", temp$, "#OK;#Clear Watchpoint")
|
||||
IF result = 2 THEN
|
||||
cmd$ = "clear last watchpoint"
|
||||
GOSUB SendCommand
|
||||
END IF
|
||||
value$ = RIGHT$(value$, 4)
|
||||
END IF
|
||||
l = CVL(value$)
|
||||
|
@ -8016,7 +8026,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
|
||||
dialogWidth = 6 + maxModuleNameLen + maxVarLen + maxTypeLen
|
||||
IF IdeDebugMode > 0 THEN dialogWidth = dialogWidth + 40 'make room for "= values"
|
||||
IF dialogWidth < 60 THEN dialogWidth = 60
|
||||
IF dialogWidth < 65 THEN dialogWidth = 65
|
||||
IF dialogWidth > idewx - 8 THEN dialogWidth = idewx - 8
|
||||
|
||||
idepar p, dialogWidth, dialogHeight, "Add Watch - Variable List"
|
||||
|
@ -8190,8 +8200,8 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
|
||||
IF y >= 1 AND y <= totalVisibleVariables THEN
|
||||
tempIndex& = varDlgList(y).index
|
||||
IF usedVariableList(tempIndex&).subfunc = currentScope$ OR usedVariableList(tempIndex&).subfunc = "" THEN
|
||||
'scope is valid
|
||||
IF (focus = 5 AND (usedVariableList(tempIndex&).subfunc = currentScope$ OR usedVariableList(tempIndex&).subfunc = "")) OR focus = 6 THEN
|
||||
'scope is valid (or we're setting a watchpoint)
|
||||
tempArrayIndex& = 0
|
||||
tempArrayIndexes$ = MKL$(0)
|
||||
tempStorage& = 0
|
||||
|
@ -8200,6 +8210,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
IF usedVariableList(tempIndex&).isarray THEN
|
||||
setArrayRange3:
|
||||
v$ = ideinputbox$(dlgTitle$, dlgPrompt$, temp$, "01234567890,", 45, 0, ok)
|
||||
_KEYCLEAR
|
||||
IF ok THEN
|
||||
IF LEN(v$) > 0 THEN
|
||||
WHILE RIGHT$(v$, 1) = ",": v$ = LEFT$(v$, LEN(v$) - 1): WEND
|
||||
|
@ -8207,6 +8218,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
i = countelements(temp$)
|
||||
IF i <> ABS(ids(usedVariableList(tempIndex&).id).arrayelements) THEN
|
||||
result = idemessagebox("Error", "Array has" + STR$(ABS(ids(usedVariableList(tempIndex&).id).arrayelements)) + " dimension(s).", "#OK")
|
||||
_KEYCLEAR
|
||||
temp$ = _TRIM$(v$)
|
||||
GOTO setArrayRange3
|
||||
END IF
|
||||
|
@ -8253,6 +8265,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
LOOP
|
||||
PCOPY 0, 4
|
||||
v$ = ideelementwatchbox$(usedVariableList(tempIndex&).name + ".", elementIndexes$, 0, -1, ok)
|
||||
_KEYCLEAR
|
||||
PCOPY 2, 0
|
||||
PCOPY 2, 1
|
||||
SCREEN , , 1, 0
|
||||
|
@ -8277,6 +8290,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
IF numelements(temp$) <> 1 THEN
|
||||
'shouldn't ever happen
|
||||
result = idemessagebox("Error", "Only one UDT element can be selected at a time", "#OK")
|
||||
_KEYCLEAR
|
||||
_CONTINUE
|
||||
END IF
|
||||
|
||||
|
@ -8290,6 +8304,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
'shouldn't ever happen
|
||||
Error_Happened = 0
|
||||
result = idemessagebox("Error", Error_Message, "#OK")
|
||||
_KEYCLEAR
|
||||
_CONTINUE
|
||||
ELSE
|
||||
typ = typ - ISUDT
|
||||
|
@ -8333,6 +8348,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
ELSE
|
||||
'shouldn't ever happen
|
||||
result = idemessagebox("Error", "Cannot select full UDT", "#OK")
|
||||
_KEYCLEAR
|
||||
GOTO dlgLoop
|
||||
END IF
|
||||
END SELECT
|
||||
|
@ -8369,6 +8385,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
END IF
|
||||
getNewValueInput:
|
||||
v$ = ideinputbox$(dlgTitle$, dlgPrompt2$, a2$, "", thisWidth, 0, ok)
|
||||
_KEYCLEAR
|
||||
IF ok THEN
|
||||
IF focus = 6 THEN
|
||||
'validate condition string first
|
||||
|
@ -8389,11 +8406,13 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
CASE ">"
|
||||
IF op2$ = "<" OR op2$ = ">" THEN
|
||||
result = idemessagebox(dlgTitle$, "Invalid expression.\nYou can use =, <>, >, >=, < and <=", "#OK")
|
||||
_KEYCLEAR
|
||||
GOTO getNewValueInput
|
||||
END IF
|
||||
CASE "<"
|
||||
CASE ELSE
|
||||
result = idemessagebox(dlgTitle$, "Invalid expression.\nYou can use =, <>, >, >=, < and <=", "#OK")
|
||||
_KEYCLEAR
|
||||
GOTO getNewValueInput
|
||||
END SELECT
|
||||
END IF
|
||||
|
@ -8408,12 +8427,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).arrayElementSize)
|
||||
cmd$ = cmd$ + MKL$(tempIsUDT&)
|
||||
cmd$ = cmd$ + MKL$(tempElement&)
|
||||
IF tempElement& THEN
|
||||
tempElementOffset& = CVL(MID$(usedVariableList(tempIndex&).elementOffset, tempElement& * 4 - 3, 4))
|
||||
ELSE
|
||||
tempElementOffset& = 0
|
||||
END IF
|
||||
cmd$ = cmd$ + MKL$(tempElementOffset&)
|
||||
cmd$ = cmd$ + tempElementOffset$
|
||||
cmd$ = cmd$ + MKL$(varSize&)
|
||||
cmd$ = cmd$ + MKL$(tempStorage&)
|
||||
cmd$ = cmd$ + MKI$(LEN(usedVariableList(tempIndex&).subfunc))
|
||||
|
@ -8429,9 +8443,11 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
|
|||
EXIT FUNCTION
|
||||
ELSE
|
||||
result = idemessagebox(dlgTitle$, "Variable is out of scope.", "#OK")
|
||||
_KEYCLEAR
|
||||
END IF
|
||||
ELSE
|
||||
result = idemessagebox(dlgTitle$, "Select a variable first.", "#OK")
|
||||
_KEYCLEAR
|
||||
END IF
|
||||
focus = filterBox
|
||||
_CONTINUE
|
||||
|
|
Loading…
Reference in a new issue