|
LCS-2016-006d |
|
1 {06-Feb-2017} 2 {22-Feb-2017} 3 {02-Mar-2017} 4 {06-Mar-2017} |
|
06-Mar-2017 |
|
Voting |
|
Patrick Lehmann |
|
Main.PatrickLehmann |
|
|
|
Allow access to system environment variables and conditional analysis identifiers. |
|
LCS-2016-061 |
package ENV is procedure STOP (STATUS: INTEGER); procedure STOP; procedure FINISH (STATUS: INTEGER); procedure FINISH; function RESOLUTION_LIMIT return DELAY_LENGTH; [... LCS-2016-011 ...] [... LCS-2016-006c ...] type ENV_VARIABLE_NAMES is access LINE_VECTOR; -- The predefined operations for this type are as follows: -- function"=" (anonymous, anonymous: ENV_VARIABLE_NAMES) return BOOLEAN; -- function"/=" (anonymous, anonymous: ENV_VARIABLE_NAMES) return BOOLEAN; -- procedure DEALLOCATE (P: inout ENV_VARIABLE_NAMES); type COND_ANALYSIS_IDS is access LINE_VECTOR; -- The predefined operations for this type are as follows: -- function"=" (anonymous, anonymous: COND_ANALYSIS_IDS) return BOOLEAN; -- function"/=" (anonymous, anonymous: COND_ANALYSIS_IDS) return BOOLEAN; -- procedure DEALLOCATE (P: inout COND_ANALYSIS_IDS); type ENVIRONMENT is record -- Resolution_Limit : DELAY_LENGTH; -- Variables : ENV_VARIABLE_NAMES; -- list of pointers to environment variable names Identifiers : COND_ANALYSIS_IDS; -- list of pointers to conditional analysis identifiers end record; procedure ENV_OPEN(Env : out ENVIRONMENT); impure function ENV_OPEN return ENVIRONMENT; procedure ENV_CLOSE(Names : in ENVIRONMENT); -- deallocate all internal access values procedure ENV_GETVARIABLE(Value : out LINE; Name : in STRING; Good : out BOOLEAN); impure function ENV_GETVARIABLE(Name : in STRING; Good : out BOOLEAN) return LINE; impure function ENV_GETVARIABLE(Name : in STRING) return LINE; impure function ENV_GETVARIABLE(Name : in STRING; Good : out BOOLEAN) return STRING; impure function ENV_GETVARIABLE(Name : in STRING) return STRING; procedure ENV_GETIDENTIFIER(Value : out LINE; Name : in STRING; Good : out BOOLEAN); impure function ENV_GETIDENTIFIER(Name : in STRING; Good : out BOOLEAN) return LINE; impure function ENV_GETIDENTIFIER(Name : in STRING) return LINE; impure function ENV_GETIDENTIFIER(Name : in STRING; Good : out BOOLEAN) return STRING; impure function ENV_GETIDENTIFIER(Name : in STRING) return STRING; type CONDITIONAL_ANALYSIS_IDENTIFIER is record VHDL_Version : STRING; -- see 24.2 Conditional Analysis Tool Directives Tool_Type : STRING; -- see 24.2 Conditional Analysis Tool Directives Tool_Vendor : STRING; -- see 24.2 Conditional Analysis Tool Directives Tool_Name : STRING; -- see 24.2 Conditional Analysis Tool Directives Tool_Edition : STRING; -- see 24.2 Conditional Analysis Tool Directives Tool_Version : STRING; -- see 24.2 Conditional Analysis Tool Directives end record; constant COND_ANALYSIS_ID : CONDITIONAL_ANALYSIS_IDENTIFIER; end package ENV;[Editor note: Three notes ...]
procedure ENV_GETVALUE(Name : in STRING; Value : out STRING; Good : out BOOLEAN); impure function ENV_GETVALUE(Name : in STRING) return STRING;But I can't see a scenario where I need anything more complex than that from VHDL. -- Rob Gaddi - 2017-02-06 For the procedure, I think it needs STRLEN (like sread) rather than Good. Like sread, if there is an error, STRLEN = 0.
procedure ENV_GETVALUE(Name : in STRING; Value : out STRING; STRLEN : out Natural);I agree with Rob about the procedure though -- Jim Lewis - 2017-02-06 So I need to return either a size or a LINE parameter, right? Some users demanded that the values for the conditional compilation should be available in code too. By adding all the identifiers from 24.2 this demand is fulfilled. I think a user should have access to all available environment variable names. If I start to use such a feature in a language, I get quickly to the point that I can't list all available variables. -- Patrick Lehmann - 2017-02-07 IMHO this appears too big a hack right now. Too many compromises to make it work with the current version of VHDL. The record
ENVIRONMENT
appears especially obscure
to me as it is an artificial join of the identifiers for conditional compilation (CC) and the OS environment variables both delivered through different abstractions.
Some kind of a map abstraction would be appropriate in both cases so as to warrant maximum flexibility. LCS 061 allows to have a CC identifier set extended by the tool
or the user. The current approach leaves those inaccessible. With what we have in VHDL, the map abstraction is best represented by a function. So, I would expect a
core set of functions like this:
function GETENV(name : in string) return string; -- would have to return an empty string for a name not defined in the environment
OR closely following the POSIX function:
function GETENV(name : in string) return line; -- returns null for a name not defined in the environment
AND, a similar access to CC identifiers:
function GETDEF(name : in string) return string/line;
Optionally, you might want to consider to give access to a list of defined names. I think functions returning a line_vector
would be most appropriate:
function GETENV_NAMES return line_vector; function GETDEF_NAMES return line_vector;-- Thomas Preusser - 2017-02-07 "For the procedure, I think it needs STRLEN (like sread) rather than Good. Like sread, if there is an error, STRLEN = 0. " But what if the variable exists, and is empty? e.g. setenv MYLIST "" I think the STRLEN should be -1 in case of an error, 0 in case of empty. I would vote definately YES on the impure function. -- Jakko Verhallen - 2017-02-07 WRT the names defined by conditional compilation, why not create a set of similarly named deferred constants here in the package std.env? -- Jim Lewis - 2017-02-10 @Jim: Introducing such constants may help for the standard identifiers, which Patrick also included in this environment record. Both approaches are not really suitable to cope with tool- and user-defined identifiers. At least I would avoid having a record type or set of pre-defined constants that are adjusted in each run to reflect the currently defined set of conditional compilation identifiers. IMHO, a lookup mechanism just as used by Patrick for the environment variables should be provided for conditional compilation identifiers as well. This:
impure function ENV_GETVARIABLE(Name : in STRING; Good : out BOOLEAN) return STRING; impure function ENV_GETIDENTIFIER(Name : in STRING; Good : out BOOLEAN) return STRING;The definition for
ENV_GETVARIABLE
is (ENV_GETIDENTIFIER
is similar):
The overloaded impure function ENV_GETVARIABLE, with parameters Name and Good returning type STRING, implements the same behavior as the impure function ENV_GETVARIABLE, with parameters Name and Good returning type LINE. The function returns the designated object: an object of type STRING.
But, if the environment variable denoted by Name is not availbale in the host environment, then the function ENV_GETVARIABLE(Name : in STRING; Good : out BOOLEAN) return LINE;
returns a null access value. Thus, the function above cannot return the designated object (as already expressed in my private e-mail to you before). There are two options here:
ENV_GETVARIABLE(Name : in STRING) return STRING;
.)
""
, and check for existence using Good.
constant Name : string := "test"; variable Value : line; variable Good : boolean; ... ENV_GETVARIABLE(Value, Name, Good);could be simply replaced by:
Value := ENV_GETVARIABLE(Name, Good);And this call could be even more simplified to:
Value := ENV_GETVARIABLE(Name);because the out parameter Good is never needed. Whether the variable exists in the host environment or not could be simply determined by the returned Value:
Value := ENV_GETVARIABLE(Name); if Value = null then report "Environment variable does not exist in host environment." severity error; elsif Value.all = "" then report "Environment variable is defined but empty."; else report "Environment variable has value: " & Value.all; end if;The discussion for the function
ENV_GETVARIABLE(Name : in STRING; Good : out BOOLEAN) return STRING;"
depends on how the undefined behavior is solved:
ENV_GETVARIABLE(Name : in STRING) return STRING;"
.
ENV_GETVARIABLE(Name : in STRING) return STRING;
is fine, especially, if the (synthesis) tool does not support access types.
Thus, the only required functions are:
impure function ENV_GETVARIABLE(Name : in STRING) return LINE; impure function ENV_GETVARIABLE(Name : in STRING) return STRING;Same discussion applies to ENV_GETIDENTIFIER. 2) Why should there be a function
ENV_OPEN
and a procedure ENV_OEPN
?
3) Why are there two types ENV_VARIABLE_NAMES
and COND_ANALYSIS_IDS
representing both an access type of LINE_VECTOR
?
4) According to the LCS text, the type ENVIRONMENT
does describe the current tool environment. But why does it contain only the identifiers and not also the values?
Added later:
5) I find writing something like if COND_ANALYSIS_ID.Tool_Type = "SIMULATION" then
just too long. The prefix COND_ANALYSIS_ID
is also hard to remember. I prefer LCS 006f instead.
-- Martin Zabel - 2017-03-07