aboutsummaryrefslogtreecommitdiff
path: root/core/sys/posix/stdlib.odin
diff options
context:
space:
mode:
authorLaytan Laats <laytanlaats@hotmail.com>2024-07-27 04:20:03 +0200
committerLaytan Laats <laytanlaats@hotmail.com>2024-08-14 01:44:35 +0200
commitefe68c2e24e0a38e591f146822ed93904e4193d7 (patch)
treec2ac0ed3d08746495aa6adcd7a1c1ab052a7ee76 /core/sys/posix/stdlib.odin
parentac68a9d52c3a9edc587e1ccab747613baf6f89de (diff)
posix: add package
Diffstat (limited to 'core/sys/posix/stdlib.odin')
-rw-r--r--core/sys/posix/stdlib.odin450
1 files changed, 450 insertions, 0 deletions
diff --git a/core/sys/posix/stdlib.odin b/core/sys/posix/stdlib.odin
new file mode 100644
index 000000000..a1e2eab50
--- /dev/null
+++ b/core/sys/posix/stdlib.odin
@@ -0,0 +1,450 @@
+package posix
+
+import "base:intrinsics"
+
+import "core:c"
+import "core:c/libc"
+
+when ODIN_OS == .Darwin {
+ foreign import lib "system:System.framework"
+} else {
+ foreign import lib "system:c"
+}
+
+// stdlib.h - standard library definitions
+
+atof :: libc.atof
+atoi :: libc.atoi
+atol :: libc.atol
+atoll :: libc.atoll
+strtod :: libc.strtod
+strtof :: libc.strtof
+strtol :: libc.strtol
+strtoll :: libc.strtoll
+strtoul :: libc.strtoul
+strtoull :: libc.strtoull
+
+rand :: libc.rand
+srand :: libc.srand
+
+calloc :: libc.calloc
+malloc :: libc.malloc
+realloc :: libc.realloc
+
+abort :: libc.abort
+atexit :: libc.atexit
+at_quick_exit :: libc.at_quick_exit
+exit :: libc.exit
+_Exit :: libc._Exit
+getenv :: libc.getenv
+quick_exit :: libc.quick_exit
+system :: libc.system
+
+bsearch :: libc.bsearch
+qsort :: libc.qsort
+
+abs :: libc.abs
+labs :: libc.labs
+llabs :: libc.llabs
+div :: libc.div
+ldiv :: libc.ldiv
+lldiv :: libc.lldiv
+
+mblen :: libc.mblen
+mbtowc :: libc.mbtowc
+wctomb :: libc.wctomb
+
+mbstowcs :: libc.mbstowcs
+wcstombs :: libc.wcstombs
+
+free :: #force_inline proc(ptr: $T) where intrinsics.type_is_pointer(T) || intrinsics.type_is_multi_pointer(T) || T == cstring {
+ libc.free(rawptr(ptr))
+}
+
+foreign lib {
+ /*
+ Takes a pointer to a radix-64 representation, in which the first digit is the least significant,
+ and return the corresponding long value.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/a64l.html ]]
+ */
+ a64l :: proc(s: cstring) -> c.long ---
+
+ /*
+ The l64a() function shall take a long argument and return a pointer to the corresponding
+ radix-64 representation.
+
+ Returns: a string that may be invalidated by subsequent calls
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/a64l.html ]]
+ */
+ l64a :: proc(value: c.long) -> cstring ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ Returns: non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0,1.0)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ drand48 :: proc() -> c.double ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ Returns: non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0,1.0)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ erand48 :: proc(xsubi: ^[3]c.ushort) -> c.double ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ Returns: return signed long integers uniformly distributed over the interval [-231,231)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ mrand48 :: proc() -> c.long ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ Returns: return signed long integers uniformly distributed over the interval [-231,231)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ jrand48 :: proc(xsubi: ^[3]c.ushort) -> c.long ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ Returns: non-negative, long integers, uniformly distributed over the interval [0,231)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ lrand48 :: proc() -> c.long ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ Returns: non-negative, long integers, uniformly distributed over the interval [0,231)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ nrand48 :: proc(xsubi: ^[3]c.ushort) -> c.long ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ The srand48(), seed48(), and lcong48() functions are initialization entry points, one of which should be invoked before either drand48(), lrand48(), or mrand48() is called.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ srand48 :: proc(seedval: c.long) ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ The srand48(), seed48(), and lcong48() functions are initialization entry points, one of which should be invoked before either drand48(), lrand48(), or mrand48() is called.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ lcong48 :: proc(param: ^[7]c.ushort) ---
+
+ /*
+ This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
+
+ The srand48(), seed48(), and lcong48() functions are initialization entry points, one of which should be invoked before either drand48(), lrand48(), or mrand48() is called.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
+ */
+ seed48 :: proc(seed16v: ^[3]c.ushort) -> ^[3]c.ushort ---
+
+ /*
+ Parses suboption arguments in a flag argument.
+
+ Returns: the index of the matched token string, or -1 if no token strings were matched
+
+ Example:
+ args := runtime.args__
+
+ Opt :: enum {
+ RO,
+ RW,
+ NAME,
+ NIL,
+ }
+ token := [Opt]cstring{
+ .RO = "ro",
+ .RW = "rw",
+ .NAME = "name",
+ .NIL = nil,
+ }
+
+ Options :: struct {
+ readonly, readwrite: bool,
+ name: cstring,
+
+ }
+ opts: Options
+
+ errfnd: bool
+ for {
+ opt := posix.getopt(i32(len(args)), raw_data(args), "o:")
+ if opt == -1 {
+ break
+ }
+
+ switch opt {
+ case 'o':
+ subopt := posix.optarg
+ value: cstring
+ for subopt != "" && !errfnd {
+ o := posix.getsubopt(&subopt, &token[.RO], &value)
+ switch Opt(o) {
+ case .RO: opts.readonly = true
+ case .RW: opts.readwrite = true
+ case .NAME:
+ if value == nil {
+ fmt.eprintfln("missing value for suboption %s", token[.NAME])
+ errfnd = true
+ continue
+ }
+
+ opts.name = value
+ case .NIL:
+ fallthrough
+ case:
+ fmt.eprintfln("no match found for token: %s", value)
+ errfnd = true
+ }
+ }
+ if opts.readwrite && opts.readonly {
+ fmt.eprintfln("Only one of %s and %s can be specified", token[.RO], token[.RW])
+ errfnd = true
+ }
+ case:
+ errfnd = true
+ }
+ }
+
+ if errfnd || len(args) == 1 {
+ fmt.eprintfln("\nUsage: %s -o <suboptstring>", args[0])
+ fmt.eprintfln("suboptions are 'ro', 'rw', and 'name=<value>'")
+ posix.exit(1)
+ }
+
+ fmt.println(opts)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsubopt.html ]]
+ */
+ getsubopt :: proc(optionp: ^cstring, keylistp: [^]cstring, valuep: ^cstring) -> c.int ---
+
+ /*
+ Changes the mode and ownership of the slave pseudo-terminal device associated with its master pseudo-terminal counterpart.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html ]]
+ */
+ grantpt :: proc(fildes: FD) -> result ---
+
+ /*
+ Allows a state array, pointed to by the state argument, to be initialized for future use.
+
+ Returns: the previous state array or nil on failure
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
+ */
+ @(link_name=LINITSTATE)
+ initstate :: proc(seed: c.uint, state: [^]byte, size: c.size_t) -> [^]byte ---
+
+ /*
+ Sets the state array of the random number generator.
+
+ Returns: the previous state array or nil on failure
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
+ */
+ setstate :: proc(state: [^]byte) -> [^]byte ---
+
+ /*
+ Use a non-linear additive feedback random-number generator employing a default state array
+ size of 31 long integers to return successive pseudo-random numbers in the range from 0 to 231-1.
+ The period of this random-number generator is approximately 16 x (231-1).
+ The size of the state array determines the period of the random-number generator.
+ Increasing the state array size shall increase the period.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
+ */
+ random :: proc() -> c.long ---
+
+ /*
+ Initializes the current state array using the value of seed.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
+ */
+ @(link_name=LSRANDOM)
+ srandom :: proc(seed: c.uint) ---
+
+ /*
+ Creates a directory with a unique name derived from template.
+ The application shall ensure that the string provided in template is a pathname ending
+ with at least six trailing 'X' characters.
+
+ Returns: nil (setting errno) on failure, template on success
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdtemp.html ]]
+ */
+ mkdtemp :: proc(template: [^]byte) -> cstring ---
+
+ /*
+ Creates a regular file with a unique name derived from template and return a file descriptor
+ for the file open for reading and writing.
+ The application shall ensure that the string provided in template is a pathname ending with
+ at least six trailing 'X' characters.
+
+ Returns: -1 (setting errno) on failure, an open file descriptor on success
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdtemp.html ]]
+ */
+ mkstemp :: proc(template: cstring) -> FD ---
+
+ /*
+ Allocates size bytes aligned on a boundary specified by alignment, and shall return a pointer
+ to the allocated memory in memptr.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html ]]
+ */
+ posix_memalign :: proc(memptr: ^[^]byte, alignment: c.size_t, size: c.size_t) -> Errno ---
+
+ /*
+ Establishes a connection between a master device for a pseudo-terminal and a file descriptor.
+
+ Returns: -1 (setting errno) on failure, an open file descriptor otherwise
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html ]]
+ */
+ posix_openpt :: proc(oflag: O_Flags) -> FD ---
+
+ /*
+ Returns the name of the slave pseudo-terminal device associated with a master pseudo-terminal device.
+
+ Returns: nil (setting errno) on failure, the name on success, which may be invalidated on subsequent calls
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/ptsname.html ]]
+ */
+ ptsname :: proc(fildes: FD) -> cstring ---
+
+ /*
+ Unlocks the slave pseudo-terminal device associated with the master to which fildes refers.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html ]]
+ */
+ unlockpt :: proc(fildes: FD) -> result ---
+
+ /*
+ Uses the string argument to set environment variable values.
+
+ Returns: 0 on success, non-zero (setting errno) on failure
+
+ Example:
+ if posix.putenv("HOME=/usr/home") != 0 {
+ fmt.panicf("putenv failure: %v", posix.strerror(posix.errno()))
+ }
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/putenv.html ]]
+ */
+ @(link_name=LPUTENV)
+ putenv :: proc(string: cstring) -> c.int ---
+
+ /*
+ Updates or add a variable in the environment of the calling process.
+
+ Example:
+ if posix.setenv("HOME", "/usr/home") != .OK {
+ fmt.panicf("putenv failure: %v", posix.strerror(posix.errno()))
+ }
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setenv.html ]]
+ */
+ setenv :: proc(envname: cstring, envval: cstring, overwrite: b32) -> result ---
+
+ /*
+ Removes an environment variable from the environment of the calling process.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unsetenv.html ]]
+ */
+ @(link_name=LUNSETENV)
+ unsetenv :: proc(name: cstring) -> result ---
+
+ /*
+ Computes a sequence of pseudo-random integers in the range [0, {RAND_MAX}].
+ (The value of the {RAND_MAX} macro shall be at least 32767.)
+
+ If rand_r() is called with the same initial value for the object pointed to by seed and that object is not modified between successive returns and calls to rand_r(), the same sequence shall be generated.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/rand_r.html ]]
+ */
+ rand_r :: proc(seed: ^c.uint) -> c.int ---
+
+ /*
+ Derive, from the pathname file_name, an absolute pathname that resolves to the same directory entry,
+ whose resolution does not involve '.', '..', or symbolic links.
+
+ If resolved_name is not `nil` it should be larger than `PATH_MAX` and the result will use it as a backing buffer.
+ If resolved_name is `nil` the returned string is allocated by `malloc`.
+
+ Returns: `nil` (setting errno) on failure, the "real path" otherwise
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html ]]
+ */
+ realpath :: proc(file_name: cstring, resolved_name: [^]byte = nil) -> cstring ---
+
+ /*
+ Provides access to an implementation-defined encoding algorithm.
+ The argument of setkey() is an array of length 64 bytes containing only the bytes with numerical
+ value of 0 and 1.
+
+ If this string is divided into groups of 8, the low-order bit in each group is ignored; this gives a 56-bit key which is used by the algorithm.
+ This is the key that shall be used with the algorithm to encode a string block passed to encrypt().
+
+ The setkey() function shall not change the setting of errno if successful.
+ An application wishing to check for error situations should set errno to 0 before calling setkey().
+ If errno is non-zero on return, an error has occurred.
+
+ Example:
+ key: [64]byte
+ // set key bytes...
+
+ posix.set_errno(.NONE)
+ posix.setkey(raw_data(key))
+ if errno := posix.errno(); errno != .NONE {
+ fmt.panicf("setkey failure: %s", posix.strerror(errno))
+ }
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setkey.html ]]
+ */
+ setkey :: proc(key: [^]byte) ---
+}
+
+EXIT_FAILURE :: libc.EXIT_FAILURE
+EXIT_SUCCESS :: libc.EXIT_SUCCESS
+
+RAND_MAX :: libc.RAND_MAX
+MB_CUR_MAX :: libc.MB_CUR_MAX
+
+div_t :: libc.div_t
+ldiv_t :: libc.ldiv_t
+lldiv_t :: libc.lldiv_t
+
+when ODIN_OS == .NetBSD {
+ @(private) LPUTENV :: "__putenv50"
+ @(private) LINITSTATE :: "__initstate60"
+ @(private) LSRANDOM :: "__srandom60"
+ @(private) LUNSETENV :: "__unsetenv13"
+} else {
+ @(private) LPUTENV :: "putenv"
+ @(private) LINITSTATE :: "initstate"
+ @(private) LSRANDOM :: "srandom"
+ @(private) LUNSETENV :: "unsetenv"
+}