pro sfloatclean, StrIn, FmtIn, StrOut, FmtOut, nocheck=NoCheck, $ strcrumbs=StrCrumbs, numcrumbs=NumCrumbs @compile_opt.pro ; On error, return to caller ;+ ; NAME: ; sfloatclean ; PURPOSE: ; Check a specified format against a specified string. ; CALLING SEQUENCE: ; sfloatclean, StrIn, FmtIn, StrOut, FmtOut, /nocheck ; INPUTS: ; StrIn character string (usually a record read from file) ; FmtIn format to be matched against string ; OPTIONAL INPUTS: ; /nocheck see procedure ; OUTPUTS: ; StrOut reduced character string (see procedure) ; FmtOut reduced format; = '()' if the input format does not ; match the input string ; OPTIONAL OUTPUTS: ; StrCrumbs string array containing the discarded portions of the ; input string ; NumCrumbs # elements in StrCrumbs ; CALLS: ; InitVar ; PROCEDURE: ; The input format is searched for the character descriptor 'A'. All 'A' ; occurrences are removed from the format, and the corresponding ; substrings are removed from the input string. ; The reduced output format will contain only numeric format desciptors ; (I,F,D,E). ; If the input string does not adequately match the format, ; string '()' is returned as output format. This occurs if: ; > If the string is longer or shorter than the length implied by the ; input format, i.e. the lengths must match exactly ; > (Only if the keyword NoCheck is not set) ; If the substring for an 'A' descriptor contains a numerical digit (0..9) ; MODIFICATION HISTORY: ; MAY-1994, Paul Hick (ARC) ; SEP-2003, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ; Bug fix. If format would end with a string (e.g. A3) then this would not ; be cleaned up properly. ;- StrOut = StrIn FmtOut = FmtIn FmtL = strlen(FmtIn) if FmtL eq 0 then return ; Empty input string InitVar, NoCheck, /key DoCheck = 1-NoCheck FmtOut = strmid( FmtOut, 1, FmtL-2 )+',' ; Remove brackets, add comma FmtL = FmtL-1 StrA = ['0','1','2','3','4','5','6','7','8','9'] FmtList = ['A','I','F','E','D','.',','] FmtN = n_elements(FmtList) PosN = intarr(FmtN, /nozero) Ntot = 0 pos = 0 NumCrumbs = 0 while pos lt FmtL do begin ; Pick up positions of FmtList chars for i=0,FmtN-1 do PosN[i] = strpos( FmtOut, FmtList[i], pos ) p = where( PosN ne -1 ) posmin = min( PosN[p], pmin ) pmin = p[pmin] ch = FmtList[pmin] ; 1st FmtList char following 'pos' if pmin gt 4 then message, 'should not have happened' case posmin of ; Format counter pos : N = 1 else: reads, strmid( FmtOut, pos, posmin-pos ), N endcase pend = (PosN[where(FmtList eq '.')])[0] ; Check for dot case pend eq -1 of 0: pend = min( [pend, PosN[ where(FmtList eq ',') ] ] ) 1: pend = PosN[ where(FmtList eq ',') ] endcase pend = pend[0] m = 0 ; reads, S,M crashes if S is 1-char string and M doesn't exist case pend-posmin eq 1 of ; Format length 0: reads, strmid( FmtOut, posmin+1, pend-posmin-1 ), M 1: message, 'Format specifier of undetermined length' endcase case ch of 'A': begin ; 'An' detected in format if DoCheck then begin ; If DoCheck is set .. StrDmp = strmid(StrOut,Ntot,M*N); .. Check whether the 'An' part ; .. of StrOut contains digits i = -1 repeat begin i = i+1 d = where( StrDmp eq StrA[i] ) if d[0] ne -1 then begin ; Digit found i = n_elements(StrA) FmtOut = '' ; Format does not fit StrOut pos = FmtL endif endrep until i ge n_elements(StrA)-1 endif if FmtOut ne '' then begin ; Remove 'An' part from FmtOut FmtOut = strmid(FmtOut,0,pos)+strmid(FmtOut,pend+1) FmtL = strlen(FmtOut) if Ntot+M*N gt strlen(StrOut) then begin ; SEP-2003 bugfix: used to be 'ge' FmtOut = '' ; StrOut too short pos = FmtL ; Break while loop endif else begin ; Remove 'An' substring from StrOut NumCrumbs = NumCrumbs+1 case NumCrumbs eq 1 of ; Collect the 'An' substrings 0: StrCrumbs = [StrCrumbs,strmid(StrOut,Ntot,M*N)] 1: StrCrumbs = strmid(StrOut,Ntot,M*N) endcase StrOut = strmid(StrOut,0,Ntot)+strmid(StrOut,Ntot+M*N) endelse endif end else: begin ; I,F,E,D detected in format Ntot = Ntot+M*N ; # chars in StrOut if strlen(StrOut) lt Ntot then begin; StrOut too short FmtOut = '' pos = FmtL ; Break while loop endif else $ ; Set pos after I,F,E,D format pos = (PosN[ where(FmtList eq ',') ])[0]+1 end endcase endwhile ; If not whole StrOut processed: format does not fit string if FmtOut ne '' then if Ntot lt strlen(StrOut) then FmtOut = '' ; Reconstruct valid format descriptor: remove comma, add brackets FmtOut = '('+strmid( FmtOut,0,strlen(FmtOut)-1 )+')' return & end