Viewing contents of file '../idllib/astron/contrib/varosi/vlib/allpro/get_proc.pro'
;+
; NAME:
; GET_PROC
; PURPOSE:
; Extract procedure from a library or directory.
; CALLING SEQUENCE:
; PROC = GET_PROC(LIB,NAME,FNAME,TEXT,
; /DOC_ONLY,/EXTRACT,/SEARCH,/LINOS,/BUFFER)
; INPUTS:
; LIB = Library name.
; NAME = Procedure name.
; TEXT = Search string.
; KEYWORDS:
; DOC_ONLY= Logical switch to decide whether only the documentation
; (between ";+" and ";-") is to be read in, or the entire file.
; EXTRACT = copy extracted library module to user's current directory
; SEARCH = Logical switch to decide whether to search for string in
; variable TEXT
; UNUSABLE KEYWORDS -- code is in place but modifications to DOC.PRO
; are needed to pass /LINOS or BUFFER=[n1,n2]
; LINOS = added line number option
; BUFFER = 2 element vector indicating display n1 lines before search
; string and n2 lines after search string. Only valid if
; /SEARCH is set
; OUTPUTS:
; FNAME = File name.
; PROC = string array with each element being a line of code.
; PROCEDURE:
; If necessary, then spawns a LIBRARY/EXTRACT command.
; MODIFICATION HISTORY:
; Written DMZ (ARC) May 1991.
; Modified WTT (ARC) Dec 1991, to support UNIX.
; Modified DMZ (ARC) Jul 1992, to speed reading and add extract keyword
; Modified EEE (HSTX) Oct 1992, 1) to find all occurrences of ;+/;_
; 2) to search for input string
; 3) to allow BUFFER keyword
;-
function get_proc,library,name,fname,text, doc_only=doc_only, $
extract=extract,search=search,linos=linos, buffer=buffer
common procb,libs,names,procs
;-- in case there was a crash earlier
n_libs=n_elements(libs)
n_names=n_elements(names)
sz=size(procs)
if sz(0) eq 2 then n_procs=sz(2) else n_procs=sz(0)
if (n_procs ne n_names) or (n_libs ne n_names) or (n_libs ne n_procs) then begin
message,'memory error; will fix',/info
names='' & procs='' & libs=''
endif
;-- strip off .pro
ext=strpos(strupcase(name),'.PRO')
if ext gt -1 then tname=strupcase(strmid(name,0,ext)) else $
tname=strupcase(name)
if keyword_set(doc_only) then doc_only=1 else doc_only=0
if !version.os eq "vms" then dirsep = '' else dirsep = '/'
lib = strtrim(library,2) & tchar = strmid(lib,0,1)
tlb = tchar eq "@"
if tlb then begin ;-- take off "@" sign
lib = strmid(lib,1,strlen(lib)-1)
fname='sys$login:'+tname+'._SCL'
endif else begin
ext=strpos(strupcase(name),'.PRO')
if ext gt -1 then fname=lib+dirsep+name else fname=lib+dirsep+name+'.pro'
endelse
;- If the name is '*INFO*', then get the file "aaareadme.txt", and get the
; entire file.
SAVE_DOC_ONLY = DOC_ONLY
IF NAME EQ '*INFO*' THEN BEGIN
FNAME = LIB + DIRSEP + "aaareadme.txt"
DOC_ONLY = 0
ENDIF
;-- extract option (copy selected procedure to current directory)
if keyword_set(extract) then begin
if tlb then begin ;-- library modules already extracted?
find = findfile( substwid( fname ), count=fc )
if fc eq 0 then begin
statement='$LIBR/EXTRACT='+tname+' '+lib+' /OUT='+fname
spawn,statement
endif
endif
cd,current=def
semic=strpos(strupcase(fname),';')
if semic lt 0 then sname=fname else sname=strmid(fname,0,semic) ;-- strip version
if name eq '*INFO*' then tname='aaareadme'
back=sname+' '+def+dirsep+tname+'.txt'
if !version.os eq 'vms' then front='copy/nolog/noconfirm ' else front='cp '
spawn,front+back
return,''
endif
;-- in memory already?; if so, then retrieve it
PROC_IN_MEMORY=0
IF N_ELEMENTS(NAMES) NE 0 THEN BEGIN
FIND=WHERE(TNAME EQ NAMES,COUNT)
IF COUNT NE 0 THEN BEGIN
FOR ICOUNT = 0,COUNT-1 DO BEGIN
IF LIBS(FIND(ICOUNT)) EQ LIB THEN BEGIN
message,'recalling '+name+' from memory',/info
PROC=PROCS(*,FIND(ICOUNT)) & PROC_IN_MEMORY=1 & GOTO,NEXT
ENDIF
ENDFOR
ENDIF
ENDIF
next:
if not PROC_IN_MEMORY then begin
;-- extract module from library or directory
if tlb then begin ;--library case
find = findfile( substwid( fname ), count=fc ) ;--modules already extracted?
if fc eq 0 then begin
statement='$LIBR/EXTRACT='+tname+' '+lib+' /OUT='+fname
spawn,statement
endif
endif else begin ;--directory case
found = findfile( substwid( fname ), count=nf )
if nf eq 0 then return,strupcase(fname)+' NOT FOUND'
endelse
;-- now read procedure into memory by using SPAWN
if !version.os eq 'vms' then cmd='type/nopage '+fname else cmd='cat '+fname
spawn,cmd,proc
;-- add line numbers
if keyword_set(linos) then begin
np=n_elements(proc)
lnums=(sindgen(np+1))(1:np)+': '
proc=strtrim(lnums,1)+proc
endif
;--now save procedure into common memory to avoid re-reading
if n_procs eq 0 then begin
LIBS = LIB
NAMES = TNAME
PROCS = PROC
endif else begin
LIBS = [LIBS,LIB]
NAMES = [NAMES,TNAME]
BOOST_ARRAY,PROCS,PROC
IF N_ELEMENTS(NAMES) GT 10 THEN BEGIN ;Save last 10
LIBS = LIBS(1:*)
NAMES = NAMES(1:*)
PROCS = PROCS(*,1:*)
ENDIF
endelse
endif
;-- If the documentation only switch has been set, then only extract the parts
; between the lines beginning with ";+" and ";-". First look for the ";+"
; line, then copy in lines until the ";-" line is found.
if doc_only then begin
tproc='NO DOCUMENTATION FOUND' & np=n_elements(proc)
BEGUN=0 & DONE=0 & i=-1
repeat begin
i=i+1 & line=proc(i)
IF NOT BEGUN THEN BEGIN
BEGUN = (STRPOS(LINE, ";+") NE -1)
END ELSE IF (STRPOS(LINE,";-") NE -1) THEN BEGIN
begun = 0 ; start again and look for more
END ELSE BEGIN
TPROC=[TPROC,LINE]
ENDELSE
endrep until (i eq np-1) ; search whole file
IF N_ELEMENTS(TPROC) GT 1 THEN TPROC=TPROC(1:*)
PROC=TPROC
endif
DOC_ONLY = SAVE_DOC_ONLY
; Now have desired output in variable array PROC so just do a search on that.
; If SEARCH is set, then show the specified lines above and below the line
; that contains the search string.
if keyword_set(search) then search=1 else search=0
if not keyword_set(buffer) then buffer = [2,2] $ ; 2 lines before and after
else buffer=buffer
if search then begin ; search file for the given string
if text eq '' then return,'NO SEARCH STRING ENTERED'
tproc='NO MATCH FOUND FOR SEARCH STRING ' + text & np=n_elements(proc)-1
textup = strupcase(text) ; find all occurrences
case n_elements(buffer) of ; is there a range to show above/below
0 : begin above=0 & below=0 & end ; only 1 line
1 : begin above=0 & below=buffer & end ; current down to input
else : begin above=buffer(0) & below=buffer(1) & end ; expand both sides
endcase
i=-1 & trail=-1
repeat begin
i=i+1 & line=strupcase(proc(i))
if STRPOS(LINE, textup) ge 0 then begin ; found a match
lead = (i-above-1) > trail+1 > 0 ; don't rewrite lines
if lead-1 ne trail then tproc = [tproc, '---LINE ' + strtrim(lead,2) + $
'---']
trail = (i+below) < np
TPROC=[TPROC, proc(lead: trail) ]
i = trail ; already have these lines
end
endrep until (i ge np) ; search whole file
IF N_ELEMENTS(TPROC) GT 1 THEN TPROC=TPROC(1:*)
PROC=TPROC
endif
return,proc & end