;+ ; NAME: ; www_help_get_info ; PURPOSE: ; Tries to find all functions and procedures used in 'name' ; CATEGORY: ; www_help ; CALLING SEQUENCE: FUNCTION www_help_get_info, name, path, search_path, count=count ; INPUTS: ; name scalar; type: string ; name of IDL procedure or function ; path scalar; type: string ; fully-qualified name of file containing 'name' ; search_path scalar; type: string ; Only used when processing IDL code. ; Defines the IDL path used to resolve 'name'. ; OUTPUTS: ; line array; type: string ; list of procedures and functions called by 'name' ; list is set to the null string if none are found ; OPTIONAL OUTPUT PARAMETERS: ; count=count scalar; type: integer ; # functions/procedures called by 'name' ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; SetFileSpec, GetFileSpec, who_am_i ; SEE ALSO: ; www_help_info ; RESTRICTIONS: ; Needs shell used by www_help_shell (currently csh) ; A temporary file is created in $www_help, i.e. environment variable 'www_help' ; must be set to a directory with write acess. If 'www_help' is not set ; program execution stops (this is done in href=www_help_style=). ; PROCEDURE: ; Convoluted. ; 1. Write 'path' and 'name' into file $www_help/www_help.info ; 2. Spawn shell script www_help_shell. This sets IDL_STARTUP to the null string, ; then starts IDL main program www_help_info.pro. ; 3. The IDL main program does four things: ; a. reads 'path' and 'name' from $www_help/www_help.info ; b. uses 'path' to set the IDL !path variable ; c. uses the IDl procedures resolve_routine and routine_name to get the ; list of routines and functions ; d. writes the number of modules found and a comma separated list of ; module names back into $www_help/www_help.info ; 4. After the spawned process completes the final $www_help/www_help.info ; is read again to fill the return variables count and list. ; MODIFICATION HISTORY: ; FEB-2002, Paul Hick (UCSD/CASS) ; DEC-2003, Paul Hick (UCSD/CASS) ; Updated code that looks for the executably ftnchek. ; On Unix the 'which' command is used first. After that ; $SSW_SMEI_UCSD/gen/exe/ is checked. For Windows only the ; last location is checked. ; JAN-2004, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ; Fixed bug in processing output from ftnchek. To find the list of ; function called by a function/subroutine FUNC a line containing ; 'FUNC calls:' was looked for. This would pick up any function ending ; with FUNC. Now the string 'FUNC calls:' is looked for at the beginning ; of a line output by ftnchek. ;- temp_dir = getenv('www_help') IF temp_dir EQ '' THEN temp_dir = getenv('TUB') IF temp_dir EQ '' THEN IF !version.os_family EQ 'unix' THEN temp_dir = '/tmp' IF temp_dir EQ '' THEN message, 'env. var. www_help is not defined' www_help_root = who_am_i(/directory) random_part = string(fix(10000 * randomu(s)), format='(I5.5)') shell = filepath(root=www_help_root , 'www_help_shell' ) prog = filepath(root=www_help_root , 'www_help_info.pro') temp_file = filepath(root=temp_dir, 'www_help'+random_part+'.tmp') SetFileSpec, path file_name = GetFileSpec(part='name') file_type = GetFileSpec(part='type') idl_code = strlowcase(file_type) EQ '.pro' f77_code = strlowcase(file_type) EQ '.f' OR strlowcase(file_type) EQ '.for' CASE 1 OF idl_code: BEGIN width = strlen(www_help_root) > strlen(name) > strlen(path) > strlen(file_name) > strlen(search_path) openw, /get_lun, iu, temp_file, width=width printf, iu, www_help_root ; Directory of www_help package source code printf, iu, name ; Name of procedure printf, iu, path ; Full path to file containing procedure printf, iu, file_name ; Name of the file containing procedure printf, iu, search_path ; IDL search path to be used when compiling procedure free_lun, iu ;spawn, shell+' '+prog+' > /dev/null 2> /dev/null' spawn, shell+' '+prog+' '+temp_file count = '' openr, /get_lun, iu, temp_file, /delete readf, iu, count count = long(count) line = '' IF count NE 0 THEN readf, iu, line free_lun, iu END f77_code: BEGIN ; ftnchek only available on Windows and Linux for now os_incl = ['win' ,'linux','unix','vms'] os_names = ['Microsoft Windows','linux'] os = (where(!version.os EQ os_names))[0] IF os EQ -1 THEN $ message, 'ftnchek not available for this platform: '+!version.os ; Pick up subdirectory where ftnchek is located. os = os_incl[os] os_not = os_incl[where(os NE os_incl)] ; Put main os include in first spot (not really necessary????) os_incl = [os,os_not] ; Set up path to ftnchek executable CASE !version.os_family OF 'unix': BEGIN spawn, 'which ftnchek', ftnchek ; Search for executable ftnchek = ftnchek[0] END ELSE: ftnchek = '' ENDCASE IF ftnchek EQ '' THEN $ ftnchek = filepath(root=getenv('SSW_SMEI_UCSD'),subdir=['gen','exe',os],'ftnchek') ; ===================================== ; THIS SECTION RUNS ONLY UNDER SSW_SMEI IF (file_search(ftnchek))[0] EQ '' THEN $ message, 'could not find ftnchek executable in: '+ftnchek ; Our Fortran code uses two include paths: $for/h and $for/h/linux. include_main = filepath(root=getenv('SSW_SMEI'),subdir='for', 'h') include = ' -include='+include_main include_main = filepath(root=getenv('SSW_SMEI_UCSD'),subdir=['gen','for'], 'h') include = include+' -include='+include_main FOR i=0,n_elements(os_incl)-1 DO include = include+' -include='+filepath(root=include_main,os_incl[i]) ; ===================================== cmd = ftnchek + $ ' -nopretty -reference -columns=132 -library' + $ include + $ ' -output=' +temp_file + $ ' '+path ; Spawn ftnchek. Output is written to temp_file message, /info, name ; !version.release lt 5.4 does not allow /hide CASE !version.os_family OF 'unix': spawn, cmd+' > /dev/null' ELSE : spawn, cmd ;, /hide ENDCASE ; The information we need is wedged between two lines of the type: ; ROUTINE_NAME calls: ; Look for this line with ROUTINE_NAME replaced by current procedure name. ; Once found look for a line with the string 'calls:' in it ; (for the next procedure name) or a blank line. line = '' record = '' calls_beg = strupcase(name)+' calls:' calls_end = ' calls:' on_ioerror, DONE openr, /get_lun, iu, temp_file, /delete on = 0 WHILE NOT eof(iu) AND on LT 2 DO BEGIN readf, iu, record CASE on OF 0: on = strpos(record, calls_beg) EQ 0 1: BEGIN on = strlen(record) GT 0 AND strpos(record,calls_end) EQ -1 CASE on OF 0: on = 2 1: line = line+' '+record ENDCASE END ENDCASE ENDWHILE DONE: IF n_elements(iu) NE 0 THEN free_lun, iu ; Return the list as a comma-separated line. count = line ne '' IF count GT 0 THEN BEGIN line = strtok(line, /extract) line = line[where(line NE 'entry')] line = line[uniq(line,sort(line))] count = n_elements(line) line = strjoin(line, ', ') ENDIF END ELSE: line = '' ENDCASE RETURN, line & END