## posix-environment.pkg
#
# A posix environment is a list of strings of the form "name=value",
# where the "=" character does not appear in "name".
#
# NOTE: Saving the user's environment in a Mythryl variable and then saving the
# heap image to disk and later reloading it can result in incorrect behavior,
# since the environment bound in the heap image may differ from the user's
# environment when the exported image is used.
# Compiled by:
#
src/lib/posix/posix.libstipulate
package ss = substring; # substring is from
src/lib/std/substring.pkg package psx = posixlib; # posixlib is from
src/lib/std/src/psx/posixlib.pkgherein
package posix_environment
: (weak) Posix_Environment # Posix_Environment is from
src/lib/posix/posix-environment.api {
stipulate
split = ss::split_off_prefix {. #c != '='; };
herein
# Given "name=value" return ("name","value"):
#
fun split_keyval s
=
{ my (a, b) = split (ss::from_string s);
#
if (ss::is_empty b) (s, "");
else (ss::to_string a, ss::to_string (ss::drop_first 1 b));
fi;
};
end;
# Return the value, if any,
# bound to the name:
#
fun get_from_env (given_name, env)
=
get env
where
#
fun get [] => NULL;
#
get (string ! rest)
=>
{ my (name, value) = split_keyval string;
#
if (name == given_name) THE value;
else get rest;
fi;
};
end;
end;
# Return the value bound to the name,
# or a default value
#
fun get_value { name, default, env }
=
case (get_from_env (name, env))
#
THE s => s;
NULL => default;
esac;
# Remove a name-value pair from an environment:
#
fun remove_from_env (name, env)
=
get env
where
fun get [] => [];
get (s ! r)
=>
{ my (n, v) = split_keyval s;
if (n == name) r;
else (s ! get r);
fi;
};
end;
end;
# Add a name-value pair to an environment,
# replacing any pre-existing pair which conflicts:
#
fun add_to_env (name_value, env)
=
get env
where
my (given_name, _) = split_keyval name_value;
fun get [] => [name_value];
get (string ! rest)
=>
{ my (name, value) = split_keyval string;
if (name == given_name) rest; # Drop conflicting name-value pair.
else (string ! get rest);
fi;
};
end;
end;
# Return the user's environment:
#
environ = psx::environment;
# Return the value of an environment variable
# in the user's environment:
#
fun get_env name
=
get_from_env (name, environ ());
};
end;