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

Implements watchpoints.

This commit is contained in:
FellippeHeitor 2021-09-16 00:04:20 -03:00
parent 71c291a7f1
commit 926b631f3b
2 changed files with 421 additions and 48 deletions

View file

@ -5,16 +5,16 @@ 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$
DIM AS LONG vw_i, vw_tempIndex, vw_localIndex, vw_varSize, vw_cmdSize
STATIC vw_buffer$, vw_globalWatchpoints$, vw_localWatchpoints$
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
DIM AS _OFFSET vw_address, vw_lBound, vw_uBound
DIM AS _MEM vw_m, vw_m2
DIM AS _BYTE vw_isArray, vw_isUDT
DIM AS _BYTE vw_isArray, vw_isUDT, vw_checkingWatchpoints
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$
DIM vw_getBytes&, vw_getBytesPosition&, vw_valueBytes$, vw_dummy%&
DIM vw_arrayIndexes$, vw_wpExpression$
DECLARE LIBRARY
SUB vwatch_stoptimers ALIAS stop_timers
@ -27,8 +27,8 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
END DECLARE
$IF WIN THEN
DECLARE DYNAMIC LIBRARY "user32"
FUNCTION SetForegroundWindow& (BYVAL hWnd AS _OFFSET)
DECLARE CUSTOMTYPE LIBRARY
FUNCTION vwSetForegroundWindow& ALIAS "SetForegroundWindow" (BYVAL hWnd AS _OFFSET)
END DECLARE
$END IF
@ -177,6 +177,20 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
REDIM vwatch_skiplines(UBOUND(vwatch_skiplines)) AS _BYTE
END SELECT
IF LEN(vw_globalWatchpoints$) > 0 OR LEN(vw_localWatchpoints$) > 0 THEN
vw_checkingWatchpoints = -1
GOSUB CheckWatchpoints
IF vw_checkingWatchpoints = 2 THEN
vw_checkingWatchpoints = 0
vw_pauseMode = -1
vw_stepOver = 0
vw_runToLine = 0
vw_cmd$ = "watchpoint:" + MKI$(LEN(vw_wpExpression$)) + vw_wpExpression$
GOTO breakReached
END IF
END IF
vw_checkingWatchpoints = 0
IF vwatch_skiplines(vwatch_linenumber) THEN vwatch_goto = -vwatch_linenumber: EXIT SUB
IF vw_stepOver = -1 AND vwatch_sublevel > vw_startLevel AND vwatch_breakpoints(vwatch_linenumber) = 0 THEN
@ -197,16 +211,17 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
EXIT SUB
END IF
vwatch_stoptimers
vw_cmd$ = "line number:"
IF vwatch_breakpoints(vwatch_linenumber) THEN vw_cmd$ = "breakpoint:"
breakReached:
vwatch_stoptimers
vw_cmd$ = vw_cmd$ + MKL$(vwatch_linenumber)
GOSUB SendCommand
vw_cmd$ = "current sub:" + LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1)
GOSUB SendCommand
$IF WIN THEN
vw_i = SetForegroundWindow&(vw_ideHwnd)
vw_i = vwSetForegroundWindow&(vw_ideHwnd)
$END IF
DO 'main loop
@ -258,25 +273,45 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
'send call stack history
GOSUB SendCallStack
CASE "get global var", "get local var"
getGlobalLocal:
vw_getBytes& = 4: GOSUB GetBytes: vw_tempIndex = CVL(vw_valueBytes$)
PRINT "vw_tempIndex =" ; vw_tempIndex
vw_getBytes& = 1: GOSUB GetBytes: vw_isArray = _CV(_BYTE, vw_valueBytes$)
PRINT "vw_isArray =" ; vw_isArray
vw_getBytes& = 4: GOSUB GetBytes: vw_originalVarLineNumber = CVL(vw_valueBytes$)
PRINT "vw_originalVarLineNumber =" ; vw_originalVarLineNumber
vw_getBytes& = 4: GOSUB GetBytes: vw_localIndex = CVL(vw_valueBytes$)
PRINT "vw_localIndex =" ; vw_localIndex
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayTotalDimensions = CVL(vw_valueBytes$)
PRINT "vw_arrayTotalDimensions =" ; vw_arrayTotalDimensions
vw_getBytes& = vw_arrayTotalDimensions: GOSUB GetBytes: vw_arrayIndexes$ = vw_valueBytes$
vw_arrayTotalDimensions = vw_arrayTotalDimensions \ 4
PRINT "vw_arrayTotalDimensions \ 4 =" ; vw_arrayTotalDimensions
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayElementSize = CVL(vw_valueBytes$)
PRINT "vw_arrayElementSize =" ; vw_arrayElementSize
IF vw_checkingWatchpoints THEN vw_getBytes& = 4: GOSUB GetBytes 'discard 4 bytes (isUDT)
vw_getBytes& = 4: GOSUB GetBytes: vw_element = CVL(vw_valueBytes$)
PRINT "vw_element =" ; vw_element
vw_getBytes& = 4: GOSUB GetBytes: vw_elementOffset = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_varSize = CVL(vw_valueBytes$)
IF vw_varSize = 0 THEN GOTO cmdProcessingDone
PRINT "vw_elementOffset =" ; vw_elementOffset
vw_getBytes& = 4: GOSUB GetBytes: PRINT "LEN() = "; LEN(vw_valueBytes$): vw_varSize = CVL(vw_valueBytes$)
PRINT "vw_varSize =" ; vw_varSize
IF vw_varSize = 0 THEN
IF vw_checkingWatchpoints THEN
PRINT "RETURNING CAUSE VAR SIZE = 0": RETURN
END IF
GOTO cmdProcessingDone
END IF
vw_getBytes& = 4: GOSUB GetBytes: vw_storage = CVL(vw_valueBytes$)
PRINT "vw_storage =" ; vw_storage
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
IF vw_i THEN
vw_getBytes& = vw_i: GOSUB GetBytes: vw_scope$ = vw_valueBytes$
PRINT "vw_scope$ = " ; vw_scope$
END IF
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
vw_getBytes& = vw_i: GOSUB GetBytes: vw_varType$ = vw_valueBytes$
PRINT "vw_varType$ =" ; vw_varType$
IF vw_cmd$ = "get global var" THEN
vw_address = _OFFSET(globalVariables) + LEN(vw_address) * vw_localIndex
@ -284,6 +319,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 PRINT "RETURNING CAUSE OUT OF SCOPE": RETURN
GOTO cmdProcessingDone
END IF
END IF
@ -294,7 +330,10 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
IF vw_isArray THEN
IF vw_originalVarLineNumber > 0 THEN
'prevent fetching array data before DIM line
IF vwatch_linenumber <= vw_originalVarLineNumber THEN GOTO cmdProcessingDone
IF vwatch_linenumber <= vw_originalVarLineNumber THEN
IF vw_checkingWatchpoints THEN PRINT "RETURNING CAUSE BEFORE DIM": RETURN
GOTO cmdProcessingDone
END IF
END IF
vw_realArrayIndex = 0
@ -305,6 +344,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 PRINT "RETURNING CAUSE OUT OF BOUNDS": RETURN
GOTO cmdProcessingDone
END IF
@ -387,18 +427,29 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
_MEMCOPY vw_m, vw_m.OFFSET, vw_m.SIZE TO vw_m2, vw_m2.OFFSET
END IF
IF vw_checkingWatchpoints THEN PRINT "RETURNING WITH VW_BUF$": RETURN
vw_cmd$ = "address read:" + MKL$(vw_tempIndex) + MKL$(vw_arrayIndex) + MKL$(vw_element) + MKL$(vw_storage) + vw_buf$
GOSUB SendCommand
CASE "set global address", "set local address"
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$)
vw_getBytes& = 4: GOSUB GetBytes: vw_localIndex = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_isArray = (CVL(vw_valueBytes$) <> 0)
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_isUDT = (CVL(vw_valueBytes$) <> 0)
vw_getBytes& = 4: GOSUB GetBytes: vw_elementOffset = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayElementSize = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_isUDT = (CVL(vw_valueBytes$) <> 0)
vw_getBytes& = 4: GOSUB GetBytes: vw_element = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_elementOffset = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_varSize = CVL(vw_valueBytes$)
IF vw_varSize = 0 THEN GOTO cmdProcessingDone
vw_getBytes& = 4: GOSUB GetBytes: vw_storage = CVL(vw_valueBytes$)
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
IF vw_i THEN
vw_getBytes& = vw_i: GOSUB GetBytes: vw_scope$ = vw_valueBytes$
END IF
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
vw_getBytes& = vw_i: GOSUB GetBytes: vw_varType$ = vw_valueBytes$
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
@ -509,6 +560,73 @@ 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 "set global watchpoint", "set local watchpoint", "clear global watchpoint", "clear local watchpoint"
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$)
vw_getBytes& = 4: GOSUB GetBytes: vw_localIndex = CVL(vw_valueBytes$)
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_arrayTotalDimensions = vw_arrayTotalDimensions \ 4
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayElementSize = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_isUDT = (CVL(vw_valueBytes$) <> 0)
vw_getBytes& = 4: GOSUB GetBytes: vw_element = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_elementOffset = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_varSize = CVL(vw_valueBytes$)
IF vw_varSize = 0 THEN GOTO cmdProcessingDone
vw_getBytes& = 4: GOSUB GetBytes: vw_storage = CVL(vw_valueBytes$)
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
IF vw_i THEN
vw_getBytes& = vw_i: GOSUB GetBytes: vw_scope$ = vw_valueBytes$
END IF
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
vw_getBytes& = vw_i: GOSUB GetBytes: vw_varType$ = vw_valueBytes$
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
vw_getBytes& = vw_i: GOSUB GetBytes: vw_wpExpression$ = vw_valueBytes$
PRINT "WATCHPOINT ----------------------------------------------"
PRINT "vw_tempIndex =" ; vw_tempIndex
PRINT "vw_isArray =" ; vw_isArray
PRINT "vw_originalVarLineNumber =" ; vw_originalVarLineNumber
PRINT "vw_localIndex =" ; vw_localIndex
PRINT "vw_arrayTotalDimensions \ 4 =" ; vw_arrayTotalDimensions
PRINT "vw_arrayElementSize =" ; vw_arrayElementSize
PRINT "vw_element =" ; vw_element
PRINT "vw_elementOffset =" ; vw_elementOffset
PRINT "vw_varSize =" ; vw_varSize
PRINT "vw_storage =" ; vw_storage
PRINT "vw_scope$ = " ; vw_scope$
PRINT "vw_varType$ =" ; vw_varType$
PRINT "vw_wpExpression$ =" ; vw_wpExpression$
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$)
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)
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$
END IF
IF vw_cmd$ = "set global watchpoint" THEN
vw_globalWatchpoints$ = vw_buf$
ELSE
vw_localWatchpoints$ = vw_buf$
END IF
CASE "current sub"
vw_cmd$ = "current sub:" + LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1)
GOSUB SendCommand
@ -595,4 +713,133 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
vw_valueBytes$ = MID$(vw_value$, vw_getBytesPosition&, vw_getBytes&)
vw_getBytesPosition& = vw_getBytesPosition& + vw_getBytes&
RETURN
CheckWatchpoints:
PRINT "Checking watchpoints."
DIM AS LONG vw_wpi, vw_wpj
DIM vw_wpTemp$, vw_v1$, vw_v2$
FOR vw_wpi = 1 TO 2
PRINT "vw_wpi ="; vw_wpi
IF vw_wpi = 1 AND LEN(vw_globalWatchpoints$) > 0 THEN
vw_wpTemp$ = vw_globalWatchpoints$
ELSEIF vw_wpi = 2 AND LEN(vw_localWatchpoints$) > 0 THEN
vw_wpTemp$ = vw_localWatchpoints$
ELSE
_CONTINUE
END IF
DO WHILE LEN(vw_wpTemp$)
vw_wpj = CVL(LEFT$(vw_wpTemp$, 4))
PRINT "vw_wpj ="; vw_wpj
vw_value$ = MID$(vw_wpTemp$, 5, vw_wpj)
vw_wpTemp$ = MID$(vw_wpTemp$, 5 + 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$
PRINT "vw_wpExpression$: "; vw_wpExpression$
vw_value$ = MID$(vw_value$, 3 + LEN(vw_wpExpression$))
PRINT "going to sub getGlobalLocal"
vw_getBytesPosition& = 1
GOSUB getGlobalLocal
PRINT "got value!! --------------------------"
PRINT "vw_varType$ = "; vw_varType$
IF INSTR(vw_varType$, "STRING") THEN
PRINT "It's a string"
IF LEFT$(vw_wpExpression$, 1) = "=" THEN
IF _TRIM$(MID$(vw_wpExpression$, 2)) = _TRIM$(vw_buf$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 2) = "<=" THEN
IF _TRIM$(MID$(vw_wpExpression$, 2)) <= _TRIM$(vw_buf$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 2) = ">=" THEN
IF _TRIM$(MID$(vw_wpExpression$, 2)) >= _TRIM$(vw_buf$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 2) = "<>" THEN
IF _TRIM$(MID$(vw_wpExpression$, 2)) <> _TRIM$(vw_buf$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 1) = "<" THEN
IF _TRIM$(MID$(vw_wpExpression$, 2)) < _TRIM$(vw_buf$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 1) = ">" THEN
IF _TRIM$(MID$(vw_wpExpression$, 2)) > _TRIM$(vw_buf$) THEN GOTO WatchPointBreak
END IF
ELSE
PRINT "It's a number"
IF LEFT$(vw_wpExpression$, 1) = "=" THEN
vw_v1$ = _TRIM$(MID$(vw_wpExpression$, 2))
ELSEIF LEFT$(vw_wpExpression$, 2) = "<=" OR LEFT$(vw_wpExpression$, 2) = ">=" OR LEFT$(vw_wpExpression$, 2) = "<>" THEN
vw_v1$ = _TRIM$(MID$(vw_wpExpression$, 3))
ELSEIF LEFT$(vw_wpExpression$, 1) = "<" OR LEFT$(vw_wpExpression$, 1) = ">" THEN
vw_v1$ = _TRIM$(MID$(vw_wpExpression$, 2))
END IF
GOSUB GetV2
PRINT "vw_v1$ = "; vw_v1$
PRINT "vw_v2$ = "; vw_v2$
IF LEFT$(vw_wpExpression$, 1) = "=" THEN
IF VAL(vw_v2$) = VAL(vw_v1$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 2) = "<=" THEN
IF VAL(vw_v2$) <= VAL(vw_v1$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 2) = ">=" THEN
IF VAL(vw_v2$) >= VAL(vw_v1$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 2) = "<>" THEN
IF VAL(vw_v2$) <> VAL(vw_v1$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 1) = "<" THEN
IF VAL(vw_v2$) < VAL(vw_v1$) THEN GOTO WatchPointBreak
ELSEIF LEFT$(vw_wpExpression$, 1) = ">" THEN
IF VAL(vw_v2$) > VAL(vw_v1$) THEN GOTO WatchPointBreak
END IF
END IF
LOOP
NEXT
RETURN
WatchPointBreak:
'send watchpoint info and pause
vw_checkingWatchpoints = 2
RETURN
GetV2:
PRINT "ENTERING GetV2 ---------------------------
PRINT "vw_varType$ = "; vw_varType$
PRINT "LEN(vw_buf$) ="; LEN(vw_buf$)
IF INSTR(vw_varType$, "BIT *") THEN
IF VAL(MID$(vw_varType$, _INSTRREV(vw_varType$, " ") + 1)) > 32 THEN
IF INSTR(vw_varType$, "UNSIGNED") THEN
vw_v2$ = STR$(_CV(_UNSIGNED _INTEGER64, vw_buf$))
ELSE
vw_v2$ = STR$(_CV(_INTEGER64, vw_buf$))
END IF
ELSE
IF INSTR(vw_varType$, "UNSIGNED") THEN
vw_v2$ = STR$(_CV(_UNSIGNED LONG, vw_buf$))
ELSE
vw_v2$ = STR$(_CV(LONG, vw_buf$))
END IF
END IF
RETURN
ELSEIF INSTR("@_BIT@BIT@_UNSIGNED _BIT@UNSIGNED BIT@", "@" + vw_varType$ + "@") THEN
IF INSTR(vw_varType$, "UNSIGNED") THEN
vw_v2$ = STR$(_CV(_UNSIGNED LONG, vw_buf$))
ELSE
vw_v2$ = STR$(_CV(LONG, vw_buf$))
END IF
RETURN
END IF
SELECT CASE vw_varType$
CASE "_BYTE", "BYTE": vw_v2$ = STR$(_CV(_BYTE, vw_buf$))
CASE "_UNSIGNED _BYTE", "UNSIGNED BYTE": vw_v2$ = STR$(_CV(_UNSIGNED _BYTE, vw_buf$))
CASE "INTEGER": vw_v2$ = STR$(_CV(INTEGER, vw_buf$))
CASE "_UNSIGNED INTEGER", "UNSIGNED INTEGER": vw_v2$ = STR$(_CV(_UNSIGNED INTEGER, vw_buf$))
CASE "LONG": vw_v2$ = STR$(_CV(LONG, vw_buf$))
CASE "_UNSIGNED LONG", "UNSIGNED LONG": vw_v2$ = STR$(_CV(_UNSIGNED LONG, vw_buf$))
CASE "_INTEGER64", "INTEGER64": vw_v2$ = STR$(_CV(_INTEGER64, vw_buf$))
CASE "_UNSIGNED _INTEGER64", "UNSIGNED INTEGER64": vw_v2$ = STR$(_CV(_UNSIGNED _INTEGER64, vw_buf$))
CASE "SINGLE": vw_v2$ = STR$(CVS(vw_buf$))
CASE "DOUBLE": vw_v2$ = STR$(CVD(vw_buf$))
CASE "_FLOAT", "FLOAT": vw_v2$ = STR$(_CV(_FLOAT, vw_buf$))
CASE "_OFFSET", "OFFSET": vw_v2$ = STR$(_CV(_OFFSET, vw_buf$))
CASE "_UNSIGNED _OFFSET", "UNSIGNED OFFSET": vw_v2$ = STR$(_CV(_UNSIGNED _OFFSET, vw_buf$))
END SELECT
RETURN
END SUB

View file

@ -7128,19 +7128,24 @@ SUB DebugMode
filter$ = ""
DO
result$ = idevariablewatchbox$(currentSub$, filter$, selectVar, returnAction)
temp$ = GetBytes$("", 0) 'reset buffer
IF returnAction = 1 THEN
temp$ = GetBytes$("", 0) 'reset buffer
'set address
tempIndex& = CVL(GetBytes$(result$, 4))
tempIsArray& = _CV(_BYTE, GetBytes$(result$, 1))
temp$ = GetBytes$(result$, 4) 'skip original line number
tempLocalIndex& = CVL(GetBytes$(result$, 4))
tempIsArray& = CVL(GetBytes$(result$, 4))
tempArrayIndex& = CVL(GetBytes$(result$, 4))
tempArrayIndexes$ = MKL$(tempArrayIndex&) + GetBytes$(result$, tempArrayIndex&)
tempIsUDT& = CVL(GetBytes$(result$, 4))
tempElementOffset& = CVL(GetBytes$(result$, 4))
tempArrayElementSize& = CVL(GetBytes$(result$, 4))
tempIsUDT& = CVL(GetBytes$(result$, 4))
temp$ = GetBytes$(result$, 4) 'skip element number
tempElementOffset& = CVL(GetBytes$(result$, 4))
temp$ = GetBytes$(result$, 4) 'skip var size
tempStorage& = CVL(GetBytes$(result$, 4))
i = CVI(GetBytes$(result$, 2))
tempScope$ = GetBytes$(result$, i)
i = CVI(GetBytes$(result$, 2))
varType$ = GetBytes$(result$, i)
i = CVI(GetBytes$(result$, 2))
value$ = GetBytes$(result$, i)
@ -7227,13 +7232,18 @@ SUB DebugMode
END IF
END SELECT
cmd$ = cmd$ + MKL$(tempIndex&)
cmd$ = cmd$ + _MK$(_BYTE, tempIsArray& <> 0)
cmd$ = cmd$ + MKL$(0)
cmd$ = cmd$ + MKL$(tempLocalIndex&)
cmd$ = cmd$ + MKL$(tempIsArray&)
cmd$ = cmd$ + tempArrayIndexes$
cmd$ = cmd$ + MKL$(tempIsUDT&)
cmd$ = cmd$ + MKL$(tempElementOffset&)
cmd$ = cmd$ + MKL$(tempArrayElementSize&)
cmd$ = cmd$ + MKL$(tempIsUDT&)
cmd$ = cmd$ + MKL$(0)
cmd$ = cmd$ + MKL$(tempElementOffset&)
cmd$ = cmd$ + MKL$(varSize&)
cmd$ = cmd$ + MKL$(tempStorage&)
cmd$ = cmd$ + MKI$(LEN(tempScope$)) + tempScope$
cmd$ = cmd$ + MKI$(LEN(varType$)) + varType$
cmd$ = cmd$ + MKI$(LEN(value$)) + value$
GOSUB SendCommand
@ -7246,7 +7256,61 @@ SUB DebugMode
WHILE _MOUSEINPUT: WEND
hidePanel = -1
GOSUB UpdateDisplay
ELSEIF returnAction = 2 THEN
ELSEIF returnAction = 2 OR returnAction = 3 THEN
'send watchpoint data
tempIndex& = CVL(GetBytes$(result$, 4))
tempIsArray& = _CV(_BYTE, GetBytes$(result$, 1)) <> 0
temp$ = GetBytes$(result$, 4) 'skip original line number
tempLocalIndex& = CVL(GetBytes$(result$, 4))
tempArrayIndex& = CVL(GetBytes$(result$, 4))
tempArrayIndexes$ = MKL$(tempArrayIndex&) + GetBytes$(result$, tempArrayIndex&)
tempArrayElementSize& = CVL(GetBytes$(result$, 4))
tempIsUDT& = CVL(GetBytes$(result$, 4))
tempElement& = CVL(GetBytes$(result$, 4))
tempElementOffset& = CVL(GetBytes$(result$, 4))
temp$ = GetBytes$(result$, 4) 'skip var size
tempStorage& = CVL(GetBytes$(result$, 4))
i = CVI(GetBytes$(result$, 2))
tempScope$ = GetBytes$(result$, i)
i = CVI(GetBytes$(result$, 2))
varType$ = GetBytes$(result$, i)
i = CVI(GetBytes$(result$, 2))
value$ = GetBytes$(result$, i)
IF returnAction = 2 THEN
temp$ = "set "
ELSE
'clear watchpoint data
temp$ = "clear "
END IF
IF LEN(usedVariableList(tempIndex&).subfunc) = 0 THEN
cmd$ = temp$ + "global watchpoint:"
ELSE
cmd$ = temp$ + "local watchpoint:"
END IF
cmd$ = cmd$ + MKL$(tempIndex&)
cmd$ = cmd$ + _MK$(_BYTE, tempIsArray& <> 0)
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).linenumber)
cmd$ = cmd$ + MKL$(tempLocalIndex&)
cmd$ = cmd$ + tempArrayIndexes$
cmd$ = cmd$ + MKL$(tempArrayElementSize&)
cmd$ = cmd$ + MKL$(tempIsUDT&)
cmd$ = cmd$ + MKL$(tempElement&)
cmd$ = cmd$ + MKL$(tempElementOffset&)
cmd$ = cmd$ + MKL$(varSize&)
cmd$ = cmd$ + MKL$(tempStorage&)
cmd$ = cmd$ + MKI$(LEN(tempScope$)) + tempScope$
cmd$ = cmd$ + MKI$(LEN(varType$)) + varType$
cmd$ = cmd$ + MKI$(LEN(value$)) + value$
GOSUB SendCommand
PCOPY 3, 0: SCREEN , , 3, 0
WHILE _MOUSEINPUT: WEND
hidePanel = -1
GOSUB UpdateDisplay
ELSEIF returnAction = -1 THEN
PCOPY 3, 0: SCREEN , , 3, 0
WHILE _MOUSEINPUT: WEND
hidePanel = -1
@ -7453,8 +7517,15 @@ SUB DebugMode
GOSUB GetCommand
SELECT CASE cmd$
CASE "breakpoint", "line number"
CASE "breakpoint", "line number", "watchpoint"
BypassRequestCallStack = 0
IF cmd$ = "watchpoint" THEN
temp$ = GetBytes$("", 0) 'reset buffer
i = CVI(GetBytes$(value$, 2))
temp$ = GetBytes$(value$, i)
result = idemessagebox("Watchpoint", temp$, "#OK")
value$ = RIGHT$(value$, 4)
END IF
l = CVL(value$)
idecy = l
ideselect = 0
@ -7969,7 +8040,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
o(buttonSet).typ = 3
o(buttonSet).y = dialogHeight
IF IdeDebugMode > 0 AND o(buttonSet).txt = 0 THEN
o(buttonSet).txt = idenewtxt("#Add All" + sep + "#Remove All" + sep + "#Send Value" + sep + "#Close")
o(buttonSet).txt = idenewtxt("#Add All" + sep + "#Remove All" + sep + "#Send Value" + sep + "Add #Watchpoint" + sep + "#Close")
ELSE
o(buttonSet).txt = idenewtxt("#Add All" + sep + "#Remove All" + sep + "#Close")
END IF
@ -8095,9 +8166,23 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
_CONTINUE
END IF
IF (IdeDebugMode > 0 AND focus = 5 AND info <> 0) THEN
'set address
IF (IdeDebugMode > 0 AND focus = 5 AND info <> 0) OR _
(IdeDebugMode > 0 AND focus = 6 AND info <> 0) THEN
'set address/add watchpoint
sendValue:
SELECT CASE focus
CASE 5
dlgTitle$ = "Change Value"
dlgPrompt$ = "#Index to change"
dlgPrompt2$ = "#New value"
thisReturnAction = 1
CASE 6
dlgTitle$ = "Add Watchpoint"
dlgPrompt$ = "#Index to monitor"
dlgPrompt2$ = "#Condition"
thisReturnAction = 2
END SELECT
y = ABS(o(varListBox).sel)
IF y >= 1 AND y <= totalVisibleVariables THEN
@ -8111,7 +8196,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
tempElementOffset$ = MKL$(0)
IF usedVariableList(tempIndex&).isarray THEN
setArrayRange3:
v$ = ideinputbox$("Change Value", "#Index to change", temp$, "01234567890,", 45, 0, ok)
v$ = ideinputbox$(dlgTitle$, dlgPrompt$, temp$, "01234567890,", 45, 0, ok)
IF ok THEN
IF LEN(v$) > 0 THEN
WHILE RIGHT$(v$, 1) = ",": v$ = LEFT$(v$, LEN(v$) - 1): WEND
@ -8188,7 +8273,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
temp$ = v$
IF numelements(temp$) <> 1 THEN
'shouldn't ever happen
result = idemessagebox("Error", "Only one UDT element can be changed at a time", "#OK")
result = idemessagebox("Error", "Only one UDT element can be selected at a time", "#OK")
_CONTINUE
END IF
@ -8244,7 +8329,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
END IF
ELSE
'shouldn't ever happen
result = idemessagebox("Error", "Cannot send value to full UDT", "#OK")
result = idemessagebox("Error", "Cannot select full UDT", "#OK")
GOTO dlgLoop
END IF
END SELECT
@ -8279,38 +8364,78 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
ELSE
thisWidth = 45
END IF
v$ = ideinputbox$("Change Value", "#New value", a2$, "", thisWidth, 0, ok)
getNewValueInput:
v$ = ideinputbox$(dlgTitle$, dlgPrompt2$, a2$, "", thisWidth, 0, ok)
IF ok THEN
temp$ = ""
temp$ = temp$ + MKL$(tempIndex&)
temp$ = temp$ + MKL$(usedVariableList(tempIndex&).localindex)
temp$ = temp$ + MKL$(usedVariableList(tempIndex&).isarray <> 0)
temp$ = temp$ + tempArrayIndexes$
temp$ = temp$ + MKL$(tempIsUDT&)
temp$ = temp$ + tempElementOffset$
temp$ = temp$ + MKL$(usedVariableList(tempIndex&).arrayElementSize)
temp$ = temp$ + MKL$(storageSlot&)
temp$ = temp$ + MKI$(LEN(varType$)) + varType$
temp$ = temp$ + MKI$(LEN(v$)) + v$
idevariablewatchbox$ = temp$
returnAction = 1 'actually send value
IF focus = 6 THEN
'validate condition string first
v$ = LTRIM$(v$)
IF LEN(v$) < 2 THEN
v$ = ""
thisReturnAction = 3 'remove watchpoint for this variable
ELSE
StartWatchPointEval:
op1$ = LEFT$(v$, 1)
op2$ = MID$(v$, 2, 1)
SELECT CASE op1$
CASE "="
IF op2$ = "<" OR op2$ = ">" THEN
MID$(v$, 1, 2) = op2$ + "="
GOTO StartWatchPointEval
END IF
CASE ">"
IF op2$ = "<" OR op2$ = ">" THEN
result = idemessagebox(dlgTitle$, "Invalid expression.\nYou can use =, <>, >, >=, < and <=", "#OK")
GOTO getNewValueInput
END IF
CASE "<"
CASE ELSE
result = idemessagebox(dlgTitle$, "Invalid expression.\nYou can use =, <>, >, >=, < and <=", "#OK")
GOTO getNewValueInput
END SELECT
END IF
END IF
cmd$ = ""
cmd$ = cmd$ + MKL$(tempIndex&)
cmd$ = cmd$ + _MK$(_BYTE, usedVariableList(tempIndex&).isarray)
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).linenumber)
cmd$ = cmd$ + MKL$(usedVariableList(tempIndex&).localIndex)
cmd$ = cmd$ + tempArrayIndexes$
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$ + MKL$(varSize&)
cmd$ = cmd$ + MKL$(tempStorage&)
cmd$ = cmd$ + MKI$(LEN(usedVariableList(tempIndex&).subfunc))
cmd$ = cmd$ + usedVariableList(tempIndex&).subfunc
cmd$ = cmd$ + MKI$(LEN(varType$)) + varType$
cmd$ = cmd$ + MKI$(LEN(v$)) + v$
idevariablewatchbox$ = cmd$
returnAction = thisReturnAction 'actually send command
ELSE
returnAction = 2 'redraw and carry on
returnAction = -1 'redraw and carry on
END IF
selectVar = y
EXIT FUNCTION
ELSE
result = idemessagebox("Change Value", "Variable is out of scope.", "#OK")
result = idemessagebox(dlgTitle$, "Variable is out of scope.", "#OK")
END IF
ELSE
result = idemessagebox("Change Value", "Select a variable first.", "#OK")
result = idemessagebox(dlgTitle$, "Select a variable first.", "#OK")
END IF
focus = filterBox
_CONTINUE
END IF
IF K$ = CHR$(27) OR (IdeDebugMode = 0 AND focus = 5 AND info <> 0) OR _
(IdeDebugMode > 0 AND focus = 6 AND info <> 0) THEN
(IdeDebugMode > 0 AND focus = 7 AND info <> 0) THEN
variableWatchList$ = ""
longestVarName = 0
nextvWatchDataSlot = 0
@ -8425,6 +8550,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
IF mCLICK AND focus = 2 THEN 'list click
IF timeElapsedSince(lastClick!) < .3 AND clickedItem = o(varListBox).sel THEN
IF doubleClickThreshold > 0 AND mX >= p.x + doubleClickThreshold AND IdeDebugMode > 0 THEN
focus = 5
GOTO sendValue
ELSE
GOTO toggleWatch