next up previous contents
Next: About this document ... Up: 3 Documentation of MPEU Previous: 19 InPackF90   Contents

Subsections

20 Package Overview

Inpak 90 is a Fortran (77/90) collection of routines/functions for accessing Resource Files in ASCII format. The package is optimized for minimizing formatted I/O, performing all of its string operations in memory using Fortran intrinsic functions.

20.1 Resource Files

A Resource File is a text file consisting of variable length lines (records), each possibly starting with a label (or key), followed by some data. A simple resource file looks like this:

   # Lines starting with # are comments which are
   # ignored during processing.
   my_file_names:         jan87.dat jan88.dat jan89.dat
   radius_of_the_earth:   6.37E6  # these are comments too
   constants:             3.1415   25
   my_favourite_colors:   green blue 022 # text & number are OK

In this example, my_file_names: and constants: are labels, while jan87.dat, jan88.dat and jan89.dat are data associated with label my_file_names:. Resource files can also contain simple tables of the form,

   my_table_name::
    1000     3000     263.0   
     925     3000     263.0
     850     3000     263.0
     700     3000     269.0
     500     3000     287.0
     400     3000     295.8
     300     3000     295.8    
   ::

Resource files are random access, the particular order of the records are not important (except between ::s in a table definition).

20.2 A Quick Stroll

The first step is to load the ASCII resource (rc) file into memory1:

         call i90_LoadF ( 'my_file.rc', iret )

The next step is to select the label (record) of interest, say

         call i90_label ( 'constants:', iret )

The 2 constants above can be retrieved with the following code fragment:

         real    r
         integer i
         call i90_label ( 'constants:', iret )
         r = i90_gfloat(iret)    ! results in r = 3.1415
         i = i90_gint(iret)      ! results in i = 25

The file names above can be retrieved with the following code fragment:

         character*20 fn1, fn2, fn3
         integer      iret
         call i90_label ( 'my_file_names:', iret )
         call i90_Gtoken ( fn1, iret )  ! ==> fn1 = 'jan87.dat'
         call i90_Gtoken ( fn2, iret )  ! ==> fn1 = 'jan88.dat'
         call i90_Gtoken ( fn3, iret )  ! ==> fn1 = 'jan89.dat'

To access the table above, the user first must use i90_label() to locate the beginning of the table, e.g.,

         call i90_label ( 'my_table_name::', iret )

Subsequently, i90_gline() can be used to gain access to each row of the table. Here is a code fragment to read the above table (7 rows, 3 columns):

         real          table(7,3)
         character*20  word
         integer       iret
         call i90_label ( 'my_table_name::', iret )
         do i = 1, 7
            call i90_gline ( iret )
            do j = 1, 3
               table(i,j) = i90_gfloat ( iret )
            end do                   
         end do

Get the idea?

20.3 Main Routine/Functions

    ------------------------------------------------------------------
           Routine/Function                  Description
    ------------------------------------------------------------------
    I90_LoadF ( filen, iret )     loads resource file into memory
    I90_Label ( label, iret )     selects a label (key)
    I90_GLine ( iret )            selects next line (for tables)
    I90_Gtoken ( word, iret )     get next token 
    I90_Gfloat ( iret )           returns next float number (function)
    I90_GInt ( iret )             returns next integer number (function)
    i90_AtoF ( string, iret )     ASCII to float (function)
    i90_AtoI ( string, iret )     ASCII to integer (function)
    I90_Len ( string )            string length without trailing blanks
    LabLin ( label )              similar to i90_label (no iret)
    FltGet ( default )            returns next float number (function)
    IntGet ( default )            returns next integer number (function)
    ChrGet ( default )            returns next character (function)
    TokGet ( string, default )    get next token
    ------------------------------------------------------------------

Common Arguments:

   character*(*)      filen       file name
   integer            iret        error return code (0 is OK)
   character*(*)      label       label (key) to locate record
   character*(*)      word        blank delimited string
   character*(*)      string      a sequence of characters

See the Prologues in the next section for additional details.

20.4 Package History

Back in the 70s Eli Isaacson wrote IOPACK in Fortran 66. In June of 1987 I wrote Inpak77 using Fortran 77 string functions; Inpak 77 is a vastly simplified IOPACK, but has its own goodies not found in IOPACK. Inpak 90 removes some obsolete functionality in Inpak77, and parses the whole resource file in memory for performance. Despite its name, Inpak 90 compiles fine under any modern Fortran 77 compiler.

20.5 Bugs

Inpak 90 is not very gracious with error messages. The interactive functionality of Inpak77 has not been implemented. The comment character # cannot be escaped.

20.6 Availability

This software is available at

           ftp://niteroi.gsfc.nasa.gov/pub/packages/i90/
There you will find the following files:
   i90.f      Fortran 77/90 source code
   i90.h      Include file needed by i90.f
   ti90.f     Test code
   i90.ps     Postscript documentation
An on-line version of this document is available at
          ftp://niteroi.gsfc.nasa.gov/www/packages/i90/i90.html

20.6.1 I90_allLoadF - populate a rooted database to all PEs


INTERFACE:

 
     subroutine I90_allLoadF(fname,root,comm,istat)
       use m_mpif90, only : MP_perr
       use m_mpif90, only : MP_comm_rank
       use m_mpif90, only : MP_CHARACTER
       use m_mpif90, only : MP_INTEGER
       use m_die, only : perr
       implicit none
       character(len=*),intent(in) :: fname
       integer,intent(in) :: root
       integer,intent(in) :: comm
       integer,intent(out) :: istat
REVISION HISTORY:
   	28Jul98 - Jing Guo <guo@thunder> - initial prototype/prolog/code

20.6.2 push_ - push on a new layer of the internal file _i90_now_


INTERFACE:

 
     subroutine push_(ier)
       use m_die, only : perr
       use m_mall,only : mall_mci,mall_ci,mall_ison
       implicit none
       integer,intent(out) :: ier
REVISION HISTORY:
   	05Aug98 - Jing Guo <guo@thunder> - initial prototype/prolog/code

20.6.3 pop_ - pop off a layer of the internal file _i90_now_


INTERFACE:

 
     subroutine pop_(ier)
       use m_die, only : perr
       use m_mall,only : mall_mco,mall_co,mall_ison
       implicit none
       integer,intent(out) :: ier
REVISION HISTORY:
   	05Aug98 - Jing Guo <guo@thunder> - initial prototype/prolog/code

20.6.4 i90_fullRelease - releases the whole stack led by _i90_now_


INTERFACE:

 
     subroutine i90_fullRelease(ier)
       use m_die,only : perr
       implicit none
       integer,intent(out) :: ier
REVISION HISTORY:
   	05Aug98 - Jing Guo <guo@thunder> - initial prototype/prolog/code

20.7 I90_LoadF() -- Loads resource file into memory. (Source File: m_inpak90.F90)

Reads resource file, strips out comments, translate TABs into blanks, and loads the modified file contents into memory. Must be called only once for each resource file.


CALLING SEQUENCE:

       call i90_LoadF ( filen, iret )
INPUT PARAMETERS:
       character*(*) filen            ! file name
OUTPUT PARAMETERS:
 
       integer       iret             ! Return code:
                                      !   0    no error
                                      ! -98    coult not get unit number
                                      !        (strange!)
                                      ! -98    talk to a wizzard
                                      ! -99    out of memory: increase
                                      !        NBUF_MAX in 'i90.h'
                                      ! other  iostat from open statement.
BUGS:
    It does not perform dynamic allocation, mostly to keep vanilla f77
    compatibility. Overall amount of static memory is small (~100K
    for default NBUF_MAX = 400*256).
SEE ALSO:
    i90_label()   selects a label (key)
FILES USED:
    File name supplied on input. The file is opened, read and then closed.
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.8 I90_Label() -- Selects a label (record). (Source File: m_inpak90.F90)

Once the buffer has been loaded with i90_loadf(), this routine selects a given ``line'' (record/table) associated with ``label''. Think of ``label'' as a resource name or data base ``key''.


CALLING SEQUENCE:

             
       call i90_Label ( label, iret )
INPUT PARAMETERS:
       character(len=*),intent(in) :: label            ! input label
OUTPUT PARAMETERS:
 
       integer       iret             ! Return code:
                                      !   0    no error
                                      !  -1    buffer not loaded
                                      !  -2    could not find label
SEE ALSO:
    i90_loadf()    load file into buffer
    i90_gtoken()   get next token
    i90_gline()    get next line (for tables)
    atof()         convert word (string) to float
    atoi()         convert word (string) to integer
REVISION HISTORY:
    19Jun96   da Silva   Original code.
    19Jan01   Jay Larson <[email protected]> - introduced CHARACTER 
              variable EOL_label, which is used to circumvent pgf90
              problems with passing concatenated characters as an argument
              to a function.

20.9 I90_GLine() -- Selects next line. (Source File: m_inpak90.F90)

Selects next line, irrespective of of label. If the next line starts with :: (end of table mark), then it lets the user know. This sequential access of the buffer is useful to assess tables, a concept introduced in Inpak 77 by Jing Guo. A table is a construct like this:

   my_table_name::
    1000     3000     263.0   
     925     3000     263.0
     850     3000     263.0
     700     3000     269.0
     500     3000     287.0
     400     3000     295.8
     300     3000     295.8    
   ::

To access this table, the user first must use i90_label() to locate the beginning of the table, e.g.,

         call i90_label ( 'my_table_name::', iret )

Subsequently, i90_gline() can be used to gain acess to each row of the table. Here is a code fragment to read the above table (7 rows, 3 columns):

         real          table(7,3)
         character*20  word
         integer       iret
         call i90_label ( 'my_table_name::', iret )
         do i = 1, 7
            call i90_gline ( iret )
            do j = 1, 3
               table(i,j) = fltget ( 0. )
            end do                   
         end do

For simplicity we have assumed that the dimensions of table were known. It is relatively simple to infer the table dimensions by manipulating ``iret''.


CALLING SEQUENCE:

       call i90_gline ( iret )
INPUT PARAMETERS:
       None.
OUTPUT PARAMETERS:
       integer       iret             ! Return code:
                                      !   0    no error
                                      !  -1    end of buffer reached
                                      !  +1    end of table  reached
SEE ALSO:
    i90_label()    selects a line (record/table)
REVISION HISTORY:
    10feb95   Guo        Wrote rdnext(), Inpak 77 extension.
    19Jun96   da Silva   Original code with functionality of rdnext()

20.10 I90_GToken() -- Gets next token. (Source File: m_inpak90.F90)

Get next token from current line. The current line is defined by a call to i90_label(). Tokens are sequences of characters (including blanks) which may be enclosed by single or double quotes. If no quotes are present, the token from the current position to the next blank of TAB is returned.

Examples of valid token:

                 single_token "second token on line"
                 "this is a token"
                 'Another example of a token'
                 'this is how you get a " inside a token'
                 "this is how you get a ' inside a token"
                 This is valid too   # the line ends before the #
The last line has 4 valid tokens: This, is, valid and too.

Invalid string constructs:

                 cannot handle mixed quotes (i.e. single/double)
                 'escaping like this \' is not implemented'
                 'this # will not work because of the #'
The # character is reserved for comments and cannot be included inside quotation marks.


CALLING SEQUENCE:

       call i90_GToken ( token, iret )
INPUT PARAMETERS:
       None.
OUTPUT PARAMETERS:
       character*(*) token            ! Next token from current line
       integer       iret             ! Return code:
                                      !   0    no error
                                      !  -1    either nothing left
                                      !        on line or mismatched
                                      !        quotation marks.
BUGS:
       Standard Unix escaping is not implemented at the moment.
SEE ALSO:
    i90_label()    selects a line (record/table)
    i90_gline()    get next line (for tables)
    atof()         convert word (string) to float
    atoi()         convert word (string) to integer
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.11 i90_GFloat() -- Returns next float number. (Source File: m_inpak90.F90)

Returns next float (real number) from the current line. If an error occurs a zero value is returned.


CALLING SEQUENCE:

        real  rnumber
        rnumber = i90_gfloat ( default )
OUTPUT PARAMETERS:
       integer,intent(out) :: iret    ! Return code:
                                      !   0    no error
                                      !  -1    either nothing left
                                      !        on line or mismatched
                                      !        quotation marks.
                                      !  -2    parsing error
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.12 I90_GInt() -- Returns next integer number. (Source File: m_inpak90.F90)

Returns next integer number from the current line. If an error occurs a zero value is returned.


CALLING SEQUENCE:

        integer number
        number = i90_gint ( default )
OUTPUT PARAMETERS:
       integer       iret             ! Return code:
                                      !   0    no error
                                      !  -1    either nothing left
                                      !        on line or mismatched
                                      !        quotation marks.
                                      !  -2    parsing error
REVISION HISTORY:
    19Jun96   da Silva   Original code.
    24may00   da Silva   delcared x as real*8 in case this module is compiled
                         with real*4

20.13 i90_AtoF() -- Translates ASCII (string) to float. (Source File: m_inpak90.F90)

Converts string to real number. Same as obsolete str2rn().


CALLING SEQUENCE:

       real  rnumber
       rnumber = i90_atof ( string, iret )
INPUT PARAMETERS:
       character(len=*),intent(in) :: string           ! a string
OUTPUT PARAMETERS:
       integer,intent(out) :: iret    ! Return code:
                                      !   0    no error
                                      !  -1    could not convert, probably
                                      !        string is not a number
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.14 I90_AtoI() -- Translates ASCII (strings) to integer. (Source File: m_inpak90.F90)

Converts string to integer number.


CALLING SEQUENCE:

       integer number
       number = i90_atoi ( string, iret )
INPUT PARAMETERS:
       character*(*) string           ! a string
OUTPUT PARAMETERS:
       integer       iret             ! Return code:
                                      !   0    no error
                                      !  -1    could not convert, probably
                                      !        string is not a number
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.15 I90_Len() -- Returns length of string. (Source File: m_inpak90.F90)

Returns the length of a string excluding trailing blanks. It follows that

                i90_len(string) .le. len(string),
where len is the intrinsic string length function. Example:
           ls = len('abc  ')       ! results in ls = 5
           ls = i90_len ('abc  ')  ! results in ls = 3


CALLING SEQUENCE:

         integer ls
         ls = i90_len ( string )
INPUT PARAMETERS:
          character*(*)   string     ! a string
OUTPUT PARAMETERS:
          The length of the string, excluding trailing blanks.
REVISION HISTORY:
    01Apr94   Guo        Original code (a.k.a. luavail())
    19Jun96   da Silva   Minor modification + prologue.

20.16 I90_Lua() -- Returns available logical unit number. (Source File: m_inpak90.F90)

Look for an available (not opened) Fortran logical unit for i/o.


CALLING SEQUENCE:

         integer lu
         lu = i90_lua()
INPUT PARAMETERS:
         None.
OUTPUT PARAMETERS:
         The desired unit number if positive, -1 if unsucessful.
REVISION HISTORY:
    01Apr94   Guo        Original code (a.k.a. luavail())
    19Jun96   da Silva   Minor modification + prologue.

20.17 I90_Pad() -- Pad strings. (Source File: m_inpak90.F90)

Pads from the right with the comment character (#). It also replaces TABs with blanks for convenience. This is a low level i90 routine.


CALLING SEQUENCE:

        call i90_pad ( string )
INPUT PARAMETERS:
        character*256 string       ! input string
OUTPUT PARAMETERS:
        character*256 string
BUGS:
        It alters TABs even inside strings.
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.18 I90_Trim() - Removes leading blanks from strings. (Source File: m_inpak90.F90)

Removes blanks and TABS from begenning of string. This is a low level i90 routine.


CALLING SEQUENCE:

       call i90_Trim ( string )
INPUT PARAMETERS:
       character*256 string    ! the input string
OUTPUT PARAMETERS:
       character*256 string    ! the modified string
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.19 Lablin() -- Selects a Label (Inpak 77) (Source File: m_inpak90.F90)

Selects a given ``line'' (record/table) associated with ``label''. Similar to i90_label(), but prints a message to stdout if it cannot locate the label. Kept for Inpak 77 upward compatibility.


CALLING SEQUENCE:

       call lablin ( label )
INPUT PARAMETERS:
 
       character(len=*),intent(in) :: label   ! string with label name
OUTPUT PARAMETERS:
      None.
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.20 FltGetsp() -- Returns next float (Inpak 77, single precision) (Source File: m_inpak90.F90)

Returns next float (real number, single precision) from the current line, or a default value if it fails to obtain the desired number. Kept for Inpak 77 upward compatibility.


CALLING SEQUENCE:

        real  rnumber, default
        rnumber = fltgetsp ( default )
INPUT PARAMETERS:
       real(SP), intent(IN) ::    default       ! default value.
REVISION HISTORY:
    19Jun96   da Silva   Original code.
    12Oct99   Guo/Larson - Built from original FltGet() function.

20.21 FltGetdp() -- Returns next float (Inpak 77) (Source File: m_inpak90.F90)

Returns next float (real number) from the current line, or a default value (double precision) if it fails to obtain the desired number. Kept for Inpak 77 upward compatibility.


CALLING SEQUENCE:

        real(DP) :: default
        real :: rnumber 
        rnumber = FltGetdp(default)
INPUT PARAMETERS:
       real(DP), intent(IN) ::    default       ! default value.
REVISION HISTORY:
    19Jun96   da Silva   Original code.
    12Oct99   Guo/Larson - Built from original FltGet() function.

20.22 IntGet() -- Returns next integer (Inpak 77). (Source File: m_inpak90.F90)

Returns next integer number from the current line, or a default value if it fails to obtain the desired number. Kept for Inpak 77 upward compatibility.


CALLING SEQUENCE:

        integer number, default
        number = intget ( default )
INPUT PARAMETERS:
        integer     default       ! default value.
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.23 ChrGet() -- Returns next character (Inpak 77). (Source File: m_inpak90.F90)

Returns next non-blank character from the current line, or a default character if it fails for whatever reason. Kept for Inpak 77 upward compatibility.


CALLING SEQUENCE:

       character*1 ch, default
       ch = chrget ( default )
INPUT PARAMETERS:
       character*1    default       ! default value.
REVISION HISTORY:
    19Jun96   da Silva   Original code.

20.24 TokGet() -- Gets next token (Inpakk 77 like). (Source File: m_inpak90.F90)

Returns next token from the current line, or a default word if it fails for whatever reason.


CALLING SEQUENCE:

        call TokGet ( token, default )
INPUT PARAMETERS:
        character*(*) default     ! default token
OUTPUT PARAMETERS:
        character*(*) token       ! desired token
REVISION HISTORY:
    19Jun96   da Silva   Original code.



next up previous contents
Next: About this document ... Up: 3 Documentation of MPEU Previous: 19 InPackF90   Contents
[email protected]