There seems to be an inconsistancy, with the processing of $ZSTEP if a call is made during execution of $ZSTEP. Probably something to do with the stack level? Or, perhaps, I'm just not understanding how $ZSTEP is intended to work.
Thanks,
-bob
gtm30 ; Example of calling out of $zstep causing unexpected behavior. ; Invoke three times: ; $ mumps -run A^gtm30 ; $ mumps -run B^gtm30 ; $ mumps -run C^gtm30 ; ; On each run when the following error will be encountered at err+4: ; ; %GTM-E-UNDEF, Undefined local variable: a ; At M source location err+4^gtm30 ; ; Give a value to 'a': ; ; GTM>s a=2 ; ; Then continue to enter "zstep" commands until the routine exits back to the shell: ; ; GTM>zstep ; ... ; ; Note that the first two tests (A and B) require 8 zstep commands, but ; the last test (C) requires only 4 because breaks are not performed ; until an intervening QUIT command has executed. ; Also, note that the first "zstep" after assigning a value to 'a' ; does not result in actually executing any code in the routine (for ; any of the tests). This probably demonstrates the normal behavior ; of zstep, however, it is not terribly intuitive. ; Entry Points: A d test("B") q B d test("w ""zstep-in> "",! b w ""<zstep-out"",!") q C d test("d zsin b d zsout") q zsin w "zstep-in> ",! q zsout w "<zstep-out",! q test(zstep) ; Perform one test. ; s $zstep=zstep ; w "test> "_$zversion_" - "_$zstep,! ; d err ; w "Exit test",! q ; >>> test err ; For testing error handling/$ZSTEP ; w "err",! i 1 d . w a,! . w "foo",! . w "bar",! ; w "Done",! q ; >>> err
Sample output follows:
$ mumps -run 'A^gtm30' test> GT.M V6.1-000 Linux x86_64 - B err %GTM-E-UNDEF, Undefined local variable: a At M source location err+4^gtm30 GTM>s a=2 GTM>zstep %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+4^gtm30 GTM>zstep 2 %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+5^gtm30 GTM>zstep foo %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+6^gtm30 GTM>zstep bar %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+8^gtm30 GTM>zstep Done %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+9^gtm30 GTM>zstep %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location test+8^gtm30 GTM>zstep Exit test %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location test+9^gtm30 GTM>zstep $ --------------------------------------------------------------------------- $ mumps -run 'B^gtm30' test> GT.M V6.1-000 Linux x86_64 - w "zstep-in> ",! b w "<zstep-out",! err %GTM-E-UNDEF, Undefined local variable: a At M source location err+4^gtm30 GTM>s a=2 GTM>zstep zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+4^gtm30 GTM>zstep <zstep-out 2 zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+5^gtm30 GTM>zstep <zstep-out foo zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+6^gtm30 GTM>zstep <zstep-out bar zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+8^gtm30 GTM>zstep <zstep-out Done zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+9^gtm30 GTM>zstep <zstep-out zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location test+8^gtm30 GTM>zstep <zstep-out Exit test zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location test+9^gtm30 GTM>zstep <zstep-out $ ---------------------------------------------------------------------------- $ mumps -run 'C^gtm30' test> GT.M V6.1-000 Linux x86_64 - d zsin b d zsout err %GTM-E-UNDEF, Undefined local variable: a At M source location err+4^gtm30 GTM>s a=2 GTM>zstep zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+4^gtm30 GTM>zstep <zstep-out 2 foo bar zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location err+8^gtm30 GTM>zstep <zstep-out Done zstep-in> %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action At M source location test+8^gtm30 GTM>zstep <zstep-out Exit test $
Actually, seems like it might be some sort of "line" oriented thing. Consider the following two additional cases:
Code to be added to previous routine and invoked via entry points D and E:
The commands in the two "handlers" are identical but case "E" will never terminate unless a ZCONTINUE command is entered at some point instead of a ZSTEP. Entry point "D" actually exhibits desirable functionality except that the breakpoints are at zsD rather than the line being "stepped".
Bob:
Just a quick review:
1) By default, zcontinuing from a ztrap'd line starts at the beginning of that line.
2) zstep does an implied zcontinue that runs until a line matching the criteria is hit (this is the beginning of a line for zstep over ("over" is the default)).
3) If $zstep contains a "do routinex" when the $zstep string is executed, routinex is placed on the stack (just as other do's would cause the routine to be placed on the stack).
Let's consider the cases you had questions about below:
Except for case A (which is the default behavior of $zstep) all of the other cases are variants of case B:
B d test("w ""zstep-in> "",! b w ""<zstep-out"",!") q <-- note: $zstep will be assigned to the parameter passed to test
Case C (writes are in separate routines):
C d test("d zsin b d zsout") q
zsin w "zstep-in> ",! q
zsout w "<zstep-out",! q
This case identified an issue where GT.M is not properly handling the line matching criteria when there is a "do" after the "break" (it seems to work fine with a "do" before the "break"). I have created a tracking number for this issue (GTM-8049). Thanks for identifying it.
Case D (the original $zstep string is now in a routine which is called by the $zstep string):
D d test("d zsD") q
zsD w "zstep-in> ",! b w "<zstep-out",! q="" ;="">>> zsD
From below:
Entry point "D" actually exhibits desirable functionality except that the breakpoints are at zsD rather than the line being "stepped".
From 3) above, this is expected since it was called by the xecution of the $zstep string (and the breakpoint is in that routine). The stack entry would be zsD^gtm30.
Case E (Case D with the commands of the routine on separate lines):
E d test("d zsE") q
zsE ;
w "zstep-in> ",!
b
w "<zstep-out",! q="" ;="">>> zsE
From 1) and 2) above, when you do the first zstep the line matching criteria are met immediately and the executed $zstep string calls zsE which stops at the break at zsE+2^gtm30. Subsequent zsteps will result in recursive calls to zsE which will also stop at zsE+2^GT.M It is a recursive call since you are already in zsE.
The reason case C does not result in recursive call is based upon 2) above. The zstep runs through the end of the line (which exits zsD) before xecuting $zstep which calls zsD.
Thanks,
Bill