Using the IDL Callstack
QUESTION: OK, this is weird, I admit. But I have reason to want to know the name of the program module I am current executing, the name of the module that called this current module, and the path to the file with the same name as this module. (Don't ask.) Oh, and if I have five files with the same name, the path should reflect the one that is currently compiled. Any chance IDL can do that?
ANSWER: No... Oh, wait a minute. Maybe. Humm. Let's see.
OK, how about this example program.
PRO FindModuleTest ; Get the current calling stack. Help, Calls=callStack ; Parse the name of this program module, and the module that called this one. IF Float(!Version.Release) GE 5.2 THEN BEGIN thisRoutine = (StrSplit(StrCompress(callStack[0])," ", /Extract))[0] callingRoutine = (StrSplit(StrCompress(callStack[1])," ", /Extract))[0] ENDIF ELSE BEGIN thisRoutine = (Str_Sep(StrCompress(callStack[0])," "))[0] callingRoutine = (Str_Sep(StrCompress(callStack[1])," "))[0] ENDELSE ; Print the information. Print, 'This program module is ' + thisRoutine + $ '. It has been called by ' + callingRoutine + '.' ; Now, find the path to this program module. thisRoutine = StrLowCase(thisRoutine) + '.pro' thePath=strmid(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine)), $ StrPos(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine)), '<') + 1, $ StrLen(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine))) - $ StrPos(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine)), '<')) ; Print the information. Print, 'The file "' + thisRoutine + '" is in this directory: ' + thePath + '.' END
Called from the program Scooter, the FindModuleTest program produces these results:
IDL> scooter This program module is FINDMODULETEST. It has been called by SCOOTER. The file "findmoduletest.pro" is in this directory: C:\IDL\David\test\.
JD Smith offers another version of this that eliminates some of the (almost) magical complexity of the original by using the built-in Routine_Info command. He would substitute this:
; Now, find the path to this program module. thisRoutine = StrLowCase(thisRoutine) source = (Routine_Info(thisRoutine, /Source)).Path thePath = StrMid(source, 0, StrPos(source, Path_Sep(), /Reverse_Search))
For this:
; Now, find the path to this program module. thisRoutine = StrLowCase(thisRoutine) + '.pro' thePath=strmid(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine)), $ StrPos(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine)), '<') + 1, $ StrLen(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine))) - $ StrPos(StrMid(callStack[0], 0, $ StrPos(callStack[0],thisRoutine)), '<'))
Please note that both of these programs assume that the file is named properly (i.e., that the name of the file is the same as the last module, also known as the "command" module, in the file), and that the file is located in a directory that is on your IDL path.
Copyright © 1997-2003 David W. Fanning
Last Updated 3 March 2003