xmlf_read_xml_primitives.f90 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. ! read_xml_prims.f90 - Read routines for primitive data
  2. !
  3. ! $Id: read_xml_prims.f90,v 1.7 2007/12/07 10:38:41 arjenmarkus Exp $
  4. !
  5. ! Arjen Markus
  6. !
  7. ! General information:
  8. ! This module is part of the XML-Fortran library. Its
  9. ! purpose is to help read individual items from an XML
  10. ! file into the variables that have been connected to
  11. ! the various tags. It is used by the code generated
  12. ! by the make_xml_reader program.
  13. !
  14. ! Because the routines differ mostly by the type of the
  15. ! output variable, the body is included, to prevent
  16. ! too much repeated blocks of code with all the maintenance
  17. ! issues that causes.
  18. !
  19. module xmlf_read_xml_primitives
  20. use xmlf_parse
  21. implicit none
  22. private :: read_from_buffer
  23. private :: read_from_buffer_integers
  24. private :: read_from_buffer_reals
  25. private :: read_from_buffer_doubles
  26. private :: read_from_buffer_logicals
  27. private :: read_from_buffer_words
  28. interface read_from_buffer
  29. module procedure read_from_buffer_integers
  30. module procedure read_from_buffer_reals
  31. module procedure read_from_buffer_doubles
  32. module procedure read_from_buffer_logicals
  33. module procedure read_from_buffer_words
  34. end interface
  35. contains
  36. ! skip_until_endtag --
  37. ! Routine to read the XML file until the end tag is encountered
  38. !
  39. ! Arguments:
  40. ! info The XML file data structure
  41. ! tag The tag in question
  42. ! attribs Array of attributes and their values
  43. ! data Array of strings, representing the data
  44. ! error Has an error occurred?
  45. !
  46. subroutine skip_until_endtag( info, tag, attribs, data, error )
  47. type(XML_PARSE), intent(inout) :: info
  48. character(len=*), intent(in) :: tag
  49. character(len=*), dimension(:,:), intent(inout) :: attribs
  50. character(len=*), dimension(:), intent(inout) :: data
  51. logical, intent(out) :: error
  52. integer :: noattribs
  53. integer :: nodata
  54. integer :: ierr
  55. logical :: endtag
  56. character(len=len(tag)) :: newtag
  57. error = .true.
  58. do
  59. call xml_get( info, newtag, endtag, attribs, noattribs, &
  60. data, nodata )
  61. if ( xml_error(info) ) then
  62. error = .true.
  63. exit
  64. endif
  65. if ( endtag .and. newtag .eq. tag ) then
  66. exit
  67. endif
  68. enddo
  69. end subroutine skip_until_endtag
  70. ! read_xml_integer --
  71. ! Routine to read a single integer from the parsed data
  72. !
  73. ! Arguments:
  74. ! info XML parser structure
  75. ! tag The tag in question (error message only)
  76. ! endtag End tag found? (Dummy argument, actually)
  77. ! attribs Array of attributes and their values
  78. ! noattribs Number of attributes found
  79. ! data Array of strings, representing the data
  80. ! nodata Number of data strings
  81. ! var Variable to be filled
  82. ! has_var Has the variable been set?
  83. !
  84. subroutine read_xml_integer( info, tag, endtag, attribs, noattribs, data, nodata, &
  85. var, has_var, status )
  86. integer, intent(inout) :: var
  87. include 'xmlf_read_xml_scalar.inc'
  88. end subroutine read_xml_integer
  89. ! read_xml_line --
  90. ! Routine to read a single line of text from the parsed data
  91. !
  92. ! Arguments:
  93. ! info XML parser structure
  94. ! tag The tag in question (error message only)
  95. ! endtag End tag found? (Dummy argument, actually)
  96. ! attribs Array of attributes and their values
  97. ! noattribs Number of attributes found
  98. ! data Array of strings, representing the data
  99. ! nodata Number of data strings
  100. ! var Variable to be filled
  101. ! has_var Has the variable been set?
  102. !
  103. subroutine read_xml_line( info, tag, endtag, attribs, noattribs, data, nodata, &
  104. var, has_var, status )
  105. type(XML_PARSE), intent(inout) :: info
  106. character(len=*), intent(in) :: tag
  107. logical, intent(inout) :: endtag
  108. character(len=*), dimension(:,:), intent(in) :: attribs
  109. integer, intent(in) :: noattribs
  110. character(len=*), dimension(:), intent(in) :: data
  111. integer, intent(in) :: nodata
  112. character(len=*), intent(inout) :: var
  113. logical, intent(inout) :: has_var
  114. integer, intent(out) :: status
  115. character(len=len(attribs(1,1))) :: buffer
  116. integer :: idx
  117. !
  118. ! The value can be stored in an attribute value="..." or in
  119. ! the data
  120. !
  121. has_var = .false.
  122. idx = xml_find_attrib( attribs, noattribs, 'value', buffer )
  123. if ( idx .gt. 0 ) then
  124. var = buffer
  125. has_var = .true.
  126. else
  127. do idx = 1,nodata
  128. if ( data(idx) .ne. ' ' ) then
  129. var = data(idx)
  130. has_var = .true.
  131. exit
  132. endif
  133. enddo
  134. endif
  135. ! ok
  136. status = 0
  137. end subroutine read_xml_line
  138. ! read_xml_real, ... --
  139. ! See read_xml_integer for an explanation
  140. !
  141. subroutine read_xml_real( info, tag, endtag, attribs, noattribs, data, nodata, &
  142. var, has_var, status )
  143. real(4), intent(inout) :: var
  144. include 'xmlf_read_xml_scalar.inc'
  145. end subroutine read_xml_real
  146. subroutine read_xml_double( info, tag, endtag, attribs, noattribs, data, nodata, &
  147. var, has_var, status )
  148. real(8), intent(inout) :: var
  149. include 'xmlf_read_xml_scalar.inc'
  150. end subroutine read_xml_double
  151. subroutine read_xml_logical( info, tag, endtag, attribs, noattribs, data, nodata, &
  152. var, has_var, status )
  153. logical, intent(inout) :: var
  154. include 'xmlf_read_xml_scalar.inc'
  155. end subroutine read_xml_logical
  156. subroutine read_xml_word( info, tag, endtag, attribs, noattribs, data, nodata, &
  157. var, has_var, status )
  158. character(len=*), intent(inout) :: var
  159. include 'xmlf_read_xml_scalar.inc'
  160. end subroutine read_xml_word
  161. ! read_xml_integer_array --
  162. ! Routine to read a one-dimensional integer array from the parsed
  163. ! ata
  164. !
  165. ! Arguments:
  166. ! info XML parser structure
  167. ! tag The tag in question (error message only)
  168. ! endtag End tag found? (Dummy argument, actually)
  169. ! attribs Array of attributes and their values
  170. ! noattribs Number of attributes found
  171. ! data Array of strings, representing the data
  172. ! nodata Number of data strings
  173. ! var Variable to be filled
  174. ! has_var Has the variable been set?
  175. !
  176. subroutine read_xml_integer_array( info, tag, endtag, attribs, noattribs, data, &
  177. nodata, var, has_var, status )
  178. integer, dimension(:), pointer :: var
  179. include 'xmlf_read_xml_array.inc'
  180. end subroutine read_xml_integer_array
  181. ! read_xml_line_array --
  182. ! Routine to read an array of lines of text from the parsed data
  183. !
  184. ! Arguments:
  185. ! info XML parser structure
  186. ! tag The tag in question (error message only)
  187. ! attribs Array of attributes and their values
  188. ! noattribs Number of attributes found
  189. ! data Array of strings, representing the data
  190. ! nodata Number of data strings
  191. ! var Variable to be filled
  192. ! has_var Has the variable been set?
  193. !
  194. subroutine read_xml_line_array( info, tag, endtag, attribs, noattribs, data, &
  195. nodata, var, has_var, status )
  196. type(XML_PARSE), intent(inout) :: info
  197. character(len=*), intent(in) :: tag
  198. logical, intent(inout) :: endtag
  199. character(len=*), dimension(:,:), intent(in) :: attribs
  200. integer, intent(in) :: noattribs
  201. character(len=*), dimension(:), intent(in) :: data
  202. integer, intent(in) :: nodata
  203. character(len=*), dimension(:), pointer :: var
  204. logical, intent(inout) :: has_var
  205. integer, intent(out) :: status
  206. character(len=len(attribs(1,1))) :: buffer
  207. integer :: idx
  208. integer :: idxv
  209. logical :: started
  210. !
  211. ! The value can be stored in an attribute values="..." or in
  212. ! the data
  213. !
  214. has_var = .false.
  215. idx = xml_find_attrib( attribs, noattribs, 'values', buffer )
  216. if ( idx .gt. 0 ) then
  217. allocate( var(1:1) )
  218. var(1) = buffer
  219. if ( buffer .ne. ' ' ) then
  220. has_var = .true.
  221. endif
  222. else
  223. idxv = 0
  224. started = .false.
  225. do idx = 1,nodata
  226. if ( data(idx) .ne. ' ' .or. started ) then
  227. if ( .not. started ) then
  228. allocate( var(1:nodata-idx+1) )
  229. started = .true.
  230. endif
  231. idxv = idxv + 1
  232. var(idxv) = data(idx)
  233. endif
  234. enddo
  235. if ( started ) then
  236. has_var = .true.
  237. endif
  238. endif
  239. ! ok
  240. status = 0
  241. end subroutine read_xml_line_array
  242. ! read_xml_real_array, ... --
  243. ! See read_xml_integer_array for an explanation
  244. !
  245. subroutine read_xml_real_array( info, tag, endtag, attribs, noattribs, data, &
  246. nodata, var, has_var, status )
  247. real(4), dimension(:), pointer :: var
  248. include 'xmlf_read_xml_array.inc'
  249. end subroutine read_xml_real_array
  250. subroutine read_xml_double_array( info, tag, endtag, attribs, noattribs, data, &
  251. nodata, var, has_var, status )
  252. real(8), dimension(:), pointer :: var
  253. include 'xmlf_read_xml_array.inc'
  254. end subroutine read_xml_double_array
  255. subroutine read_xml_logical_array( info, tag, endtag, attribs, noattribs, data, &
  256. nodata, var, has_var, status )
  257. logical, dimension(:), pointer :: var
  258. include 'xmlf_read_xml_array.inc'
  259. end subroutine read_xml_logical_array
  260. subroutine read_xml_word_array( info, tag, endtag, attribs, noattribs, data, &
  261. nodata, var, has_var, status )
  262. character(len=*), dimension(:), pointer :: var
  263. include 'xmlf_read_xml_array.inc'
  264. end subroutine read_xml_word_array
  265. ! read_from_buffer_integers --
  266. ! Routine to read all integers from a long string
  267. !
  268. ! Arguments:
  269. ! buffer String containing the data
  270. ! var Variable to be filled
  271. ! ierror Error flag
  272. !
  273. subroutine read_from_buffer_integers( buffer, var, ierror )
  274. integer, dimension(:), pointer :: var
  275. integer, dimension(:), pointer :: work
  276. include 'xmlf_read_from_buffer.inc'
  277. end subroutine read_from_buffer_integers
  278. ! read_xml_from_buffer_reals, ... -
  279. ! See read_xml_from_buffer_integers for an explanation
  280. !
  281. subroutine read_from_buffer_reals( buffer, var, ierror )
  282. real(4), dimension(:), pointer :: var
  283. real(4), dimension(:), pointer :: work
  284. include 'xmlf_read_from_buffer.inc'
  285. end subroutine read_from_buffer_reals
  286. subroutine read_from_buffer_doubles( buffer, var, ierror )
  287. real(8), dimension(:), pointer :: var
  288. real(8), dimension(:), pointer :: work
  289. include 'xmlf_read_from_buffer.inc'
  290. end subroutine read_from_buffer_doubles
  291. subroutine read_from_buffer_logicals( buffer, var, ierror )
  292. logical, dimension(:), pointer :: var
  293. logical, dimension(:), pointer :: work
  294. include 'xmlf_read_from_buffer.inc'
  295. end subroutine read_from_buffer_logicals
  296. subroutine read_from_buffer_words( buffer, var, ierror )
  297. character(len=*), dimension(:), pointer :: var
  298. character(len=len(var)), dimension(:), pointer :: work
  299. include 'xmlf_read_from_buffer.inc'
  300. end subroutine read_from_buffer_words
  301. ! read_xml_word_1dim, ... -
  302. ! Read an array of "words" (or ...) but from different elements
  303. !
  304. subroutine read_xml_integer_1dim( info, tag, endtag, attribs, noattribs, data, nodata, &
  305. var, has_var, status )
  306. type(XML_PARSE), intent(inout) :: info
  307. character(len=*), intent(in) :: tag
  308. logical, intent(inout) :: endtag
  309. character(len=*), dimension(:,:), intent(in) :: attribs
  310. integer, intent(in) :: noattribs
  311. character(len=*), dimension(:), intent(in) :: data
  312. integer, intent(in) :: nodata
  313. integer, dimension(:), pointer :: var
  314. logical, intent(inout) :: has_var
  315. integer, intent(out) :: status
  316. integer,dimension(:), pointer :: newvar
  317. character(len=len(attribs(1,1))) :: buffer
  318. integer :: newsize
  319. newsize = size(var) + 1
  320. allocate( newvar(1:newsize) )
  321. newvar(1:newsize-1) = var
  322. deallocate( var )
  323. var => newvar
  324. call read_xml_integer( info, tag, endtag, attribs, noattribs, data, nodata, &
  325. var(newsize), has_var, status )
  326. end subroutine read_xml_integer_1dim
  327. subroutine read_xml_real_1dim( info, tag, endtag, attribs, noattribs, data, nodata, &
  328. var, has_var, status )
  329. type(XML_PARSE), intent(inout) :: info
  330. character(len=*), intent(in) :: tag
  331. logical, intent(inout) :: endtag
  332. character(len=*), dimension(:,:), intent(in) :: attribs
  333. integer, intent(in) :: noattribs
  334. character(len=*), dimension(:), intent(in) :: data
  335. integer, intent(in) :: nodata
  336. real(4), dimension(:), pointer :: var
  337. logical, intent(inout) :: has_var
  338. integer, intent(out) :: status
  339. real(4), dimension(:), pointer :: newvar
  340. character(len=len(attribs(1,1))) :: buffer
  341. integer :: newsize
  342. newsize = size(var) + 1
  343. allocate( newvar(1:newsize) )
  344. newvar(1:newsize-1) = var
  345. deallocate( var )
  346. var => newvar
  347. call read_xml_real( info, tag, endtag, attribs, noattribs, data, nodata, &
  348. var(newsize), has_var, status )
  349. end subroutine read_xml_real_1dim
  350. subroutine read_xml_double_1dim( info, tag, endtag, attribs, noattribs, data, nodata, &
  351. var, has_var, status )
  352. type(XML_PARSE), intent(inout) :: info
  353. character(len=*), intent(in) :: tag
  354. logical, intent(inout) :: endtag
  355. character(len=*), dimension(:,:), intent(in) :: attribs
  356. integer, intent(in) :: noattribs
  357. character(len=*), dimension(:), intent(in) :: data
  358. integer, intent(in) :: nodata
  359. real(8), dimension(:), pointer :: var
  360. logical, intent(inout) :: has_var
  361. integer, intent(out) :: status
  362. real(8), dimension(:), pointer :: newvar
  363. character(len=len(attribs(1,1))) :: buffer
  364. integer :: newsize
  365. newsize = size(var) + 1
  366. allocate( newvar(1:newsize) )
  367. newvar(1:newsize-1) = var
  368. deallocate( var )
  369. var => newvar
  370. call read_xml_double( info, tag, endtag, attribs, noattribs, data, nodata, &
  371. var(newsize), has_var, status )
  372. end subroutine read_xml_double_1dim
  373. subroutine read_xml_logical_1dim( info, tag, endtag, attribs, noattribs, data, nodata, &
  374. var, has_var, status )
  375. type(XML_PARSE), intent(inout) :: info
  376. character(len=*), intent(in) :: tag
  377. logical, intent(inout) :: endtag
  378. character(len=*), dimension(:,:), intent(in) :: attribs
  379. integer, intent(in) :: noattribs
  380. character(len=*), dimension(:), intent(in) :: data
  381. integer, intent(in) :: nodata
  382. logical, dimension(:), pointer :: var
  383. logical, intent(inout) :: has_var
  384. integer, intent(out) :: status
  385. logical, dimension(:), pointer :: newvar
  386. character(len=len(attribs(1,1))) :: buffer
  387. integer :: newsize
  388. newsize = size(var) + 1
  389. allocate( newvar(1:newsize) )
  390. newvar(1:newsize-1) = var
  391. deallocate( var )
  392. var => newvar
  393. call read_xml_logical( info, tag, endtag, attribs, noattribs, data, nodata, &
  394. var(newsize), has_var, status )
  395. end subroutine read_xml_logical_1dim
  396. subroutine read_xml_word_1dim( info, tag, endtag, attribs, noattribs, data, nodata, &
  397. var, has_var, status )
  398. type(XML_PARSE), intent(inout) :: info
  399. character(len=*), intent(in) :: tag
  400. logical, intent(inout) :: endtag
  401. character(len=*), dimension(:,:), intent(in) :: attribs
  402. integer, intent(in) :: noattribs
  403. character(len=*), dimension(:), intent(in) :: data
  404. integer, intent(in) :: nodata
  405. character(len=*), dimension(:), pointer :: var
  406. logical, intent(inout) :: has_var
  407. integer, intent(out) :: status
  408. character(len=len(var)),dimension(:), pointer :: newvar
  409. character(len=len(attribs(1,1))) :: buffer
  410. integer :: newsize
  411. newsize = size(var) + 1
  412. allocate( newvar(1:newsize) )
  413. newvar(1:newsize-1) = var
  414. deallocate( var )
  415. var => newvar
  416. call read_xml_word( info, tag, endtag, attribs, noattribs, data, nodata, &
  417. var(newsize), has_var, status )
  418. end subroutine read_xml_word_1dim
  419. subroutine read_xml_line_1dim( info, tag, endtag, attribs, noattribs, data, nodata, &
  420. var, has_var, status )
  421. type(XML_PARSE), intent(inout) :: info
  422. character(len=*), intent(in) :: tag
  423. logical, intent(inout) :: endtag
  424. character(len=*), dimension(:,:), intent(in) :: attribs
  425. integer, intent(in) :: noattribs
  426. character(len=*), dimension(:), intent(in) :: data
  427. integer, intent(in) :: nodata
  428. character(len=*), dimension(:), pointer :: var
  429. logical, intent(inout) :: has_var
  430. integer, intent(out) :: status
  431. character(len=len(var)),dimension(:), pointer :: newvar
  432. character(len=len(attribs(1,1))) :: buffer
  433. integer :: newsize
  434. newsize = size(var) + 1
  435. allocate( newvar(1:newsize) )
  436. newvar(1:newsize-1) = var
  437. deallocate( var )
  438. var => newvar
  439. call read_xml_line( info, tag, endtag, attribs, noattribs, data, nodata, &
  440. var(newsize), has_var, status )
  441. end subroutine read_xml_line_1dim
  442. end module xmlf_read_xml_primitives