From 436a7b6ef7fbcd8a9b478d697ad521a02689e26c Mon Sep 17 00:00:00 2001 From: Paolo Giannozzi Date: Fri, 5 Jun 2020 14:39:08 +0000 Subject: [PATCH] Better treatment for attributes, less susceptible to run into trouble with attributes containing single quotes into double quotes, or vice versa --- upflib/xmltools.f90 | 72 ++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/upflib/xmltools.f90 b/upflib/xmltools.f90 index 60ab0530a..293eee70b 100644 --- a/upflib/xmltools.f90 +++ b/upflib/xmltools.f90 @@ -118,48 +118,41 @@ CONTAINS CHARACTER(LEN=*), INTENT(IN) :: attrname CHARACTER(LEN=*), INTENT(OUT) :: attrval_c ! + CHARACTER(LEN=1) :: quote INTEGER :: j0, j1 + LOGICAL :: found ! - ! search for attrname in attrlist + ! search for attribute name in attrlist: attr1="val1" attr2="val2" ... + ! + attrval_c = '' + if ( .not. allocated(attrlist) ) return + if ( len_trim(attrlist) < 1 ) return ! - if ( .not. allocated(attrlist) ) then - attrval_c = '' - return - else if ( len_trim(attrlist) < 1 ) then - attrval_c = '' - return - end if j0 = 1 do while ( j0 < len_trim(attrlist) ) - j1 = index ( attrlist(j0:), ',' ) - if ( j1 == 0 ) then - ! no more commas: check if found - if ( attrname == attrlist(j0:) ) exit - ! here if not found - attrval_c = ' ' + ! locate = and first quote + j1 = index ( attrlist(j0:), '=' ) + quote = attrlist(j0+j1:j0+j1) + ! next line: something is not right + if ( quote /= '"' .and. quote /= "'" ) return + ! check if attribute found: need exact match + found = ( trim(attrname) == adjustl(trim(attrlist(j0:j0+j1-2))) ) + ! locate next quote + j0 = j0+j1+1 + j1 = index ( attrlist(j0:), quote ) + if ( found) then + if ( j1 == 1 ) then + ! two quotes, one after the other ("") + attrval_c = ' ' + else + ! get value between two quotes + attrval_c = adjustl(trim(attrlist(j0:j0+j1-2))) + end if return - else - ! check if found: need exact match between commas - if ( trim(attrname) == attrlist(j0:j0+j1-2) ) exit end if j0 = j0+j1 end do ! - ! next item between commas is the value - ! - j0 = j0+j1 - j1 = index ( attrlist(j0:), ',' ) - if ( j1 == 0 ) then - ! no more commas - attrval_c = attrlist(j0:) - else if ( j1 == 1 ) then - ! two commas, one after the other (,,) - attrval_c = ' ' - else - ! take field between two commas - attrval_c = attrlist(j0:j0+j1-2) - end if - ! END SUBROUTINE get_c_attr ! SUBROUTINE add_i_attr ( attrname, attrval_i ) @@ -743,29 +736,28 @@ CONTAINS return ! else if ( line(j:j) == '=' ) then - ! end of attribute located: save attribute + ! end of attribute located: save attribute (with final =) nattr=nattr+1 ! print *, 'attr=',line(j0:j-1) if ( nattr == 1 ) then - attrlist = line(j0:j-1) + attrlist = line(j0:j) else - attrlist = attrlist//','//line(j0:j-1) + attrlist = attrlist//' '//line(j0:j) end if ! continue searching for attribute value j = j+1 else if ( line(j:j) == '"' .or. line(j:j) =="'" ) then ! first occurrence of ' or " found, look for next quote = line(j:j) - j=j+1 - i = index(line(j:),quote) + i = index(line(j+1:),quote) if ( i < 1 ) then ! print *, 'Error: matching quote not found' go to 10 else - ! save attribute value and continue scanning + ! save attribute value (with quotes) and continue scanning ! print *, 'attrval=',line(j:j+i-2) - attrlist = attrlist//','//line(j:j+i-2) - j = j+i + attrlist = attrlist//line(j:j+i) + j = j+i+1 end if else ! continue scanning until end of attribute