;---------------------------------------------------------------------------- ; $Id: duplicate_pro.pro,v 1.6 2002/09/14 00:36:00 johnny Exp $ ;+ ; NAME: ; DUPLICATE_PRO ; ; PURPOSE: ; Searches all directories in system variable !PATH to find whether ; there are duplicates of any of the *.pro files in those directories. ; Returns a vector of all filenames of which there are more than one ; version. ; ; CATEGORY: ; File Management. ; ; CALLING SEQUENCE: ; Result = DUPLICATE_PRO() ; ; INPUTS: ; None. ; ; INPUT KEYWORD PARAMETERS: ; VERBOSE: If keyword set true, prints out diagnostic messages. ; Default is not verbose. Keyword unchanged by function. ; ; OUTPUT KEYWORD PARAMETERS: ; CURRENT: Keyword is set to whatever the working directory was ; when the function was called. Created by function. ; ; DIR: If defined, returns a string array dimensioned (NPRO, ; NPATH) in which each column is a vector of the direc- ; tory names that have a *.pro file named the correspon- ; ding column index in Result (not all duplicate files ; have NPATH copies; in those cases extra array spaces ; in the column have null values). If there are none, ; a scalar null string is returned. NPATH is the number ; of directories in !PATH. Created by function. ; ; OUTPUTS: ; Result: String array of file names that are duplicated, dimen- ; sioned (NPRO). If there are none, a scalar null string ; is returned. Created by function. ; ; FILE DEVICE I/O: ; None. ; ; COMMON BLOCKS: ; None. ; ; EXAMPLE: ; If !PATH='/home/johnny/prog/idl:/home/johnny/idl' and both have the ; files nlinesl.pro and nlinesL.pro, then the function call: ; ; Result = DUPLICATE_PRO(Dir=dir) ; ; will give: ; ; IDL> PRINT, Result ; nlinesL.pro nlinesl.pro ; IDL> PRINT, dir ; /home/johnny/prog/idl /home/johnny/prog/idl ; /home/johnny/idl /home/johnny/idl ; [ rows of null values are truncated for clarity ] ; ; MODIFICATION HISTORY: ; - 13 Sep 2002: Orig. ver. Johnny Lin, CIRES/University of Colorado. ; Email: air_jlin@yahoo.com. Passed passably adequate tests. ; ; NOTES: ; - Written for IDL 5.5. ; - All keyword parameters are optional unless otherwise stated. ; - If Dir returns the signifier for current directory ('.' in Unix) or ; parent directory ('..' in Unix), this is meant in reference to what- ; ever the working directory was when the function was called. ; - Note that !PATH is not sorted in any order and neither is the output ; within a column in the array passed via Dir. If any of the director- ; ies in !PATH don't exist, function just passes them over. ; - Current version only works for Unix. Other OS's should be able to ; be easily accomodated by adding the appropriate code in the "Break-up ; !PATH Into a String Array" section. ; - No procedures called with _Extra keyword invoked. ; - No user-written procedures called. ;- ; Copyright (c) 2002 Johnny Lin. For licensing, distribution conditions, ; and contact information, see http://www.johnny-lin.com/lib.html. ;---------------------------------------------------------------------------- FUNCTION DUPLICATE_PRO, VERBOSE = in_verbose $ , CURRENT = out_current $ , DIR = out_dir $ , _EXTRA = extra ; -------------------- Error Check and Parameter Setting -------------------- COMPILE_OPT IDL2 ON_ERROR, 0 ; ------------------- Break-up !PATH Into a String Array -------------------- ; ; Variable dirs is a string array each element of which a directory in ; system variable !PATH. Variable NPATH is the number of these directories. ; Also obtain the current working directory (orig_dir), depending on the OS. case ( STRLOWCASE(!VERSION.OS_FAMILY) ) of 'unix' : begin dirs = STRSPLIT(!PATH, ':', /Extract) CD, '.', Current=orig_dir end 'macos': begin MESSAGE, 'error--ver. for macos not yet written/tested' end 'win' : begin MESSAGE, 'error--ver. for win os not yet written/tested' end 'vms' : begin MESSAGE, 'error--ver. for vms os not yet written/tested' end else : MESSAGE, 'error--unrecognized os family' endcase NPATH = N_ELEMENTS(dirs) ;- set NPATH ; -------------- List All *.pro files in All !PATH Directories -------------- ; ; Algorithm: Go through each !PATH directory and compile list of all the ; *.pro files in those directories. The CATCH error catching routine is ; added in case a directory in !PATH doesn't exist. Note, after every ; directory in !PATH is examined, I return to the original working direc- ; tory in case the current or parent directory strings are part of !PATH. ; ; Variable allpro is the list of all files found in !PATH. Variable alldir ; is the directories all those files are found in. for idir=0,NPATH-1 do begin ;- go through each !PATH directory CATCH, error_status ;+ error catching (usu. for CD) if (error_status ne 0) then begin if (KEYWORD_SET(in_verbose) eq 1) then $ PRINT, 'DUPLICATE_PRO: ', dirs[idir], ' may not exist.' CATCH, /Cancel CONTINUE endif CD, dirs[idir] ;+ change dir. to one in !PATH tmp = FINDFILE('*.pro') ;+ list all *.pro files if (N_ELEMENTS(allpro) eq 0) then begin ;+ append to list of all *.pro allpro = tmp ; files and their directories alldir = REPLICATE( dirs[idir] $ , N_ELEMENTS(tmp) ) endif else begin allpro = [allpro, tmp] alldir = [alldir, REPLICATE( dirs[idir], N_ELEMENTS(tmp) )] endelse CD, orig_dir ;+ return to orig. directory endfor dirs = 0 ;- dealloc. variable good_pts = WHERE(allpro ne '', count) ;- remove null string "file" if (count gt 0) then begin ; names allpro = allpro[good_pts] alldir = alldir[good_pts] endif NAP = N_ELEMENTS(allpro) ;- set no. of all *.pro files found if (N_ELEMENTS(alldir) ne NAP) then $ ;- error check allpro and alldir MESSAGE, 'error--dims mismatch' ; dimensions the same ; ------------------------ Check for Duplicate Files ------------------------ ; ; Algorithm: Check if number of unique values in allpro (stored as variable ; uniq_allpro) equals the number of values in allpro. If so then no *.pro ; files are duplicated. If not, cycle through all unique files to find ; which files are duplicated. Variable NPRO is the number of duplicated ; files while NPROm is the max. possible NPRO. uniq_allpro = allpro[UNIQ(allpro, SORT(allpro))] ;- unique elem. in allpro if (N_ELEMENTS(uniq_allpro) eq NAP) then begin if (KEYWORD_SET(in_verbose) eq 1) then $ PRINT, 'DUPLICATE_PRO: No *.pro files are duplicated' dupl_fn = '' dupl_dir = '' endif else begin NPROm = N_ELEMENTS(allpro) - N_ELEMENTS(uniq_allpro) ;- set max. NPRO dupl_fn = STRARR(NPROm) ;- init. arrays to dupl_dir = STRARR(NPROm,NPATH) ; max. values npro_count = 0 ;- set counter for element index for ; dimension 1 of dupl_fn and dupl_dir for ifn=0,N_ELEMENTS(uniq_allpro)-1 do begin fn_examine = uniq_allpro[ifn] dupl_pts = WHERE(allpro eq fn_examine, count) if (count gt 1) then begin dupl_fn [npro_count] = fn_examine dupl_dir[npro_count, 0:count-1] = alldir[dupl_pts] npro_count = npro_count+1 endif endfor good_pts = WHERE(dupl_fn ne '', count) ;- remove null values, if NPRO is if (count gt 0) then begin ; less than NPROm; NPRO isn't dupl_fn = dupl_fn[good_pts] ; ever set, but is equal to count dupl_dir = dupl_dir[good_pts, *] ; in this code block endif endelse ; ----------------------------- Prepare Output ------------------------------ out_current = TEMPORARY(orig_dir) ;- return input working dir. (optional) out_dir = TEMPORARY(dupl_dir) ;- return directories (optional) Result = TEMPORARY(dupl_fn) ;- return duplicate files RETURN, Result END ;=== end of function === ; ========== end file ==========