X
46 Rate this article:
No rating

IDL routine for showing C source for IDL internals

Anonym
Topic:
From Jim Pendleton: IDL routine for showing C source for IDL internals

This is written to run under IDL 5.4, but you can run it under 5.3 by commenting out the /NO_WAIT and /HIDE keywords to SPAWN.Discussion:
Attached is a short IDL procedure you can use to display the C source code associated with a given IDL command.

The syntax is
    IDL> idlsource, 'command-name' [, viewer = viewer]

For example

    IDL> idlsource, 'obj_new', viewer = 'idlde.exe'

The default value of VIEWER is "msdev.exe".

The procedure will search your current drive list for a disk containing the /rsi/dist/daily/idl/CODE directory. If no such drive exists, the routine will stop.

The procedure then searches sysnames.tbl for the command you've specified. If it locates it, it determines the corresponding source file name then spawns off the viewer.

Since there's no generic way to have a viewer scroll to the appropriate line in the code, the procedure will display the name of the routine for which you should search by hand.

At the moment the procedure only works in Windows because the Get_Drive_List() command seems to return -1 on Unix. Unix users are welcome to modify the code as required.

Note that not all system procedures and methods are defined in sysnames.tbl, in particular DLM routines.Solution:

Pro IDLSource, Command, Viewer = Viewer
If (N_Params() ne 1) then Begin
   Message, 'A procedure or function name argument is required.', /Traceback
   Return
EndIf
LocalViewer = N_elements(Viewer) eq 1 ? Viewer : 'msdev.exe'
Drives = Get_Drive_List()
DriveID = 0
Repeat Begin
   SourcePath = FilePath('', Root = Drives[DriveID], $
      SubDir = ['build', 'daily', 'idl', 'CODE'])
   CheckFile = FindFile(FilePath('*', Root = SourcePath), Count = Count)
   Found = Count ne 0
   DriveID = DriveID + 1
EndRep Until (Found or (DriveID eq N_elements(Drives)))
If (not Found) then Begin
   v = Dialog_Message('The IDL daily build disk is not mounted on your system.', /Error)
   Return
EndIf
OpenR, LUN, FilePath('sysnames.tbl', Root = SourcePath), /Get_LUN
Found = 0
Line = ''
Repeat Begin
   ReadF, LUN, Line
   If (StrMid(Line, 0, 1) ne '#') then Begin
      Components = StrTok(StrCompress(Line), ' ', /Extract)
      If (N_elements(Components) ge 6) then Begin
         CommandName = Components[1]
         If (CommandName eq StrUpCase(Command)) then Begin
            InternalName = Components[2]
            SourceName = Components[N_elements(Components) - 1]
            Found = 1
         EndIf
      EndIf
   EndIf
EndRep Until (Found or EOF(LUN))
Free_LUN, LUN
If (Found) then Begin
   Info = 'The source routine is ' + InternalName + '.'
   Print, Info
   v = Dialog_Message(/Information, Info)
   SourceFile = FilePath(SourceName + '.c', Root = SourcePath)
   Spawn, LocalViewer + ' ' + SourceFile, /NoWait, /Hide
EndIf Else Begin
   v = Dialog_Message(['The command "' + Command + '" was not located in sysnames.tbl.', $
      'Check for its presence instead in a system DLM.'])
EndElse
End