subroutine dat_intprt(text, putval, userarg) ! ! Interprete TEXT containing name / value parameters. ! You must call DAT_DELIMITERS(SEP, ASS, QUOTE) before in order to define ! the separator symbol SEP ! the assignment symbol ASS and ! the text quote character QUOTE. ! ! DAT_INTPRT calls the subroutine PUTVAL(NAME, VALUE, USERARG) ! for each name/value pair. ! For numeric values NAME and VALUE contain name and value. ! For textual values, the argument NAME contains a concatenation ! of name '=' and the text between the quotes. In that case, VALUE ! is guaranteed to be 0.0. ! ! There may be up to 32 numeric values per name in TEXT, separated by ! blanks or commas (comma not allowed when SEP=','). ! If more then one value per name is given, PUTVAL is called several times ! ! Example: ! ! CALL DAT_DELIMITERS(';', ':=', '"') ! TEXT='first:=3.3;second:="name";third:=10,10.5,11' ! CALL DAT_INTPRT(TEXT, PUTVAL, 0) ! ! we are using ':=' as assignment symbol ! ';' as separator ! '"' as quote character ! ! DAT_INTPRT will call PUTVAL(NAME, VALUE, 0) 5 times with the following arguments: ! ! NAME VALUE ! ------------------ ! 'first' 3.3 ! 'second=name' 0.0 ! 'third' 10.0 ! 'third' 10.5 ! 'third' 11.0 ! character text*(*) ! text to interprete. must not be longer than 160-len(ASS) characters external putval ! procedure to call for each name/value pair external userarg ! user argument ! arguments for dat_delimiters: character sep_symbol*(*) ! separator between subsequent name/value pairs ! must not be blank character ass_symbol*(*) ! assignment symbol separator between name and values ! must not be blank character quote_char*1 ! quote character (may be blank) integer l,p,m,j,ln,i,k,q character line*160 logical nodecpoint integer maxarr parameter (maxarr=32) real arr(maxarr) integer ls/0/, la/0/ character sep*32, ass*32, quote*1 save sep, ass, quote if (ls .eq. 0) 1 stop 'DAT_INTPRT: DAT_DELIMITERS must be called first' if (len(text)+max(la,ls) .gt. len(line)) 1 stop 'DAT_INTPRT: text too long' call str_trim(line, text, l) line(l+1:l+1)='!' l=index(line,'!')-1 if (l .le. 0) RETURN if (line(1:l) .eq. ' ') RETURN p=0 1 continue line(l+1:l+la)=ass ! set stopper ! read blanks if (p .lt. l) then do while (line(p+1:p+1) .le. ' ') p=p+1 enddo endif if (p .ge. l) RETURN j=p p=p+index(line(p+1:), ass(1:la))-1 ! position of assignment char. 12 i=index(line(j+1:p+1), sep(1:ls)) if (i .ne. 0) then print *,'DAT_INTPRT: missing "',ass(1:la),'" : ' 1 , line(1:j+i+ls-1) p=j+i+ls goto 1 endif if (j .eq. p) then print *,'DAT_INTPRT: missing name: ', line line(l+1:l+ls)=sep ! set stopper p=j+index(line(j+1:), sep(1:ls))+ls goto 1 endif m=p do while (line(m:m) .le. ' ') m=m-1 enddo if (p .ge. l) then print *,'DAT_INTPRT: missing "',ass(1:la),'" : ', line(1:p) RETURN endif p=p+la ! read blanks line(l+1:l+1)=quote ! stopper if (line(p+1:l+1) .eq. ' ') then p=l else do while (line(p+1:p+1) .le. ' ') p=p+1 enddo endif if (quote .gt. ' ' .and. line(p+1:p+1) .eq. quote) then ! --- quoted text p=p+1 ln=index(line(p+1:), quote)-1 if (ln .eq. 0) then call putval(line(j+1:m)//'= ', 0.0, userarg) else call putval(line(j+1:m)//'='//line(p+1:p+ln), 0.0, userarg) endif p=p+ln ln=index(line(p+1:),sep(1:ls))-1 if (ln .lt. 0) ln=l-p if (line(p+1:p+ln) .ne. quote) then print *,'DAT_INTPRT: superflous characters: ',line(1:p+ln) endif p=p+ln+ls elseif (index('-.0123456789',line(p+1:p+1)) .ne. 0) then ! --- numeric i=0 line(l+1:l+ls)=sep(1:ls) ! stopper k=p do while (line(k+1:k+1) .eq. ' ') ! skip blanks k=k+1 enddo q=p 11 continue nodecpoint=.true. do while (line(k+1:k+1) .ne. ' ' 1 .and. line(k+1:k+1) .ne. ',' 1 .and. line(k+1:k+ls) .ne. sep(1:ls)) k=k+1 enddo do while (line(k+1:k+1) .eq. ' ') ! skip blanks k=k+1 enddo if (line(k+1:k+1) .eq. ',' .and. 1 line(k+1:k+ls) .ne. sep(1:ls)) then ! skip one comma k=k+1 do while (line(k+1:k+1) .eq. ' ') ! skip blanks k=k+1 enddo endif if (i .lt. maxarr) then if (index(line(p+1:k), '.') .ne. 0) nodecpoint=.false. read(line(p+1:k), *, err=103) arr(i+1) endif i=i+1 if (line(k+1:k+ls) .ne. sep(1:ls)) then p=k goto 11 endif p=k+ls if (nodecpoint) call meta_format(5003) ! set to integer format if (i .eq. 1) then call putval(line(j+1:m), arr(1), userarg) else ln=i if (ln .gt. maxarr) goto 103 do i=1,ln call putval(line(j+1:m), arr(i), userarg) enddo endif if (nodecpoint) call meta_format(0) ! reset format else ! --- literal ln=index(line(p+1:),sep(1:ls))-1 if (ln .lt. 0) ln=l-p i=p+ln do while (line(i:i) .le. ' ') ! truncate trailing blanks i=i-1 enddo if (i .le. p) then call putval(line(j+1:m)//'= ', 0.0, userarg) else call putval(line(j+1:m)//'='//line(p+1:i), 0.0, userarg) endif p=p+ln+ls endif goto 1 103 p=p+index(line(p+1:), sep(1:ls))-1 call str_trim(line(q+1:p), line(q+1:p), ln) call putval(line(j+1:m)//'='//line(q+1:q+ln), 0.0, userarg) p=p+ls goto 1 entry dat_delimiters(sep_symbol, ass_symbol, quote_char) quote=quote_char call str_trim(sep, sep_symbol, ls) call str_trim(ass, ass_symbol, la) if (sep(1:ls) .le. ' ') 1 stop 'DAT_DELIMITERS: separator must not be blank' if (ass(1:la) .le. ' ') 1 stop 'DAT_DELIMITERS: assignment symbol must not be blank' if (quote .eq. sep(1:1) .or. quote .eq. ass(1:1)) then stop 'DAT_DELIMITERS: QUOTE must be different from SEP and ASS' endif end