! read_xml_prims.f90 - Read routines for primitive data ! ! $Id: read_xml_prims.f90,v 1.7 2007/12/07 10:38:41 arjenmarkus Exp $ ! ! Arjen Markus ! ! General information: ! This module is part of the XML-Fortran library. Its ! purpose is to help read individual items from an XML ! file into the variables that have been connected to ! the various tags. It is used by the code generated ! by the make_xml_reader program. ! ! Because the routines differ mostly by the type of the ! output variable, the body is included, to prevent ! too much repeated blocks of code with all the maintenance ! issues that causes. ! module xmlf_read_xml_primitives use xmlf_parse implicit none private :: read_from_buffer private :: read_from_buffer_integers private :: read_from_buffer_reals private :: read_from_buffer_doubles private :: read_from_buffer_logicals private :: read_from_buffer_words interface read_from_buffer module procedure read_from_buffer_integers module procedure read_from_buffer_reals module procedure read_from_buffer_doubles module procedure read_from_buffer_logicals module procedure read_from_buffer_words end interface contains ! skip_until_endtag -- ! Routine to read the XML file until the end tag is encountered ! ! Arguments: ! info The XML file data structure ! tag The tag in question ! attribs Array of attributes and their values ! data Array of strings, representing the data ! error Has an error occurred? ! subroutine skip_until_endtag( info, tag, attribs, data, error ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag character(len=*), dimension(:,:), intent(inout) :: attribs character(len=*), dimension(:), intent(inout) :: data logical, intent(out) :: error integer :: noattribs integer :: nodata integer :: ierr logical :: endtag character(len=len(tag)) :: newtag error = .true. do call xml_get( info, newtag, endtag, attribs, noattribs, & data, nodata ) if ( xml_error(info) ) then error = .true. exit endif if ( endtag .and. newtag .eq. tag ) then exit endif enddo end subroutine skip_until_endtag ! read_xml_integer -- ! Routine to read a single integer from the parsed data ! ! Arguments: ! info XML parser structure ! tag The tag in question (error message only) ! endtag End tag found? (Dummy argument, actually) ! attribs Array of attributes and their values ! noattribs Number of attributes found ! data Array of strings, representing the data ! nodata Number of data strings ! var Variable to be filled ! has_var Has the variable been set? ! subroutine read_xml_integer( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) integer, intent(inout) :: var include 'xmlf_read_xml_scalar.inc' end subroutine read_xml_integer ! read_xml_line -- ! Routine to read a single line of text from the parsed data ! ! Arguments: ! info XML parser structure ! tag The tag in question (error message only) ! endtag End tag found? (Dummy argument, actually) ! attribs Array of attributes and their values ! noattribs Number of attributes found ! data Array of strings, representing the data ! nodata Number of data strings ! var Variable to be filled ! has_var Has the variable been set? ! subroutine read_xml_line( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata character(len=*), intent(inout) :: var logical, intent(inout) :: has_var integer, intent(out) :: status character(len=len(attribs(1,1))) :: buffer integer :: idx ! ! The value can be stored in an attribute value="..." or in ! the data ! has_var = .false. idx = xml_find_attrib( attribs, noattribs, 'value', buffer ) if ( idx .gt. 0 ) then var = buffer has_var = .true. else do idx = 1,nodata if ( data(idx) .ne. ' ' ) then var = data(idx) has_var = .true. exit endif enddo endif ! ok status = 0 end subroutine read_xml_line ! read_xml_real, ... -- ! See read_xml_integer for an explanation ! subroutine read_xml_real( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) real(4), intent(inout) :: var include 'xmlf_read_xml_scalar.inc' end subroutine read_xml_real subroutine read_xml_double( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) real(8), intent(inout) :: var include 'xmlf_read_xml_scalar.inc' end subroutine read_xml_double subroutine read_xml_logical( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) logical, intent(inout) :: var include 'xmlf_read_xml_scalar.inc' end subroutine read_xml_logical subroutine read_xml_word( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) character(len=*), intent(inout) :: var include 'xmlf_read_xml_scalar.inc' end subroutine read_xml_word ! read_xml_integer_array -- ! Routine to read a one-dimensional integer array from the parsed ! ata ! ! Arguments: ! info XML parser structure ! tag The tag in question (error message only) ! endtag End tag found? (Dummy argument, actually) ! attribs Array of attributes and their values ! noattribs Number of attributes found ! data Array of strings, representing the data ! nodata Number of data strings ! var Variable to be filled ! has_var Has the variable been set? ! subroutine read_xml_integer_array( info, tag, endtag, attribs, noattribs, data, & nodata, var, has_var, status ) integer, dimension(:), pointer :: var include 'xmlf_read_xml_array.inc' end subroutine read_xml_integer_array ! read_xml_line_array -- ! Routine to read an array of lines of text from the parsed data ! ! Arguments: ! info XML parser structure ! tag The tag in question (error message only) ! attribs Array of attributes and their values ! noattribs Number of attributes found ! data Array of strings, representing the data ! nodata Number of data strings ! var Variable to be filled ! has_var Has the variable been set? ! subroutine read_xml_line_array( info, tag, endtag, attribs, noattribs, data, & nodata, var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata character(len=*), dimension(:), pointer :: var logical, intent(inout) :: has_var integer, intent(out) :: status character(len=len(attribs(1,1))) :: buffer integer :: idx integer :: idxv logical :: started ! ! The value can be stored in an attribute values="..." or in ! the data ! has_var = .false. idx = xml_find_attrib( attribs, noattribs, 'values', buffer ) if ( idx .gt. 0 ) then allocate( var(1:1) ) var(1) = buffer if ( buffer .ne. ' ' ) then has_var = .true. endif else idxv = 0 started = .false. do idx = 1,nodata if ( data(idx) .ne. ' ' .or. started ) then if ( .not. started ) then allocate( var(1:nodata-idx+1) ) started = .true. endif idxv = idxv + 1 var(idxv) = data(idx) endif enddo if ( started ) then has_var = .true. endif endif ! ok status = 0 end subroutine read_xml_line_array ! read_xml_real_array, ... -- ! See read_xml_integer_array for an explanation ! subroutine read_xml_real_array( info, tag, endtag, attribs, noattribs, data, & nodata, var, has_var, status ) real(4), dimension(:), pointer :: var include 'xmlf_read_xml_array.inc' end subroutine read_xml_real_array subroutine read_xml_double_array( info, tag, endtag, attribs, noattribs, data, & nodata, var, has_var, status ) real(8), dimension(:), pointer :: var include 'xmlf_read_xml_array.inc' end subroutine read_xml_double_array subroutine read_xml_logical_array( info, tag, endtag, attribs, noattribs, data, & nodata, var, has_var, status ) logical, dimension(:), pointer :: var include 'xmlf_read_xml_array.inc' end subroutine read_xml_logical_array subroutine read_xml_word_array( info, tag, endtag, attribs, noattribs, data, & nodata, var, has_var, status ) character(len=*), dimension(:), pointer :: var include 'xmlf_read_xml_array.inc' end subroutine read_xml_word_array ! read_from_buffer_integers -- ! Routine to read all integers from a long string ! ! Arguments: ! buffer String containing the data ! var Variable to be filled ! ierror Error flag ! subroutine read_from_buffer_integers( buffer, var, ierror ) integer, dimension(:), pointer :: var integer, dimension(:), pointer :: work include 'xmlf_read_from_buffer.inc' end subroutine read_from_buffer_integers ! read_xml_from_buffer_reals, ... - ! See read_xml_from_buffer_integers for an explanation ! subroutine read_from_buffer_reals( buffer, var, ierror ) real(4), dimension(:), pointer :: var real(4), dimension(:), pointer :: work include 'xmlf_read_from_buffer.inc' end subroutine read_from_buffer_reals subroutine read_from_buffer_doubles( buffer, var, ierror ) real(8), dimension(:), pointer :: var real(8), dimension(:), pointer :: work include 'xmlf_read_from_buffer.inc' end subroutine read_from_buffer_doubles subroutine read_from_buffer_logicals( buffer, var, ierror ) logical, dimension(:), pointer :: var logical, dimension(:), pointer :: work include 'xmlf_read_from_buffer.inc' end subroutine read_from_buffer_logicals subroutine read_from_buffer_words( buffer, var, ierror ) character(len=*), dimension(:), pointer :: var character(len=len(var)), dimension(:), pointer :: work include 'xmlf_read_from_buffer.inc' end subroutine read_from_buffer_words ! read_xml_word_1dim, ... - ! Read an array of "words" (or ...) but from different elements ! subroutine read_xml_integer_1dim( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata integer, dimension(:), pointer :: var logical, intent(inout) :: has_var integer, intent(out) :: status integer,dimension(:), pointer :: newvar character(len=len(attribs(1,1))) :: buffer integer :: newsize newsize = size(var) + 1 allocate( newvar(1:newsize) ) newvar(1:newsize-1) = var deallocate( var ) var => newvar call read_xml_integer( info, tag, endtag, attribs, noattribs, data, nodata, & var(newsize), has_var, status ) end subroutine read_xml_integer_1dim subroutine read_xml_real_1dim( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata real(4), dimension(:), pointer :: var logical, intent(inout) :: has_var integer, intent(out) :: status real(4), dimension(:), pointer :: newvar character(len=len(attribs(1,1))) :: buffer integer :: newsize newsize = size(var) + 1 allocate( newvar(1:newsize) ) newvar(1:newsize-1) = var deallocate( var ) var => newvar call read_xml_real( info, tag, endtag, attribs, noattribs, data, nodata, & var(newsize), has_var, status ) end subroutine read_xml_real_1dim subroutine read_xml_double_1dim( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata real(8), dimension(:), pointer :: var logical, intent(inout) :: has_var integer, intent(out) :: status real(8), dimension(:), pointer :: newvar character(len=len(attribs(1,1))) :: buffer integer :: newsize newsize = size(var) + 1 allocate( newvar(1:newsize) ) newvar(1:newsize-1) = var deallocate( var ) var => newvar call read_xml_double( info, tag, endtag, attribs, noattribs, data, nodata, & var(newsize), has_var, status ) end subroutine read_xml_double_1dim subroutine read_xml_logical_1dim( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata logical, dimension(:), pointer :: var logical, intent(inout) :: has_var integer, intent(out) :: status logical, dimension(:), pointer :: newvar character(len=len(attribs(1,1))) :: buffer integer :: newsize newsize = size(var) + 1 allocate( newvar(1:newsize) ) newvar(1:newsize-1) = var deallocate( var ) var => newvar call read_xml_logical( info, tag, endtag, attribs, noattribs, data, nodata, & var(newsize), has_var, status ) end subroutine read_xml_logical_1dim subroutine read_xml_word_1dim( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata character(len=*), dimension(:), pointer :: var logical, intent(inout) :: has_var integer, intent(out) :: status character(len=len(var)),dimension(:), pointer :: newvar character(len=len(attribs(1,1))) :: buffer integer :: newsize newsize = size(var) + 1 allocate( newvar(1:newsize) ) newvar(1:newsize-1) = var deallocate( var ) var => newvar call read_xml_word( info, tag, endtag, attribs, noattribs, data, nodata, & var(newsize), has_var, status ) end subroutine read_xml_word_1dim subroutine read_xml_line_1dim( info, tag, endtag, attribs, noattribs, data, nodata, & var, has_var, status ) type(XML_PARSE), intent(inout) :: info character(len=*), intent(in) :: tag logical, intent(inout) :: endtag character(len=*), dimension(:,:), intent(in) :: attribs integer, intent(in) :: noattribs character(len=*), dimension(:), intent(in) :: data integer, intent(in) :: nodata character(len=*), dimension(:), pointer :: var logical, intent(inout) :: has_var integer, intent(out) :: status character(len=len(var)),dimension(:), pointer :: newvar character(len=len(attribs(1,1))) :: buffer integer :: newsize newsize = size(var) + 1 allocate( newvar(1:newsize) ) newvar(1:newsize-1) = var deallocate( var ) var => newvar call read_xml_line( info, tag, endtag, attribs, noattribs, data, nodata, & var(newsize), has_var, status ) end subroutine read_xml_line_1dim end module xmlf_read_xml_primitives