1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-01 15:00:38 +00:00

Implements Watchpoints

Merges Debug mode branch
This commit is contained in:
Fellippe Heitor 2021-09-18 23:32:33 -03:00 committed by GitHub
commit d651f37bc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 632 additions and 57 deletions

View file

@ -5,16 +5,16 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
STATIC AS LONG vw_runToLine, vw_originalVarLineNumber STATIC AS LONG vw_runToLine, vw_originalVarLineNumber
STATIC AS _BYTE vw_pauseMode, vw_stepOver, vw_bypass, vw_setNextLine, vw_hwndSent STATIC AS _BYTE vw_pauseMode, vw_stepOver, vw_bypass, vw_setNextLine, vw_hwndSent
STATIC AS _OFFSET vw_ideHwnd STATIC AS _OFFSET vw_ideHwnd
STATIC vw_buffer$ STATIC vw_buffer$, vw_globalWatchpoints$, vw_localWatchpoints$, vw_lastWatchpoint$
DIM AS LONG vw_i, vw_tempIndex, vw_localIndex, vw_varSize, vw_cmdSize 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_arrayElementSize, vw_element, vw_elementOffset, vw_storage, vw_blockSize
DIM AS LONG vw_arrayDimension, vw_arrayTotalDimensions, vw_arrayIndex, vw_realArrayIndex DIM AS LONG vw_arrayDimension, vw_arrayTotalDimensions, vw_arrayIndex, vw_realArrayIndex
DIM AS _OFFSET vw_address, vw_lBound, vw_uBound DIM AS _OFFSET vw_address, vw_lBound, vw_uBound
DIM AS _MEM vw_m, vw_m2 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_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_getBytes&, vw_getBytesPosition&, vw_valueBytes$, vw_dummy%&
DIM vw_arrayIndexes$ DIM vw_arrayIndexes$, vw_wpExpression$
DECLARE LIBRARY DECLARE LIBRARY
SUB vwatch_stoptimers ALIAS stop_timers SUB vwatch_stoptimers ALIAS stop_timers
@ -27,8 +27,8 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
END DECLARE END DECLARE
$IF WIN THEN $IF WIN THEN
DECLARE DYNAMIC LIBRARY "user32" DECLARE CUSTOMTYPE LIBRARY
FUNCTION SetForegroundWindow& (BYVAL hWnd AS _OFFSET) FUNCTION vwSetForegroundWindow& ALIAS "SetForegroundWindow" (BYVAL hWnd AS _OFFSET)
END DECLARE END DECLARE
$END IF $END IF
@ -177,6 +177,20 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
REDIM vwatch_skiplines(UBOUND(vwatch_skiplines)) AS _BYTE REDIM vwatch_skiplines(UBOUND(vwatch_skiplines)) AS _BYTE
END SELECT 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:" + MKL$(vw_tempIndex) + MKL$(LEN(vw_arrayIndexes$)) + vw_arrayIndexes$ + MKL$(vw_elementOffset) + 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 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 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 EXIT SUB
END IF END IF
vwatch_stoptimers
vw_cmd$ = "line number:" vw_cmd$ = "line number:"
IF vwatch_breakpoints(vwatch_linenumber) THEN vw_cmd$ = "breakpoint:" IF vwatch_breakpoints(vwatch_linenumber) THEN vw_cmd$ = "breakpoint:"
breakReached:
vwatch_stoptimers
vw_cmd$ = vw_cmd$ + MKL$(vwatch_linenumber) vw_cmd$ = vw_cmd$ + MKL$(vwatch_linenumber)
GOSUB SendCommand GOSUB SendCommand
vw_cmd$ = "current sub:" + LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1) vw_cmd$ = "current sub:" + LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1)
GOSUB SendCommand GOSUB SendCommand
$IF WIN THEN $IF WIN THEN
vw_i = SetForegroundWindow&(vw_ideHwnd) vw_i = vwSetForegroundWindow&(vw_ideHwnd)
$END IF $END IF
DO 'main loop DO 'main loop
@ -258,6 +273,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
'send call stack history 'send call stack history
GOSUB SendCallStack GOSUB SendCallStack
CASE "get global var", "get local var" CASE "get global var", "get local var"
getGlobalLocal:
vw_getBytes& = 4: GOSUB GetBytes: vw_tempIndex = CVL(vw_valueBytes$) vw_getBytes& = 4: GOSUB GetBytes: vw_tempIndex = CVL(vw_valueBytes$)
vw_getBytes& = 1: GOSUB GetBytes: vw_isArray = _CV(_BYTE, 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_originalVarLineNumber = CVL(vw_valueBytes$)
@ -266,10 +282,14 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
vw_getBytes& = vw_arrayTotalDimensions: GOSUB GetBytes: vw_arrayIndexes$ = vw_valueBytes$ vw_getBytes& = vw_arrayTotalDimensions: GOSUB GetBytes: vw_arrayIndexes$ = vw_valueBytes$
vw_arrayTotalDimensions = vw_arrayTotalDimensions \ 4 vw_arrayTotalDimensions = vw_arrayTotalDimensions \ 4
vw_getBytes& = 4: GOSUB GetBytes: vw_arrayElementSize = CVL(vw_valueBytes$) vw_getBytes& = 4: GOSUB GetBytes: vw_arrayElementSize = CVL(vw_valueBytes$)
IF vw_checkingWatchpoints THEN vw_getBytes& = 4: GOSUB GetBytes 'discard 4 bytes (isUDT)
vw_getBytes& = 4: GOSUB GetBytes: vw_element = CVL(vw_valueBytes$) 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_elementOffset = CVL(vw_valueBytes$)
vw_getBytes& = 4: GOSUB GetBytes: vw_varSize = CVL(vw_valueBytes$) vw_getBytes& = 4: GOSUB GetBytes: vw_varSize = CVL(vw_valueBytes$)
IF vw_varSize = 0 THEN GOTO cmdProcessingDone IF vw_varSize = 0 THEN
IF vw_checkingWatchpoints THEN RETURN
GOTO cmdProcessingDone
END IF
vw_getBytes& = 4: GOSUB GetBytes: vw_storage = CVL(vw_valueBytes$) vw_getBytes& = 4: GOSUB GetBytes: vw_storage = CVL(vw_valueBytes$)
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$) vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
IF vw_i THEN IF vw_i THEN
@ -284,6 +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 IF vw_scope$ = LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1) THEN
vw_address = _OFFSET(localVariables) + LEN(vw_address) * vw_localIndex vw_address = _OFFSET(localVariables) + LEN(vw_address) * vw_localIndex
ELSE ELSE
IF vw_checkingWatchpoints THEN vw_varType$ = "": RETURN
GOTO cmdProcessingDone GOTO cmdProcessingDone
END IF END IF
END IF END IF
@ -294,7 +315,10 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
IF vw_isArray THEN IF vw_isArray THEN
IF vw_originalVarLineNumber > 0 THEN IF vw_originalVarLineNumber > 0 THEN
'prevent fetching array data before DIM line '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 vw_varType$ = "": RETURN
GOTO cmdProcessingDone
END IF
END IF END IF
vw_realArrayIndex = 0 vw_realArrayIndex = 0
@ -305,6 +329,7 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
vw_uBound = check_ubound%&(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)) vw_arrayIndex = CVL(MID$(vw_arrayIndexes$, vw_arrayDimension * 4 - 3, 4))
IF vw_arrayIndex < vw_lBound OR vw_arrayIndex > vw_uBound THEN IF vw_arrayIndex < vw_lBound OR vw_arrayIndex > vw_uBound THEN
IF vw_checkingWatchpoints THEN vw_varType$ = "": RETURN
GOTO cmdProcessingDone GOTO cmdProcessingDone
END IF END IF
@ -381,24 +406,36 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
vw_address = _CV(LONG, LEFT$(vw_buf$, 4)) 'Pointer to data vw_address = _CV(LONG, LEFT$(vw_buf$, 4)) 'Pointer to data
vw_varSize = CVL(MID$(vw_buf$, 5)) vw_varSize = CVL(MID$(vw_buf$, 5))
END IF END IF
vw_buf$ = SPACE$(vw_varSize) vw_buf$ = SPACE$(vw_varSize)
vw_m = _MEM(vw_address, vw_varSize) vw_m = _MEM(vw_address, vw_varSize)
vw_m2 = _MEM(_OFFSET(vw_buf$), vw_varSize) vw_m2 = _MEM(_OFFSET(vw_buf$), vw_varSize)
_MEMCOPY vw_m, vw_m.OFFSET, vw_m.SIZE TO vw_m2, vw_m2.OFFSET _MEMCOPY vw_m, vw_m.OFFSET, vw_m.SIZE TO vw_m2, vw_m2.OFFSET
END IF END IF
IF vw_checkingWatchpoints THEN RETURN
vw_cmd$ = "address read:" + MKL$(vw_tempIndex) + MKL$(vw_arrayIndex) + MKL$(vw_element) + MKL$(vw_storage) + vw_buf$ vw_cmd$ = "address read:" + MKL$(vw_tempIndex) + MKL$(vw_arrayIndex) + MKL$(vw_element) + MKL$(vw_storage) + vw_buf$
GOSUB SendCommand GOSUB SendCommand
CASE "set global address", "set local address" 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_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& = 4: GOSUB GetBytes: vw_arrayTotalDimensions = CVL(vw_valueBytes$)
vw_getBytes& = vw_arrayTotalDimensions: GOSUB GetBytes: vw_arrayIndexes$ = vw_valueBytes$ vw_getBytes& = vw_arrayTotalDimensions: GOSUB GetBytes: vw_arrayIndexes$ = vw_valueBytes$
vw_arrayTotalDimensions = vw_arrayTotalDimensions \ 4 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_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$) 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& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
vw_getBytes& = vw_i: GOSUB GetBytes: vw_varType$ = vw_valueBytes$ vw_getBytes& = vw_i: GOSUB GetBytes: vw_varType$ = vw_valueBytes$
vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$) vw_getBytes& = 2: GOSUB GetBytes: vw_i = CVI(vw_valueBytes$)
@ -509,6 +546,72 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
'vw_address now points to the actual data 'vw_address now points to the actual data
vw_m = _MEM(vw_address, vw_varSize) vw_m = _MEM(vw_address, vw_varSize)
_MEMPUT vw_m, vw_m.OFFSET, vw_value$ _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$)
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 + 33)
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$
IF INSTR(vw_cmd$, " global ") THEN
vw_buf$ = vw_globalWatchpoints$
ELSE
vw_buf$ = vw_localWatchpoints$
END IF
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 - 1) + MID$(vw_buf$, vw_i + vw_j + 8)
END IF
IF LEFT$(vw_cmd$, 4) = "set " THEN
vw_value$ = vw_value$ + MKL$(LEN(vw_wpExpression$))
vw_buf$ = vw_buf$ + MKL$(-1) + MKL$(LEN(vw_value$)) + vw_value$
END IF
IF INSTR(vw_cmd$, " global ") THEN
vw_globalWatchpoints$ = vw_buf$
ELSE
vw_localWatchpoints$ = vw_buf$
END IF
CASE "current sub" CASE "current sub"
vw_cmd$ = "current sub:" + LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1) vw_cmd$ = "current sub:" + LEFT$(vwatch_stack(vwatch_sublevel), INSTR(vwatch_stack(vwatch_sublevel), ",") - 1)
GOSUB SendCommand GOSUB SendCommand
@ -595,4 +698,123 @@ SUB vwatch (globalVariables AS _OFFSET, localVariables AS _OFFSET)
vw_valueBytes$ = MID$(vw_value$, vw_getBytesPosition&, vw_getBytes&) vw_valueBytes$ = MID$(vw_value$, vw_getBytesPosition&, vw_getBytes&)
vw_getBytesPosition& = vw_getBytesPosition& + vw_getBytes& vw_getBytesPosition& = vw_getBytesPosition& + vw_getBytes&
RETURN RETURN
CheckWatchpoints:
DIM AS LONG vw_wpi, vw_wpj
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$ = MID$(vw_globalWatchpoints$, 5)
ELSEIF vw_wpi = 2 AND LEN(vw_localWatchpoints$) > 0 THEN
vw_wpTemp$ = MID$(vw_localWatchpoints$, 5)
ELSE
_CONTINUE
END IF
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$, 9 + vw_wpj)
IF vw_wpi = 1 THEN vw_cmd$ = "get global var" ELSE vw_cmd$ = "get local var"
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
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
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
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
IF INSTR(vw_cmd$, "global") THEN
vw_lastWatchpoint$ = "g" + vw_value$
ELSE
vw_lastWatchpoint$ = "l" + vw_value$
END IF
vw_checkingWatchpoints = 2
RETURN
GetV2:
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 END SUB

View file

@ -18,7 +18,7 @@ DIM SHARED WatchListToConsole AS _BYTE
DIM SHARED windowSettingsSection$, colorSettingsSection$, customDictionarySection$ DIM SHARED windowSettingsSection$, colorSettingsSection$, customDictionarySection$
DIM SHARED mouseSettingsSection$, generalSettingsSection$, displaySettingsSection$ DIM SHARED mouseSettingsSection$, generalSettingsSection$, displaySettingsSection$
DIM SHARED colorSchemesSection$, debugSettingsSection$, iniFolderIndex$, DebugInfoIniWarning$, ConfigFile$ DIM SHARED colorSchemesSection$, debugSettingsSection$, iniFolderIndex$, DebugInfoIniWarning$, ConfigFile$
DIM SHARED idebaseTcpPort AS LONG DIM SHARED idebaseTcpPort AS LONG, AutoAddDebugCommand AS _BYTE
ConfigFile$ = "internal/config.ini" ConfigFile$ = "internal/config.ini"
iniFolderIndex$ = STR$(tempfolderindex) iniFolderIndex$ = STR$(tempfolderindex)
@ -241,6 +241,18 @@ ELSE
WriteConfigSetting debugSettingsSection$, "WatchListToConsole", "False" WriteConfigSetting debugSettingsSection$, "WatchListToConsole", "False"
END IF END IF
IF ReadConfigSetting(debugSettingsSection$, "AutoAddDebugCommand", value$) THEN
IF UCASE$(value$) = "TRUE" OR VAL(value$) = -1 THEN
AutoAddDebugCommand = -1
ELSE
AutoAddDebugCommand = 0
WriteConfigSetting debugSettingsSection$, "AutoAddDebugCommand", "False"
END IF
ELSE
AutoAddDebugCommand = -1
WriteConfigSetting debugSettingsSection$, "AutoAddDebugCommand", "True"
END IF
'Display settings ------------------------------------------------------------- 'Display settings -------------------------------------------------------------
IF ReadConfigSetting(displaySettingsSection$, "IDE_SortSUBs", value$) THEN IF ReadConfigSetting(displaySettingsSection$, "IDE_SortSUBs", value$) THEN
IF UCASE$(value$) = "TRUE" OR VAL(value$) = -1 THEN IF UCASE$(value$) = "TRUE" OR VAL(value$) = -1 THEN

View file

@ -11,8 +11,8 @@ DIM SHARED IDEBuildModeChanged
DIM SHARED IdeInfo AS STRING DIM SHARED IdeInfo AS STRING
DIM SHARED IdeContextHelpSF AS _BYTE DIM SHARED IdeContextHelpSF AS _BYTE
DIM SHARED host&, debugClient&, hostport$, variableWatchList$ DIM SHARED host&, debugClient&, hostport$, variableWatchList$, watchpointList$
DIM SHARED vWatchReceivedData$(1 TO 1000), nextvWatchDataSlot DIM SHARED vWatchReceivedData$(1 TO 1000), nextvWatchDataSlot, latestWatchpointMet&
DIM SHARED startPausedPending AS _BYTE DIM SHARED startPausedPending AS _BYTE
DIM SHARED IdeSystem AS LONG DIM SHARED IdeSystem AS LONG
@ -222,6 +222,7 @@ DIM SHARED ViewMenuShowSeparatorID AS INTEGER, ViewMenuShowBGID AS INTEGER
DIM SHARED ViewMenuCompilerWarnings AS INTEGER DIM SHARED ViewMenuCompilerWarnings AS INTEGER
DIM SHARED RunMenuID AS INTEGER, RunMenuSaveExeWithSource AS INTEGER, brackethighlight AS INTEGER DIM SHARED RunMenuID AS INTEGER, RunMenuSaveExeWithSource AS INTEGER, brackethighlight AS INTEGER
DIM SHARED DebugMenuID AS INTEGER, DebugMenuCallStack AS INTEGER, DebugMenuWatchListToConsole AS INTEGER DIM SHARED DebugMenuID AS INTEGER, DebugMenuCallStack AS INTEGER, DebugMenuWatchListToConsole AS INTEGER
DIM SHARED DebugMenuAutoAddCommand AS INTEGER
DIM SHARED multihighlight AS INTEGER, keywordHighlight AS INTEGER DIM SHARED multihighlight AS INTEGER, keywordHighlight AS INTEGER
DIM SHARED PresetColorSchemes AS INTEGER, TotalColorSchemes AS INTEGER, ColorSchemes$(0) DIM SHARED PresetColorSchemes AS INTEGER, TotalColorSchemes AS INTEGER, ColorSchemes$(0)
DIM SHARED LastValidColorScheme AS INTEGER DIM SHARED LastValidColorScheme AS INTEGER

View file

@ -357,6 +357,12 @@ FUNCTION ide2 (ignore)
menu$(DebugMenuID, DebugMenuCallStack) = "Call #Stack... F12": i = i + 1 menu$(DebugMenuID, DebugMenuCallStack) = "Call #Stack... F12": i = i + 1
menuDesc$(m, i - 1) = "Displays the call stack of the current program's last execution" menuDesc$(m, i - 1) = "Displays the call stack of the current program's last execution"
menu$(m, i) = "-": i = i + 1 menu$(m, i) = "-": i = i + 1
DebugMenuAutoAddCommand = i
menu$(m, i) = "Auto-add $#Debug Metacommand": i = i + 1
menuDesc$(m, i - 1) = "Toggles whether the IDE will auto-add the $Debug metacommand as required"
IF AutoAddDebugCommand THEN
menu$(DebugMenuID, DebugMenuAutoAddCommand) = CHR$(7) + menu$(DebugMenuID, DebugMenuAutoAddCommand)
END IF
DebugMenuWatchListToConsole = i DebugMenuWatchListToConsole = i
menu$(m, i) = "#Output Watch List to Console": i = i + 1 menu$(m, i) = "#Output Watch List to Console": i = i + 1
menuDesc$(m, i - 1) = "Toggles directing the output of the watch list to the console window" menuDesc$(m, i - 1) = "Toggles directing the output of the watch list to the console window"
@ -500,6 +506,7 @@ FUNCTION ide2 (ignore)
REDIM IdeBreakpoints(iden) AS _BYTE REDIM IdeBreakpoints(iden) AS _BYTE
REDIM IdeSkipLines(iden) AS _BYTE REDIM IdeSkipLines(iden) AS _BYTE
variableWatchList$ = "" variableWatchList$ = ""
watchpointList$ = ""
callstacklist$ = "": callStackLength = 0 callstacklist$ = "": callStackLength = 0
ideunsaved = -1 ideunsaved = -1
idechangemade = 1 idechangemade = 1
@ -596,6 +603,7 @@ FUNCTION ide2 (ignore)
REDIM IdeBreakpoints(iden) AS _BYTE REDIM IdeBreakpoints(iden) AS _BYTE
REDIM IdeSkipLines(iden) AS _BYTE REDIM IdeSkipLines(iden) AS _BYTE
variableWatchList$ = "" variableWatchList$ = ""
watchpointList$ = ""
callstacklist$ = "": callStackLength = 0 callstacklist$ = "": callStackLength = 0
IF ideStartAtLine > 0 AND ideStartAtLine <= iden THEN IF ideStartAtLine > 0 AND ideStartAtLine <= iden THEN
idecy = ideStartAtLine idecy = ideStartAtLine
@ -1147,6 +1155,7 @@ FUNCTION ide2 (ignore)
IF idelayoutallow THEN idelayoutallow = idelayoutallow - 1 IF idelayoutallow THEN idelayoutallow = idelayoutallow - 1
variableWatchList$ = "" variableWatchList$ = ""
watchpointList$ = ""
idecurrentlinelayouti = 0 'invalidate idecurrentlinelayouti = 0 'invalidate
idefocusline = 0 idefocusline = 0
idechangemade = 0 idechangemade = 0
@ -4988,6 +4997,19 @@ FUNCTION ide2 (ignore)
GOTO ideloop GOTO ideloop
END IF END IF
IF RIGHT$(menu$(m, s), 28) = "Auto-add $#Debug Metacommand" THEN
PCOPY 2, 0
AutoAddDebugCommand = NOT AutoAddDebugCommand
IF AutoAddDebugCommand THEN
WriteConfigSetting debugSettingsSection$, "AutoAddDebugCommand", "True"
menu$(DebugMenuID, DebugMenuAutoAddCommand) = CHR$(7) + "Auto-add $#Debug Metacommand"
ELSE
WriteConfigSetting debugSettingsSection$, "AutoAddDebugCommand", "False"
menu$(DebugMenuID, DebugMenuAutoAddCommand) = "Auto-add $#Debug Metacommand"
END IF
PCOPY 3, 0: SCREEN , , 3, 0
GOTO ideloop
END IF
IF MID$(menu$(m, s), 1, 17) = "#Quick Navigation" OR MID$(menu$(m, s), 2, 17) = "#Quick Navigation" THEN IF MID$(menu$(m, s), 1, 17) = "#Quick Navigation" OR MID$(menu$(m, s), 2, 17) = "#Quick Navigation" THEN
PCOPY 2, 0 PCOPY 2, 0
@ -5703,6 +5725,16 @@ FUNCTION ide2 (ignore)
PCOPY 3, 0: SCREEN , , 3, 0 PCOPY 3, 0: SCREEN , , 3, 0
startPausedMenuHandler: startPausedMenuHandler:
IF vWatchOn = 0 THEN IF vWatchOn = 0 THEN
IF AutoAddDebugCommand = 0 THEN
SCREEN , , 3, 0
clearStatusWindow 2
COLOR 14, 1
x = 2
y = idewy - 2
printWrapStatus x, y, x, "$DEBUG metacommand is required to start paused."
PCOPY 3, 0
GOTO ideloop
END IF
result = idemessagebox("Start Paused", "Insert $DEBUG metacommand?", "#Yes;#No") result = idemessagebox("Start Paused", "Insert $DEBUG metacommand?", "#Yes;#No")
IF result = 1 THEN IF result = 1 THEN
ideselect = 0 ideselect = 0
@ -5726,6 +5758,16 @@ FUNCTION ide2 (ignore)
PCOPY 2, 0 PCOPY 2, 0
showWatchList: showWatchList:
IF vWatchOn = 0 THEN IF vWatchOn = 0 THEN
IF AutoAddDebugCommand = 0 THEN
SCREEN , , 3, 0
clearStatusWindow 2
COLOR 14, 1
x = 2
y = idewy - 2
printWrapStatus x, y, x, "$DEBUG metacommand is required for Watch List functionality."
PCOPY 3, 0
GOTO ideloop
END IF
result = idemessagebox("Watch List", "Insert $DEBUG metacommand?", "#Yes;#No") result = idemessagebox("Watch List", "Insert $DEBUG metacommand?", "#Yes;#No")
IF result = 1 THEN IF result = 1 THEN
ideselect = 0 ideselect = 0
@ -5807,6 +5849,16 @@ FUNCTION ide2 (ignore)
PCOPY 3, 0: SCREEN , , 3, 0 PCOPY 3, 0: SCREEN , , 3, 0
toggleBreakpoint: toggleBreakpoint:
IF vWatchOn = 0 THEN IF vWatchOn = 0 THEN
IF AutoAddDebugCommand = 0 THEN
SCREEN , , 3, 0
clearStatusWindow 2
COLOR 14, 1
x = 2
y = idewy - 2
printWrapStatus x, y, x, "$DEBUG metacommand is required to enable breakpoints."
PCOPY 3, 0
GOTO ideloop
END IF
result = idemessagebox("Toggle Breakpoint", "Insert $DEBUG metacommand?", "#Yes;#No") result = idemessagebox("Toggle Breakpoint", "Insert $DEBUG metacommand?", "#Yes;#No")
IF result = 1 THEN IF result = 1 THEN
ideselect = 0 ideselect = 0
@ -5843,6 +5895,16 @@ FUNCTION ide2 (ignore)
PCOPY 3, 0: SCREEN , , 3, 0 PCOPY 3, 0: SCREEN , , 3, 0
toggleSkipLine: toggleSkipLine:
IF vWatchOn = 0 THEN IF vWatchOn = 0 THEN
IF AutoAddDebugCommand = 0 THEN
SCREEN , , 3, 0
clearStatusWindow 2
COLOR 14, 1
x = 2
y = idewy - 2
printWrapStatus x, y, x, "$DEBUG metacommand is required to enable line skipping."
PCOPY 3, 0
GOTO ideloop
END IF
result = idemessagebox("Toggle Skip Line", "Insert $DEBUG metacommand?", "#Yes;#No") result = idemessagebox("Toggle Skip Line", "Insert $DEBUG metacommand?", "#Yes;#No")
IF result = 1 THEN IF result = 1 THEN
ideselect = 0 ideselect = 0
@ -5946,6 +6008,7 @@ FUNCTION ide2 (ignore)
REDIM IdeBreakpoints(1) AS _BYTE REDIM IdeBreakpoints(1) AS _BYTE
REDIM IdeSkipLines(1) AS _BYTE REDIM IdeSkipLines(1) AS _BYTE
variableWatchList$ = "" variableWatchList$ = ""
watchpointList$ = ""
callstacklist$ = "": callStackLength = 0 callstacklist$ = "": callStackLength = 0
idet$ = MKL$(0) + MKL$(0): idel = 1: ideli = 1: iden = 1: IdeBmkN = 0 idet$ = MKL$(0) + MKL$(0): idel = 1: ideli = 1: iden = 1: IdeBmkN = 0
idesx = 1 idesx = 1
@ -6413,6 +6476,7 @@ SUB DebugMode
vWatchPanel.h = 5 vWatchPanel.h = 5
END IF END IF
watchpointList$ = ""
vWatchPanel.w = 40 vWatchPanel.w = 40
vWatchPanel.x = idewx - vWatchPanel.w - 6 vWatchPanel.x = idewx - vWatchPanel.w - 6
vWatchPanel.y = 4 vWatchPanel.y = 4
@ -7069,19 +7133,24 @@ SUB DebugMode
filter$ = "" filter$ = ""
DO DO
result$ = idevariablewatchbox$(currentSub$, filter$, selectVar, returnAction) result$ = idevariablewatchbox$(currentSub$, filter$, selectVar, returnAction)
temp$ = GetBytes$("", 0) 'reset buffer
IF returnAction = 1 THEN IF returnAction = 1 THEN
temp$ = GetBytes$("", 0) 'reset buffer
'set address 'set address
tempIndex& = CVL(GetBytes$(result$, 4)) tempIndex& = CVL(GetBytes$(result$, 4))
tempIsArray& = _CV(_BYTE, GetBytes$(result$, 1))
temp$ = GetBytes$(result$, 4) 'skip original line number
tempLocalIndex& = CVL(GetBytes$(result$, 4)) tempLocalIndex& = CVL(GetBytes$(result$, 4))
tempIsArray& = CVL(GetBytes$(result$, 4))
tempArrayIndex& = CVL(GetBytes$(result$, 4)) tempArrayIndex& = CVL(GetBytes$(result$, 4))
tempArrayIndexes$ = MKL$(tempArrayIndex&) + GetBytes$(result$, tempArrayIndex&) tempArrayIndexes$ = MKL$(tempArrayIndex&) + GetBytes$(result$, tempArrayIndex&)
tempIsUDT& = CVL(GetBytes$(result$, 4))
tempElementOffset& = CVL(GetBytes$(result$, 4))
tempArrayElementSize& = 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)) tempStorage& = CVL(GetBytes$(result$, 4))
i = CVI(GetBytes$(result$, 2)) i = CVI(GetBytes$(result$, 2))
tempScope$ = GetBytes$(result$, i)
i = CVI(GetBytes$(result$, 2))
varType$ = GetBytes$(result$, i) varType$ = GetBytes$(result$, i)
i = CVI(GetBytes$(result$, 2)) i = CVI(GetBytes$(result$, 2))
value$ = GetBytes$(result$, i) value$ = GetBytes$(result$, i)
@ -7092,6 +7161,7 @@ SUB DebugMode
cmd$ = "set local address:" cmd$ = "set local address:"
END IF END IF
findVarSize:
tempVarType$ = varType$ tempVarType$ = varType$
fixedVarSize& = 0 fixedVarSize& = 0
IF INSTR(varType$, "STRING *") THEN IF INSTR(varType$, "STRING *") THEN
@ -7168,13 +7238,20 @@ SUB DebugMode
END IF END IF
END SELECT END SELECT
IF returnAction = 2 OR returnAction = 3 THEN RETURN
cmd$ = cmd$ + MKL$(tempIndex&)
cmd$ = cmd$ + _MK$(_BYTE, tempIsArray& <> 0)
cmd$ = cmd$ + MKL$(0)
cmd$ = cmd$ + MKL$(tempLocalIndex&) cmd$ = cmd$ + MKL$(tempLocalIndex&)
cmd$ = cmd$ + MKL$(tempIsArray&)
cmd$ = cmd$ + tempArrayIndexes$ cmd$ = cmd$ + tempArrayIndexes$
cmd$ = cmd$ + MKL$(tempIsUDT&)
cmd$ = cmd$ + MKL$(tempElementOffset&)
cmd$ = cmd$ + MKL$(tempArrayElementSize&) cmd$ = cmd$ + MKL$(tempArrayElementSize&)
cmd$ = cmd$ + MKL$(tempIsUDT&)
cmd$ = cmd$ + MKL$(0)
cmd$ = cmd$ + MKL$(tempElementOffset&)
cmd$ = cmd$ + MKL$(varSize&) cmd$ = cmd$ + MKL$(varSize&)
cmd$ = cmd$ + MKL$(tempStorage&)
cmd$ = cmd$ + MKI$(LEN(tempScope$)) + tempScope$
cmd$ = cmd$ + MKI$(LEN(varType$)) + varType$ cmd$ = cmd$ + MKI$(LEN(varType$)) + varType$
cmd$ = cmd$ + MKI$(LEN(value$)) + value$ cmd$ = cmd$ + MKI$(LEN(value$)) + value$
GOSUB SendCommand GOSUB SendCommand
@ -7187,7 +7264,68 @@ SUB DebugMode
WHILE _MOUSEINPUT: WEND WHILE _MOUSEINPUT: WEND
hidePanel = -1 hidePanel = -1
GOSUB UpdateDisplay 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
temp$ = value$
IF INSTR(varType$, "STRING") = 0 THEN
GOSUB findVarSize
ELSE
varSize& = LEN(dummy%&) + LEN(dummy&)
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(temp$)) + temp$
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 PCOPY 3, 0: SCREEN , , 3, 0
WHILE _MOUSEINPUT: WEND WHILE _MOUSEINPUT: WEND
hidePanel = -1 hidePanel = -1
@ -7394,8 +7532,43 @@ SUB DebugMode
GOSUB GetCommand GOSUB GetCommand
SELECT CASE cmd$ SELECT CASE cmd$
CASE "breakpoint", "line number" CASE "breakpoint", "line number", "watchpoint"
BypassRequestCallStack = 0 BypassRequestCallStack = 0
IF cmd$ = "watchpoint" THEN
temp$ = GetBytes$("", 0) 'reset buffer
tempIndex& = CVL(GetBytes$(value$, 4))
latestWatchpointMet& = tempIndex&
tempArrayIndexes$ = GetBytes$(value$, 4)
tempArrayIndexes$ = tempArrayIndexes$ + GetBytes$(value$, CVL(tempArrayIndexes$))
tempElementOffset$ = GetBytes$(value$, 4)
i = CVI(GetBytes$(value$, 2))
temp$ = usedVariableList(tempIndex&).name + GetBytes$(value$, i)
result = idemessagebox("Watchpoint condition met", temp$, "#OK;#Clear Watchpoint")
IF result = 2 THEN
'find existing watchpoint for the same variable/index/element
temp$ = MKL$(tempIndex&) + tempArrayIndexes$ + tempElementOffset$
i = 0
i = INSTR(i + 1, watchpointList$, MKL$(-1))
DO WHILE i
IF MID$(watchpointList$, i + 8, LEN(temp$)) = temp$ THEN EXIT DO
i = INSTR(i + 1, watchpointList$, MKL$(-1))
LOOP
IF i > 0 THEN
'remove it
j = CVL(MID$(watchpointList$, i + 4, 4))
watchpointList$ = LEFT$(watchpointList$, i - 1) + MID$(watchpointList$, i + j + 8)
END IF
cmd$ = "clear last watchpoint"
GOSUB SendCommand
END IF
value$ = RIGHT$(value$, 4)
ELSE
latestWatchpointMet& = 0
END IF
PCOPY 3, 0: SCREEN , , 3, 0
WHILE _MOUSEINPUT: WEND
l = CVL(value$) l = CVL(value$)
idecy = l idecy = l
ideselect = 0 ideselect = 0
@ -7405,6 +7578,8 @@ SUB DebugMode
clearStatusWindow 1 clearStatusWindow 1
IF cmd$ = "breakpoint" THEN IF cmd$ = "breakpoint" THEN
setStatusMessage 1, "Breakpoint reached on line" + STR$(l), 2 setStatusMessage 1, "Breakpoint reached on line" + STR$(l), 2
ELSEIF cmd$ = "watchpoint" THEN
setStatusMessage 1, "Watchpoint condition met (" + temp$ + ")", 2
ELSE ELSE
setStatusMessage 1, "Paused.", 2 setStatusMessage 1, "Paused.", 2
END IF END IF
@ -7774,6 +7949,20 @@ SUB showvWatchPanel (this AS vWatchPanelType, currentScope$, action as _BYTE)
END IF END IF
IF LEN(item$) > this.contentWidth THEN this.contentWidth = LEN(item$) IF LEN(item$) > this.contentWidth THEN this.contentWidth = LEN(item$)
IF WatchListToConsole = 0 THEN IF WatchListToConsole = 0 THEN
'find existing watchpoint for this variable/index/element
temp2$ = MKL$(tempIndex&) + MKL$(tempTotalArrayIndexes& * 4) + tempArrayIndexes$ + MKL$(tempElementOffset&)
j = 0
j = INSTR(j + 1, watchpointList$, MKL$(-1))
DO WHILE j
IF MID$(watchpointList$, j + 8, LEN(temp2$)) = temp2$ THEN EXIT DO
j = INSTR(j + 1, watchpointList$, MKL$(-1))
LOOP
IF j > 0 THEN
IF latestWatchpointMet& = tempIndex& THEN COLOR 15 ELSE COLOR 4
_PRINTSTRING (this.x + 1, this.y + y), CHR$(7) 'watchpoint bullet indicator
COLOR fg
END IF
_PRINTSTRING (this.x + 2, this.y + y), MID$(item$, this.hPos, this.w - 4) _PRINTSTRING (this.x + 2, this.y + y), MID$(item$, this.hPos, this.w - 4)
ELSE ELSE
_ECHO item$ _ECHO item$
@ -7853,7 +8042,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
selectedBG = 2 selectedBG = 2
TYPE varDlgList TYPE varDlgList
AS LONG index, bgColorFlag, colorFlag, colorFlag2, indicator AS LONG index, bgColorFlag, colorFlag, colorFlag2, indicator, indicator2
AS _BYTE selected AS _BYTE selected
AS STRING varType AS STRING varType
END TYPE END TYPE
@ -7883,7 +8072,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
dialogWidth = 6 + maxModuleNameLen + maxVarLen + maxTypeLen dialogWidth = 6 + maxModuleNameLen + maxVarLen + maxTypeLen
IF IdeDebugMode > 0 THEN dialogWidth = dialogWidth + 40 'make room for "= values" IF IdeDebugMode > 0 THEN dialogWidth = dialogWidth + 40 'make room for "= values"
IF dialogWidth < 60 THEN dialogWidth = 60 IF dialogWidth < 70 THEN dialogWidth = 70
IF dialogWidth > idewx - 8 THEN dialogWidth = idewx - 8 IF dialogWidth > idewx - 8 THEN dialogWidth = idewx - 8
idepar p, dialogWidth, dialogHeight, "Add Watch - Variable List" idepar p, dialogWidth, dialogHeight, "Add Watch - Variable List"
@ -7910,7 +8099,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
o(buttonSet).typ = 3 o(buttonSet).typ = 3
o(buttonSet).y = dialogHeight o(buttonSet).y = dialogHeight
IF IdeDebugMode > 0 AND o(buttonSet).txt = 0 THEN 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 ELSE
o(buttonSet).txt = idenewtxt("#Add All" + sep + "#Remove All" + sep + "#Close") o(buttonSet).txt = idenewtxt("#Add All" + sep + "#Remove All" + sep + "#Close")
END IF END IF
@ -8036,15 +8225,29 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
_CONTINUE _CONTINUE
END IF END IF
IF (IdeDebugMode > 0 AND focus = 5 AND info <> 0) THEN IF (IdeDebugMode > 0 AND focus = 5 AND info <> 0) OR _
'set address (IdeDebugMode > 0 AND focus = 6 AND info <> 0) THEN
'set address/add watchpoint
sendValue: 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) y = ABS(o(varListBox).sel)
IF y >= 1 AND y <= totalVisibleVariables THEN IF y >= 1 AND y <= totalVisibleVariables THEN
tempIndex& = varDlgList(y).index tempIndex& = varDlgList(y).index
IF usedVariableList(tempIndex&).subfunc = currentScope$ OR usedVariableList(tempIndex&).subfunc = "" THEN IF (focus = 5 AND (usedVariableList(tempIndex&).subfunc = currentScope$ OR usedVariableList(tempIndex&).subfunc = "")) OR focus = 6 THEN
'scope is valid 'scope is valid (or we're setting a watchpoint)
tempArrayIndex& = 0 tempArrayIndex& = 0
tempArrayIndexes$ = MKL$(0) tempArrayIndexes$ = MKL$(0)
tempStorage& = 0 tempStorage& = 0
@ -8052,7 +8255,8 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
tempElementOffset$ = MKL$(0) tempElementOffset$ = MKL$(0)
IF usedVariableList(tempIndex&).isarray THEN IF usedVariableList(tempIndex&).isarray THEN
setArrayRange3: setArrayRange3:
v$ = ideinputbox$("Change Value", "#Index to change", temp$, "01234567890,", 45, 0, ok) v$ = ideinputbox$(dlgTitle$, dlgPrompt$, temp$, "01234567890,", 45, 0, ok)
_KEYCLEAR
IF ok THEN IF ok THEN
IF LEN(v$) > 0 THEN IF LEN(v$) > 0 THEN
WHILE RIGHT$(v$, 1) = ",": v$ = LEFT$(v$, LEN(v$) - 1): WEND WHILE RIGHT$(v$, 1) = ",": v$ = LEFT$(v$, LEN(v$) - 1): WEND
@ -8060,6 +8264,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
i = countelements(temp$) i = countelements(temp$)
IF i <> ABS(ids(usedVariableList(tempIndex&).id).arrayelements) THEN IF i <> ABS(ids(usedVariableList(tempIndex&).id).arrayelements) THEN
result = idemessagebox("Error", "Array has" + STR$(ABS(ids(usedVariableList(tempIndex&).id).arrayelements)) + " dimension(s).", "#OK") result = idemessagebox("Error", "Array has" + STR$(ABS(ids(usedVariableList(tempIndex&).id).arrayelements)) + " dimension(s).", "#OK")
_KEYCLEAR
temp$ = _TRIM$(v$) temp$ = _TRIM$(v$)
GOTO setArrayRange3 GOTO setArrayRange3
END IF END IF
@ -8106,6 +8311,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
LOOP LOOP
PCOPY 0, 4 PCOPY 0, 4
v$ = ideelementwatchbox$(usedVariableList(tempIndex&).name + ".", elementIndexes$, 0, -1, ok) v$ = ideelementwatchbox$(usedVariableList(tempIndex&).name + ".", elementIndexes$, 0, -1, ok)
_KEYCLEAR
PCOPY 2, 0 PCOPY 2, 0
PCOPY 2, 1 PCOPY 2, 1
SCREEN , , 1, 0 SCREEN , , 1, 0
@ -8129,7 +8335,8 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
temp$ = v$ temp$ = v$
IF numelements(temp$) <> 1 THEN IF numelements(temp$) <> 1 THEN
'shouldn't ever happen '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")
_KEYCLEAR
_CONTINUE _CONTINUE
END IF END IF
@ -8143,6 +8350,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
'shouldn't ever happen 'shouldn't ever happen
Error_Happened = 0 Error_Happened = 0
result = idemessagebox("Error", Error_Message, "#OK") result = idemessagebox("Error", Error_Message, "#OK")
_KEYCLEAR
_CONTINUE _CONTINUE
ELSE ELSE
typ = typ - ISUDT typ = typ - ISUDT
@ -8185,7 +8393,8 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
END IF END IF
ELSE ELSE
'shouldn't ever happen 'shouldn't ever happen
result = idemessagebox("Error", "Cannot send value to full UDT", "#OK") result = idemessagebox("Error", "Cannot select full UDT", "#OK")
_KEYCLEAR
GOTO dlgLoop GOTO dlgLoop
END IF END IF
END SELECT END SELECT
@ -8212,46 +8421,153 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
LOOP LOOP
END IF END IF
a2$ = "" a2$ = ""
IF storageSlot& > 0 THEN IF storageSlot& > 0 AND focus = 5 THEN
a2$ = vWatchReceivedData$(storageSlot&) a2$ = vWatchReceivedData$(storageSlot&)
ELSEIF focus = 6 THEN
'find existing watchpoint for this variable/index/element
temp$ = MKL$(tempIndex&) + tempArrayIndexes$ + tempElementOffset$
i = 0
i = INSTR(i + 1, watchpointList$, MKL$(-1))
DO WHILE i
IF MID$(watchpointList$, i + 8, LEN(temp$)) = temp$ THEN EXIT DO
i = INSTR(i + 1, watchpointList$, MKL$(-1))
LOOP
IF i > 0 THEN
j = CVL(MID$(watchpointList$, i + 4, 4))
temp$ = MID$(watchpointList$, i + 8, j)
j = CVI(RIGHT$(temp$, 2))
a2$ = MID$(temp$, LEN(temp$) - (2 + j) + 1, j)
END IF
END IF END IF
IF INSTR(varType$, "STRING") THEN IF INSTR(varType$, "STRING") THEN
thisWidth = idewx - 20 thisWidth = idewx - 20
ELSE ELSE
thisWidth = 45 thisWidth = 45
END IF END IF
v$ = ideinputbox$("Change Value", "#New value", a2$, "", thisWidth, 0, ok) getNewValueInput:
v$ = ideinputbox$(dlgTitle$, dlgPrompt2$, a2$, "", thisWidth, 0, ok)
_KEYCLEAR
IF ok THEN IF ok THEN
temp$ = "" IF focus = 6 THEN
temp$ = temp$ + MKL$(tempIndex&) 'validate condition string first
temp$ = temp$ + MKL$(usedVariableList(tempIndex&).localindex) v$ = LTRIM$(v$)
temp$ = temp$ + MKL$(usedVariableList(tempIndex&).isarray <> 0) IF LEN(v$) < 2 THEN
temp$ = temp$ + tempArrayIndexes$ result = idemessagebox(dlgTitle$, "Watchpoint cleared.", "#OK")
temp$ = temp$ + MKL$(tempIsUDT&) _KEYCLEAR
temp$ = temp$ + tempElementOffset$ v$ = ""
temp$ = temp$ + MKL$(usedVariableList(tempIndex&).arrayElementSize) thisReturnAction = 3 'remove watchpoint for this variable
temp$ = temp$ + MKL$(storageSlot&) ELSE
temp$ = temp$ + MKI$(LEN(varType$)) + varType$ StartWatchPointEval:
temp$ = temp$ + MKI$(LEN(v$)) + v$ op1$ = LEFT$(v$, 1)
idevariablewatchbox$ = temp$ op2$ = MID$(v$, 2, 1)
returnAction = 1 'actually send value SELECT CASE op1$
CASE "="
IF op2$ = "<" OR op2$ = ">" THEN
MID$(v$, 1, 2) = op2$ + "="
GOTO StartWatchPointEval
END IF
op$ = "="
actualValue$ = _TRIM$(MID$(v$, 2))
CASE ">"
IF op2$ = "<" OR op2$ = ">" THEN
result = idemessagebox(dlgTitle$, "Invalid expression.\nYou can use =, <>, >, >=, <, <=, and a literal value", "#OK")
_KEYCLEAR
GOTO getNewValueInput
END IF
IF op2$ = "=" THEN
op$ = ">="
actualValue$ = _TRIM$(MID$(v$, 3))
ELSE
op$ = ">"
actualValue$ = _TRIM$(MID$(v$, 2))
END IF
CASE "<"
IF op2$ = ">" OR op2$ = "=" THEN
op$ = "<" + op2$
actualValue$ = _TRIM$(MID$(v$, 3))
ELSE
op$ = "<"
actualValue$ = _TRIM$(MID$(v$, 2))
END IF
CASE ELSE
result = idemessagebox(dlgTitle$, "Invalid expression.\nYou can use =, <>, >, >=, <, <=, and a literal value", "#OK")
_KEYCLEAR
GOTO getNewValueInput
END SELECT
END IF
END IF
IF INSTR(varType$, "STRING") = 0 AND thisReturnAction <> 3 THEN
v$ = op$ + actualValue$
IF v$ <> op$ + LTRIM$(STR$(VAL(actualValue$))) THEN
result = idemessagebox(dlgTitle$, "Invalid expression.\nYou can use =, <>, >, >=, <, <=, and a literal value\n(scientific notation not allowed).", "#OK")
_KEYCLEAR
GOTO getNewValueInput
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&)
cmd$ = cmd$ + tempElementOffset$
cmd$ = cmd$ + MKL$(0)
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$
IF thisReturnAction = 2 OR thisReturnAction = 3 THEN
'find existing watchpoint for the same variable/index/element
temp$ = MKL$(tempIndex&) + tempArrayIndexes$ + tempElementOffset$
i = 0
i = INSTR(i + 1, watchpointList$, MKL$(-1))
DO WHILE i
IF MID$(watchpointList$, i + 8, LEN(temp$)) = temp$ THEN EXIT DO
i = INSTR(i + 1, watchpointList$, MKL$(-1))
LOOP
IF i > 0 THEN
'remove it
j = CVL(MID$(watchpointList$, i + 4, 4))
watchpointList$ = LEFT$(watchpointList$, i - 1) + MID$(watchpointList$, i + j + 8)
END IF
END IF
IF thisReturnAction = 2 THEN
'add watchpoint
temp$ = temp$ + v$ + MKI$(LEN(v$))
watchpointList$ = watchpointList$ + MKL$(-1) + MKL$(LEN(temp$)) + temp$
END IF
returnAction = thisReturnAction 'actually send command
ELSE ELSE
returnAction = 2 'redraw and carry on returnAction = -1 'redraw and carry on
END IF END IF
selectVar = y selectVar = y
EXIT FUNCTION EXIT FUNCTION
ELSE ELSE
result = idemessagebox("Change Value", "Variable is out of scope.", "#OK") result = idemessagebox(dlgTitle$, "Variable is out of scope.", "#OK")
_KEYCLEAR
END IF END IF
ELSE ELSE
result = idemessagebox("Change Value", "Select a variable first.", "#OK") result = idemessagebox(dlgTitle$, "Select a variable first.", "#OK")
_KEYCLEAR
END IF END IF
focus = filterBox focus = filterBox
_CONTINUE _CONTINUE
END IF END IF
IF K$ = CHR$(27) OR (IdeDebugMode = 0 AND focus = 5 AND info <> 0) OR _ 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$ = "" variableWatchList$ = ""
longestVarName = 0 longestVarName = 0
nextvWatchDataSlot = 0 nextvWatchDataSlot = 0
@ -8366,6 +8682,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
IF mCLICK AND focus = 2 THEN 'list click IF mCLICK AND focus = 2 THEN 'list click
IF timeElapsedSince(lastClick!) < .3 AND clickedItem = o(varListBox).sel THEN IF timeElapsedSince(lastClick!) < .3 AND clickedItem = o(varListBox).sel THEN
IF doubleClickThreshold > 0 AND mX >= p.x + doubleClickThreshold AND IdeDebugMode > 0 THEN IF doubleClickThreshold > 0 AND mX >= p.x + doubleClickThreshold AND IdeDebugMode > 0 THEN
focus = 5
GOTO sendValue GOTO sendValue
ELSE ELSE
GOTO toggleWatch GOTO toggleWatch
@ -8668,7 +8985,7 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
maxVarLen = LEN("Variable") maxVarLen = LEN("Variable")
FOR x = 1 TO totalVariablesCreated FOR x = 1 TO totalVariablesCreated
IF usedVariableList(x).includedLine THEN _CONTINUE 'don't deal with variables in $INCLUDEs IF usedVariableList(x).includedLine THEN _CONTINUE 'don't deal with variables in $INCLUDEs
thisLen = LEN(usedVariableList(x).name) thisLen = LEN(usedVariableList(x).name) + 3 'extra room for the eventual bullet
IF LEN(usedVariableList(x).watchRange) > 0 THEN IF LEN(usedVariableList(x).watchRange) > 0 THEN
thisLen = thisLen + LEN(usedVariableList(x).watchRange) thisLen = thisLen + LEN(usedVariableList(x).watchRange)
END IF END IF
@ -8721,6 +9038,22 @@ FUNCTION idevariablewatchbox$(currentScope$, filter$, selectVar, returnAction)
IF LEN(usedVariableList(x).watchRange) THEN IF LEN(usedVariableList(x).watchRange) THEN
thisName$ = LEFT$(thisName$, LEN(thisName$) - 1) + usedVariableList(x).watchRange + ")" thisName$ = LEFT$(thisName$, LEN(thisName$) - 1) + usedVariableList(x).watchRange + ")"
END IF END IF
'find existing watchpoint for this variable/index/element
temp$ = MKL$(x)
i = 0
i = INSTR(i + 1, watchpointList$, MKL$(-1))
DO WHILE i
IF MID$(watchpointList$, i + 8, LEN(temp$)) = temp$ THEN EXIT DO
i = INSTR(i + 1, watchpointList$, MKL$(-1))
LOOP
IF i > 0 THEN
thisName$ = thisName$ + CHR$(16) + CHR$(4) + CHR$(7) 'red bullet to indicate watchpoint
ELSE
thisName$ = thisName$ + CHR$(16) + CHR$(16) + " "
END IF
text$ = thisName$ + CHR$(16) text$ = thisName$ + CHR$(16)
varDlgList(totalVisibleVariables).colorFlag2 = LEN(l$) + LEN(text$) + 1 varDlgList(totalVisibleVariables).colorFlag2 = LEN(l$) + LEN(text$) + 1
IF usedVariableList(x).watch THEN IF usedVariableList(x).watch THEN
@ -14655,7 +14988,14 @@ FUNCTION idemessagebox (titlestr$, messagestr$, buttons$)
'specific post controls 'specific post controls
IF K$ = CHR$(27) THEN EXIT FUNCTION IF K$ = CHR$(27) THEN EXIT FUNCTION
IF K$ = CHR$(13) OR (info <> 0) THEN idemessagebox = focus: EXIT FUNCTION IF K$ = CHR$(13) OR (info <> 0) THEN
idemessagebox = focus
DO UNTIL mCLICK = 0
GetInput
_LIMIT 100
LOOP
EXIT FUNCTION
END IF
'end of custom controls 'end of custom controls
mousedown = 0 mousedown = 0