hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

platform_environ.ha (3076B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use errors;
      5 use math;
      6 use rt;
      7 use strings;
      8 use types::c;
      9 
     10 // The command line arguments provided to the program. By convention, the first
     11 // member is usually the name of the program.
     12 export let args: []str = [];
     13 
     14 // Statically allocate arg strings if there are few enough arguments, saves a
     15 // syscall if we don't need it.
     16 let args_static: [32]str = [""...];
     17 
     18 @init fn args() void = {
     19 	if (rt::argc < len(args_static)) {
     20 		args = args_static[..rt::argc];
     21 		for (let i = 0z; i < rt::argc; i += 1) {
     22 			args[i] = c::tostr(rt::argv[i]: *const c::char)!;
     23 		};
     24 	} else {
     25 		args = alloc([], rt::argc);
     26 		for (let i = 0z; i < rt::argc; i += 1) {
     27 			append(args, c::tostr(rt::argv[i]: *const c::char)!);
     28 		};
     29 	};
     30 };
     31 
     32 @fini fn args() void = {
     33 	if (rt::argc >= len(args_static)) {
     34 		free(args);
     35 	};
     36 };
     37 
     38 // Returns a slice of the environment strings in form KEY=VALUE.
     39 export fn getenvs() []str = {
     40 	if (len(envp) > 0) {
     41 		return envp;
     42 	};
     43 	for (let i = 0z; rt::envp[i] != null; i += 1) {
     44 		let s = c::tostr(rt::envp[i]: *const c::char)!;
     45 		append(envp, strings::dup(s));
     46 	};
     47 	return envp;
     48 };
     49 
     50 // Returns the host kernel name
     51 export fn sysname() const str = {
     52 	let name: [2]int = [rt::CTL_KERN, rt::KERN_OSTYPE];
     53 
     54 	static let buf: [32]u8 = [0...];
     55 	let buf_sz = len(buf);
     56 
     57 	rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!;
     58 	return strings::fromutf8(buf[..(buf_sz -1)])!;
     59 };
     60 
     61 // Returns the host system hostname
     62 export fn hostname() const str = {
     63 	let name: [2]int = [rt::CTL_KERN, rt::KERN_HOSTNAME];
     64 
     65 	static let buf: [rt::MAXHOSTNAMELEN]u8 = [0...];
     66 	let buf_sz = len(buf);
     67 
     68 	rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!;
     69 	return strings::fromutf8(buf[..(buf_sz -1)])!;
     70 };
     71 
     72 // Returns the host operating system version
     73 export fn version() const str = {
     74 	let name: [2]int = [rt::CTL_KERN, rt::KERN_OSRELEASE];
     75 
     76 	static let buf: [32]u8 = [0...];
     77 	let buf_sz = len(buf);
     78 
     79 	rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!;
     80 	return strings::fromutf8(buf[..(buf_sz -1)])!;
     81 };
     82 
     83 // Returns the host CPU architecture, in a platform-specific format. See
     84 // [[architecture]] for a more portable wrapper.
     85 export fn machine() const str = {
     86 	let name: [2]int = [rt::CTL_HW, rt::HW_MACHINE];
     87 
     88 	static let buf: [32]u8 = [0...];
     89 	let buf_sz = len(buf);
     90 
     91 	rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!;
     92 
     93 	return strings::fromutf8(buf[..(buf_sz - 1)])!;
     94 };
     95 
     96 // Returns the host CPU architecture.
     97 export fn architecture() arch = {
     98 	switch (machine()) {
     99 	case "arm64" =>
    100 		return arch::AARCH64;
    101 	case "riscv64" =>
    102 		return arch::RISCV64;
    103 	case "amd64" =>
    104 		return arch::X86_64;
    105 	case => abort(); // unreachable
    106 	};
    107 };
    108 
    109 // Returns the number of usable CPUs.
    110 export fn cpucount() (size | errors::error) = {
    111 	let name: [2]int = [rt::CTL_HW, rt::HW_NCPUONLINE];
    112 
    113 	let ncpu: int = 0;
    114 	let ncpu_sz = size(int);
    115 
    116 	match (rt::sysctl(name, len(name): uint, &ncpu, &ncpu_sz, null, 0)) {
    117 	case void =>
    118 		return ncpu: size;
    119 	case let err: rt::errno =>
    120 		return errors::errno(err);
    121 	};
    122 };