C+ C NAME: C FileSelection C PURPOSE: C Set wildcards for locating data files C CATEGORY: C I/O C CALLING SEQUENCE: subroutine FileSelection(cStr,cWild) C INPUTS: C cStr character*(*) info from which to construct wildcard C OUTPUTS: C cWild character*(*) file name (incl. directory) with wildcard C CALLS: C LocFirst, LocFirstLen, itrim, Say, Str2Flt, lowercase, iFilePath C iSetFileSpec, iPutFileSpec, iGetFileSpec, iGetLogical, iCheckDirectory C INCLUDE: include 'dirspec.h' include 'filparts.h' C PROCEDURE: C > The directory information cStr has the following format, C filename.type,root,sub1,sub2,.... C All except the first part (the filename) are optional C 'filename.type' is used to determine the file name including a wildcard. C C 'root' is used to set a directory name. 'root' can be a logical (it's C translation is substituted), a relative directory name (the working directory C is prepended) or an absolute directory name. C C 'root' is concatenated with 'sub1', 'sub2',... to form the final directory. C This directory must exist. If it does not then program execution stops. C C 'filename.type' can contain any number of substrings of the form '(n)' or '[n]' where n C is an integer. Each substring '(n)' is replaced with n single wildcharacters. C C > If '(n)' is omitted then 'filename.type(4)' is assumed, i.e. C four wild characters are appended to the file type. C E.g. 'nagoya' becomes 'nagoya.????' C C > If 'root' is omitted then 'filename' and 'type' are checked for C a non-zero-length prefix, and 'root'='$dat,prefix' is assumed. C E.g. 'nagoya.????' becomes 'nagoya.????,$dat,nagoya' C '????.srf' becomes '????.srf,$dat,srf' C C > Examples: (for logical $dat = /mnt/work/dat/) C nagoya --> /mnt/work/dat/nagoya/nagoya.???? C nagoya,dat,yearly --> /mnt/work/dat/nagoya/yearly/nagoya.???? C wind_(4).hravg,dat,insitu --> /mnt/work/dat/insitu/wind_????.hravg C C If tmp is not defined as a logical C nagoya,tmp,somewhere,sub --> ./somewhere/sub/nagoya.???? C where the leading dot is replaced by the working directory. C MODIFICATION HISTORY: C JUL-2000, Paul Hick (UCSD/CASS) C APR-2002, Paul Hick (UCSD/CASS) C Added option to specify multiple wildcard patterns C MAY-2002, Paul Hick (UCSD/CASS) C Added option to use square brackets instead of round brackets for C wildcard specification. Round brackets will cause problems in C bash unless explicit quotes are used. C AUG-2003, Paul Hick (UCSD/CASS, pphick@ucsd.edu) C Added option to replace (0) by single wildcard *. C- character cStr *(*) character cWild*(*) character cFil*120 character cDir*120 character cTop*120 character cTmp*120 character cBracketB character cBracketE character cSay*13 /'FileSelection'/ parameter (nSub = 8) character cSub(nSub)*20 if (itrim(cStr) .eq. 0) call Say(cSay, 'E', 'Missing', 'file info') if (LocFirst('*',cStr) .ne. 0 .or. LocFirst(cWildChar(:1),cStr) .ne. 0) then cWild = cStr return end if !------- ! cStr is of form fileinfo,dirinfo. Split in two parts at the comma I = LocFirst(',',cStr) if (I .eq. 0) then ! No comma; check for directory I = iSetFileSpec(cStr) I = iGetFileSpec(0,FIL__DIRECTORY,cDir) I = iGetFileSpec(FIL__NAME,0,cFil) else cFil = cStr(:I-1) cDir = cStr(I+1:) end if !------- ! Stop if there is no file info if (itrim(cFil) .eq. 0) call Say(cSay, 'E', cStr, 'invalid file info') !------- ! Check the file info for substrings of the form (n). ! If found replace by n wild chars. cBracketB = '(' cBracketE = ')' iB = LocFirst(cBracketB,cFil) iE = LocFirst(cBracketE,cFil) if (iB .eq. 0 .and. iE .eq. 0) then cBracketB = '[' cBracketE = ']' iB = LocFirst(cBracketB,cFil) iE = LocFirst(cBracketE,cFil) end if do while (iE-1 .ge. iB+1) ! Something present between brackets iW = 1 ! Look for one number call Str2Flt(cFil(iB+1:iE-1),iW,rVec) if (iW .eq. 0) then ! Remove brackets cFil = cFil(:iB-1)//cFil(iE+1:) else iW = nint(rVec) ! Convert to nearest integer if (iW .eq. 0) then ! Remove brackets, insert * wildcard char cFil = cFil(:iB-1)//'*'//cFil(iE+1:) else ! Remove brackets, insert iW wildcard chars cFil = cFil(:iB-1)//cWildChar(:iW)//cFil(iE+1:) end if end if iB = LocFirst(cBracketB,cFil) iE = LocFirst(cBracketE,cFil) end do I = iSetFileSpec(cFil) !------- ! If no (n) substring found then append four wild chars to file type if (LocFirst(cWildChar(:1),cFil) .eq. 0) then I = iGetFileSpec(FIL__TYPE, FIL__TYPE, cTmp) cTmp(itrim(cTmp)+1:) = cWildChar(:4) I = iPutFileSpec(FIL__TYPE, FIL__TYPE, cTmp) I = iGetFileSpec(0,FIL__TYPE, cFil) end if ! If no directory info is specified or if the first subdirectory ! is set to a blank, then insert $dat with appended the part of ! cFil preceding the wildcard. if (cDir .eq. ' ' .or. cDir(:1) .eq. ',') then I = iGetFileSpec(FIL__NAME, FIL__NAME, cTmp) I = LocFirstLen(cWildChar(:1),cTmp(:I)) if (I .eq. 1) then ! No file name, check type I = iGetFileSpec(FIL__TYPE, FIL__TYPE, cTmp) cTmp = cTmp(2:) I = LocFirstLen(cWildChar(:1),cTmp(:I-1)) end if if (I .eq. 1) then cDir = cEnvi//'DAT'//cDir else cDir = cEnvi//'DAT,'//cTmp(:I-1)//cDir end if end if L = itrim(cDir) I = LocFirstLen(',',cDir(:L)) cTop = cDir(:I-1) !------- ! Pick up the subdirectory strings in cSub iSub = 0 do while (I .lt. L) J = LocFirstLen(',',cDir(I+1:L)) if (J .gt. 1 .and. iSub .le. nSub) then iSub = iSub+1 cSub(iSub) = cDir(I+1:I+J-1) end if I = I+J end do !------- ! Try translating cTop as a logical. Put translation in cTmp. if (iGetLogical(cTop, cTmp) .eq. 0) cTmp = cTop I = iFilePath(cTmp,iSub,cSub,' ',cTop) !------- ! Make sure the specified directory exists. I = iCheckDirectory(cTop) I = iGetFileSpec(0,FIL__DIRECTORY,cTmp) !if (iCheckDirectory(cTop) .eq. 0) call Say(cSay,'E',cTop,'non-existent directory') if (iCheckDirectory(cTop) .eq. 0) call Say(cSay,'E',cTmp,'non-existent directory') I = iGetFileSpec(0,FIL__DIRECTORY,cTmp) I = iFilePath(cTmp,0,cSub,cFil,cWild) return end