[m-dev.] call for volunteers: get_environment_var_map

Julien Fischer jfischer at opturion.com
Thu Aug 19 00:14:10 AEST 2021


Hi Zoltan,

On Wed, 18 Aug 2021, Zoltan Somogyi wrote:

> On Wed, 18 Aug 2021 22:53:29 +1000 (AEST), Julien Fischer <jfischer at opturion.com> wrote:
>> Sure, I'll add them.
>
> Thank you.
>
>> Rather than putting this facility in the compiler, we should consider
>> adding it alongside the other predicates that deal with the environment
>> in the io module, e.g. as io.get_environment/3.
>
> That is a good idea.
>
> At the moment, io.m is north of 13k lines of code. I think we should
> consider

Ideally, io.m should be broken up, but certainly not before the next
release.

>
> - adding this get_environment predicate to a new library module, named
>   probably env.m or environment.m,

I think environment.m.  Should that be a top-level module in the library
or a submodule of the io module?

> - moving the existing io.get_environment_var predicate to the
>  new module, leaving a forwarding predicate behind, and
>
> - adding an "obsolete in favour of" pragma for that forwarding predicate.

I'll do so in the next couple of days.

I have committed the diff below which implements get_envrionment_var_map
for C# and Java.  I suspect the C implementation is broken on macOS and
MinGW(?) (at least if the comments in the io module regarding the
environ global are up-to-date).

Julien.

--------------------------------

Implement get_environment_var_map for C# and Java.

compiler/options_file.m:
     As above.

diff --git a/compiler/options_file.m b/compiler/options_file.m
index dc4ac80..273dc95 100644
--- a/compiler/options_file.m
+++ b/compiler/options_file.m
@@ -1660,7 +1660,7 @@ get_environment_var_map(EnvVarMap, !IO) :-

  :- pragma foreign_proc("C",
      get_environment_var_assoc_list(EnvVarAL0::in, EnvVarAL::out,
-        IO0::di, IO::uo),
+        _IO0::di, _IO::uo),
      [may_call_mercury, promise_pure, tabled_for_io],
  "
      MR_Word cur_env = EnvVarAL0;
@@ -1673,27 +1673,36 @@ get_environment_var_map(EnvVarMap, !IO) :-
      }

      EnvVarAL = cur_env;
-    IO = IO0;
  ").

-/*
-Commented out until this has been tested.
  :- pragma foreign_proc("Java",
      get_environment_var_assoc_list(EnvVarAL0::in, EnvVarAL::out,
-        IO0::di, IO::uo),
-    [may_call_mercury, promise_pure, tabled_for_io],
+        _IO0::di, _IO::uo),
+    [may_call_mercury, promise_pure],
  "
-    Map<String, String> env = System.getenv();
-    for (String name : env.keySet()) {
-        String value = env.get(name);
-        MC_record_env_var_and_value(name, value, EnvVarAL0, EnvVarAL);
-        EnvVarAL0 = EnvVarAL;
+    EnvVarAL = EnvVarAL0;
+    java.util.Map<String, String> env = java.lang.System.getenv();
+    for (java.util.Map.Entry<String, String> entry : env.entrySet()) {
+        String name = entry.getKey();
+        String value = entry.getValue();
+        EnvVarAL = MC_record_env_var_and_value(name, value, EnvVarAL);
      }
-    IO = IO0;
  ").
-*/

-get_environment_var_assoc_list(_, [], !IO).
+:- pragma foreign_proc("C#",
+    get_environment_var_assoc_list(EnvVarAL0::in, EnvVarAL::out,
+        _IO0::di, _IO::uo),
+    [may_call_mercury, promise_pure],
+"
+    EnvVarAL = EnvVarAL0;
+    System.Collections.IDictionary env =
+        System.Environment.GetEnvironmentVariables();
+    foreach (System.Collections.DictionaryEntry entry in env) {
+        string name = (string) entry.Key;
+        string value = (string) entry.Value;
+        EnvVarAL = MC_record_env_var_and_value(name, value, EnvVarAL);
+    }
+").

  :- pred record_env_var_equal_value(string::in,
      env_var_assoc_list::in, env_var_assoc_list::out) is det.
@@ -1715,6 +1724,8 @@ record_env_var_equal_value(EnvVarNameEqValue, !EnvVarAL) :-
      env_var_assoc_list::in, env_var_assoc_list::out) is det.
  :- pragma foreign_export("C#", record_env_var_and_value(in, in, in, out),
      "MC_record_env_var_and_value").
+:- pragma foreign_export("Java", record_env_var_and_value(in, in, in, out),
+    "MC_record_env_var_and_value").

  record_env_var_and_value(EnvVarName, EnvVarValue, !EnvVarAL) :-
      !:EnvVarAL = [EnvVarName - EnvVarValue | !.EnvVarAL].


More information about the developers mailing list