Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add _NEWHANDLER option for ON ERROR GOTO... #531

Merged
merged 1 commit into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions source/qb64pe.bas
Original file line number Diff line number Diff line change
Expand Up @@ -9099,22 +9099,32 @@ DO
END IF
END IF

IF n = 4 THEN
IF n = 4 OR n = 5 THEN
IF getelements(a$, 1, 3) = "ON" + sp + "ERROR" + sp + "GOTO" THEN
l$ = SCase$("On" + sp + "Error" + sp + "GoTo")
lbl$ = getelement$(ca$, 4)
IF lbl$ = "0" THEN
hhc$ = UCASE$(lbl$) '(H)andler(H)istory(C)ommand
IF n = 5 THEN
IF hhc$ = "_LASTHANDLER" OR (hhc$ = "LASTHANDLER" AND qb64prefix_set = 1) THEN a$ = "No label allowed after _LASTHANDLER": GOTO errmes
IF hhc$ <> "_NEWHANDLER" AND (hhc$ <> "NEWHANDLER" AND qb64prefix_set = 1) THEN a$ = "Expected: ON ERROR GOTO [_NEWHANDLER] label": GOTO errmes
lbl$ = getelement$(ca$, 5)
IF lbl$ = "0" THEN a$ = "Zero not allowed after _NEWHANDLER": GOTO errmes
END IF
IF lbl$ = "0" THEN 'independent from hhc$ (i.e. always clear history)
WriteBufLine MainTxtBuf, "error_goto_line=0;"
WriteBufLine MainTxtBuf, "qbs_set(error_handler_history, qbs_new_txt_len(" + MKI$(&H2222) + ", 0));"
WriteBufLine MainTxtBuf, "qbs_cleanup(qbs_tmp_base, 0);"
l$ = l$ + sp + "0"
layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$
GOTO finishedline
ELSEIF UCASE$(lbl$) = "_LASTHANDLER" OR (UCASE$(lbl$) = "LASTHANDLER" AND qb64prefix_set = 1) THEN
ELSEIF hhc$ = "_NEWHANDLER" OR (hhc$ = "NEWHANDLER" AND qb64prefix_set = 1) THEN
IF n = 4 THEN a$ = "Expected: ON ERROR GOTO [_NEWHANDLER] label": GOTO errmes
IF ASC(hhc$, 1) = 95 THEN l$ = l$ + sp + SCase$("_NewHandler") ELSE l$ = l$ + sp + SCase$("NewHandler")
ELSEIF hhc$ = "_LASTHANDLER" OR (hhc$ = "LASTHANDLER" AND qb64prefix_set = 1) THEN
WriteBufLine MainTxtBuf, "error_goto_line = qbr(func_val(error_handler_history));"
WriteBufLine MainTxtBuf, "qbs_set(error_handler_history, func_mid(error_handler_history, func_instr(NULL, error_handler_history, qbs_new_txt_len(" + CHR$(34) + "|" + CHR$(34) + ", 1), 0) + 1 , NULL, 0));"
WriteBufLine MainTxtBuf, "qbs_cleanup(qbs_tmp_base, 0);"
IF ASC(lbl$, 1) = 95 THEN l$ = l$ + sp + SCase$("_LastHandler") ELSE l$ = l$ + sp + SCase$("LastHandler")
IF ASC(hhc$, 1) = 95 THEN l$ = l$ + sp + SCase$("_LastHandler") ELSE l$ = l$ + sp + SCase$("LastHandler")
layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$
GOTO finishedline
END IF
Expand Down Expand Up @@ -9148,12 +9158,13 @@ DO
Labels(r).Scope_Restriction = subfuncn
END IF 'x


l$ = l$ + sp + tlayout$
layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$
errorlabels = errorlabels + 1
WriteBufLine MainTxtBuf, "qbs_set(error_handler_history, qbs_add(qbs_add(qbs_str((int32)(error_goto_line)), qbs_new_txt_len(" + CHR$(34) + "|" + CHR$(34) + ", 1)), error_handler_history));"
WriteBufLine MainTxtBuf, "qbs_cleanup(qbs_tmp_base, 0);"
IF hhc$ = "_NEWHANDLER" OR (hhc$ = "NEWHANDLER" AND qb64prefix_set = 1) THEN
WriteBufLine MainTxtBuf, "qbs_set(error_handler_history, qbs_add(qbs_add(qbs_str((int32)(error_goto_line)), qbs_new_txt_len(" + CHR$(34) + "|" + CHR$(34) + ", 1)), error_handler_history));"
WriteBufLine MainTxtBuf, "qbs_cleanup(qbs_tmp_base, 0);"
END IF
WriteBufLine MainTxtBuf, "error_goto_line=" + str2(errorlabels) + ";"
WriteBufLine ErrTxtBuf, "if (error_goto_line==" + str2(errorlabels) + "){error_handling=1; goto LABEL_" + lbl$ + ";}"
GOTO finishedline
Expand Down
2 changes: 1 addition & 1 deletion source/subs_functions/syntax_highlighter_list.bas
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ listOfKeywords$ = "@?@$CHECKING@$ERROR@$CONSOLE@ONLY@$DYNAMIC@$ELSE@$ELSEIF@$END
listOfKeywords$ = listOfKeywords$ + "_ERRORLINE@_ERRORMESSAGE$@_EXIT@_EXPLICIT@_EXPLICITARRAY@_FILEEXISTS@_FLOAT@_FONT@_FONTHEIGHT@_FONTWIDTH@_FREEFONT@_FREEIMAGE@_FREETIMER@_FULLSCREEN@_G2D@_G2R@_GLRENDER@_GREEN@_GREEN32@_HEIGHT@_HIDE@_HYPOT@_ICON@_INCLERRORFILE$@_INCLERRORLINE@_INTEGER64@_KEYCLEAR@_KEYDOWN@_KEYHIT@_LASTAXIS@_LASTBUTTON@_LASTWHEEL@_LIMIT@_LOADFONT@_LOADIMAGE@_MAPTRIANGLE@_MAPUNICODE@_MEM@_MEMCOPY@_MEMELEMENT@_MEMEXISTS@_MEMFILL@_MEMFREE@_MEMGET@_MEMIMAGE@_MEMSOUND@_MEMNEW@_MEMPUT@_MIDDLE@_MK$@_MOUSEBUTTON@_MOUSEHIDE@_MOUSEINPUT@_MOUSEMOVE@_MOUSEMOVEMENTX@_MOUSEMOVEMENTY@_MOUSEPIPEOPEN@_MOUSESHOW@_MOUSEWHEEL@_MOUSEX@_MOUSEY@_NEWIMAGE@_OFFSET@_OPENCLIENT@_OPENCONNECTION@_OPENHOST@_OS$@_PALETTECOLOR@_PI@_PIXELSIZE@_PRESERVE@_PRINTIMAGE@_PRINTMODE@_PRINTSTRING@_PRINTWIDTH@_PUTIMAGE@_R2D@_R2G@_RED@_RED32@_RESIZE@_RESIZEHEIGHT@_RESIZEWIDTH@_RGB@_RGB32@_RGBA@_RGBA32@_ROUND@_SCREENCLICK@_SCREENEXISTS@_SCREENHIDE@_SCREENICON@_SCREENIMAGE@_SCREENMOVE@_SCREENPRINT@_SCREENSHOW@_SCREENX@_SCREENY@_SEC@_SECH@_SETALPHA@_SHELLHIDE@_SINH@_SNDBAL@_SNDCLOSE@_SNDCOPY@_SNDGETPOS@_SNDLEN@_SNDLIMIT@_SNDLOOP@_SNDOPEN@_SNDOPENRAW@_SNDPAUSE@_SNDPAUSED@_SNDPLAY@_SNDPLAYCOPY@_SNDPLAYFILE@_SNDPLAYING@_SNDRATE@_SNDRAW@_SNDRAWDONE@_SNDRAWLEN@_SNDSETPOS@_SNDSTOP@_SNDVOL@_SOURCE@_STARTDIR$@_STRCMP@_STRICMP@_TANH@_TITLE@_TITLE$@_UNSIGNED@_WHEEL@_WIDTH@_WINDOWHANDLE@_WINDOWHASFOCUS@_GLACCUM@_GLALPHAFUNC@_GLARETEXTURESRESIDENT@_GLARRAYELEMENT@_GLBEGIN@_GLBINDTEXTURE@_GLBITMAP@_GLBLENDFUNC@_GLCALLLIST@_GLCALLLISTS@_GLCLEAR@_GLCLEARACCUM@_GLCLEARCOLOR@_GLCLEARDEPTH@_GLCLEARINDEX@_GLCLEARSTENCIL@_GLCLIPPLANE@_GLCOLOR3B@_GLCOLOR3BV@_GLCOLOR3D@_GLCOLOR3DV@_GLCOLOR3F@_GLCOLOR3FV@_GLCOLOR3I@_GLCOLOR3IV@_GLCOLOR3S@_GLCOLOR3SV@_GLCOLOR3UB@_GLCOLOR3UBV@_GLCOLOR3UI@_GLCOLOR3UIV@_GLCOLOR3US@_GLCOLOR3USV@_GLCOLOR4B@_GLCOLOR4BV@_GLCOLOR4D@_GLCOLOR4DV@_GLCOLOR4F@_GLCOLOR4FV@_GLCOLOR4I@_GLCOLOR4IV@_GLCOLOR4S@_GLCOLOR4SV@_GLCOLOR4UB@_GLCOLOR4UBV@_GLCOLOR4UI@_GLCOLOR4UIV@_GLCOLOR4US@_GLCOLOR4USV@_GLCOLORMASK@_GLCOLORMATERIAL@_GLCOLORPOINTER@_GLCOPYPIXELS@_GLCOPYTEXIMAGE1D@_GLCOPYTEXIMAGE2D@_GLCOPYTEXSUBIMAGE1D@"
listOfKeywords$ = listOfKeywords$ + "_GLCOPYTEXSUBIMAGE2D@_GLCULLFACE@_GLDELETELISTS@_GLDELETETEXTURES@_GLDEPTHFUNC@_GLDEPTHMASK@_GLDEPTHRANGE@_GLDISABLE@_GLDISABLECLIENTSTATE@_GLDRAWARRAYS@_GLDRAWBUFFER@_GLDRAWELEMENTS@_GLDRAWPIXELS@_GLEDGEFLAG@_GLEDGEFLAGPOINTER@_GLEDGEFLAGV@_GLENABLE@_GLENABLECLIENTSTATE@_GLEND@_GLENDLIST@_GLEVALCOORD1D@_GLEVALCOORD1DV@_GLEVALCOORD1F@_GLEVALCOORD1FV@_GLEVALCOORD2D@_GLEVALCOORD2DV@_GLEVALCOORD2F@_GLEVALCOORD2FV@_GLEVALMESH1@_GLEVALMESH2@_GLEVALPOINT1@_GLEVALPOINT2@_GLFEEDBACKBUFFER@_GLFINISH@_GLFLUSH@_GLFOGF@_GLFOGFV@_GLFOGI@_GLFOGIV@_GLFRONTFACE@_GLFRUSTUM@_GLGENLISTS@_GLGENTEXTURES@_GLGETBOOLEANV@_GLGETCLIPPLANE@_GLGETDOUBLEV@_GLGETERROR@_GLGETFLOATV@_GLGETINTEGERV@_GLGETLIGHTFV@_GLGETLIGHTIV@_GLGETMAPDV@_GLGETMAPFV@_GLGETMAPIV@_GLGETMATERIALFV@_GLGETMATERIALIV@_GLGETPIXELMAPFV@_GLGETPIXELMAPUIV@_GLGETPIXELMAPUSV@_GLGETPOINTERV@_GLGETPOLYGONSTIPPLE@_GLGETSTRING@_GLGETTEXENVFV@_GLGETTEXENVIV@_GLGETTEXGENDV@_GLGETTEXGENFV@_GLGETTEXGENIV@_GLGETTEXIMAGE@_GLGETTEXLEVELPARAMETERFV@_GLGETTEXLEVELPARAMETERIV@_GLGETTEXPARAMETERFV@_GLGETTEXPARAMETERIV@_GLHINT@_GLINDEXMASK@_GLINDEXPOINTER@_GLINDEXD@_GLINDEXDV@_GLINDEXF@_GLINDEXFV@_GLINDEXI@_GLINDEXIV@_GLINDEXS@_GLINDEXSV@_GLINDEXUB@_GLINDEXUBV@_GLINITNAMES@_GLINTERLEAVEDARRAYS@_GLISENABLED@_GLISLIST@_GLISTEXTURE@_GLLIGHTMODELF@_GLLIGHTMODELFV@_GLLIGHTMODELI@_GLLIGHTMODELIV@_GLLIGHTF@_GLLIGHTFV@_GLLIGHTI@_GLLIGHTIV@_GLLINESTIPPLE@_GLLINEWIDTH@_GLLISTBASE@_GLLOADIDENTITY@_GLLOADMATRIXD@_GLLOADMATRIXF@_GLLOADNAME@_GLLOGICOP@_GLMAP1D@_GLMAP1F@_GLMAP2D@_GLMAP2F@_GLMAPGRID1D@_GLMAPGRID1F@_GLMAPGRID2D@_GLMAPGRID2F@_GLMATERIALF@_GLMATERIALFV@_GLMATERIALI@_GLMATERIALIV@_GLMATRIXMODE@_GLMULTMATRIXD@_GLMULTMATRIXF@_GLNEWLIST@_GLNORMAL3B@_GLNORMAL3BV@_GLNORMAL3D@_GLNORMAL3DV@_GLNORMAL3F@_GLNORMAL3FV@_GLNORMAL3I@_GLNORMAL3IV@_GLNORMAL3S@_GLNORMAL3SV@_GLNORMALPOINTER@_GLORTHO@_GLPASSTHROUGH@_GLPIXELMAPFV@_GLPIXELMAPUIV@_GLPIXELMAPUSV@_GLPIXELSTOREF@_GLPIXELSTOREI@_GLPIXELTRANSFERF@_GLPIXELTRANSFERI@_GLPIXELZOOM@_GLPOINTSIZE@_GLPOLYGONMODE@_GLPOLYGONOFFSET@_GLPOLYGONSTIPPLE@"
listOfKeywords$ = listOfKeywords$ + "_GLPOPATTRIB@_GLPOPCLIENTATTRIB@_GLPOPMATRIX@_GLPOPNAME@_GLPRIORITIZETEXTURES@_GLPUSHATTRIB@_GLPUSHCLIENTATTRIB@_GLPUSHMATRIX@_GLPUSHNAME@_GLRASTERPOS2D@_GLRASTERPOS2DV@_GLRASTERPOS2F@_GLRASTERPOS2FV@_GLRASTERPOS2I@_GLRASTERPOS2IV@_GLRASTERPOS2S@_GLRASTERPOS2SV@_GLRASTERPOS3D@_GLRASTERPOS3DV@_GLRASTERPOS3F@_GLRASTERPOS3FV@_GLRASTERPOS3I@_GLRASTERPOS3IV@_GLRASTERPOS3S@_GLRASTERPOS3SV@_GLRASTERPOS4D@_GLRASTERPOS4DV@_GLRASTERPOS4F@_GLRASTERPOS4FV@_GLRASTERPOS4I@_GLRASTERPOS4IV@_GLRASTERPOS4S@_GLRASTERPOS4SV@_GLREADBUFFER@_GLREADPIXELS@_GLRECTD@_GLRECTDV@_GLRECTF@_GLRECTFV@_GLRECTI@_GLRECTIV@_GLRECTS@_GLRECTSV@_GLRENDERMODE@_GLROTATED@_GLROTATEF@_GLSCALED@_GLSCALEF@_GLSCISSOR@_GLSELECTBUFFER@_GLSHADEMODEL@_GLSTENCILFUNC@_GLSTENCILMASK@_GLSTENCILOP@_GLTEXCOORD1D@_GLTEXCOORD1DV@_GLTEXCOORD1F@_GLTEXCOORD1FV@_GLTEXCOORD1I@_GLTEXCOORD1IV@_GLTEXCOORD1S@_GLTEXCOORD1SV@_GLTEXCOORD2D@_GLTEXCOORD2DV@_GLTEXCOORD2F@_GLTEXCOORD2FV@_GLTEXCOORD2I@_GLTEXCOORD2IV@_GLTEXCOORD2S@_GLTEXCOORD2SV@_GLTEXCOORD3D@_GLTEXCOORD3DV@_GLTEXCOORD3F@_GLTEXCOORD3FV@_GLTEXCOORD3I@_GLTEXCOORD3IV@_GLTEXCOORD3S@_GLTEXCOORD3SV@_GLTEXCOORD4D@_GLTEXCOORD4DV@_GLTEXCOORD4F@_GLTEXCOORD4FV@_GLTEXCOORD4I@_GLTEXCOORD4IV@_GLTEXCOORD4S@_GLTEXCOORD4SV@_GLTEXCOORDPOINTER@_GLTEXENVF@_GLTEXENVFV@_GLTEXENVI@_GLTEXENVIV@_GLTEXGEND@_GLTEXGENDV@_GLTEXGENF@_GLTEXGENFV@_GLTEXGENI@_GLTEXGENIV@_GLTEXIMAGE1D@_GLTEXIMAGE2D@_GLTEXPARAMETERF@_GLTEXPARAMETERFV@_GLTEXPARAMETERI@_GLTEXPARAMETERIV@_GLTEXSUBIMAGE1D@_GLTEXSUBIMAGE2D@_GLTRANSLATED@_GLTRANSLATEF@_GLVERTEX2D@_GLVERTEX2DV@_GLVERTEX2F@_GLVERTEX2FV@_GLVERTEX2I@_GLVERTEX2IV@_GLVERTEX2S@_GLVERTEX2SV@_GLVERTEX3D@_GLVERTEX3DV@_GLVERTEX3F@_GLVERTEX3FV@_GLVERTEX3I@_GLVERTEX3IV@_GLVERTEX3S@_GLVERTEX3SV@_GLVERTEX4D@_GLVERTEX4DV@_GLVERTEX4F@_GLVERTEX4FV@_GLVERTEX4I@_GLVERTEX4IV@_GLVERTEX4S@_GLVERTEX4SV@_GLVERTEXPOINTER@_GLVIEWPORT@SMOOTH@STRETCH@_ANTICLOCKWISE@_BEHIND@_CLEAR@_FILLBACKGROUND@_GLUPERSPECTIVE@_HARDWARE@_HARDWARE1@_KEEPBACKGROUND@_NONE@_OFF@_ONLY@_ONLYBACKGROUND@_ONTOP@_SEAMLESS@_SMOOTH@_SMOOTHSHRUNK@_SMOOTHSTRETCHED@"
listOfKeywords$ = listOfKeywords$ + "_SOFTWARE@_SQUAREPIXELS@_STRETCH@_ALLOWFULLSCREEN@_ALL@_ECHO@_READFILE$@_WRITEFILE@_INSTRREV@_LASTHANDLER@_TRIM$@_ACCEPTFILEDROP@_FINISHDROP@_TOTALDROPPEDFILES@_DROPPEDFILE@_DROPPEDFILE$@_SHR@_SHL@_ROR@_ROL@"
listOfKeywords$ = listOfKeywords$ + "_SOFTWARE@_SQUAREPIXELS@_STRETCH@_ALLOWFULLSCREEN@_ALL@_ECHO@_READFILE$@_WRITEFILE@_INSTRREV@_LASTHANDLER@_NEWHANDLER@_TRIM$@_ACCEPTFILEDROP@_FINISHDROP@_TOTALDROPPEDFILES@_DROPPEDFILE@_DROPPEDFILE$@_SHR@_SHL@_ROR@_ROL@"
listOfKeywords$ = listOfKeywords$ + "_ADLER32@_CRC32@_MD5$@_DEFLATE$@_INFLATE$@_READBIT@_RESETBIT@_SETBIT@_TOGGLEBIT@$INCLUDEONCE@$ASSERTS@CONSOLE@_ASSERT@_CAPSLOCK@_NUMLOCK@_SCROLLLOCK@_TOGGLE@_CONSOLEFONT@_CONSOLECURSOR@_CONSOLEINPUT@_CINP@$NOPREFIX@$COLOR@$DEBUG@$EMBED@_EMBEDDED$@_ENVIRONCOUNT@$UNSTABLE@$MIDISOUNDFONT@"
listOfKeywords$ = listOfKeywords$ + "_NOTIFYPOPUP@_MESSAGEBOX@_INPUTBOX$@_SELECTFOLDERDIALOG$@_COLORCHOOSERDIALOG@_OPENFILEDIALOG$@_SAVEFILEDIALOG$@_SAVEIMAGE@_FILES$@_FULLPATH$@_NEGATE@_ANDALSO@_ORELSE@"
listOfKeywords$ = listOfKeywords$ + "_STATUSCODE@_SNDNEW@_SCALEDWIDTH@_SCALEDHEIGHT@_UFONTHEIGHT@_UPRINTWIDTH@_ULINESPACING@_UPRINTSTRING@_UCHARPOS@_MIDISOUNDBANK@"
40 changes: 20 additions & 20 deletions tests/compile_tests/on_error/errtest.bas
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ END DECLARE

'testing handler behavior
Status
ON ERROR GOTO mainHandler
ON ERROR GOTO mainHandler 'set w/o history entry
Status
ERROR 5
NormalTest
ERROR 5
RecursiveTest 3
ERROR 5
ON ERROR GOTO _LASTHANDLER
ON ERROR GOTO _LASTHANDLER 'no more history entries => silent fallback to "unhandled"
Status

'return to test script
Expand All @@ -36,30 +36,30 @@ RESUME NEXT

'-----------------------------------------------------------------------
SUB NormalTest
ON ERROR GOTO nSubHandler
Status
ERROR 5
ON ERROR GOTO _LASTHANDLER
Status
ON ERROR GOTO _NEWHANDLER nSubHandler 'set with history entry
Status
ERROR 5
ON ERROR GOTO _LASTHANDLER 'restore to the last handler from history
Status
END SUB
'-----
SUB RecursiveTest (n%)
ON ERROR GOTO rSubHandler
Status
ERROR 5
IF n% > 1 THEN RecursiveTest n% - 1
ON ERROR GOTO _LASTHANDLER
Status
ON ERROR GOTO _NEWHANDLER rSubHandler 'set with history entry
Status
ERROR 5
IF n% > 1 THEN RecursiveTest n% - 1
ON ERROR GOTO _LASTHANDLER 'restore to the last handler from history
Status
END SUB

'-----------------------------------------------------------------------
SUB Status
PRINT: PRINT "HISTORY: "; "<"; GetErrorHistory$; ">"
SELECT CASE GetErrorGotoLine&
CASE 0: PRINT " ACTIVE: unhandled"
CASE 1: PRINT " ACTIVE: main handler"
CASE 2: PRINT " ACTIVE: normal sub handler"
CASE 3: PRINT " ACTIVE: recursive sub handler"
END SELECT
PRINT: PRINT "HISTORY: "; "<"; GetErrorHistory$; ">"
SELECT CASE GetErrorGotoLine&
CASE 0: PRINT " ACTIVE: unhandled"
CASE 1: PRINT " ACTIVE: main handler"
CASE 2: PRINT " ACTIVE: normal sub handler"
CASE 3: PRINT " ACTIVE: recursive sub handler"
END SELECT
END SUB

18 changes: 9 additions & 9 deletions tests/compile_tests/on_error/errtest.output
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,37 @@
HISTORY: <>
ACTIVE: unhandled

HISTORY: < 0|>
HISTORY: <>
ACTIVE: main handler
CALLED: main handler

HISTORY: < 1| 0|>
HISTORY: < 1|>
ACTIVE: normal sub handler
CALLED: normal sub handler

HISTORY: < 0|>
HISTORY: <>
ACTIVE: main handler
CALLED: main handler

HISTORY: < 1| 0|>
HISTORY: < 1|>
ACTIVE: recursive sub handler
CALLED: recursive sub handler

HISTORY: < 3| 1| 0|>
HISTORY: < 3| 1|>
ACTIVE: recursive sub handler
CALLED: recursive sub handler

HISTORY: < 3| 3| 1| 0|>
HISTORY: < 3| 3| 1|>
ACTIVE: recursive sub handler
CALLED: recursive sub handler

HISTORY: < 3| 1| 0|>
HISTORY: < 3| 1|>
ACTIVE: recursive sub handler

HISTORY: < 1| 0|>
HISTORY: < 1|>
ACTIVE: recursive sub handler

HISTORY: < 0|>
HISTORY: <>
ACTIVE: main handler
CALLED: main handler

Expand Down