/*---------------------------------------------------------------------------
  Copyright 2012-2021, Microsoft Research, Daan Leijen.

  This is free software; you can redistribute it and/or modify it under the
  terms of the Apache License, Version 2.0. A copy of the License can be
  found in the LICENSE file at the root of this distribution.
---------------------------------------------------------------------------*/

/*
Access to the program environment and command line arguments.

Print the environment: `get-env().map(fn(p) { p.fst + "=" + p.snd }).join("\n").print`
*/
module std/os/envstd/os/env

import std/os/pathstd/os/path

pub alias envstd/os/env/env: V = liststd/core/types/list: V -> V<(std/core/types/tuple2: (V, V) -> Vstringstd/core/types/string: V,stringstd/core/types/string: V)>

val environstd/os/env/environ: delayed<ndet,env> : delayedstd/core/delayed/delayed: (E, V) -> V<<std/core/types/total: Endetstd/core/types/ndet: X>,envstd/os/env/env: V> = delaystd/core/delayed/delay: (action : () -> ndet env) -> delayed<ndet,env>{ os-get-envstd/os/env/os-get-env: () -> ndet vector<string>().liststd/core/vector/list: (v : vector<string>) -> ndet list<string>.to-tuplesstd/os/env/to-tuples: (xs : list<string>) -> ndet env }

fun to-tuplesstd/os/env/to-tuples: (xs : list<string>) -> env( xsxs: list<string> : liststd/core/types/list: V -> V<stringstd/core/types/string: V> )result: -> total env : envstd/os/env/env: V
  match(xsxs: list<string>)
    Consstd/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(namename: string,Consstd/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(valuevalue: string,xxxx: list<string>)) -> Consstd/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>((std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)namename: string,valuevalue: string)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b), xxxx: list<string>.to-tuplesstd/os/env/to-tuples: (xs : list<string>) -> env)
    Consstd/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(namename: string,Nilstd/core/types/Nil: forall<a> list<a>)            -> [std/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)namename: string,""literal: string
count= 0
)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)]std/core/types/Nil: forall<a> list<a> Nilstd/core/types/Nil: forall<a> list<a> -> [std/core/types/Nil: forall<a> list<a>
]std/core/types/Nil: forall<a> list<a> extern os-get-envstd/os/env/os-get-env: () -> ndet vector<string>() : ndetstd/core/types/ndet: X vectorstd/core/types/vector: V -> V<stringstd/core/types/string: V> // vector as [name1,value1,...,nameN,valueN] c "kk_os_get_env" js inline "(typeof process !== 'undefined' ? (function(){ var env = []; Object.keys(process.env).forEach(function(name){ env.push(name); env.push(process.env[name]); }); return env; })() : [])" // Get the environment variables for this program pub fun get-envstd/os/env/get-env: () -> ndet env()result: -> ndet env : ndetstd/core/types/ndet: X envstd/os/env/env: V environstd/os/env/environ: delayed<ndet,env>.forcestd/core/delayed/force: (delayed : delayed<ndet,env>) -> ndet env // Returns the value of an environment variable `name` (or `Nothing` if not present) pub fun get-env-valuestd/os/env/get-env-value: (name : string) -> ndet maybe<string>( namename: string : stringstd/core/types/string: V )result: -> ndet maybe<string> : ndetstd/core/types/ndet: X maybestd/core/types/maybe: V -> V<stringstd/core/types/string: V> get-envstd/os/env/get-env: () -> ndet env().lookupstd/core/list/lookup: (xs : list<(string, string)>, pred : (string) -> ndet bool) -> ndet maybe<string>(fnfn: (nm : string) -> ndet bool(nmnm: string){ nmnm: string ==std/core/string/(==): (string, string) -> ndet bool namename: string }) val argvstd/os/env/argv: delayed<ndet,list<string>> : delayedstd/core/delayed/delayed: (E, V) -> V<<std/core/types/total: Endetstd/core/types/ndet: X>,liststd/core/types/list: V -> V<stringstd/core/types/string: V>> = delaystd/core/delayed/delay: (action : () -> ndet list<string>) -> delayed<ndet,list<string>>{ os-get-argvstd/os/env/os-get-argv: () -> ndet vector<string>().liststd/core/vector/list: (v : vector<string>) -> ndet list<string> } extern os-get-argvstd/os/env/os-get-argv: () -> ndet vector<string>() : ndetstd/core/types/ndet: X vectorstd/core/types/vector: V -> V<stringstd/core/types/string: V> c "kk_os_get_argv" cs "System.Environment.GetCommandLineArgs" js inline "(typeof process !== 'undefined' ? process.argv : [])" // The unprocessed command line that was used to start this program. // On ''Node'' the first arguments will often be of the form `["node","interactive.js",...]`. pub fun get-argvstd/os/env/get-argv: () -> ndet list<string>()result: -> ndet list<string> : ndetstd/core/types/ndet: X liststd/core/types/list: V -> V<stringstd/core/types/string: V> argvstd/os/env/argv: delayed<ndet,list<string>>.forcestd/core/delayed/force: (delayed : delayed<ndet,list<string>>) -> ndet list<string> // Return the arguments that were passed to program itself. // Strips off the initial program from the unprocessed command line. // i.e. If a program started as: // ```` // > node myprogram.js --flag bla // ```` // The `arguments` list will be `["--flag","bla"]` pub fun get-argsstd/os/env/get-args: () -> ndet list<string>()result: -> ndet list<string> : ndetstd/core/types/ndet: X liststd/core/types/list: V -> V<stringstd/core/types/string: V> val is-nodeis-node: bool = (hoststd/core/host: () -> ndet string() ==std/core/string/(==): (string, string) -> ndet bool "node"literal: string
count= 4
) match get-argvstd/os/env/get-argv: () -> ndet list<string>() Consstd/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: string,xxxx: list<string>) | is-nodeis-node: bool &&std/core/types/(&&): (x : bool, y : bool) -> bool xx: string.pathstd/os/path/path: (s : string) -> path.stemnamestd/os/path/stemname: (p : path) -> string ==std/core/string/(==): (string, string) -> bool "node"literal: string
count= 4
-> xxxx: list<string>.dropstd/core/list/drop: (xs : list<string>, n : int) -> ndet list<string>(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
) xsxs: list<string> -> xsxs: list<string>.dropstd/core/list/drop: (xs : list<string>, n : int) -> ndet list<string>(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
) // Return the main OS name: windows, linux, macos, unix, posix, ios, tvos, watchos, unknown. // Sometimes has a _dash_ subsystem, like: unix-&lt;freebsd,openbsd,dragonfly,bsd&gt;, and windows-mingw. pub extern get-os-namestd/os/env/get-os-name: () -> ndet string() : ndetstd/core/types/ndet: X stringstd/core/types/string: V c "kk_os_name" js inline "$std_core.host()" // Return the main processor architecture: x64, x86, arm64, arm32, riscv32, riscv64, alpha64, ppc64, etc. pub extern get-cpu-archstd/os/env/get-cpu-arch: () -> ndet string() : ndetstd/core/types/ndet: X stringstd/core/types/string: V c "kk_cpu_arch" js inline "$std_core.host()" // Return the available CPU's. // This is the logical core count including hyper-threaded cores. pub extern get-cpu-countstd/os/env/get-cpu-count: () -> ndet int() : ndetstd/core/types/ndet: X intstd/core/types/int: V c inline "kk_integer_from_int(kk_cpu_count(kk_context()),kk_context())" js inline "1" // The current compiler version. pub extern get-compiler-versionstd/os/env/get-compiler-version: () -> ndet string() : ndetstd/core/types/ndet: X stringstd/core/types/string: V c "kk_compiler_version" js inline "\"2\"" // The backend compiler name, like `gcc`, `clang`, `cl`, `clang-cl`, `mingw`, or `icc` (and `js` for JavaScript). pub extern get-cc-namestd/os/env/get-cc-name: () -> ndet string() : ndetstd/core/types/ndet: X stringstd/core/types/string: V c "kk_cc_name" js inline "\"js\"" cs inline "\"csc\"" // Is the byte-order little-endian? // If not, it is big-endian; other byte orders are not supported. pub extern get-cpu-is-little-endianstd/os/env/get-cpu-is-little-endian: () -> ndet bool() : ndetstd/core/types/ndet: X boolstd/core/types/bool: V c "kk_cpu_is_little_endian" js inline "true" // Return the processor natural integer register size in bits. // // Note: Usually this equals the `get-cpu-size-bits` and `get-cpu-pointer-bits` on modern cpu's // but they can differ on segmented architectures. // For example, on the old x86 FAR-NEAR model, the addresses are 32-bit but the integer register size is 16-bit. // Or on the more recent-[x32 ABI](https://en.wikipedia.org/wiki/X32_ABI) // the addresses and object sizes are 32-bits but the architecture has 64-bit integer registers. pub extern get-cpu-int-bitsstd/os/env/get-cpu-int-bits: () -> ndet int() : ndetstd/core/types/ndet: X intstd/core/types/int: V c inline "kk_integer_from_size_t(CHAR_BIT*sizeof(kk_intx_t),kk_context())" js inline "32" // Return the processor maximum object size in bits (`8*sizeof(size_t)`). This is usually // equal to the `get-cpu-int-bits` but may be different on segmented architectures. pub extern get-cpu-size-bitsstd/os/env/get-cpu-size-bits: () -> ndet int() : ndetstd/core/types/ndet: X intstd/core/types/int: V c inline "kk_integer_from_size_t(CHAR_BIT*sizeof(size_t),kk_context())" js inline "32" // Return the processor maximum address size in bits (`8*sizeof(vaddr_t)`). This is usually // equal to the `get-cpu-pointer-bits` but may be smaller on capability architectures like ARM CHERI. pub extern get-cpu-address-bitsstd/os/env/get-cpu-address-bits: () -> ndet int() : ndetstd/core/types/ndet: X intstd/core/types/int: V c inline "kk_integer_from_int(kk_cpu_address_bits(kk_context()),kk_context())" js inline "32" // Return the processor maximum pointer size in bits (`8*sizeof(void*)`). This is usually // equal to the `get-cpu-address-bits` but may be larger on capability architectures like ARM CHERI. pub extern get-cpu-pointer-bitsstd/os/env/get-cpu-pointer-bits: () -> ndet int() : ndetstd/core/types/ndet: X intstd/core/types/int: V c inline "kk_integer_from_size_t(CHAR_BIT*sizeof(void*),kk_context())" js inline "32" // Return the size of boxed values in the heap (`8*sizeof(kk_box_t)`). This is usually // equal to `8*sizeof(void*)` but can be less if compressed pointers are used (when // compiled with `--target=c64c` for example). pub extern get-cpu-boxed-bitsstd/os/env/get-cpu-boxed-bits: () -> ndet int() : ndetstd/core/types/ndet: X intstd/core/types/int: V c inline "kk_integer_from_size_t(CHAR_BIT*sizeof(kk_intb_t),kk_context())" js inline "32"