ENVINT(), ENVDBLE(), ENVREAL(), ENVSTR(), ENVYN()
are Fortran wrappers calling the Cenvintc(), envdblec(), envrealc(), envstrc(), envync()
respectively.
New routines for I/O API-3.2 and later:BENVINT(), BENVINT8(), BENVDBLE(), BENVREAL()
are "bounded" versions ofENVINT(), ENVINT8(), ENVDBLE(), ENVREAL()
: instead of aDEFAULT
argument, they have threeMINVAL, MAXVAL, DEFAULT
arguments: the result is guaranteed to be betweenMINVAL
andMAXVAL
, out-of-range environment values will causeSTATUS=2
.Routine
ENVGET()
is a generic routine that can invoke any of the following:
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()
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.
These routines are wrappers around the getenv() system call: find, log, and return the value of shell variable/logical nameLNAME
from the environment , and interpret it in the appropriate manner (e.g., as anINTEGER
forENVINT()
), returningDEFAULT
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. ReturnsSTATUS
indicating the nature of theDEFAULT
returned.STATUS
takes the following values:
- 2 for out-of-bounds value, returning
DEFAULT
(forBENV*()
)- 1 for improperly formatted value, returning
DEFAULT
- 0 for normal value
- -1 for environment value set but empty (returning
DEFAULT
)- -2 for environment value not set (returning
DEFAULT
)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 haveMINVAL, MAXVAL
arguments and return a result within this indicated range.For Fortran-90 declarations and interface checking:
USE M3UTILIOSee also
ENVDBLE,
ENVINT and ENVINT8,
ENVREAL,
ENVSTR,
ENVYN,
NAMEVAL; and
SETENVVAR() for setting environment variables from within a program
.
USE M3UTILIO
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 ) ...
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] ...
Next: FINDC, FINDKEY, FIND1, FIND2, FIND3, FIND4, FINDR1, FINDR2, FINDR3, FINDR4
To: Models-3/EDSS I/O API: The Help Pages