;+ ; ; @file_comments ; based on FILE_SEARCH, but it is possible to specify ; a set of possibles names and a different set of ; possibles directories names. ; ; By default look for files included in !path ; ; all FILE_SEARCH keywords can be used. ; ; @categories ; find a file ; ; @param FILEIN {in}{required} {type=scalar string or array of strings} ; File name[s] to match. Input names specifications may contain ; wildcard characters, enabling them to match multiple files ; (see FILE_SEARCH for more informations). By default and if ; necessary, find is looking for filename and also for filename ; completed with '.pro' ; ; @keyword FIRSTFOUND ; activate this keyword to stop looking for the file as soon as we ; found one. Return a scalar string containing the first file found ; ; @keyword IODIRECTORY {type=scalar string or array of strings} {default=['.',!path]} ; Directories names where we are looking for the file. ; Different directories can be separated by ; path_sep(/search_path) (':' on unix type machine) as it is done ; to define !path. ; Note that if filename's dirname is different from '.', this ; keyword is not taken into account. ; ; @keyword LOOKALLDIR ; activate to look for the file (with a recursive search if needed) ; in . iodir, homedir, !path + the DATA:TestsData directory if it exists. ; ; @keyword NOPRO ; activate to avoid the automatic search of filename completed with '.pro' ; ; @keyword ONLYPRO ; force to look only at file ending with .pro ; ; @keyword ONLYNC ; force to look only at file ending with .nc ; ; @keyword RECURSIVE ; performs recursive searching of directory hierarchies. ; In a recursive search, find looks recursively for any and all ; subdirectories in the file hierarchy rooted at the IODIRECTORY argument. ; ; @keyword REPERTOIRE ; obsolete. keep for compatibility, use IODIRECTORY keyword ; ; @keyword UNIQUE ; activate to make sure that each element of the output vector is unique. ; ; @keyword TRYFIND ; if the file was not found and this keyword is activated, find ; will call ; itself with the keywords /LOOKALLDIR and /FIRSTFOUND to try to find ; the file we are looking for. Note that if the file was found at the ; first try this keyword as no effect (which is not the case with LOOKALLDIR) ; ; @keyword _EXTRA ; Used to pass keywords ; ; @returns ; A scalar or array variable of string type, containing the ; name (with the full path of the matching files. If no files ; exist with names matching the input arguments, find returns ; the scalar string : 'NOT FOUND' ; ; @examples ; ; IDL> print, find('*loadct') ; /usr/local/rsi/idl_6.0/lib/utilities/xloadct.pro ; /usr/local/rsi/idl_6.0/lib/loadct.pro ; IDL> print, find('*loadct', iodir=!dir,/recursive) ; /usr/local/rsi/idl_6.0/lib/loadct.pro ; /usr/local/rsi/idl_6.0/lib/utilities/xloadct.pro ; IDL> print, find('*loadct.pro') ; /usr/local/rsi/idl_6.0/lib/utilities/xloadct.pro ; /usr/local/rsi/idl_6.0/lib/loadct.pro ; IDL> print, find('*loadct',/nopro) ; NOT FOUND ; IDL> print, find('*loadct', iodir = '/usr/local/rsi/idl_6.0/lib') ; /usr/local/rsi/idl_6.0/lib/loadct.pro ; IDL> print, find('*loadct', iodir = '/usr/local/rsi/idl_6.0/lib', /test_write) ; NOT FOUND ; IDL> print, find('*loadct', iodir = '/usr/local/rsi/idl_6.0/lib', /recursive) ; /usr/local/rsi/idl_6.0/lib/loadct.pro ; /usr/local/rsi/idl_6.0/lib/utilities/xloadct.pro ; IDL> print, find('mesh*', iodirectory = [iodir, !path]) ; /Users/sebastie/DATA/ORCA2/meshmaskORCA2closea.nc ; /Users/sebastie/IDL/meshmaskclosesea.pro ; /Users/sebastie/IDL/meshmaskclosesea.pro~ ; /Users/sebastie/SAXO_RD/Obsolete/meshlec.pro ; /usr/local/rsi/idl_6.0/lib/mesh_obj.pro ; ; @history ; Sebastien Masson (smasson\@lodyc.jussieu.fr) ; - 28/4/1999 ; - 6/7/1999: compatibility mac and windows ; - June 2005: Sebastien Masson: cleaning, use for file_* functions ; ; @version ; $Id$ ; ;- FUNCTION find, filein, IODIRECTORY=iodirectory, RECURSIVE=recursive $ , REPERTOIRE=repertoire, NOPRO=nopro, ONLYPRO=onlypro $ , ONLYNC=onlync, UNIQUE=unique, FIRSTFOUND=firstfound $ , LOOKALLDIR=LOOKALLDIR, TRYFIND=tryfind, _EXTRA=ex ; compile_opt idl2, strictarrsubs ; ; define where we look for the file cd, current = current current = current + path_sep() CASE 1 OF keyword_set(lookalldir):BEGIN @cm_general dirnames = [current, iodir, homedir, !path] tstdtadir= file_dirname(find('find', /onlypro), /mark_directory) parent = path_sep(/parent_directory)+path_sep() tstdtadir = (file_search(tstdtadir+parent+parent+'DATA/TestsData'))[0] IF tstdtadir NE '' THEN dirnames = [tstdtadir, dirnames] END keyword_set(iodirectory): dirnames = iodirectory keyword_set(repertoire): dirnames = repertoire ELSE: dirnames = [current, !path] ENDCASE tmp = dirnames dirnames = 'dummy' FOR i = 0, n_elements(tmp)-1 DO $ dirnames = [dirnames, strsplit(tmp[i], path_sep(/search_path), /extract)] dirnames = dirnames[1:*] ; fileout = 'dummy' FOR i = 0, n_elements(filein)-1 DO BEGIN dir = file_dirname(filein[i]) base = file_basename(filein[i]) ; try to complete the file name with .pro or .nc if needed... CASE 1 OF keyword_set(onlypro):BEGIN promiss = strpos(base, '.pro', /reverse_search) promiss = promiss - (strlen(base) - 4) bad = where(promiss NE 0 OR strlen(base) LE 4, cnt) IF cnt NE 0 THEN base[bad] = base[bad] + '.pro' end keyword_set(onlync):BEGIN ncmiss = strpos(base, '.nc', /reverse_search) ncmiss = ncmiss - (strlen(base) - 3) bad = where(ncmiss NE 0 OR strlen(base) LE 3, cnt) IF cnt NE 0 THEN base[bad] = base[bad] + '.nc' END ELSE:if strmid(base, 0, 1, /reverse_offset) NE '*' $ AND NOT keyword_set(nopro) THEN base = base + '{.pro,}' ENDCASE ; use dirnames only if dir eq '.' IF dir EQ '.' THEN BEGIN if keyword_set(recursive) THEN $ found = file_search(dirnames, base, _extra = ex) $ ELSE found = file_search(dirnames + '/' + base, _extra = ex) ENDIF ELSE found = file_search(dir + '/' + base, _extra = ex) IF found[0] NE '' THEN BEGIN IF keyword_set(firstfound) THEN return, found[0] fileout = [fileout, found] ENDIF ENDFOR IF n_elements(fileout) EQ 1 THEN fileout = 'NOT FOUND' $ ELSE fileout = fileout[1:*] ; IF n_elements(fileout) GT 1 THEN BEGIN IF keyword_set(unique) THEN fileout = fileout[uniq(fileout, sort(fileout))] ENDIF ELSE fileout = fileout[0] ; IF keyword_set(lookalldir) AND fileout[0] EQ 'NOT FOUND' $ AND NOT keyword_set(recursive) THEN $ filout = find(file_basename(filein[0]), /lookalldir $ , /recursive, _extra = ex) ; IF keyword_set(tryfind) AND fileout[0] EQ 'NOT FOUND' THEN BEGIN fileout = find(file_basename(filein[0]), /lookalldir, /firstfound, _extra = ex) fileout = fileout[0] ENDIF ; RETURN, fileout END