m_inpak90.F90 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049
  1. !-------------------------------------------------------------------------
  2. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  3. !-------------------------------------------------------------------------
  4. ! CVS m_inpak90.F90,v 1.8 2006-12-19 00:22:35 jacob Exp
  5. ! CVS MCT_2_8_0
  6. !-------------------------------------------------------------------------
  7. !BOI
  8. !
  9. ! !TITLE: Inpak 90 Documentation \\ Version 1.01
  10. !
  11. ! !AUTHORS: Arlindo da Silva
  12. !
  13. ! !AFFILIATION: Data Assimilation Office, NASA/GSFC, Greenbelt, MD 20771
  14. !
  15. ! !DATE: June 20, 1996
  16. !
  17. ! !INTRODUCTION: Package Overview
  18. !
  19. ! Inpak 90 is a Fortran (77/90) collection of
  20. ! routines/functions for accessing {\em Resource Files}
  21. ! in ASCII format. The package is optimized
  22. ! for minimizing formatted I/O, performing all of its string
  23. ! operations in memory using Fortran intrinsic functions.
  24. !
  25. ! \subsection{Resource Files}
  26. !
  27. ! A {\em Resource File} is a text file consisting of variable
  28. ! length lines (records), each possibly starting with a {\em label}
  29. ! (or {\em key}), followed by some data. A simple resource file
  30. ! looks like this:
  31. !
  32. ! \begin{verbatim}
  33. ! # Lines starting with # are comments which are
  34. ! # ignored during processing.
  35. ! my_file_names: jan87.dat jan88.dat jan89.dat
  36. ! radius_of_the_earth: 6.37E6 # these are comments too
  37. ! constants: 3.1415 25
  38. ! my_favourite_colors: green blue 022 # text & number are OK
  39. ! \end{verbatim}
  40. !
  41. ! In this example, {\tt my\_file\_names:} and {\tt constants:}
  42. ! are labels, while {\tt jan87.dat, jan88.dat} and {\tt jan89.dat} are
  43. ! data associated with label {\tt my\_file\_names:}.
  44. ! Resource files can also contain simple tables of the form,
  45. !
  46. ! \begin{verbatim}
  47. ! my_table_name::
  48. ! 1000 3000 263.0
  49. ! 925 3000 263.0
  50. ! 850 3000 263.0
  51. ! 700 3000 269.0
  52. ! 500 3000 287.0
  53. ! 400 3000 295.8
  54. ! 300 3000 295.8
  55. ! ::
  56. ! \end{verbatim}
  57. !
  58. ! Resource files are random access, the particular order of the
  59. ! records are not important (except between ::s in a table definition).
  60. !
  61. ! \subsection{A Quick Stroll}
  62. !
  63. ! The first step is to load the ASCII resource (rc) file into
  64. ! memory\footnote{See next section for a complete description
  65. ! of parameters for each routine/function}:
  66. !
  67. ! \begin{verbatim}
  68. ! call i90_LoadF ( 'my_file.rc', iret )
  69. ! \end{verbatim}
  70. !
  71. ! The next step is to select the label (record) of interest, say
  72. !
  73. ! \begin{verbatim}
  74. ! call i90_label ( 'constants:', iret )
  75. ! \end{verbatim}
  76. !
  77. ! The 2 constants above can be retrieved with the following code
  78. ! fragment:
  79. ! \begin{verbatim}
  80. ! real r
  81. ! integer i
  82. ! call i90_label ( 'constants:', iret )
  83. ! r = i90_gfloat(iret) ! results in r = 3.1415
  84. ! i = i90_gint(iret) ! results in i = 25
  85. ! \end{verbatim}
  86. !
  87. ! The file names above can be retrieved with the following
  88. ! code fragment:
  89. ! \begin{verbatim}
  90. ! character*20 fn1, fn2, fn3
  91. ! integer iret
  92. ! call i90_label ( 'my_file_names:', iret )
  93. ! call i90_Gtoken ( fn1, iret ) ! ==> fn1 = 'jan87.dat'
  94. ! call i90_Gtoken ( fn2, iret ) ! ==> fn1 = 'jan88.dat'
  95. ! call i90_Gtoken ( fn3, iret ) ! ==> fn1 = 'jan89.dat'
  96. ! \end{verbatim}
  97. !
  98. ! To access the table above, the user first must use {\tt i90\_label()} to
  99. ! locate the beginning of the table, e.g.,
  100. !
  101. ! \begin{verbatim}
  102. ! call i90_label ( 'my_table_name::', iret )
  103. ! \end{verbatim}
  104. !
  105. ! Subsequently, {\tt i90\_gline()} can be used to gain access to each
  106. ! row of the table. Here is a code fragment to read the above
  107. ! table (7 rows, 3 columns):
  108. !
  109. ! \begin{verbatim}
  110. ! real table(7,3)
  111. ! character*20 word
  112. ! integer iret
  113. ! call i90_label ( 'my_table_name::', iret )
  114. ! do i = 1, 7
  115. ! call i90_gline ( iret )
  116. ! do j = 1, 3
  117. ! table(i,j) = i90_gfloat ( iret )
  118. ! end do
  119. ! end do
  120. ! \end{verbatim}
  121. !
  122. ! Get the idea?
  123. !
  124. ! \newpage
  125. ! \subsection{Main Routine/Functions}
  126. !
  127. ! \begin{verbatim}
  128. ! ------------------------------------------------------------------
  129. ! Routine/Function Description
  130. ! ------------------------------------------------------------------
  131. ! I90_LoadF ( filen, iret ) loads resource file into memory
  132. ! I90_Label ( label, iret ) selects a label (key)
  133. ! I90_GLine ( iret ) selects next line (for tables)
  134. ! I90_Gtoken ( word, iret ) get next token
  135. ! I90_Gfloat ( iret ) returns next float number (function)
  136. ! I90_GInt ( iret ) returns next integer number (function)
  137. ! i90_AtoF ( string, iret ) ASCII to float (function)
  138. ! i90_AtoI ( string, iret ) ASCII to integer (function)
  139. ! I90_Len ( string ) string length without trailing blanks
  140. ! LabLin ( label ) similar to i90_label (no iret)
  141. ! FltGet ( default ) returns next float number (function)
  142. ! IntGet ( default ) returns next integer number (function)
  143. ! ChrGet ( default ) returns next character (function)
  144. ! TokGet ( string, default ) get next token
  145. ! ------------------------------------------------------------------
  146. ! \end{verbatim}
  147. !
  148. ! {\em Common Arguments:}
  149. !
  150. ! \begin{verbatim}
  151. ! character*(*) filen file name
  152. ! integer iret error return code (0 is OK)
  153. ! character*(*) label label (key) to locate record
  154. ! character*(*) word blank delimited string
  155. ! character*(*) string a sequence of characters
  156. ! \end{verbatim}
  157. !
  158. ! See the Prologues in the next section for additional details.
  159. !
  160. !
  161. ! \subsection{Package History}
  162. ! Back in the 70s Eli Isaacson wrote IOPACK in Fortran
  163. ! 66. In June of 1987 I wrote Inpak77 using
  164. ! Fortran 77 string functions; Inpak 77 is a vastly
  165. ! simplified IOPACK, but has its own goodies not found in
  166. ! IOPACK. Inpak 90 removes some obsolete functionality in
  167. ! Inpak77, and parses the whole resource file in memory for
  168. ! performance. Despite its name, Inpak 90 compiles fine
  169. ! under any modern Fortran 77 compiler.
  170. !
  171. ! \subsection{Bugs}
  172. ! Inpak 90 is not very gracious with error messages.
  173. ! The interactive functionality of Inpak77 has not been implemented.
  174. ! The comment character \# cannot be escaped.
  175. !
  176. ! \subsection{Availability}
  177. !
  178. ! This software is available at
  179. ! \begin{verbatim}
  180. ! ftp://niteroi.gsfc.nasa.gov/pub/packages/i90/
  181. ! \end{verbatim}
  182. ! There you will find the following files:
  183. ! \begin{verbatim}
  184. ! i90.f Fortran 77/90 source code
  185. ! i90.h Include file needed by i90.f
  186. ! ti90.f Test code
  187. ! i90.ps Postscript documentation
  188. ! \end{verbatim}
  189. ! An on-line version of this document is available at
  190. ! \begin{verbatim}
  191. ! ftp://niteroi.gsfc.nasa.gov/www/packages/i90/i90.html
  192. ! \end{verbatim}
  193. !
  194. !EOI
  195. !-------------------------------------------------------------------------
  196. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  197. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  198. !-----------------------------------------------------------------------
  199. !
  200. ! !REVISION HISTORY:
  201. ! 03Jul96 - J. Guo - evolved to Fortran 90 module. The
  202. ! modifications include 1) additional subroutines to
  203. ! dynamically manage the memory, 2) privatized most
  204. ! entries, 3) included "i90.h" into the module source
  205. ! with better initializations, 4) removed blockdata, 5)
  206. ! used a portable opntext() call to avoid I/O portability
  207. ! problems.
  208. !
  209. ! See I90_page() I90_Release(), and I90_LoadF() for
  210. ! details.
  211. !
  212. ! 05Aug98 - Jing Guo -
  213. ! Removed i90_page() and its references.
  214. ! Added internal subroutines push_() and pop_().
  215. ! Modified i90_release().
  216. ! Added i90_fullrelease().
  217. ! Removed %loaded. Check i90_depth instead.
  218. ! 06Aug98 - Todling - made I90_gstr public
  219. ! 20Dec98 - Jing Guo - replaced the description of I90_Gstr
  220. ! 28Sep99 - Jing Guo - Merged with the MPI version with
  221. ! some addtional changes based on
  222. ! merging decisions.
  223. ! 12Oct99 - Larson/Guo - Overloaded fltget() to new routines
  224. ! getfltsp() and fltgetdp(), providing better support
  225. ! for 32 and 64 bit platforms, respectively.
  226. !_______________________________________________________________________
  227. module m_inpak90
  228. use m_stdio, only : stderr,stdout
  229. use m_realkinds, only: FP, SP, DP,kind_r8
  230. implicit none
  231. private
  232. public :: I90_LoadF ! loads a resource file into memory
  233. public :: I90_allLoadF! loads/populates a resource file to all PEs
  234. public :: I90_Release ! Releases one cached resource file
  235. public :: I90_fullRelease ! Releases the whole stack
  236. public :: I90_Label ! selects a label (key)
  237. public :: I90_GLine ! selects the next line (for tables)
  238. public :: I90_Gtoken ! gets the next token
  239. public :: I90_Gstr ! get a string upto to a "$" or EOL
  240. public :: I90_AtoF ! ASCII to float (function)
  241. public :: I90_AtoI ! ASCII to integer (function)
  242. public :: I90_Gfloat ! returns next float number (function)
  243. public :: I90_GInt ! returns next integer number (function)
  244. public :: lablin,rdnext,fltget,intget,getwrd,str2rn,chrget,getstr
  245. public :: strget
  246. interface fltget; module procedure &
  247. fltgetsp, &
  248. fltgetdp
  249. end interface
  250. !-----------------------------------------------------------------------
  251. !
  252. ! This part was originally in "i90.h", but included for module.
  253. !
  254. ! revised parameter table to fit Fortran 90 standard
  255. integer, parameter :: LSZ = 256
  256. !ams
  257. ! On Linux with the Fujitsu compiler, I needed to reduce NBUF_MAX
  258. !ams
  259. ! integer, parameter :: NBUF_MAX = 400*(LSZ) ! max size of buffer
  260. ! integer, parameter :: NBUF_MAX = 200*(LSZ) ! max size of buffer
  261. ! Further reduction of NBUF_MAX was necessary for the Fujitsu VPP:
  262. integer, parameter :: NBUF_MAX = 128*(LSZ)-1 ! Maximum buffer size
  263. ! that works with the
  264. ! Fujitsu-VPP platform.
  265. character, parameter :: BLK = achar(32) ! blank (space)
  266. character, parameter :: TAB = achar(09) ! TAB
  267. character, parameter :: EOL = achar(10) ! end of line mark (newline)
  268. character, parameter :: EOB = achar(00) ! end of buffer mark (null)
  269. character, parameter :: NULL= achar(00) ! what it says
  270. type inpak90
  271. ! May be easily paged for extentable file size (J.G.)
  272. integer :: nbuf ! actual size of buffer
  273. character(len=NBUF_MAX),pointer :: buffer ! hold the whole file?
  274. character(len=LSZ), pointer :: this_line ! the current line
  275. integer :: next_line ! index for next line on buffer
  276. type(inpak90),pointer :: last
  277. end type inpak90
  278. integer,parameter :: MALLSIZE_=10 ! just an estimation
  279. character(len=*),parameter :: myname='MCT(MPEU)::m_inpak90'
  280. !-----------------------------------------------------------------------
  281. integer,parameter :: i90_MXDEP = 4
  282. integer,save :: i90_depth = 0
  283. type(inpak90),save,pointer :: i90_now
  284. !-----------------------------------------------------------------------
  285. contains
  286. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  287. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  288. !BOP -------------------------------------------------------------------
  289. !
  290. ! !IROUTINE: I90_allLoadF - populate a rooted database to all PEs
  291. !
  292. ! !DESCRIPTION:
  293. !
  294. ! !INTERFACE:
  295. subroutine I90_allLoadF(fname,root,comm,istat)
  296. use m_mpif90, only : MP_perr
  297. use m_mpif90, only : MP_comm_rank
  298. use m_mpif90, only : MP_CHARACTER
  299. use m_mpif90, only : MP_INTEGER
  300. use m_die, only : perr
  301. implicit none
  302. character(len=*),intent(in) :: fname
  303. integer,intent(in) :: root
  304. integer,intent(in) :: comm
  305. integer,intent(out) :: istat
  306. ! !REVISION HISTORY:
  307. ! 28Jul98 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  308. !EOP ___________________________________________________________________
  309. character(len=*),parameter :: myname_=myname//'::I90_allLoadF'
  310. integer :: myID,ier
  311. istat=0
  312. call MP_comm_rank(comm,myID,ier)
  313. if(ier/=0) then
  314. call MP_perr(myname_,'MP_comm_rank()',ier)
  315. istat=ier
  316. return
  317. endif
  318. if(myID == root) then
  319. call i90_LoadF(fname,ier)
  320. if(ier /= 0) then
  321. call perr(myname_,'i90_LoadF("//trim(fname)//")',ier)
  322. istat=ier
  323. return
  324. endif
  325. else
  326. call push_(ier)
  327. if(ier /= 0) then
  328. call perr(myname_,'push_()',ier)
  329. istat=ier
  330. return
  331. endif
  332. endif
  333. ! Initialize the buffer on all PEs
  334. call MPI_Bcast(i90_now%buffer,NBUF_MAX,MP_CHARACTER,root,comm,ier)
  335. if(ier /= 0) then
  336. call MP_perr(myname_,'MPI_Bcast(%buffer)',ier)
  337. istat=ier
  338. return
  339. endif
  340. call MPI_Bcast(i90_now%nbuf,1,MP_INTEGER,root,comm,ier)
  341. if(ier /= 0) then
  342. call MP_perr(myname_,'MPI_Bcast(%nbuf)',ier)
  343. istat=ier
  344. return
  345. endif
  346. i90_now%this_line=' '
  347. i90_now%next_line=0
  348. end subroutine I90_allLoadF
  349. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  350. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  351. !BOP -------------------------------------------------------------------
  352. !
  353. ! !IROUTINE: push_ - push on a new layer of the internal file _i90_now_
  354. !
  355. ! !DESCRIPTION:
  356. !
  357. ! !INTERFACE:
  358. subroutine push_(ier)
  359. use m_die, only : perr
  360. use m_mall,only : mall_mci,mall_ci,mall_ison
  361. implicit none
  362. integer,intent(out) :: ier
  363. ! !REVISION HISTORY:
  364. ! 05Aug98 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  365. !EOP ___________________________________________________________________
  366. character(len=*),parameter :: myname_=myname//'::push_'
  367. type(inpak90),pointer :: new
  368. if(i90_depth <= 0) nullify(i90_now) ! just an initialization
  369. ! Too many levels
  370. if(i90_depth >= i90_MXDEP) then
  371. call perr(myname_,'(overflow)',i90_depth)
  372. ier=1
  373. return
  374. endif
  375. allocate(new,stat=ier)
  376. if(ier /= 0) then
  377. call perr(myname_,'allocate(new)',ier)
  378. return
  379. endif
  380. if(mall_ison()) call mall_ci(MALLSIZE_,myname)
  381. allocate(new%buffer,new%this_line,stat=ier)
  382. if(ier /= 0) then
  383. call perr(myname_,'allocate(new%..)',ier)
  384. return
  385. endif
  386. if(mall_ison()) then
  387. call mall_mci(new%buffer,myname)
  388. call mall_mci(new%this_line,myname)
  389. endif
  390. new%last => i90_now
  391. i90_now => new
  392. nullify(new)
  393. i90_depth = i90_depth+1
  394. end subroutine push_
  395. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  396. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  397. !BOP -------------------------------------------------------------------
  398. !
  399. ! !IROUTINE: pop_ - pop off a layer of the internal file _i90_now_
  400. !
  401. ! !DESCRIPTION:
  402. !
  403. ! !INTERFACE:
  404. subroutine pop_(ier)
  405. use m_die, only : perr
  406. use m_mall,only : mall_mco,mall_co,mall_ison
  407. implicit none
  408. integer,intent(out) :: ier
  409. ! !REVISION HISTORY:
  410. ! 05Aug98 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  411. !EOP ___________________________________________________________________
  412. character(len=*),parameter :: myname_=myname//'::pop_'
  413. type(inpak90),pointer :: old
  414. if(i90_depth <= 0) then
  415. call perr(myname_,'(underflow)',i90_depth)
  416. ier=1
  417. return
  418. endif
  419. old => i90_now%last
  420. if(mall_ison()) then
  421. call mall_mco(i90_now%this_line,myname)
  422. call mall_mco(i90_now%buffer,myname)
  423. endif
  424. deallocate(i90_now%buffer,i90_now%this_line,stat=ier)
  425. if(ier /= 0) then
  426. call perr(myname_,'deallocate(new%..)',ier)
  427. return
  428. endif
  429. if(mall_ison()) call mall_co(MALLSIZE_,myname)
  430. deallocate(i90_now,stat=ier)
  431. if(ier /= 0) then
  432. call perr(myname_,'deallocate(new)',ier)
  433. return
  434. endif
  435. i90_now => old
  436. nullify(old)
  437. i90_depth = i90_depth - 1
  438. end subroutine pop_
  439. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  440. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  441. !-----------------------------------------------------------------------
  442. !
  443. ! !ROUTINE: I90_Release - deallocate memory used to load a resource file
  444. !
  445. ! !INTERFACE:
  446. !
  447. subroutine I90_Release(stat)
  448. use m_die,only : perr,die
  449. implicit none
  450. integer,optional, intent(out) :: stat
  451. !
  452. ! !DESCRIPTION:
  453. !
  454. ! I90_Release() is used to pair I90_LoadF() to release the memory
  455. ! used by I90_LoadF() for resourse data input.
  456. !
  457. ! !SEE ALSO:
  458. !
  459. ! !REVISION HISTORY:
  460. ! 03Jul96 - J. Guo - added to Arlindos inpak90 for its
  461. ! Fortran 90 revision.
  462. !_______________________________________________________________________
  463. character(len=*),parameter :: myname_=myname//'::i90_Release'
  464. integer :: ier
  465. if(present(stat)) stat=0
  466. call pop_(ier)
  467. if(ier/=0) then
  468. call perr(myname_,'pop_()',ier)
  469. if(.not.present(stat)) call die(myname_)
  470. stat=ier
  471. return
  472. endif
  473. end subroutine I90_Release
  474. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  475. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  476. !BOP -------------------------------------------------------------------
  477. !
  478. ! !IROUTINE: i90_fullRelease - releases the whole stack led by _i90_now_
  479. !
  480. ! !DESCRIPTION:
  481. !
  482. ! !INTERFACE:
  483. subroutine i90_fullRelease(ier)
  484. use m_die,only : perr
  485. implicit none
  486. integer,intent(out) :: ier
  487. ! !REVISION HISTORY:
  488. ! 05Aug98 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  489. !EOP ___________________________________________________________________
  490. character(len=*),parameter :: myname_=myname//'::i90_fullRelease'
  491. do while(i90_depth > 0)
  492. call pop_(ier)
  493. if(ier /= 0) then
  494. call perr(myname_,'pop_()',ier)
  495. return
  496. endif
  497. end do
  498. ier=0
  499. end subroutine i90_fullRelease
  500. !=======================================================================
  501. subroutine I90_LoadF ( filen, iret )
  502. use m_ioutil, only : luavail,opntext,clstext
  503. use m_die, only : perr
  504. implicit NONE
  505. !-------------------------------------------------------------------------
  506. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  507. !-------------------------------------------------------------------------
  508. !BOP
  509. !
  510. ! !ROUTINE: I90_LoadF() --- Loads resource file into memory.
  511. !
  512. ! !DESCRIPTION:
  513. !
  514. ! Reads resource file, strips out comments, translate TABs into
  515. ! blanks, and loads the modified file contents into memory.
  516. ! Must be called only once for each resource file.
  517. !
  518. ! !CALLING SEQUENCE:
  519. !
  520. ! call i90_LoadF ( filen, iret )
  521. !
  522. ! !INPUT PARAMETERS:
  523. !
  524. character*(*) filen ! file name
  525. ! !OUTPUT PARAMETERS:
  526. integer iret ! Return code:
  527. ! 0 no error
  528. ! -98 coult not get unit number
  529. ! (strange!)
  530. ! -98 talk to a wizzard
  531. ! -99 out of memory: increase
  532. ! NBUF_MAX in 'i90.h'
  533. ! other iostat from open statement.
  534. !
  535. ! !BUGS:
  536. !
  537. ! It does not perform dynamic allocation, mostly to keep vanilla f77
  538. ! compatibility. Overall amount of static memory is small (~100K
  539. ! for default NBUF_MAX = 400*256).
  540. !
  541. ! !SEE ALSO:
  542. !
  543. ! i90_label() selects a label (key)
  544. !
  545. ! !FILES USED:
  546. !
  547. ! File name supplied on input. The file is opened, read and then closed.
  548. !
  549. ! !REVISION HISTORY:
  550. !
  551. ! 19Jun96 da Silva Original code.
  552. !
  553. !EOP
  554. !-------------------------------------------------------------------------
  555. integer lu, ios, loop, ls, ptr
  556. character*256 line
  557. character(len=*), parameter :: myname_ = myname//'::i90_loadf'
  558. ! Check to make sure there is not too many levels
  559. ! of the stacked resource files
  560. if(i90_depth >= i90_MXDEP) then
  561. call perr(myname_,'(overflow)',i90_depth)
  562. iret=1
  563. return
  564. endif
  565. ! Open file
  566. ! ---------
  567. ! lu = i90_lua()
  568. lu = luavail() ! a more portable version
  569. if ( lu .lt. 0 ) then
  570. iret = -97
  571. return
  572. end if
  573. ! A open through an interface to avoid portability problems.
  574. ! (J.G.)
  575. call opntext(lu,filen,'old',ios)
  576. if ( ios .ne. 0 ) then
  577. write(stderr,'(2a,i5)') myname_,': opntext() error, ios =',ios
  578. iret = ios
  579. return
  580. end if
  581. ! Create a dynamic page to store the file. It might be expanded
  582. ! to allocate memory on requests (a link list) (J.G.)
  583. ! Changed from page_() to push_(), to allow multiple (stacked)
  584. ! inpak90 buffers. J.G.
  585. call push_(ios) ! to create buffer space
  586. if ( ios .ne. 0 ) then
  587. write(stderr,'(2a,i5)') myname_,': push_() error, ios =',ios
  588. iret = ios
  589. return
  590. end if
  591. ! Read to end of file
  592. ! -------------------
  593. i90_now%buffer(1:1) = EOL
  594. ptr = 2 ! next buffer position
  595. do loop = 1, NBUF_MAX
  596. ! Read next line
  597. ! --------------
  598. read(lu,'(a)', end=11) line ! read next line
  599. call i90_trim ( line ) ! remove trailing blanks
  600. call i90_pad ( line ) ! Pad with # from end of line
  601. ! A non-empty line
  602. ! ----------------
  603. ls = index(line,'#' ) - 1 ! line length
  604. if ( ls .gt. 0 ) then
  605. if ( (ptr+ls) .gt. NBUF_MAX ) then
  606. iret = -99
  607. return
  608. end if
  609. i90_now%buffer(ptr:ptr+ls) = line(1:ls) // EOL
  610. ptr = ptr + ls + 1
  611. end if
  612. end do
  613. iret = -98 ! good chance i90_now%buffer is not big enough
  614. return
  615. 11 continue
  616. ! All done
  617. ! --------
  618. ! close(lu)
  619. call clstext(lu,ios)
  620. if(ios /= 0) then
  621. iret=-99
  622. return
  623. endif
  624. i90_now%buffer(ptr:ptr) = EOB
  625. i90_now%nbuf = ptr
  626. i90_now%this_line=' '
  627. i90_now%next_line=0
  628. iret = 0
  629. return
  630. end subroutine I90_LoadF
  631. !...................................................................
  632. subroutine i90_label ( label, iret )
  633. implicit NONE
  634. !-------------------------------------------------------------------------
  635. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  636. !-------------------------------------------------------------------------
  637. !BOP
  638. !
  639. ! !ROUTINE: I90_Label() --- Selects a label (record).
  640. !
  641. ! !DESCRIPTION:
  642. !
  643. ! Once the buffer has been loaded with {\tt i90\_loadf()}, this routine
  644. ! selects a given ``line'' (record/table) associated with ``label''.
  645. ! Think of ``label'' as a resource name or data base ``key''.
  646. !
  647. ! !CALLING SEQUENCE:
  648. !
  649. ! call i90_Label ( label, iret )
  650. !
  651. ! !INPUT PARAMETERS:
  652. !
  653. character(len=*),intent(in) :: label ! input label
  654. ! !OUTPUT PARAMETERS:
  655. integer iret ! Return code:
  656. ! 0 no error
  657. ! -1 buffer not loaded
  658. ! -2 could not find label
  659. !
  660. ! !SEE ALSO:
  661. !
  662. ! i90_loadf() load file into buffer
  663. ! i90_gtoken() get next token
  664. ! i90_gline() get next line (for tables)
  665. ! atof() convert word (string) to float
  666. ! atoi() convert word (string) to integer
  667. !
  668. ! !REVISION HISTORY:
  669. !
  670. ! 19Jun96 da Silva Original code.
  671. ! 19Jan01 Jay Larson <larson@mcs.anl.gov> - introduced CHARACTER
  672. ! variable EOL_label, which is used to circumvent pgf90
  673. ! problems with passing concatenated characters as an argument
  674. ! to a function.
  675. !
  676. !EOP
  677. !-------------------------------------------------------------------------
  678. integer i, j
  679. character(len=(len(label)+len(EOL))) :: EOL_label
  680. ! Make sure that a buffer is defined (JG)
  681. ! ----------------------------------
  682. if(i90_depth <= 0) then
  683. iret = -1
  684. return
  685. endif
  686. ! Determine whether label exists
  687. ! ------------------------------
  688. EOL_label = EOL // label
  689. i = index ( i90_now%buffer(1:i90_now%nbuf), EOL_label ) + 1
  690. if ( i .le. 1 ) then
  691. i90_now%this_line = BLK // EOL
  692. iret = -2
  693. return
  694. end if
  695. ! Extract the line associated with this label
  696. ! -------------------------------------------
  697. i = i + len ( label )
  698. j = i + index(i90_now%buffer(i:i90_now%nbuf),EOL) - 2
  699. i90_now%this_line = i90_now%buffer(i:j) // BLK // EOL
  700. i90_now%next_line = j + 2
  701. iret = 0
  702. return
  703. end subroutine i90_label
  704. !...................................................................
  705. subroutine i90_gline ( iret )
  706. implicit NONE
  707. !-------------------------------------------------------------------------
  708. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  709. !-------------------------------------------------------------------------
  710. !BOP
  711. !
  712. ! !ROUTINE: I90_GLine() --- Selects next line.
  713. !
  714. ! !DESCRIPTION:
  715. !
  716. ! Selects next line, irrespective of of label. If the next line starts
  717. ! with :: (end of table mark), then it lets the user know. This sequential
  718. ! access of the buffer is useful to assess tables, a concept introduced
  719. ! in Inpak 77 by Jing Guo. A table is a construct like this:
  720. !
  721. ! \begin{verbatim}
  722. ! my_table_name::
  723. ! 1000 3000 263.0
  724. ! 925 3000 263.0
  725. ! 850 3000 263.0
  726. ! 700 3000 269.0
  727. ! 500 3000 287.0
  728. ! 400 3000 295.8
  729. ! 300 3000 295.8
  730. ! ::
  731. ! \end{verbatim}
  732. !
  733. ! To access this table, the user first must use {\tt i90\_label()} to
  734. ! locate the beginning of the table, e.g.,
  735. !
  736. ! \begin{verbatim}
  737. ! call i90_label ( 'my_table_name::', iret )
  738. ! \end{verbatim}
  739. !
  740. ! Subsequently, {\tt i90\_gline()} can be used to gain acess to each
  741. ! row of the table. Here is a code fragment to read the above
  742. ! table (7 rows, 3 columns):
  743. !
  744. ! \begin{verbatim}
  745. ! real table(7,3)
  746. ! character*20 word
  747. ! integer iret
  748. ! call i90_label ( 'my_table_name::', iret )
  749. ! do i = 1, 7
  750. ! call i90_gline ( iret )
  751. ! do j = 1, 3
  752. ! table(i,j) = fltget ( 0. )
  753. ! end do
  754. ! end do
  755. ! \end{verbatim}
  756. !
  757. ! For simplicity we have assumed that the dimensions of table were
  758. ! known. It is relatively simple to infer the table dimensions
  759. ! by manipulating ``iret''.
  760. !
  761. ! !CALLING SEQUENCE:
  762. !
  763. ! call i90_gline ( iret )
  764. !
  765. ! !INPUT PARAMETERS:
  766. !
  767. ! None.
  768. !
  769. ! !OUTPUT PARAMETERS:
  770. !
  771. integer iret ! Return code:
  772. ! 0 no error
  773. ! -1 end of buffer reached
  774. ! +1 end of table reached
  775. ! !SEE ALSO:
  776. !
  777. ! i90_label() selects a line (record/table)
  778. !
  779. ! !REVISION HISTORY:
  780. !
  781. ! 10feb95 Guo Wrote rdnext(), Inpak 77 extension.
  782. ! 19Jun96 da Silva Original code with functionality of rdnext()
  783. !
  784. !EOP
  785. !-------------------------------------------------------------------------
  786. integer i, j
  787. ! Make sure that a buffer is defined (JG)
  788. ! ----------------------------------
  789. if(i90_depth <= 0) then
  790. iret = -1
  791. return
  792. endif
  793. if ( i90_now%next_line .ge. i90_now%nbuf ) then
  794. iret = -1
  795. return
  796. end if
  797. i = i90_now%next_line
  798. j = i + index(i90_now%buffer(i:i90_now%nbuf),EOL) - 2
  799. i90_now%this_line = i90_now%buffer(i:j) // BLK // EOL
  800. if ( i90_now%this_line(1:2) .eq. '::' ) then
  801. iret = 1 ! end of table
  802. i90_now%next_line = i90_now%nbuf + 1
  803. return
  804. end if
  805. i90_now%next_line = j + 2
  806. iret = 0
  807. return
  808. end subroutine i90_gline
  809. !...................................................................
  810. subroutine i90_GToken ( token, iret )
  811. implicit NONE
  812. !-------------------------------------------------------------------------
  813. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  814. !-------------------------------------------------------------------------
  815. !BOP
  816. !
  817. ! !ROUTINE: I90_GToken() --- Gets next token.
  818. !
  819. ! !DESCRIPTION:
  820. !
  821. ! Get next token from current line. The current line is defined by a
  822. ! call to {\tt i90\_label()}. Tokens are sequences of characters (including
  823. ! blanks) which may be enclosed by single or double quotes.
  824. ! If no quotes are present, the token from the current position to the next
  825. ! blank of TAB is returned.
  826. !
  827. ! {\em Examples of valid token:}
  828. !
  829. ! \begin{verbatim}
  830. ! single_token "second token on line"
  831. ! "this is a token"
  832. ! 'Another example of a token'
  833. ! 'this is how you get a " inside a token'
  834. ! "this is how you get a ' inside a token"
  835. ! This is valid too # the line ends before the #
  836. ! \end{verbatim}
  837. ! The last line has 4 valid tokens: {\tt This, is, valid} and {\tt too}.
  838. !
  839. ! {\em Invalid string constructs:}
  840. !
  841. ! \begin{verbatim}
  842. ! cannot handle mixed quotes (i.e. single/double)
  843. ! 'escaping like this \' is not implemented'
  844. ! 'this # will not work because of the #'
  845. ! \end{verbatim}
  846. ! The \# character is reserved for comments and cannot be included
  847. ! inside quotation marks.
  848. !
  849. ! !CALLING SEQUENCE:
  850. !
  851. ! call i90_GToken ( token, iret )
  852. !
  853. ! !INPUT PARAMETERS:
  854. !
  855. ! None.
  856. !
  857. ! !OUTPUT PARAMETERS:
  858. !
  859. character*(*) token ! Next token from current line
  860. integer iret ! Return code:
  861. ! 0 no error
  862. ! -1 either nothing left
  863. ! on line or mismatched
  864. ! quotation marks.
  865. ! !BUGS:
  866. !
  867. ! Standard Unix escaping is not implemented at the moment.
  868. !
  869. !
  870. ! !SEE ALSO:
  871. !
  872. ! i90_label() selects a line (record/table)
  873. ! i90_gline() get next line (for tables)
  874. ! atof() convert word (string) to float
  875. ! atoi() convert word (string) to integer
  876. !
  877. !
  878. ! !REVISION HISTORY:
  879. !
  880. ! 19Jun96 da Silva Original code.
  881. !
  882. !EOP
  883. !-------------------------------------------------------------------------
  884. character*1 ch
  885. integer ib, ie
  886. ! Make sure that a buffer is defined (JG)
  887. ! ----------------------------------
  888. if(i90_depth <= 0) then
  889. iret = -1
  890. return
  891. endif
  892. call i90_trim ( i90_now%this_line )
  893. ch = i90_now%this_line(1:1)
  894. if ( ch .eq. '"' .or. ch .eq. "'" ) then
  895. ib = 2
  896. ie = index ( i90_now%this_line(ib:), ch )
  897. else
  898. ib = 1
  899. ie = min(index(i90_now%this_line,BLK), &
  900. index(i90_now%this_line,EOL)) - 1
  901. end if
  902. if ( ie .lt. ib ) then
  903. token = BLK
  904. iret = -1
  905. return
  906. else
  907. ! Get the token, and shift the rest of %this_line to
  908. ! the left
  909. token = i90_now%this_line(ib:ie)
  910. i90_now%this_line = i90_now%this_line(ie+2:)
  911. iret = 0
  912. end if
  913. return
  914. end subroutine i90_gtoken
  915. !...................................................................
  916. subroutine i90_gstr ( string, iret )
  917. implicit NONE
  918. !-------------------------------------------------------------------------
  919. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  920. !-------------------------------------------------------------------------
  921. !
  922. ! !ROUTINE: I90\_GStr()
  923. !
  924. ! !DESCRIPTION:
  925. !
  926. ! Get next string from current line. The current line is defined by a
  927. ! call to {\tt i90\_label()}. Strings are sequence of characters (including
  928. ! blanks) enclosed by single or double quotes. If no quotes
  929. ! are present, the string from the current position to the end of
  930. ! the line is returned.
  931. !
  932. ! NOTE: This routine is defined differently from \verb"i90_GTolen()",
  933. ! where a {\sl token} is white-space delimited, but this routine
  934. ! will try to fetch a string either terminated by a "$" or by the
  935. ! end of the line.
  936. !
  937. ! {\em Examples of valid strings:}
  938. !
  939. ! \begin{verbatim}
  940. ! "this is a string"
  941. ! 'Another example of string'
  942. ! 'this is how you get a " inside a string'
  943. ! "this is how you get a ' inside a string"
  944. ! This is valid too # the line ends before the #
  945. !
  946. ! \end{verbatim}
  947. !
  948. ! {\em Invalid string constructs:}
  949. !
  950. ! \begin{verbatim}
  951. ! cannot handle mixed quotes
  952. ! 'escaping like this \' is not implemented'
  953. ! \end{verbatim}
  954. !
  955. ! {\em Obsolete feature (for Inpak 77 compatibility):}
  956. !
  957. ! \begin{verbatim}
  958. ! the string ends after a $ this is another string
  959. ! \end{verbatim}
  960. !
  961. ! !CALLING SEQUENCE:
  962. !
  963. ! \begin{verbatim}
  964. ! call i90_Gstr ( string, iret )
  965. ! \end{verbatim}
  966. !
  967. ! !INPUT PARAMETERS:
  968. !
  969. character*(*) string ! A NULL (char(0)) delimited string.
  970. ! !OUTPUT PARAMETERS:
  971. !
  972. integer iret ! Return code:
  973. ! 0 no error
  974. ! -1 either nothing left
  975. ! on line or mismatched
  976. ! quotation marks.
  977. ! !BUGS:
  978. !
  979. ! Standard Unix escaping is not implemented at the moment.
  980. ! No way to tell sintax error from end of line (same iret).
  981. !
  982. !
  983. ! !SEE ALSO:
  984. !
  985. ! i90_label() selects a line (record/table)
  986. ! i90_gtoken() get next token
  987. ! i90_gline() get next line (for tables)
  988. ! atof() convert word (string) to float
  989. ! atoi() convert word (string) to integer
  990. !
  991. !
  992. ! !REVISION HISTORY:
  993. !
  994. ! 19Jun96 da Silva Original code.
  995. ! 01Oct96 Jing Guo Removed the null terminitor
  996. !
  997. !-------------------------------------------------------------------------
  998. character*1 ch
  999. integer ib, ie
  1000. ! Make sure that a buffer is defined (JG)
  1001. ! ----------------------------------
  1002. if(i90_depth <= 0) then
  1003. iret = -1
  1004. return
  1005. endif
  1006. call i90_trim ( i90_now%this_line )
  1007. ch = i90_now%this_line(1:1)
  1008. if ( ch .eq. '"' .or. ch .eq. "'" ) then
  1009. ib = 2
  1010. ie = index ( i90_now%this_line(ib:), ch )
  1011. else
  1012. ib = 1
  1013. ie = index(i90_now%this_line,'$')-1 ! undocumented feature!
  1014. if ( ie .lt. 1 ) ie = index(i90_now%this_line,EOL)-2
  1015. end if
  1016. if ( ie .lt. ib ) then
  1017. ! string = NULL
  1018. iret = -1
  1019. return
  1020. else
  1021. string = i90_now%this_line(ib:ie) ! // NULL
  1022. i90_now%this_line = i90_now%this_line(ie+2:)
  1023. iret = 0
  1024. end if
  1025. return
  1026. end subroutine i90_gstr
  1027. !...................................................................
  1028. real(FP) function i90_GFloat( iret )
  1029. implicit NONE
  1030. !-------------------------------------------------------------------------
  1031. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1032. !-------------------------------------------------------------------------
  1033. !BOP
  1034. !
  1035. ! !ROUTINE: i90_GFloat() --- Returns next float number.
  1036. !
  1037. ! !DESCRIPTION:
  1038. !
  1039. ! Returns next float (real number) from the current line.
  1040. ! If an error occurs a zero value is returned.
  1041. !
  1042. ! !CALLING SEQUENCE:
  1043. !
  1044. ! real rnumber
  1045. ! rnumber = i90_gfloat ( default )
  1046. !
  1047. ! !OUTPUT PARAMETERS:
  1048. !
  1049. integer,intent(out) :: iret ! Return code:
  1050. ! 0 no error
  1051. ! -1 either nothing left
  1052. ! on line or mismatched
  1053. ! quotation marks.
  1054. ! -2 parsing error
  1055. !
  1056. ! !REVISION HISTORY:
  1057. !
  1058. ! 19Jun96 da Silva Original code.
  1059. !
  1060. !EOP
  1061. !-------------------------------------------------------------------------
  1062. character*256 token
  1063. integer ios
  1064. real(FP) x
  1065. ! Make sure that a buffer is defined (JG)
  1066. ! ----------------------------------
  1067. if(i90_depth <= 0) then
  1068. iret = -1
  1069. return
  1070. endif
  1071. call i90_gtoken ( token, iret )
  1072. if ( iret .eq. 0 ) then
  1073. read(token,*,iostat=ios) x ! Does it require an extension?
  1074. if ( ios .ne. 0 ) iret = -2
  1075. end if
  1076. if ( iret .ne. 0 ) x = 0.
  1077. i90_GFloat = x
  1078. return
  1079. end function i90_GFloat
  1080. !...................................................................
  1081. integer function I90_GInt ( iret )
  1082. implicit NONE
  1083. !-------------------------------------------------------------------------
  1084. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1085. !-------------------------------------------------------------------------
  1086. !BOP
  1087. !
  1088. ! !ROUTINE: I90_GInt() --- Returns next integer number.
  1089. !
  1090. ! !DESCRIPTION:
  1091. !
  1092. ! Returns next integer number from the current line.
  1093. ! If an error occurs a zero value is returned.
  1094. !
  1095. ! !CALLING SEQUENCE:
  1096. !
  1097. ! integer number
  1098. ! number = i90_gint ( default )
  1099. !
  1100. ! !OUTPUT PARAMETERS:
  1101. !
  1102. integer iret ! Return code:
  1103. ! 0 no error
  1104. ! -1 either nothing left
  1105. ! on line or mismatched
  1106. ! quotation marks.
  1107. ! -2 parsing error
  1108. !
  1109. ! !REVISION HISTORY:
  1110. !
  1111. ! 19Jun96 da Silva Original code.
  1112. ! 24may00 da Silva delcared x as real*8 in case this module is compiled
  1113. ! with real*4
  1114. !
  1115. !EOP
  1116. !-------------------------------------------------------------------------
  1117. character*256 token
  1118. real(kind_r8) x
  1119. integer ios
  1120. ! Make sure that a buffer is defined (JG)
  1121. ! ----------------------------------
  1122. if(i90_depth <= 0) then
  1123. iret = -1
  1124. return
  1125. endif
  1126. call i90_gtoken ( token, iret )
  1127. if ( iret .eq. 0 ) then
  1128. read(token,*,iostat=ios) x
  1129. if ( ios .ne. 0 ) iret = -2
  1130. end if
  1131. if ( iret .ne. 0 ) x = 0
  1132. i90_gint = nint(x)
  1133. return
  1134. end function i90_gint
  1135. !...................................................................
  1136. real(FP) function i90_AtoF( string, iret )
  1137. implicit NONE
  1138. !-------------------------------------------------------------------------
  1139. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1140. !-------------------------------------------------------------------------
  1141. !BOP
  1142. !
  1143. ! !ROUTINE: i90_AtoF() --- Translates ASCII (string) to float.
  1144. !
  1145. ! !DESCRIPTION:
  1146. !
  1147. ! Converts string to real number. Same as obsolete {\tt str2rn()}.
  1148. !
  1149. ! !CALLING SEQUENCE:
  1150. !
  1151. ! real rnumber
  1152. ! rnumber = i90_atof ( string, iret )
  1153. !
  1154. ! !INPUT PARAMETERS:
  1155. !
  1156. character(len=*),intent(in) :: string ! a string
  1157. ! !OUTPUT PARAMETERS:
  1158. !
  1159. integer,intent(out) :: iret ! Return code:
  1160. ! 0 no error
  1161. ! -1 could not convert, probably
  1162. ! string is not a number
  1163. !
  1164. ! !REVISION HISTORY:
  1165. !
  1166. ! 19Jun96 da Silva Original code.
  1167. !
  1168. !EOP
  1169. !-------------------------------------------------------------------------
  1170. read(string,*,end=11,err=11) i90_AtoF
  1171. iret = 0
  1172. return
  1173. 11 iret = -1
  1174. return
  1175. end function i90_AtoF
  1176. !...................................................................
  1177. integer function i90_atoi ( string, iret )
  1178. implicit NONE
  1179. !-------------------------------------------------------------------------
  1180. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1181. !-------------------------------------------------------------------------
  1182. !BOP
  1183. !
  1184. ! !ROUTINE: I90_AtoI() --- Translates ASCII (strings) to integer.
  1185. !
  1186. ! !DESCRIPTION:
  1187. !
  1188. ! Converts string to integer number.
  1189. !
  1190. ! !CALLING SEQUENCE:
  1191. !
  1192. ! integer number
  1193. ! number = i90_atoi ( string, iret )
  1194. !
  1195. ! !INPUT PARAMETERS:
  1196. !
  1197. character*(*) string ! a string
  1198. ! !OUTPUT PARAMETERS:
  1199. !
  1200. integer iret ! Return code:
  1201. ! 0 no error
  1202. ! -1 could not convert, probably
  1203. ! string is not a number
  1204. !
  1205. ! !REVISION HISTORY:
  1206. !
  1207. ! 19Jun96 da Silva Original code.
  1208. !
  1209. !EOP
  1210. !-------------------------------------------------------------------------
  1211. read(string,*,end=11,err=11) i90_atoi
  1212. iret = 0
  1213. return
  1214. 11 iret = -1
  1215. return
  1216. end function i90_atoi
  1217. !...................................................................
  1218. integer function i90_Len ( string )
  1219. implicit NONE
  1220. !-------------------------------------------------------------------------
  1221. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1222. !-------------------------------------------------------------------------
  1223. !BOP
  1224. !
  1225. ! !ROUTINE: I90_Len() --- Returns length of string.
  1226. !
  1227. ! !DESCRIPTION:
  1228. !
  1229. ! Returns the length of a string excluding trailing blanks.
  1230. ! It follows that
  1231. ! \begin{verbatim}
  1232. ! i90_len(string) .le. len(string),
  1233. ! \end{verbatim}
  1234. ! where {\tt len} is the intrinsic string length function.
  1235. ! Example:
  1236. ! \begin{verbatim}
  1237. ! ls = len('abc ') ! results in ls = 5
  1238. ! ls = i90_len ('abc ') ! results in ls = 3
  1239. ! \end{verbatim}
  1240. !
  1241. ! !CALLING SEQUENCE:
  1242. !
  1243. ! integer ls
  1244. ! ls = i90_len ( string )
  1245. !
  1246. ! !INPUT PARAMETERS:
  1247. !
  1248. character*(*) string ! a string
  1249. !
  1250. ! !OUTPUT PARAMETERS:
  1251. !
  1252. ! The length of the string, excluding trailing blanks.
  1253. !
  1254. ! !REVISION HISTORY:
  1255. !
  1256. ! 01Apr94 Guo Original code (a.k.a. luavail())
  1257. ! 19Jun96 da Silva Minor modification + prologue.
  1258. !
  1259. !EOP
  1260. !-------------------------------------------------------------------------
  1261. integer ls, i, l
  1262. ls = len(string)
  1263. do i = ls, 1, -1
  1264. l = i
  1265. if ( string(i:i) .ne. BLK ) go to 11
  1266. end do
  1267. l = l - 1
  1268. 11 continue
  1269. i90_len = l
  1270. return
  1271. end function i90_len
  1272. !...................................................................
  1273. integer function I90_Lua()
  1274. implicit NONE
  1275. !-------------------------------------------------------------------------
  1276. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1277. !-------------------------------------------------------------------------
  1278. !BOP
  1279. !
  1280. ! !ROUTINE: I90_Lua() --- Returns available logical unit number.
  1281. !
  1282. ! !DESCRIPTION:
  1283. !
  1284. ! Look for an available (not opened) Fortran logical unit for i/o.
  1285. !
  1286. ! !CALLING SEQUENCE:
  1287. !
  1288. ! integer lu
  1289. ! lu = i90_lua()
  1290. !
  1291. ! !INPUT PARAMETERS:
  1292. !
  1293. ! None.
  1294. !
  1295. ! !OUTPUT PARAMETERS:
  1296. !
  1297. ! The desired unit number if positive, -1 if unsucessful.
  1298. !
  1299. ! !REVISION HISTORY:
  1300. !
  1301. ! 01Apr94 Guo Original code (a.k.a. luavail())
  1302. ! 19Jun96 da Silva Minor modification + prologue.
  1303. !
  1304. !EOP
  1305. !-------------------------------------------------------------------------
  1306. integer lu,ios
  1307. logical opnd
  1308. lu=7
  1309. inquire(unit=lu,opened=opnd,iostat=ios)
  1310. do while(ios.eq.0.and.opnd)
  1311. lu=lu+1
  1312. inquire(unit=lu,opened=opnd,iostat=ios)
  1313. end do
  1314. if(ios.ne.0) lu=-1
  1315. i90_lua=lu
  1316. return
  1317. end function i90_lua
  1318. !...................................................................
  1319. subroutine i90_pad ( string )
  1320. implicit NONE
  1321. !-------------------------------------------------------------------------
  1322. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1323. !-------------------------------------------------------------------------
  1324. !BOP
  1325. !
  1326. ! !ROUTINE: I90_Pad() --- Pad strings.
  1327. !
  1328. ! !DESCRIPTION:
  1329. !
  1330. ! Pads from the right with the comment character (\#). It also
  1331. ! replaces TABs with blanks for convenience. This is a low level
  1332. ! i90 routine.
  1333. !
  1334. ! !CALLING SEQUENCE:
  1335. !
  1336. ! call i90_pad ( string )
  1337. !
  1338. ! !INPUT PARAMETERS:
  1339. !
  1340. character*256 string ! input string
  1341. ! !OUTPUT PARAMETERS: ! modified string
  1342. !
  1343. ! character*256 string
  1344. !
  1345. ! !BUGS:
  1346. !
  1347. ! It alters TABs even inside strings.
  1348. !
  1349. !
  1350. ! !REVISION HISTORY:
  1351. !
  1352. ! 19Jun96 da Silva Original code.
  1353. !
  1354. !EOP
  1355. !-------------------------------------------------------------------------
  1356. integer i
  1357. ! Pad end of string with #
  1358. ! ------------------------
  1359. do i = 256, 1, -1
  1360. if ( string(i:i) .ne. ' ' .and. &
  1361. string(i:i) .ne. '$' ) go to 11
  1362. string(i:i) = '#'
  1363. end do
  1364. 11 continue
  1365. ! Replace TABs with blanks
  1366. ! -------------------------
  1367. do i = 1, 256
  1368. if ( string(i:i) .eq. TAB ) string(i:i) = BLK
  1369. if ( string(i:i) .eq. '#' ) go to 21
  1370. end do
  1371. 21 continue
  1372. return
  1373. end subroutine i90_pad
  1374. !...................................................................
  1375. subroutine I90_Trim ( string )
  1376. implicit NONE
  1377. !-------------------------------------------------------------------------
  1378. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1379. !-------------------------------------------------------------------------
  1380. !BOP
  1381. !
  1382. ! !ROUTINE: I90_Trim() - Removes leading blanks from strings.
  1383. !
  1384. ! !DESCRIPTION:
  1385. !
  1386. ! Removes blanks and TABS from begenning of string.
  1387. ! This is a low level i90 routine.
  1388. !
  1389. ! !CALLING SEQUENCE:
  1390. !
  1391. ! call i90_Trim ( string )
  1392. !
  1393. ! !INPUT PARAMETERS:
  1394. !
  1395. character*256 string ! the input string
  1396. !
  1397. ! !OUTPUT PARAMETERS:
  1398. !
  1399. ! character*256 string ! the modified string
  1400. !
  1401. !
  1402. ! !REVISION HISTORY:
  1403. !
  1404. ! 19Jun96 da Silva Original code.
  1405. !
  1406. !EOP
  1407. !-------------------------------------------------------------------------
  1408. integer ib, i
  1409. ! Get rid of leading blanks
  1410. ! -------------------------
  1411. ib = 1
  1412. do i = 1, 255
  1413. if ( string(i:i) .ne. ' ' .and. &
  1414. string(i:i) .ne. TAB ) go to 21
  1415. ib = ib + 1
  1416. end do
  1417. 21 continue
  1418. ! String without trailling blanks
  1419. ! -------------------------------
  1420. string = string(ib:)
  1421. return
  1422. end subroutine i90_trim
  1423. !==========================================================================
  1424. ! -----------------------------
  1425. ! Inpak 77 Upward Compatibility
  1426. ! -----------------------------
  1427. subroutine lablin ( label )
  1428. implicit NONE
  1429. !-------------------------------------------------------------------------
  1430. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1431. !-------------------------------------------------------------------------
  1432. !BOP
  1433. !
  1434. ! !ROUTINE: Lablin() --- Selects a Label (Inpak 77)
  1435. !
  1436. ! !DESCRIPTION:
  1437. !
  1438. ! Selects a given ``line'' (record/table) associated with ``label''.
  1439. ! Similar to {\tt i90\_label()}, but prints a message to {\tt stdout}
  1440. ! if it cannot locate the label. Kept for Inpak 77 upward compatibility.
  1441. !
  1442. ! !CALLING SEQUENCE:
  1443. !
  1444. ! call lablin ( label )
  1445. !
  1446. ! !INPUT PARAMETERS:
  1447. character(len=*),intent(in) :: label ! string with label name
  1448. !
  1449. ! !OUTPUT PARAMETERS:
  1450. !
  1451. ! None.
  1452. !
  1453. ! !REVISION HISTORY:
  1454. !
  1455. ! 19Jun96 da Silva Original code.
  1456. !
  1457. !EOP
  1458. !-------------------------------------------------------------------------
  1459. integer iret
  1460. call i90_label ( label, iret )
  1461. if ( iret .ne. 0 ) then
  1462. write(stderr,'(2a)') 'i90/lablin: cannot find label ', label
  1463. endif
  1464. end subroutine lablin
  1465. !...................................................................
  1466. real(SP) function fltgetsp ( default )
  1467. implicit NONE
  1468. !-------------------------------------------------------------------------
  1469. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1470. !-------------------------------------------------------------------------
  1471. !BOP
  1472. !
  1473. ! !ROUTINE: FltGetsp() --- Returns next float (Inpak 77, single precision)
  1474. !
  1475. ! !DESCRIPTION:
  1476. !
  1477. ! Returns next float (real number, single precision) from the current
  1478. ! line, or a default value if it fails to obtain the desired number.
  1479. ! Kept for Inpak 77 upward compatibility.
  1480. !
  1481. ! !CALLING SEQUENCE:
  1482. !
  1483. ! real rnumber, default
  1484. ! rnumber = fltgetsp ( default )
  1485. !
  1486. ! !INPUT PARAMETERS:
  1487. !
  1488. real(SP), intent(IN) :: default ! default value.
  1489. !
  1490. ! !REVISION HISTORY:
  1491. !
  1492. ! 19Jun96 da Silva Original code.
  1493. ! 12Oct99 Guo/Larson - Built from original FltGet() function.
  1494. !
  1495. !EOP
  1496. !-------------------------------------------------------------------------
  1497. character*256 token
  1498. real(FP) x
  1499. integer iret
  1500. call i90_gtoken ( token, iret )
  1501. if ( iret .eq. 0 ) then
  1502. read(token,*,iostat=iret) x
  1503. end if
  1504. if ( iret .ne. 0 ) x = default
  1505. !print *, x
  1506. fltgetsp = x
  1507. return
  1508. end function fltgetsp
  1509. !...................................................................
  1510. real(DP) function fltgetdp ( default )
  1511. implicit NONE
  1512. !-------------------------------------------------------------------------
  1513. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1514. !-------------------------------------------------------------------------
  1515. !BOP
  1516. !
  1517. ! !ROUTINE: FltGetdp() --- Returns next float (Inpak 77)
  1518. !
  1519. ! !DESCRIPTION:
  1520. !
  1521. ! Returns next float (real number) from the current line, or a
  1522. ! default value (double precision) if it fails to obtain the desired
  1523. ! number. Kept for Inpak 77 upward compatibility.
  1524. !
  1525. ! !CALLING SEQUENCE:
  1526. !
  1527. ! real(DP) :: default
  1528. ! real :: rnumber
  1529. ! rnumber = FltGetdp(default)
  1530. !
  1531. ! !INPUT PARAMETERS:
  1532. !
  1533. real(DP), intent(IN) :: default ! default value.
  1534. !
  1535. ! !REVISION HISTORY:
  1536. !
  1537. ! 19Jun96 da Silva Original code.
  1538. ! 12Oct99 Guo/Larson - Built from original FltGet() function.
  1539. !
  1540. !EOP
  1541. !-------------------------------------------------------------------------
  1542. character*256 token
  1543. real(FP) x
  1544. integer iret
  1545. call i90_gtoken ( token, iret )
  1546. if ( iret .eq. 0 ) then
  1547. read(token,*,iostat=iret) x
  1548. end if
  1549. if ( iret .ne. 0 ) x = default
  1550. !print *, x
  1551. fltgetdp = x
  1552. return
  1553. end function fltgetdp
  1554. !...................................................................
  1555. integer function intget ( default )
  1556. implicit NONE
  1557. !-------------------------------------------------------------------------
  1558. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1559. !-------------------------------------------------------------------------
  1560. !BOP
  1561. !
  1562. ! !ROUTINE: IntGet() --- Returns next integer (Inpak 77).
  1563. !
  1564. ! !DESCRIPTION:
  1565. !
  1566. ! Returns next integer number from the current line, or a default
  1567. ! value if it fails to obtain the desired number.
  1568. ! Kept for Inpak 77 upward compatibility.
  1569. !
  1570. ! !CALLING SEQUENCE:
  1571. !
  1572. ! integer number, default
  1573. ! number = intget ( default )
  1574. !
  1575. ! !INPUT PARAMETERS:
  1576. !
  1577. integer default ! default value.
  1578. !
  1579. ! !REVISION HISTORY:
  1580. !
  1581. ! 19Jun96 da Silva Original code.
  1582. !
  1583. !EOP
  1584. !-------------------------------------------------------------------------
  1585. character*256 token
  1586. real(FP) x
  1587. integer iret
  1588. call i90_gtoken ( token, iret )
  1589. if ( iret .eq. 0 ) then
  1590. read(token,*,iostat=iret) x
  1591. end if
  1592. if ( iret .ne. 0 ) x = default
  1593. intget = nint(x)
  1594. !print *, intget
  1595. return
  1596. end function intget
  1597. !...................................................................
  1598. character(len=1) function chrget ( default )
  1599. implicit NONE
  1600. !-------------------------------------------------------------------------
  1601. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1602. !-------------------------------------------------------------------------
  1603. !BOP
  1604. !
  1605. ! !ROUTINE: ChrGet() --- Returns next character (Inpak 77).
  1606. !
  1607. ! !DESCRIPTION:
  1608. !
  1609. ! Returns next non-blank character from the current line, or a default
  1610. ! character if it fails for whatever reason.
  1611. ! Kept for Inpak 77 upward compatibility.
  1612. !
  1613. ! !CALLING SEQUENCE:
  1614. !
  1615. ! character*1 ch, default
  1616. ! ch = chrget ( default )
  1617. !
  1618. ! !INPUT PARAMETERS:
  1619. !
  1620. character*1 default ! default value.
  1621. !
  1622. ! !REVISION HISTORY:
  1623. !
  1624. ! 19Jun96 da Silva Original code.
  1625. !
  1626. !EOP
  1627. !-------------------------------------------------------------------------
  1628. character*256 token
  1629. integer iret
  1630. call i90_gtoken ( token, iret )
  1631. if ( iret .ne. 0 ) then
  1632. chrget = default
  1633. else
  1634. chrget = token(1:1)
  1635. end if
  1636. !print *, chrget
  1637. return
  1638. end function chrget
  1639. !...................................................................
  1640. subroutine TokGet ( token, default )
  1641. implicit NONE
  1642. !-------------------------------------------------------------------------
  1643. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1644. !-------------------------------------------------------------------------
  1645. !BOP
  1646. !
  1647. ! !ROUTINE: TokGet() --- Gets next token (Inpakk 77 like).
  1648. !
  1649. ! !DESCRIPTION:
  1650. !
  1651. ! Returns next token from the current line, or a default
  1652. ! word if it fails for whatever reason.
  1653. !
  1654. ! !CALLING SEQUENCE:
  1655. !
  1656. ! call TokGet ( token, default )
  1657. !
  1658. ! !INPUT PARAMETERS:
  1659. !
  1660. character*(*) default ! default token
  1661. ! !OUTPUT PARAMETERS:
  1662. !
  1663. character*(*) token ! desired token
  1664. !
  1665. ! !REVISION HISTORY:
  1666. !
  1667. ! 19Jun96 da Silva Original code.
  1668. !
  1669. !EOP
  1670. !-------------------------------------------------------------------------
  1671. integer iret
  1672. call i90_GToken ( token, iret )
  1673. if ( iret .ne. 0 ) then
  1674. token = default
  1675. end if
  1676. !print *, token
  1677. return
  1678. end subroutine tokget
  1679. !====================================================================
  1680. ! --------------------------
  1681. ! Obsolete Inpak 77 Routines
  1682. ! (Not Documented)
  1683. ! --------------------------
  1684. !...................................................................
  1685. subroutine iniin()
  1686. print *, &
  1687. 'i90: iniin() is obsolete, use i90_loadf() instead!'
  1688. return
  1689. end subroutine iniin
  1690. !...................................................................
  1691. subroutine iunits ( mifans, moftrm, moferr, miftrm )
  1692. integer mifans, moftrm, moferr, miftrm
  1693. print *, &
  1694. 'i90: iunits() is obsolete, use i90_loadf() instead!'
  1695. return
  1696. end subroutine iunits
  1697. !...................................................................
  1698. subroutine getstr ( iret, string )
  1699. implicit NONE
  1700. character*(*) string
  1701. integer iret !, ls
  1702. call i90_gstr ( string, iret )
  1703. return
  1704. end subroutine getstr
  1705. !...................................................................
  1706. subroutine getwrd ( iret, word )
  1707. implicit NONE
  1708. character*(*) word
  1709. integer iret
  1710. call i90_gtoken ( word, iret )
  1711. return
  1712. end subroutine getwrd
  1713. !...................................................................
  1714. subroutine rdnext ( iret )
  1715. implicit NONE
  1716. integer iret
  1717. call i90_gline ( iret )
  1718. return
  1719. end subroutine rdnext
  1720. !...................................................................
  1721. real(FP) function str2rn ( string, iret )
  1722. implicit NONE
  1723. character*(*) string
  1724. integer iret
  1725. read(string,*,end=11,err=11) str2rn
  1726. iret = 0
  1727. return
  1728. 11 iret = 1
  1729. return
  1730. end function str2rn
  1731. !...................................................................
  1732. subroutine strget ( string, default )
  1733. implicit NONE
  1734. !-------------------------------------------------------------------------
  1735. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  1736. !-------------------------------------------------------------------------
  1737. !
  1738. ! !ROUTINE: StrGet()
  1739. !
  1740. ! !DESCRIPTION:
  1741. !
  1742. ! Returns next string on the current line, or a default
  1743. ! string if it fails for whatever reason. Similar to {\tt i90\_gstr()}.
  1744. ! Kept for Inpak 77 upward compatibility.
  1745. !
  1746. ! NOTE: This is an obsolete routine. The notion of "string" used
  1747. ! here is not conventional. Please use routine {\tt TokGet()}
  1748. ! instead.
  1749. !
  1750. ! !CALLING SEQUENCE:
  1751. !
  1752. ! call strget ( string, default )
  1753. !
  1754. ! !INPUT PARAMETERS:
  1755. !
  1756. character*(*) default ! default string
  1757. ! !OUTPUT PARAMETERS:
  1758. character*(*) string ! desired string
  1759. !
  1760. ! !REVISION HISTORY:
  1761. !
  1762. ! 19Jun96 da Silva Original code.
  1763. ! 01Oct96 Jing Guo Removed the null terminitor
  1764. !
  1765. !-------------------------------------------------------------------------
  1766. integer iret
  1767. call i90_gstr ( string, iret )
  1768. if ( iret .ne. 0 ) then
  1769. string = default
  1770. end if
  1771. return
  1772. end subroutine strget
  1773. end module m_inpak90