In hindsight, it should be obvious. But it turns out that in Visual FoxPro 9.0 (and, I suspect, every previous version as well) the SYS(16) function returns different results depending on the setting of the Debug Info checkbox in the Project Information dialog. So if you are relying on these results, you’d better make sure you understand the difference.

To recap, here are some extracts from the Help file:

SYS( 16 ) returns the file name of the program being executed.

[..]

If n is 0 or 1, SYS( 16, n ) returns the name of the main program (the program first executed). The name of the currently executing program is returned if n is omitted. The empty string is returned if n is greater than the program nesting depth.

[..]

When the executing program is part of an application (.app), SYS(16) returns only the name of the program, that is, without the path. SYS(16) returns the name of the executable file if called from an executable (.exe) file. If a procedure or function is being executed, SYS(16) returns the name of the file containing the procedure or function after the procedure or function name.

I’m not sure I completely understood that, so when in doubt, I do some empirical tests. Using the source code to ReportBuilder.App (conveniently included in the XSOURCE.ZIP file in the TOOLS directory in the Visual FoxPro home directory) I added a breakpoint on a particular method and displayed the Watch Window and took a look around in the call stack using SYS(16,n):

SYS(16,8)  "PROCEDURE FRXSETUPUTILS.GETAPPLICATIONPATH FRXSETUP.FXP"
SYS(16,7)  "PROCEDURE FRXSETUPUTILS.GETBUILDERREGISTRYTABLENAME FRXSETUP.FXP"
SYS(16,6)  "PROCEDURE FRXEVENT.GETREGISTRYTABLENAME C:\TEMP\REPORTBUILDER\FRXBUILDER.VCT"
SYS(16,5)  "PROCEDURE FRXOPTIONS.EXECUTE C:\TEMP\REPORTBUILDER\FRXBUILDER.VCT"
SYS(16,4)  "PROCEDURE FRXEVENT.SHOWOPTIONS C:\TEMP\REPORTBUILDER\FRXBUILDER.VCT"
SYS(16,3)  "PROCEDURE FRXEVENT.EXECUTE C:\TEMP\REPORTBUILDER\FRXBUILDER.VCT"
SYS(16,2)  "PROCEDURE REPORTBUILDER.PROCESSEVENT C:\TEMP\REPORTBUILDER\REPORTBUILDER.APP"
SYS(16,1)  "C:\TEMP\REPORTBUILDER\REPORTBUILDER.APP"

This is all fine and good. It may even match the documentation, it’s a little hard to be sure. The interesting thing that does not appear to be documented is that these results are affected by the “debug info” checkbox in the Project Information dialog box. Here’s a picture of it in case you don’t remember seeing it before. Open a project, and select Project->Project Info from the menu (or press Ctrl-J):

Normally, it’s checked. So I cleared the checkbox (indicating that I did not want additional debug information compiled into the application), recompiled, ran, and suspended at the same point:

SYS(16,8)  "PROCEDURE FRXSETUPUTILS.GETAPPLICATIONPATH FRXSETUP.FXP"
SYS(16,7)  "PROCEDURE FRXSETUPUTILS.GETBUILDERREGISTRYTABLENAME FRXSETUP.FXP"
SYS(16,6)  "PROCEDURE FRXEVENT.GETREGISTRYTABLENAME "
SYS(16,5)  "PROCEDURE FRXOPTIONS.EXECUTE "
SYS(16,4)  "PROCEDURE FRXEVENT.SHOWOPTIONS "
SYS(16,3)  "PROCEDURE FRXEVENT.EXECUTE "
SYS(16,2)  "PROCEDURE REPORTBUILDER.PROCESSEVENT C:\TEMP\REPORTBUILDER\REPORTBUILDER.APP"
SYS(16,1)  "C:\TEMP\REPORTBUILDER\REPORTBUILDER.APP"

Interesting. We can still read the names of the procedure (.FXP) files, but not the class library (.VCT) files. I wonder why that is? Your guess is as good as mine.