PreviousUpNext

15.4.826  src/lib/posix/posix-environment.pkg

## 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.lib


stipulate
    package ss  =  substring;                                                   # substring                     is from   src/lib/std/substring.pkg
    package psx =  posixlib;                                                    # posixlib                              is from   src/lib/std/src/psx/posixlib.pkg
herein

    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;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext