ref: e3a9307d99e1a2936e63b6ffa5d80a5929d4b549
dir: /lib/std/env+posixy.myr/
use sys
use "alloc"
use "cstrconv"
use "die"
use "extremum"
use "fmt"
use "memops"
use "option"
use "sldup"
use "slcp"
use "sleq"
pkg std =
	const getenv	: (name : byte[:] -> option(byte[:]))
	const getenvv	: (name : byte[:], default : byte[:] -> byte[:])
	const setenv	: (name : byte[:], val : byte[:] -> void)
;;
const Zenvp = (0 : byte#)
var envduped	: bool = false
var environ	: byte#[:]
const getenv = {name
	var n, env
	envinit()
	for envp in environ
		env = cstrconvp(envp)
		n = min(name.len, env.len)
		if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
			-> `Some env[n+1:]
		;;
	;;
	-> `None
}
const getenvv = {name, default
	match getenv(name)
	| `Some v:	-> v
	| `None:	-> default
	;;
}
const setenv = {name, val
	var n, e, env, idx
	envdup()
	idx = 0
	for envp in environ
		env = cstrconvp(envp)
		n = min(name.len, env.len)
		if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
			break
		;;
		idx++
	;;
	if idx == environ.len
		slgrow(&environ, environ.len + 1)
	else
		e = cstrconvp(environ[idx])
		std.slfree(e)
	;;
	e = fmt("{}={}\0", name, val)
	environ[idx] = (e : byte#)
	sys.__cenvp = (environ : byte##)
}
const envinit = {
	var len
	if environ.len != 0
		-> void
	;;
	environ = sys.__cenvp[:1]
	len = 0
	while true
		len++
		environ = sys.__cenvp[:len + 1]
		if environ[len] == Zenvp
			environ = sys.__cenvp[:len]
			break
		;;
	;;
}
const envdup = {
	var e, s, dup
	if envduped
		-> void
	;;
	envduped = true
	envinit()
	dup = std.slalloc(environ.len + 1)
	for var i = 0; i < environ.len; i++
		s = cstrconvp(environ[i])
		e = std.slalloc(s.len + 1)
		slcp(e[:e.len - 1], s)
		e[e.len - 1] = 0
		dup[i] = (e : byte#)
	;;
	dup[dup.len - 1] = Zenvp
	environ = dup[:dup.len - 1]
	sys.__cenvp = (environ : byte##)
}