ENVGET(), [B]ENV*() and env*c()

ENVINT(), ENVDBLE(), ENVREAL(), ENVSTR(), ENVYN() are Fortran wrappers calling the C envintc(), envdblec(), envrealc(), envstrc(), envync() respectively.

For I/O API Version 3.2 and later:

New routines for I/O API-3.2 and later: BENVINT(), BENVINT8(), BENVDBLE(), BENVREAL() are "bounded" versions of ENVINT(), ENVINT8(), ENVDBLE(), ENVREAL(): instead of a DEFAULT argument, they have three MINVAL, MAXVAL, DEFAULT arguments: the result is guaranteed to be between MINVAL and MAXVAL, out-of-range environment values will cause STATUS=2.

Routine ENVGET() is a generic routine that can invoke any of the following:

Fortran version:

INTERFACE ENVGET(... )      !! generic:  I/O API v3.2 or later, only

    !!...  REAL*8 (DOUBLE PRECISION) arguments MINVAL, MAXVAL, DEFAULT; return a REAL*8:

    DOUBLE PRECISION FUNCTION BENVDBLE( LNAME, DESCRIP, MINVAL, MAXVAL, DEFAULT, STATUS )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESC    ! description of the value
        REAL*8       , INTENT(IN   ) :: MINVAL
        REAL*8       , INTENT(IN   ) :: MAXVAL
        REAL*8       , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection
    DOUBLE PRECISION FUNCTION ENVDBLE( LNAME, DESCRIP, DEFAULT, STATUS )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESC    ! description of the value
        REAL*8       , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection

    !!...  INTEGER arguments; return a INTEGER:

    INTEGER FUNCTION BENVINT( LNAME, DESCRIP, MINVAL, MAXVAL, DEFAULT, STAT )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESC    ! description of the value
        INTEGER      , INTENT(IN   ) :: MINVAL
        INTEGER      , INTENT(IN   ) :: MAXVAL
        INTEGER      , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection
   INTEGER FUNCTION ENVINT( LNAME, DESCRIP, DEFAULT, STAT )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESC    ! description of the value
        INTEGER      , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection

    !!...  INTEGER(8) (64-bit) arguments; return a INTEGER(8):

    INTEGER(8) FUNCTION BENVINT8( LNAME, DESCRIP, MINVAL, MAXVAL, DEFAULT, STAT )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESC    ! description of the value
        INTEGER(8)   , INTENT(IN   ) :: MINVAL
        INTEGER(8)   , INTENT(IN   ) :: MAXVAL
        INTEGER(8)   , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection
   INTEGER(8) FUNCTION ENVINT8( LNAME, DESCRIP, DEFAULT, STAT )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESC    ! description of the value
        INTEGER(8)   , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection

    !!...  REAL arguments; return a REAL:

    REAL FUNCTION BENVREAL( LNAME, DESCRIP, MINVAL, MAXVAL, DEFAULT, STATUS )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESCRIP ! description of the value
        REAL         , INTENT(IN   ) :: MINVAL
        REAL         , INTENT(IN   ) :: MAXVAL
        REAL         , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection
    REAL FUNCTION ENVREAL( LNAME, DESCRIP, DEFAULT, STATUS )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESCRIP ! description of the value
        REAL         , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STAT    ! for error/default-case detection

    !!...  CHARACTER-string arguments; return a CHARACTER-string:

    SUBROUTINE ENVSTR( LNAME, DESCRIP, DEFAULT, EVALUE, STATUS )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESCRIP ! description of the value
        CHARACTER*(*), INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        CHARACTER*(*), INTENT(IN   ) :: EVALUE  ! result
        INTEGER      , INTENT(  OUT) :: STATUS  ! for error/default-case detection

    !!...  LOGICAL arguments; return a LOGICAL:
    !!...  Environment variable should have values from {T, F, Y, N}

    LOGICAL FUNCTION ENVYN( LNAME, DESCRIP, DEFAULT, STATUS )
        CHARACTER*(*), INTENT(IN   ) :: LNAME   ! logical name to evaluate
        CHARACTER*(*), INTENT(IN   ) :: DESCRIP ! description of the value
        LOGICAL      , INTENT(IN   ) :: DEFAULT ! default value (if LNAME not set, or empty)
        INTEGER      , INTENT(  OUT) :: STATUS  !  for distinguishing error/default-value cases

END INTERFACE           !! envget()

    !!...  CHARACTER-string arguments:

INTERFACE

    SUBROUTINE ENVSTR( LNAME, DESC, DEFAULT, EQNAME, STAT )
    CHARACTER*(*), INTENT(IN   ) :: LNAME
    CHARACTER*(*), INTENT(IN   ) :: DESC
    CHARACTER*(*), INTENT(IN   ) :: DEFAULT
    CHARACTER*(*), INTENT(  OUT) :: EQNAME
    INTEGER      , INTENT(  OUT) :: STAT
    END SUBROUTINE ENVSTR

END INTERFACE           !! envstr()

C versions:

double envdblec( const char * lname       ,
                 const char * description ,
                 double       defaultval  ,
                 int        * status )
int envintc( const char * lname       ,
             const char * description ,
             int          defaultval  ,
             int        * status )
int envint64c( const char * lname       ,
               const char * description ,
               int64_t      defaultval  ,
               int        * status )
float envrealc( const char * lname       ,
                const char * description ,
                float        defaultval  ,
                int        * status )
void envstrc( const char * lname        ,   /* logical name */
               const char * description ,   /* description */
               const char * defaultval  ,   /* default value */
               char       * evalue      ,   /* result buffer */
               int        * status      ,   /* error/default-case  */
               int          elen /* length of the "evalue" buffer */
	       )
int envync( const char * lname       , 
            const char * description , 
            int          defaultval  ,
            int        * status )
NOTE 1: envstrc() null-terminates the returned value iff its length is at most elen. Otherwise, it pads from the end of the value up to elen with ASCII NULLs (i.e., its behavior is similar to strncpy() ).

NOTE 2: It is a serious offense against good software engineering principles to use somethng meaningless (like a blank) as the description argument. Doing so may justifiably be taken as an attempt to make the code unreadable and unusable by anyone except the original author.

Summary:

These routines are wrappers around the getenv() system call: find, log, and return the value of shell variable/logical name LNAME from the environment , and interpret it in the appropriate manner (e.g., as an INTEGER for ENVINT()), returning DEFAULT if the logical name is not defined, is defined but has an empty value, or has an improper value. Writes a message to the log indicating the value returned -- and if the value was improper, writes a warning notice. Returns STATUS indicating the nature of the DEFAULT returned. STATUS takes the following values:

Note that the new ENVGET() generic routine acts as any of these, the compiler selecting which one is actually used on the basis of the types of the arguments.

Note that the new BENV*() routines also have MINVAL, MAXVAL arguments and return a result within this indicated range.

For Fortran-90 declarations and interface checking:

    USE M3UTILIO
    

See also

ENVDBLE,
ENVINT and ENVINT8,
ENVREAL,
ENVSTR,
ENVYN,
NAMEVAL; and
SETENVVAR() for setting environment variables from within a program
.

Preconditions:

USE M3UTILIO

Fortran Usage:

In the calling script, set program-control parameters for logical names FOO*:
...
setenv FOOC /work/qux/data
setenv FOOD 123.4D5
setenv FOOI 23
setenv FOOR 3.14159
setenv FOOY T
setenv FOON N
setenv FOO
...

Below are explicit-routine uses in the Fortran program. It is not necessary that the environment variable name be the same as the Fortran-program-variable name; however, it is good software engineering practice to do so where feasible.

    ...
    USE M3UTILIO
    ...
    CHARACTER*16, PARAMETER :: BLANK = ' '
    CHARACTER*256   FOOC
    INTEGER         FOOI, FOOJ, FOOK
    REAL            FOOR
    REAL*8          FOOD
    LOGICAL         FOOY
    INTEGER         STATUS
    ...
    !!  the following all return the environment value (23, etc...)
    !!  with STATUS = 0, normal environment value:
    !!  FOOI==23, FOOJ==23, FOOR=3.14159, FOOD=123.4D5, FOOY=.TRUE.
    !!  FOOC=='/work/qux/data'
    
    FOOI = ENVINT(  'FOOI', 'Env vble FOOI',        17, STATUS )
    FOOJ = BENVINT( 'FOOI', 'Env vble FOOI', 0, 30, 14, STATUS )
    FOOR = ENVREAL( 'FOOR', 'Env vble FOOR', 1.41424, STATUS )
    FOOD = ENVDBLE( 'FOOD', 'Env vble FOOD', 1.0d3,   STATUS )
    FOOY = ENVYN(   'FOOY', 'Env flag FOOY', .FALSE., STATUS )
    CALL   ENVSTR(  'FOOC;, 'Env string FOOC', BLANK, FOOC, STATUS )
    ...

    !!  the following return the default value, with STATUS = -1,
    !!  environment-variable set-but-empty
    !!  FOOI==17, FOOR==1.41424, FOOC=BLANK
    
    FOOI = ENVINT(  'FOO', 'Env vble FOO', 17, STATUS )
    FOOR = ENVREAL( 'FOO', 'Env vble FOO', 1.41424, STATUS )
    CALL   ENVSTR(  'FOO;, 'Env string FOO', BLANK, FOOC, STATUS )
    ...

    !!  the following return the default value, with STATUS = 1,
    !!  environment variable improperly formatted;
    !!  the FOOC-value '/work/qux/data' is not an INTEGER:
    
    FOOK = ENVINT( 'FOOC', 'Env vble FOOC', 17, STATUS )

    !!  the following returns the default value, with STATUS = -2,
    !!  environment-variable not set:  FOOJ==17
    
    FOOJ = ENVINT( 'BAR', 'Env vble BAR', 17, STATUS )

    !!  the following return the default value, with STATUS = 2,
    !!  environment-variable value out-of-bounds:
    !!  FOOJ==17, FOOR== 1.41424
    
    FOOJ = BENVINT( 'FOOI', 'Env vble FOOI', 0,   20,  17,      STATUS )
    FOOR = BENVREAL('FOOR', 'Env vble FOOR', 0.0, 2.0, 1.41424, STATUS )
    ...
    
and here are generic-routine uses in the Fortran program, equivalent to various of the calls in the explicit-routine code above:
    ...
    FOOI = ENVGET( 'FOOI', 'Env vble FOOI',        17, STATUS )
    FOOJ = ENVGET( 'FOOI', 'Env vble FOOI', 0, 30, 17, STATUS )
    FOOR = ENVGET( 'FOOR', 'Env vble FOOR', 1.41424, STATUS )
    FOOD = ENVGET( 'FOOD', 'Env vble FOOD', 1.0d3,   STATUS )
    FOOL = ENVGET( 'FOOY', 'Env flag FOOY', .FALSE., STATUS )
    CALL   ENVGET( 'FOOC', 'Env string FOOL', BLANK, FOOC,, STATUS )
    CALL   ENVGET( 'FOO',  'Env string FOOL', BLANK, FOOC,, STATUS )
    FOOL = ENVGET( 'FOOY', 'Env flag   FOOY', .FALSE., STATUS )    
    FOOJ = ENVGET( 'FOOI', 'Env vble FOOI', 0,   20,  17,      STATUS )
    FOOR = ENVGET( 'FOOR', 'Env vble FOOR', 0.0, 2.0, 1.41424, STATUS )
    ...

C Usage:

No generics; no equivalent to the BENV*()

Similar to the Fortran above:

#include "iodecl3.h"
...
int   status, ivalue, lvalue ;
double dvalue ;
float  rvalue ;
char   svalue[ 257 ] ;
...
ivalue =  envintc( "FOO",
                  "Here is where I put a description",
                  17 ,
                  & status ) )
if ( status  0 )
    {
    ... stuff for bad (non-integer) value of environment variable FOO
    }
else if ( status == -1 )
    {
    ... stuff for empty-but-defined FOO
    }
else if ( status == -2 )
    {
    ... stuff for not-defined-at-all FOO
    }
...
use ivalue...
...
dvalue = envdblec( "FOO",
                   "Here is where I put a description",
                   17.0 ,
                   & status ) )
...[and check status]
...
rvalue = envrealc( "FOO",
                   "Here is where I put a description",
                   17.0 ,
                   & status ) )
...[and check status]
...
lvalue =  envync( "FOOOFLAG", 
                  "Here is where I put a description",
                  0 ,
                  & status ) )
...[and check status]
...
if ( lvalue ) 
    {
    ... stuff for FOOFLAG TRUE
    }
else{
    ...stuff for FOOFLAG FALSE
    }
...
envstrc( "FOO", 
                  "Here is where I put a description",
                  "some_default",
                  svalue,
                  & status ) )
...[and check status]
...


Previous: DSCGRID

Next: FINDC, FINDKEY, FIND1, FIND2, FIND3, FIND4, FINDR1, FINDR2, FINDR3, FINDR4

Up: Utility Routines

To: Models-3/EDSS I/O API: The Help Pages