This commit is contained in:
gingerBill
2022-09-06 12:57:28 +01:00
21 changed files with 2307 additions and 343 deletions

View File

@@ -705,4 +705,4 @@ _alloc_command_line_arguments :: proc() -> []string {
res[i] = string(arg)
}
return res
}
}

View File

@@ -0,0 +1,26 @@
//+build arm32, arm64
package sysinfo
// TODO: Set up an enum with the ARM equivalent of the above.
CPU_Feature :: enum u64 {}
cpu_features: Maybe(CPU_Feature)
cpu_name: Maybe(string)
@(init, private)
init_cpu_features :: proc "c" () {
}
@(private)
_cpu_name_buf: [72]u8
@(init, private)
init_cpu_name :: proc "c" () {
when ODIN_ARCH == .arm32 {
copy(_cpu_name_buf[:], "ARM")
cpu_name = string(_cpu_name_buf[:3])
} else {
copy(_cpu_name_buf[:], "ARM64")
cpu_name = string(_cpu_name_buf[:5])
}
}

View File

@@ -1,5 +1,5 @@
//+build i386, amd64
package simd_x86
package sysinfo
import "core:intrinsics"
@@ -9,7 +9,6 @@ cpuid :: intrinsics.x86_cpuid
// xgetbv :: proc(cx: u32) -> (eax, edx: u32) ---
xgetbv :: intrinsics.x86_xgetbv
CPU_Feature :: enum u64 {
aes, // AES hardware implementation (AES NI)
adx, // Multi-precision add-carry instruction extensions
@@ -34,6 +33,7 @@ CPU_Feature :: enum u64 {
CPU_Features :: distinct bit_set[CPU_Feature; u64]
cpu_features: Maybe(CPU_Features)
cpu_name: Maybe(string)
@(init, private)
init_cpu_features :: proc "c" () {
@@ -67,6 +67,13 @@ init_cpu_features :: proc "c" () {
try_set(&set, .os_xsave, 27, ecx1)
try_set(&set, .rdrand, 30, ecx1)
when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD {
// xgetbv is an illegal instruction under FreeBSD 13 & OpenBSD 7.1
// return before probing further
cpu_features = set
return
}
os_supports_avx := false
if .os_xsave in set {
eax, _ := xgetbv(0)
@@ -92,3 +99,31 @@ init_cpu_features :: proc "c" () {
cpu_features = set
}
@(private)
_cpu_name_buf: [72]u8
@(init, private)
init_cpu_name :: proc "c" () {
number_of_extended_ids, _, _, _ := cpuid(0x8000_0000, 0)
if number_of_extended_ids < 0x8000_0004 {
return
}
_buf := transmute(^[0x12]u32)&_cpu_name_buf
_buf[ 0], _buf[ 1], _buf[ 2], _buf[ 3] = cpuid(0x8000_0002, 0)
_buf[ 4], _buf[ 5], _buf[ 6], _buf[ 7] = cpuid(0x8000_0003, 0)
_buf[ 8], _buf[ 9], _buf[10], _buf[11] = cpuid(0x8000_0004, 0)
// Some CPUs like may include leading or trailing spaces. Trim them.
// e.g. ` Intel(R) Xeon(R) CPU E5-1650 v2 @ 3.50GHz`
brand := string(_cpu_name_buf[:])
for len(brand) > 0 && brand[0] == 0 || brand[0] == ' ' {
brand = brand[1:]
}
for len(brand) > 0 && brand[len(brand) - 1] == 0 || brand[len(brand) - 1] == ' ' {
brand = brand[:len(brand) - 1]
}
cpu_name = brand
}

78
core/sys/info/doc.odin Normal file
View File

@@ -0,0 +1,78 @@
/*
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
Package `core:sys/info` gathers system information on:
Windows, Linux, macOS, FreeBSD & OpenBSD.
Simply import the package and you'll have access to the OS version, RAM amount
and CPU information.
On Windows, GPUs will also be enumerated using the registry.
CPU feature flags can be tested against `cpu_features`, where applicable, e.g.
`if .aes in si.aes { ... }`
*/
// +ignore
package sysinfo
import "core:fmt"
import si "core:sys/info"
main :: proc() {
fmt.printf("Odin: %v\n", ODIN_VERSION)
fmt.printf("OS: %v\n", si.os_version.as_string)
fmt.printf("OS: %#v\n", si.os_version)
fmt.printf("CPU: %v\n", si.cpu_name)
fmt.printf("RAM: %v MiB\n", si.ram.total_ram / 1024 / 1024)
fmt.println()
for gpu, i in si.gpus {
fmt.printf("GPU #%v:\n", i)
fmt.printf("\tVendor: %v\n", gpu.vendor_name)
fmt.printf("\tModel: %v\n", gpu.model_name)
fmt.printf("\tVRAM: %v MiB\n", gpu.total_ram / 1024 / 1024)
}
}
/*
Example Windows output:
Odin: dev-2022-09
OS: Windows 10 Professional (version: 20H2), build: 19042.1466
OS: OS_Version{
platform = "Windows",
major = 10,
minor = 0,
patch = 0,
build = [
19042,
1466,
],
version = "20H2",
as_string = "Windows 10 Professional (version: 20H2), build: 19042.1466",
}
CPU: AMD Ryzen 7 1800X Eight-Core Processor
RAM: 65469 MiB
GPU #0:
Vendor: Advanced Micro Devices, Inc.
Model: Radeon RX Vega
VRAM: 8176 MiB
Example macOS output:
ODIN: dev-2022-09
OS: OS_Version{
platform = "MacOS",
major = 21,
minor = 5,
patch = 0,
build = [
0,
0,
],
version = "21F79",
as_string = "macOS Monterey 12.4 (build 21F79, kernel 21.5.0)",
}
CPU: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
RAM: 8192 MiB
*/

View File

@@ -0,0 +1,510 @@
// +build darwin
package sysinfo
import sys "core:sys/unix"
import "core:strconv"
import "core:strings"
@(private)
version_string_buf: [1024]u8
@(init, private)
init_os_version :: proc () {
os_version.platform = .MacOS
// Start building display version
b := strings.builder_from_bytes(version_string_buf[:])
mib := []i32{sys.CTL_KERN, sys.KERN_OSVERSION}
build_buf: [12]u8
ok := sys.sysctl(mib, &build_buf)
if !ok {
strings.write_string(&b, "macOS Unknown")
os_version.as_string = strings.to_string(b)
return
}
build := string(cstring(&build_buf[0]))
// Do we have an exact match?
match: Darwin_Match
rel, exact := macos_release_map[build]
if exact {
match = .Exact
} else {
// Match on XNU kernel version
mib = []i32{sys.CTL_KERN, sys.KERN_OSRELEASE}
version_bits: [12]u8 // enough for 999.999.999\x00
have_kernel_version := sys.sysctl(mib, &version_bits)
major_ok, minor_ok, patch_ok: bool
triplet := strings.split(string(cstring(&version_bits[0])), ".", context.temp_allocator)
if len(triplet) != 3 {
have_kernel_version = false
} else {
rel.darwin.x, major_ok = strconv.parse_int(triplet[0])
rel.darwin.y, minor_ok = strconv.parse_int(triplet[1])
rel.darwin.z, patch_ok = strconv.parse_int(triplet[2])
if !(major_ok && minor_ok && patch_ok) {
have_kernel_version = false
}
}
if !have_kernel_version {
// We don't know the kernel version, but we do know the build
strings.write_string(&b, "macOS Unknown (build ")
l := strings.builder_len(b)
strings.write_string(&b, build)
os_version.version = strings.to_string(b)[l:]
strings.write_rune(&b, ')')
os_version.as_string = strings.to_string(b)
return
}
rel, match = map_darwin_kernel_version_to_macos_release(build, rel.darwin)
}
os_version.major = rel.darwin.x
os_version.minor = rel.darwin.y
os_version.patch = rel.darwin.z
strings.write_string(&b, rel.os_name)
if match == .Exact || match == .Nearest {
strings.write_rune(&b, ' ')
strings.write_string(&b, rel.release.name)
strings.write_rune(&b, ' ')
strings.write_int(&b, rel.release.version.x)
if rel.release.version.y > 0 || rel.release.version.z > 0 {
strings.write_rune(&b, '.')
strings.write_int(&b, rel.release.version.y)
}
if rel.release.version.z > 0 {
strings.write_rune(&b, '.')
strings.write_int(&b, rel.release.version.z)
}
if match == .Nearest {
strings.write_rune(&b, '?')
}
} else {
strings.write_string(&b, " Unknown")
}
strings.write_string(&b, " (build ")
l := strings.builder_len(b)
strings.write_string(&b, build)
os_version.version = strings.to_string(b)[l:]
strings.write_string(&b, ", kernel ")
strings.write_int(&b, rel.darwin.x)
strings.write_rune(&b, '.')
strings.write_int(&b, rel.darwin.y)
strings.write_rune(&b, '.')
strings.write_int(&b, rel.darwin.z)
strings.write_rune(&b, ')')
os_version.as_string = strings.to_string(b)
}
@(init)
init_ram :: proc() {
// Retrieve RAM info using `sysctl`
mib := []i32{sys.CTL_HW, sys.HW_MEMSIZE}
mem_size: u64
if sys.sysctl(mib, &mem_size) {
ram.total_ram = int(mem_size)
}
}
@(private)
Darwin_To_Release :: struct {
darwin: [3]int, // Darwin kernel triplet
os_name: string, // OS X, MacOS
release: struct {
name: string, // Monterey, Mojave, etc.
version: [3]int, // 12.4, etc.
},
}
// Important: Order from lowest to highest kernel version
@(private)
macos_release_map: map[string]Darwin_To_Release = {
// MacOS Tiger
"8A428" = {{8, 0, 0}, "macOS", {"Tiger", {10, 4, 0}}},
"8A432" = {{8, 0, 0}, "macOS", {"Tiger", {10, 4, 0}}},
"8B15" = {{8, 1, 0}, "macOS", {"Tiger", {10, 4, 1}}},
"8B17" = {{8, 1, 0}, "macOS", {"Tiger", {10, 4, 1}}},
"8C46" = {{8, 2, 0}, "macOS", {"Tiger", {10, 4, 2}}},
"8C47" = {{8, 2, 0}, "macOS", {"Tiger", {10, 4, 2}}},
"8E102" = {{8, 2, 0}, "macOS", {"Tiger", {10, 4, 2}}},
"8E45" = {{8, 2, 0}, "macOS", {"Tiger", {10, 4, 2}}},
"8E90" = {{8, 2, 0}, "macOS", {"Tiger", {10, 4, 2}}},
"8F46" = {{8, 3, 0}, "macOS", {"Tiger", {10, 4, 3}}},
"8G32" = {{8, 4, 0}, "macOS", {"Tiger", {10, 4, 4}}},
"8G1165" = {{8, 4, 0}, "macOS", {"Tiger", {10, 4, 4}}},
"8H14" = {{8, 5, 0}, "macOS", {"Tiger", {10, 4, 5}}},
"8G1454" = {{8, 5, 0}, "macOS", {"Tiger", {10, 4, 5}}},
"8I127" = {{8, 6, 0}, "macOS", {"Tiger", {10, 4, 6}}},
"8I1119" = {{8, 6, 0}, "macOS", {"Tiger", {10, 4, 6}}},
"8J135" = {{8, 7, 0}, "macOS", {"Tiger", {10, 4, 7}}},
"8J2135a" = {{8, 7, 0}, "macOS", {"Tiger", {10, 4, 7}}},
"8K1079" = {{8, 7, 0}, "macOS", {"Tiger", {10, 4, 7}}},
"8N5107" = {{8, 7, 0}, "macOS", {"Tiger", {10, 4, 7}}},
"8L127" = {{8, 8, 0}, "macOS", {"Tiger", {10, 4, 8}}},
"8L2127" = {{8, 8, 0}, "macOS", {"Tiger", {10, 4, 8}}},
"8P135" = {{8, 9, 0}, "macOS", {"Tiger", {10, 4, 9}}},
"8P2137" = {{8, 9, 0}, "macOS", {"Tiger", {10, 4, 9}}},
"8R218" = {{8, 10, 0}, "macOS", {"Tiger", {10, 4, 10}}},
"8R2218" = {{8, 10, 0}, "macOS", {"Tiger", {10, 4, 10}}},
"8R2232" = {{8, 10, 0}, "macOS", {"Tiger", {10, 4, 10}}},
"8S165" = {{8, 11, 0}, "macOS", {"Tiger", {10, 4, 11}}},
"8S2167" = {{8, 11, 0}, "macOS", {"Tiger", {10, 4, 11}}},
// MacOS Leopard
"9A581" = {{9, 0, 0}, "macOS", {"Leopard", {10, 5, 0}}},
"9B18" = {{9, 1, 0}, "macOS", {"Leopard", {10, 5, 1}}},
"9B2117" = {{9, 1, 1}, "macOS", {"Leopard", {10, 5, 1}}},
"9C31" = {{9, 2, 0}, "macOS", {"Leopard", {10, 5, 2}}},
"9C7010" = {{9, 2, 0}, "macOS", {"Leopard", {10, 5, 2}}},
"9D34" = {{9, 3, 0}, "macOS", {"Leopard", {10, 5, 3}}},
"9E17" = {{9, 4, 0}, "macOS", {"Leopard", {10, 5, 4}}},
"9F33" = {{9, 5, 0}, "macOS", {"Leopard", {10, 5, 5}}},
"9G55" = {{9, 6, 0}, "macOS", {"Leopard", {10, 5, 6}}},
"9G66" = {{9, 6, 0}, "macOS", {"Leopard", {10, 5, 6}}},
"9G71" = {{9, 6, 0}, "macOS", {"Leopard", {10, 5, 6}}},
"9J61" = {{9, 7, 0}, "macOS", {"Leopard", {10, 5, 7}}},
"9L30" = {{9, 8, 0}, "macOS", {"Leopard", {10, 5, 8}}},
"9L34" = {{9, 8, 0}, "macOS", {"Leopard", {10, 5, 8}}},
// MacOS Snow Leopard
"10A432" = {{10, 0, 0}, "macOS", {"Snow Leopard", {10, 6, 0}}},
"10A433" = {{10, 0, 0}, "macOS", {"Snow Leopard", {10, 6, 0}}},
"10B504" = {{10, 1, 0}, "macOS", {"Snow Leopard", {10, 6, 1}}},
"10C540" = {{10, 2, 0}, "macOS", {"Snow Leopard", {10, 6, 2}}},
"10D573" = {{10, 3, 0}, "macOS", {"Snow Leopard", {10, 6, 3}}},
"10D575" = {{10, 3, 0}, "macOS", {"Snow Leopard", {10, 6, 3}}},
"10D578" = {{10, 3, 0}, "macOS", {"Snow Leopard", {10, 6, 3}}},
"10F569" = {{10, 4, 0}, "macOS", {"Snow Leopard", {10, 6, 4}}},
"10H574" = {{10, 5, 0}, "macOS", {"Snow Leopard", {10, 6, 5}}},
"10J567" = {{10, 6, 0}, "macOS", {"Snow Leopard", {10, 6, 6}}},
"10J869" = {{10, 7, 0}, "macOS", {"Snow Leopard", {10, 6, 7}}},
"10J3250" = {{10, 7, 0}, "macOS", {"Snow Leopard", {10, 6, 7}}},
"10J4138" = {{10, 7, 0}, "macOS", {"Snow Leopard", {10, 6, 7}}},
"10K540" = {{10, 8, 0}, "macOS", {"Snow Leopard", {10, 6, 8}}},
"10K549" = {{10, 8, 0}, "macOS", {"Snow Leopard", {10, 6, 8}}},
// MacOS Lion
"11A511" = {{11, 0, 0}, "macOS", {"Lion", {10, 7, 0}}},
"11A511s" = {{11, 0, 0}, "macOS", {"Lion", {10, 7, 0}}},
"11A2061" = {{11, 0, 2}, "macOS", {"Lion", {10, 7, 0}}},
"11A2063" = {{11, 0, 2}, "macOS", {"Lion", {10, 7, 0}}},
"11B26" = {{11, 1, 0}, "macOS", {"Lion", {10, 7, 1}}},
"11B2118" = {{11, 1, 0}, "macOS", {"Lion", {10, 7, 1}}},
"11C74" = {{11, 2, 0}, "macOS", {"Lion", {10, 7, 2}}},
"11D50" = {{11, 3, 0}, "macOS", {"Lion", {10, 7, 3}}},
"11E53" = {{11, 4, 0}, "macOS", {"Lion", {10, 7, 4}}},
"11G56" = {{11, 4, 2}, "macOS", {"Lion", {10, 7, 5}}},
"11G63" = {{11, 4, 2}, "macOS", {"Lion", {10, 7, 5}}},
// MacOS Mountain Lion
"12A269" = {{12, 0, 0}, "macOS", {"Mountain Lion", {10, 8, 0}}},
"12B19" = {{12, 1, 0}, "macOS", {"Mountain Lion", {10, 8, 1}}},
"12C54" = {{12, 2, 0}, "macOS", {"Mountain Lion", {10, 8, 2}}},
"12C60" = {{12, 2, 0}, "macOS", {"Mountain Lion", {10, 8, 2}}},
"12C2034" = {{12, 2, 0}, "macOS", {"Mountain Lion", {10, 8, 2}}},
"12C3104" = {{12, 2, 0}, "macOS", {"Mountain Lion", {10, 8, 2}}},
"12D78" = {{12, 3, 0}, "macOS", {"Mountain Lion", {10, 8, 3}}},
"12E55" = {{12, 4, 0}, "macOS", {"Mountain Lion", {10, 8, 4}}},
"12E3067" = {{12, 4, 0}, "macOS", {"Mountain Lion", {10, 8, 4}}},
"12E4022" = {{12, 4, 0}, "macOS", {"Mountain Lion", {10, 8, 4}}},
"12F37" = {{12, 5, 0}, "macOS", {"Mountain Lion", {10, 8, 5}}},
"12F45" = {{12, 5, 0}, "macOS", {"Mountain Lion", {10, 8, 5}}},
"12F2501" = {{12, 5, 0}, "macOS", {"Mountain Lion", {10, 8, 5}}},
"12F2518" = {{12, 5, 0}, "macOS", {"Mountain Lion", {10, 8, 5}}},
"12F2542" = {{12, 5, 0}, "macOS", {"Mountain Lion", {10, 8, 5}}},
"12F2560" = {{12, 5, 0}, "macOS", {"Mountain Lion", {10, 8, 5}}},
// MacOS Mavericks
"13A603" = {{13, 0, 0}, "macOS", {"Mavericks", {10, 9, 0}}},
"13B42" = {{13, 0, 0}, "macOS", {"Mavericks", {10, 9, 1}}},
"13C64" = {{13, 1, 0}, "macOS", {"Mavericks", {10, 9, 2}}},
"13C1021" = {{13, 1, 0}, "macOS", {"Mavericks", {10, 9, 2}}},
"13D65" = {{13, 2, 0}, "macOS", {"Mavericks", {10, 9, 3}}},
"13E28" = {{13, 3, 0}, "macOS", {"Mavericks", {10, 9, 4}}},
"13F34" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1066" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1077" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1096" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1112" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1134" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1507" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1603" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1712" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1808" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
"13F1911" = {{13, 4, 0}, "macOS", {"Mavericks", {10, 9, 5}}},
// MacOS Yosemite
"14A389" = {{14, 0, 0}, "macOS", {"Yosemite", {10, 10, 0}}},
"14B25" = {{14, 0, 0}, "macOS", {"Yosemite", {10, 10, 1}}},
"14C109" = {{14, 1, 0}, "macOS", {"Yosemite", {10, 10, 2}}},
"14C1510" = {{14, 1, 0}, "macOS", {"Yosemite", {10, 10, 2}}},
"14C2043" = {{14, 1, 0}, "macOS", {"Yosemite", {10, 10, 2}}},
"14C1514" = {{14, 1, 0}, "macOS", {"Yosemite", {10, 10, 2}}},
"14C2513" = {{14, 1, 0}, "macOS", {"Yosemite", {10, 10, 2}}},
"14D131" = {{14, 3, 0}, "macOS", {"Yosemite", {10, 10, 3}}},
"14D136" = {{14, 3, 0}, "macOS", {"Yosemite", {10, 10, 3}}},
"14E46" = {{14, 4, 0}, "macOS", {"Yosemite", {10, 10, 4}}},
"14F27" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1021" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1505" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1509" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1605" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1713" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1808" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1909" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F1912" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F2009" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F2109" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F2315" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F2411" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
"14F2511" = {{14, 5, 0}, "macOS", {"Yosemite", {10, 10, 5}}},
// MacOS El Capitan
"15A284" = {{15, 0, 0}, "macOS", {"El Capitan", {10, 11, 0}}},
"15B42" = {{15, 0, 0}, "macOS", {"El Capitan", {10, 11, 1}}},
"15C50" = {{15, 2, 0}, "macOS", {"El Capitan", {10, 11, 2}}},
"15D21" = {{15, 3, 0}, "macOS", {"El Capitan", {10, 11, 3}}},
"15E65" = {{15, 4, 0}, "macOS", {"El Capitan", {10, 11, 4}}},
"15F34" = {{15, 5, 0}, "macOS", {"El Capitan", {10, 11, 5}}},
"15G31" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1004" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1011" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1108" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1212" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1217" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1421" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1510" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G1611" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G17023" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G18013" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G19009" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G20015" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G21013" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
"15G22010" = {{15, 6, 0}, "macOS", {"El Capitan", {10, 11, 6}}},
// MacOS Sierra
"16A323" = {{16, 0, 0}, "macOS", {"Sierra", {10, 12, 0}}},
"16B2555" = {{16, 1, 0}, "macOS", {"Sierra", {10, 12, 1}}},
"16B2657" = {{16, 1, 0}, "macOS", {"Sierra", {10, 12, 1}}},
"16C67" = {{16, 3, 0}, "macOS", {"Sierra", {10, 12, 2}}},
"16C68" = {{16, 3, 0}, "macOS", {"Sierra", {10, 12, 2}}},
"16D32" = {{16, 4, 0}, "macOS", {"Sierra", {10, 12, 3}}},
"16E195" = {{16, 5, 0}, "macOS", {"Sierra", {10, 12, 4}}},
"16F73" = {{16, 6, 0}, "macOS", {"Sierra", {10, 12, 5}}},
"16F2073" = {{16, 6, 0}, "macOS", {"Sierra", {10, 12, 5}}},
"16G29" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1036" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1114" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1212" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1314" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1408" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1510" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1618" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1710" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1815" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1917" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G1918" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G2016" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G2127" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G2128" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
"16G2136" = {{16, 7, 0}, "macOS", {"Sierra", {10, 12, 6}}},
// MacOS High Sierra
"17A365" = {{17, 0, 0}, "macOS", {"High Sierra", {10, 13, 0}}},
"17A405" = {{17, 0, 0}, "macOS", {"High Sierra", {10, 13, 0}}},
"17B48" = {{17, 2, 0}, "macOS", {"High Sierra", {10, 13, 1}}},
"17B1002" = {{17, 2, 0}, "macOS", {"High Sierra", {10, 13, 1}}},
"17B1003" = {{17, 2, 0}, "macOS", {"High Sierra", {10, 13, 1}}},
"17C88" = {{17, 3, 0}, "macOS", {"High Sierra", {10, 13, 2}}},
"17C89" = {{17, 3, 0}, "macOS", {"High Sierra", {10, 13, 2}}},
"17C205" = {{17, 3, 0}, "macOS", {"High Sierra", {10, 13, 2}}},
"17C2205" = {{17, 3, 0}, "macOS", {"High Sierra", {10, 13, 2}}},
"17D47" = {{17, 4, 0}, "macOS", {"High Sierra", {10, 13, 3}}},
"17D2047" = {{17, 4, 0}, "macOS", {"High Sierra", {10, 13, 3}}},
"17D102" = {{17, 4, 0}, "macOS", {"High Sierra", {10, 13, 3}}},
"17D2102" = {{17, 4, 0}, "macOS", {"High Sierra", {10, 13, 3}}},
"17E199" = {{17, 5, 0}, "macOS", {"High Sierra", {10, 13, 4}}},
"17E202" = {{17, 5, 0}, "macOS", {"High Sierra", {10, 13, 4}}},
"17F77" = {{17, 6, 0}, "macOS", {"High Sierra", {10, 13, 5}}},
"17G65" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G2208" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G2307" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G3025" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G4015" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G5019" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G6029" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G6030" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G7024" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G8029" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G8030" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G8037" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G9016" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G10021" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G11023" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G12034" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G13033" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G13035" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G14019" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G14033" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
"17G14042" = {{17, 7, 0}, "macOS", {"High Sierra", {10, 13, 6}}},
// MacOS Mojave
"18A391" = {{18, 0, 0}, "macOS", {"Mojave", {10, 14, 0}}},
"18B75" = {{18, 2, 0}, "macOS", {"Mojave", {10, 14, 1}}},
"18B2107" = {{18, 2, 0}, "macOS", {"Mojave", {10, 14, 1}}},
"18B3094" = {{18, 2, 0}, "macOS", {"Mojave", {10, 14, 1}}},
"18C54" = {{18, 2, 0}, "macOS", {"Mojave", {10, 14, 2}}},
"18D42" = {{18, 2, 0}, "macOS", {"Mojave", {10, 14, 3}}},
"18D43" = {{18, 2, 0}, "macOS", {"Mojave", {10, 14, 3}}},
"18D109" = {{18, 2, 0}, "macOS", {"Mojave", {10, 14, 3}}},
"18E226" = {{18, 5, 0}, "macOS", {"Mojave", {10, 14, 4}}},
"18E227" = {{18, 5, 0}, "macOS", {"Mojave", {10, 14, 4}}},
"18F132" = {{18, 6, 0}, "macOS", {"Mojave", {10, 14, 5}}},
"18G84" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G87" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G95" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G103" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G1012" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G2022" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G3020" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G4032" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G5033" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G6020" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G6032" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G6042" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G7016" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G8012" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G8022" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G9028" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G9216" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
"18G9323" = {{18, 7, 0}, "macOS", {"Mojave", {10, 14, 6}}},
// MacOS Catalina
"19A583" = {{19, 0, 0}, "macOS", {"Catalina", {10, 15, 0}}},
"19A602" = {{19, 0, 0}, "macOS", {"Catalina", {10, 15, 0}}},
"19A603" = {{19, 0, 0}, "macOS", {"Catalina", {10, 15, 0}}},
"19B88" = {{19, 0, 0}, "macOS", {"Catalina", {10, 15, 1}}},
"19C57" = {{19, 2, 0}, "macOS", {"Catalina", {10, 15, 2}}},
"19C58" = {{19, 2, 0}, "macOS", {"Catalina", {10, 15, 2}}},
"19D76" = {{19, 3, 0}, "macOS", {"Catalina", {10, 15, 3}}},
"19E266" = {{19, 4, 0}, "macOS", {"Catalina", {10, 15, 4}}},
"19E287" = {{19, 4, 0}, "macOS", {"Catalina", {10, 15, 4}}},
"19F96" = {{19, 5, 0}, "macOS", {"Catalina", {10, 15, 5}}},
"19F101" = {{19, 5, 0}, "macOS", {"Catalina", {10, 15, 5}}},
"19G73" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 6}}},
"19G2021" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 6}}},
"19H2" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H4" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H15" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H114" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H512" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H524" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1030" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1217" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1323" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1417" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1419" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1519" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1615" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1713" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1715" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1824" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H1922" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
"19H2026" = {{19, 6, 0}, "macOS", {"Catalina", {10, 15, 7}}},
// MacOS Big Sur
"20A2411" = {{20, 1, 0}, "macOS", {"Big Sur", {11, 0, 0}}},
"20B29" = {{20, 1, 0}, "macOS", {"Big Sur", {11, 0, 1}}},
"20B50" = {{20, 1, 0}, "macOS", {"Big Sur", {11, 0, 1}}},
"20C69" = {{20, 2, 0}, "macOS", {"Big Sur", {11, 1, 0}}},
"20D64" = {{20, 3, 0}, "macOS", {"Big Sur", {11, 2, 0}}},
"20D74" = {{20, 3, 0}, "macOS", {"Big Sur", {11, 2, 1}}},
"20D75" = {{20, 3, 0}, "macOS", {"Big Sur", {11, 2, 1}}},
"20D80" = {{20, 3, 0}, "macOS", {"Big Sur", {11, 2, 2}}},
"20D91" = {{20, 3, 0}, "macOS", {"Big Sur", {11, 2, 3}}},
"20E232" = {{20, 4, 0}, "macOS", {"Big Sur", {11, 3, 0}}},
"20E241" = {{20, 4, 0}, "macOS", {"Big Sur", {11, 3, 1}}},
"20F71" = {{20, 5, 0}, "macOS", {"Big Sur", {11, 4, 0}}},
"20G71" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 5, 0}}},
"20G80" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 5, 1}}},
"20G95" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 5, 2}}},
"20G165" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 0}}},
"20G224" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 1}}},
"20G314" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 2}}},
"20G415" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 3}}},
"20G417" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 4}}},
"20G527" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 5}}},
"20G624" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 6}}},
"20G630" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 7}}},
"20G730" = {{20, 6, 0}, "macOS", {"Big Sur", {11, 6, 8}}},
// MacOS Monterey
"21A344" = {{21, 0, 1}, "macOS", {"Monterey", {12, 0, 0}}},
"21A559" = {{21, 1, 0}, "macOS", {"Monterey", {12, 0, 1}}},
"21C52" = {{21, 2, 0}, "macOS", {"Monterey", {12, 1, 0}}},
"21D49" = {{21, 3, 0}, "macOS", {"Monterey", {12, 2, 0}}},
"21D62" = {{21, 3, 0}, "macOS", {"Monterey", {12, 2, 1}}},
"21E230" = {{21, 4, 0}, "macOS", {"Monterey", {12, 3, 0}}},
"21E258" = {{21, 4, 0}, "macOS", {"Monterey", {12, 3, 1}}},
"21F79" = {{21, 5, 0}, "macOS", {"Monterey", {12, 4, 0}}},
"21F2081" = {{21, 5, 0}, "macOS", {"Monterey", {12, 4, 0}}},
"21F2092" = {{21, 5, 0}, "macOS", {"Monterey", {12, 4, 0}}},
"21G72" = {{21, 6, 0}, "macOS", {"Monterey", {12, 5, 0}}},
"21G83" = {{21, 6, 0}, "macOS", {"Monterey", {12, 5, 1}}},
}
@(private)
Darwin_Match :: enum {
Unknown,
Exact,
Nearest,
}
@(private)
map_darwin_kernel_version_to_macos_release :: proc(build: string, darwin: [3]int) -> (res: Darwin_To_Release, match: Darwin_Match) {
// Find exact release match if possible.
if v, v_ok := macos_release_map[build]; v_ok {
return v, .Exact
}
nearest: Darwin_To_Release
for _, v in macos_release_map {
// Try an exact match on XNU version first.
if darwin == v.darwin {
return v, .Exact
}
// Major kernel version needs to match exactly,
// otherwise the release is considered .Unknown
if darwin.x == v.darwin.x {
if nearest == {} {
nearest = v
}
if darwin.y >= v.darwin.y && v.darwin != nearest.darwin {
nearest = v
if darwin.z >= v.darwin.z && v.darwin != nearest.darwin {
nearest = v
}
}
}
}
if nearest == {} {
return {darwin, "macOS", {"Unknown", {}}}, .Unknown
} else {
return nearest, .Nearest
}
}

View File

@@ -0,0 +1,76 @@
// +build freebsd
package sysinfo
import sys "core:sys/unix"
import "core:strings"
import "core:strconv"
@(private)
version_string_buf: [1024]u8
@(init, private)
init_os_version :: proc () {
os_version.platform = .FreeBSD
kernel_version_buf: [129]u8
b := strings.builder_from_bytes(version_string_buf[:])
// Retrieve kernel info using `sysctl`, e.g. FreeBSD 13.1-RELEASE-p2 GENERIC
mib := []i32{sys.CTL_KERN, sys.KERN_VERSION}
if !sys.sysctl(mib, &kernel_version_buf) {
return
}
pretty_name := string(cstring(raw_data(kernel_version_buf[:])))
pretty_name = strings.trim(pretty_name, "\n")
strings.write_string(&b, pretty_name)
// l := strings.builder_len(b)
// Retrieve kernel revision using `sysctl`, e.g. 199506
mib = []i32{sys.CTL_KERN, sys.KERN_OSREV}
revision: int
if !sys.sysctl(mib, &revision) {
return
}
os_version.patch = revision
strings.write_string(&b, ", revision ")
strings.write_int(&b, revision)
// Finalize pretty name.
os_version.as_string = strings.to_string(b)
// Retrieve kernel release using `sysctl`, e.g. 13.1-RELEASE-p2
mib = []i32{sys.CTL_KERN, sys.KERN_OSRELEASE}
if !sys.sysctl(mib, &kernel_version_buf) {
return
}
// Parse kernel version
release := string(cstring(raw_data(kernel_version_buf[:])))
version_bits := strings.split_n(release, "-", 2, context.temp_allocator)
if len(version_bits) > 1 {
// Parse major, minor from KERN_OSRELEASE
triplet := strings.split(version_bits[0], ".", context.temp_allocator)
if len(triplet) == 2 {
major, major_ok := strconv.parse_int(triplet[0])
minor, minor_ok := strconv.parse_int(triplet[1])
if major_ok && minor_ok {
os_version.major = major
os_version.minor = minor
}
}
}
}
@(init)
init_ram :: proc() {
// Retrieve RAM info using `sysctl`
mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM}
mem_size: u64
if sys.sysctl(mib, &mem_size) {
ram.total_ram = int(mem_size)
}
}

View File

@@ -0,0 +1,136 @@
// +build linux
package sysinfo
import "core:c"
import sys "core:sys/unix"
import "core:intrinsics"
import "core:os"
import "core:strings"
import "core:strconv"
@(private)
version_string_buf: [1024]u8
@(init, private)
init_os_version :: proc () {
os_version.platform = .Linux
// Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
fd, err := os.open("/etc/os-release", os.O_RDONLY, 0)
if err != 0 {
return
}
defer os.close(fd)
os_release_buf: [2048]u8
n, read_err := os.read(fd, os_release_buf[:])
if read_err != 0 {
return
}
release := string(os_release_buf[:n])
NEEDLE :: "PRETTY_NAME=\""
pretty_start := strings.index(release, NEEDLE)
b := strings.builder_from_bytes(version_string_buf[:])
if pretty_start > 0 {
for r, i in release[pretty_start + len(NEEDLE):] {
if r == '"' {
strings.write_string(&b, release[pretty_start + len(NEEDLE):][:i])
break
} else if r == '\r' || r == '\n' {
strings.write_string(&b, "Unknown Linux Distro")
break
}
}
}
NEW_UTS_LEN :: 64
UTS_Name :: struct {
sys_name: [NEW_UTS_LEN + 1]u8 `fmt:"s,0"`,
node_name: [NEW_UTS_LEN + 1]u8 `fmt:"s,0"`,
release: [NEW_UTS_LEN + 1]u8 `fmt:"s,0"`,
version: [NEW_UTS_LEN + 1]u8 `fmt:"s,0"`,
machine: [NEW_UTS_LEN + 1]u8 `fmt:"s,0"`,
domain_name: [NEW_UTS_LEN + 1]u8 `fmt:"s,0"`,
}
uts: UTS_Name
// Grab kernel info using `uname()` syscall, https://linux.die.net/man/2/uname
if intrinsics.syscall(sys.SYS_uname, uintptr(&uts)) != 0 {
return
}
strings.write_string(&b, ", ")
strings.write_string(&b, string(cstring(&uts.sys_name[0])))
strings.write_rune(&b, ' ')
l := strings.builder_len(b)
strings.write_string(&b, string(cstring(&uts.release[0])))
// Parse kernel version, as substrings of the version info in `version_string_buf`
version_bits := strings.split_n(strings.to_string(b)[l:], "-", 2, context.temp_allocator)
if len(version_bits) > 1 {
os_version.version = version_bits[1]
}
// Parse major, minor, patch from release info
triplet := strings.split(version_bits[0], ".", context.temp_allocator)
if len(triplet) == 3 {
major, major_ok := strconv.parse_int(triplet[0])
minor, minor_ok := strconv.parse_int(triplet[1])
patch, patch_ok := strconv.parse_int(triplet[2])
if major_ok && minor_ok && patch_ok {
os_version.major = major
os_version.minor = minor
os_version.patch = patch
}
}
// Finish the string
os_version.as_string = strings.to_string(b)
}
Sys_Info :: struct {
uptime: c.long, // Seconds since boot
loads: [3]c.long, // 1, 5, 15 minute load averages
totalram: c.ulong, // Total usable main memory size
freeram: c.ulong, // Available memory size
sharedram: c.ulong, // Amount of shared memory
bufferram: c.ulong, // Memory used by buffers
totalswap: c.ulong, // Total swap space size
freeswap: c.ulong, // Swap space still available
procs: c.ushort, // Number of current processes
totalhigh: c.ulong, // Total high memory size
freehigh: c.ulong, // Available high memory size
mem_unit: c.int, // Memory unit size in bytes
_padding: [20 - (2 * size_of(c.long)) - size_of(c.int)]u8,
}
get_sysinfo :: proc "c" () -> (res: Sys_Info, ok: bool) {
si: Sys_Info
err := intrinsics.syscall(sys.SYS_sysinfo, uintptr(rawptr(&si)))
if err != 0 {
// Unable to retrieve sysinfo
return {}, false
}
return si, true
}
@(init)
init_ram :: proc() {
// Retrieve RAM info using `sysinfo`
si, ok := get_sysinfo()
if !ok {
return
}
ram = RAM{
total_ram = int(si.totalram) * int(si.mem_unit),
free_ram = int(si.freeram) * int(si.mem_unit),
total_swap = int(si.totalswap) * int(si.mem_unit),
free_swap = int(si.freeswap) * int(si.mem_unit),
}
}

View File

@@ -0,0 +1,69 @@
// +build openbsd
package sysinfo
import sys "core:sys/unix"
import "core:strings"
import "core:strconv"
@(private)
version_string_buf: [1024]u8
@(init, private)
init_os_version :: proc () {
os_version.platform = .OpenBSD
kernel_version_buf: [1024]u8
b := strings.builder_from_bytes(version_string_buf[:])
// Retrieve kernel info using `sysctl`, e.g. OpenBSD
mib := []i32{sys.CTL_KERN, sys.KERN_OSTYPE}
if !sys.sysctl(mib, &kernel_version_buf) {
return
}
os_type := string(cstring(raw_data(kernel_version_buf[:])))
strings.write_string(&b, os_type)
mib = []i32{sys.CTL_KERN, sys.KERN_OSRELEASE}
if !sys.sysctl(mib, &kernel_version_buf) {
return
}
strings.write_rune(&b, ' ')
version := string(cstring(raw_data(kernel_version_buf[:])))
strings.write_string(&b, version)
// // Parse kernel version
triplet := strings.split(version, ".", context.temp_allocator)
if len(triplet) == 2 {
major, major_ok := strconv.parse_int(triplet[0])
minor, minor_ok := strconv.parse_int(triplet[1])
if major_ok && minor_ok {
os_version.major = major
os_version.minor = minor
}
}
// Retrieve kernel revision using `sysctl`, e.g. 199506
mib = []i32{sys.CTL_KERN, sys.KERN_OSREV}
revision: int
if !sys.sysctl(mib, &revision) {
return
}
os_version.patch = revision
strings.write_string(&b, ", build ")
strings.write_int(&b, revision)
// Finalize pretty name.
os_version.as_string = strings.to_string(b)
}
@(init)
init_ram :: proc() {
// Retrieve RAM info using `sysctl`
mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM64}
mem_size: u64
if sys.sysctl(mib, &mem_size) {
ram.total_ram = int(mem_size)
}
}

View File

@@ -0,0 +1,375 @@
// +build windows
package sysinfo
import sys "core:sys/windows"
import "core:intrinsics"
import "core:strings"
import "core:unicode/utf16"
import "core:fmt"
@(private)
version_string_buf: [1024]u8
@(init, private)
init_os_version :: proc () {
/*
NOTE(Jeroen):
`GetVersionEx` will return 6.2 for Windows 10 unless the program is manifested for Windows 10.
`RtlGetVersion` will return the true version.
Rather than include the WinDDK, we ask the kernel directly.
`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion` is for the minor build version (Update Build Release)
*/
os_version.platform = .Windows
osvi: sys.OSVERSIONINFOEXW
osvi.dwOSVersionInfoSize = size_of(osvi)
status := sys.RtlGetVersion(&osvi)
if status != 0 {
return
}
product_type: sys.Windows_Product_Type
sys.GetProductInfo(
osvi.dwMajorVersion, osvi.dwMinorVersion,
u32(osvi.wServicePackMajor), u32(osvi.wServicePackMinor),
&product_type,
)
os_version.major = int(osvi.dwMajorVersion)
os_version.minor = int(osvi.dwMinorVersion)
os_version.build[0] = int(osvi.dwBuildNumber)
b := strings.builder_from_bytes(version_string_buf[:])
strings.write_string(&b, "Windows ")
switch osvi.dwMajorVersion {
case 10:
switch osvi.wProductType {
case 1: // VER_NT_WORKSTATION:
if osvi.dwBuildNumber < 22000 {
strings.write_string(&b, "10 ")
} else {
strings.write_string(&b, "11 ")
}
format_windows_product_type(&b, product_type)
case: // Server or Domain Controller
switch osvi.dwBuildNumber {
case 14393:
strings.write_string(&b, "2016 Server")
case 17763:
strings.write_string(&b, "2019 Server")
case 20348:
strings.write_string(&b, "2022 Server")
case:
strings.write_string(&b, "Unknown Server")
}
}
case 6:
switch osvi.dwMinorVersion {
case 0:
switch osvi.wProductType {
case 1: // VER_NT_WORKSTATION
strings.write_string(&b, "Windows Vista ")
format_windows_product_type(&b, product_type)
case 3:
strings.write_string(&b, "Windows Server 2008")
}
case 1:
switch osvi.wProductType {
case 1: // VER_NT_WORKSTATION:
strings.write_string(&b, "Windows 7 ")
format_windows_product_type(&b, product_type)
case 3:
strings.write_string(&b, "Windows Server 2008 R2")
}
case 2:
switch osvi.wProductType {
case 1: // VER_NT_WORKSTATION:
strings.write_string(&b, "Windows 8 ")
format_windows_product_type(&b, product_type)
case 3:
strings.write_string(&b, "Windows Server 2012")
}
case 3:
switch osvi.wProductType {
case 1: // VER_NT_WORKSTATION:
strings.write_string(&b, "Windows 8.1 ")
format_windows_product_type(&b, product_type)
case 3:
strings.write_string(&b, "Windows Server 2012 R2")
}
}
case 5:
switch osvi.dwMinorVersion {
case 0:
strings.write_string(&b, "Windows 2000")
case 1:
strings.write_string(&b, "Windows XP")
case 2:
strings.write_string(&b, "Windows Server 2003")
}
}
// Grab DisplayVersion
os_version.version = format_display_version(&b)
// Grab build number and UBR
os_version.build[1] = format_build_number(&b, int(osvi.dwBuildNumber))
// Finish the string
os_version.as_string = strings.to_string(b)
format_windows_product_type :: proc (b: ^strings.Builder, prod_type: sys.Windows_Product_Type) {
#partial switch prod_type {
case .ULTIMATE:
strings.write_string(b, "Ultimate")
case .HOME_BASIC:
strings.write_string(b, "Home Basic")
case .HOME_PREMIUM:
strings.write_string(b, "Home Premium")
case .ENTERPRISE:
strings.write_string(b, "Enterprise")
case .CORE:
strings.write_string(b, "Home Basic")
case .HOME_BASIC_N:
strings.write_string(b, "Home Basic N")
case .EDUCATION:
strings.write_string(b, "Education")
case .EDUCATION_N:
strings.write_string(b, "Education N")
case .BUSINESS:
strings.write_string(b, "Business")
case .STANDARD_SERVER:
strings.write_string(b, "Standard Server")
case .DATACENTER_SERVER:
strings.write_string(b, "Datacenter")
case .SMALLBUSINESS_SERVER:
strings.write_string(b, "Windows Small Business Server")
case .ENTERPRISE_SERVER:
strings.write_string(b, "Enterprise Server")
case .STARTER:
strings.write_string(b, "Starter")
case .DATACENTER_SERVER_CORE:
strings.write_string(b, "Datacenter Server Core")
case .STANDARD_SERVER_CORE:
strings.write_string(b, "Server Standard Core")
case .ENTERPRISE_SERVER_CORE:
strings.write_string(b, "Enterprise Server Core")
case .BUSINESS_N:
strings.write_string(b, "Business N")
case .HOME_SERVER:
strings.write_string(b, "Home Server")
case .SERVER_FOR_SMALLBUSINESS:
strings.write_string(b, "Windows Server 2008 for Windows Essential Server Solutions")
case .SMALLBUSINESS_SERVER_PREMIUM:
strings.write_string(b, "Small Business Server Premium")
case .HOME_PREMIUM_N:
strings.write_string(b, "Home Premium N")
case .ENTERPRISE_N:
strings.write_string(b, "Enterprise N")
case .ULTIMATE_N:
strings.write_string(b, "Ultimate N")
case .HYPERV:
strings.write_string(b, "HyperV")
case .STARTER_N:
strings.write_string(b, "Starter N")
case .PROFESSIONAL:
strings.write_string(b, "Professional")
case .PROFESSIONAL_N:
strings.write_string(b, "Professional N")
case:
strings.write_string(b, "Unknown Edition")
}
}
// Grab Windows DisplayVersion (like 20H02)
format_display_version :: proc (b: ^strings.Builder) -> (version: string) {
dv, ok := read_reg(
sys.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
"DisplayVersion",
string,
)
defer delete(dv) // It'll be interned into `version_string_buf`
if ok {
strings.write_string(b, " (version: ")
l := strings.builder_len(b^)
strings.write_string(b, dv)
version = strings.to_string(b^)[l:][:len(dv)]
strings.write_rune(b, ')')
}
return
}
// Grab build number and UBR
format_build_number :: proc (b: ^strings.Builder, major_build: int) -> (ubr: int) {
res, ok := read_reg(
sys.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
"UBR",
i32,
)
if ok {
ubr = int(res)
strings.write_string(b, ", build: ")
strings.write_int(b, major_build)
strings.write_rune(b, '.')
strings.write_int(b, ubr)
}
return
}
}
@(init)
init_ram :: proc() {
state: sys.MEMORYSTATUSEX
state.dwLength = size_of(state)
ok := sys.GlobalMemoryStatusEx(&state)
if !ok {
return
}
ram = RAM{
total_ram = int(state.ullTotalPhys),
free_ram = int(state.ullAvailPhys),
total_swap = int(state.ullTotalPageFil),
free_swap = int(state.ullAvailPageFil),
}
}
@(init, private)
init_gpu_info :: proc() {
GPU_INFO_BASE :: "SYSTEM\\ControlSet001\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\"
gpu_list: [dynamic]GPU
gpu_index: int
for {
key := fmt.tprintf("%v\\%04d", GPU_INFO_BASE, gpu_index)
if vendor, ok := read_reg(sys.HKEY_LOCAL_MACHINE, key, "ProviderName", string); ok {
append(&gpu_list, GPU{vendor_name = vendor})
} else {
break
}
if desc, ok := read_reg(sys.HKEY_LOCAL_MACHINE, key, "DriverDesc", string); ok {
gpu_list[gpu_index].model_name = desc
}
if vram, ok := read_reg(sys.HKEY_LOCAL_MACHINE, key, "HardwareInformation.qwMemorySize", i64); ok {
gpu_list[gpu_index].total_ram = int(vram)
}
gpu_index += 1
}
gpus = gpu_list[:]
}
@(private)
read_reg :: proc(hkey: sys.HKEY, subkey, val: string, $T: typeid) -> (res: T, ok: bool) {
BUF_SIZE :: 1024
if len(subkey) == 0 || len(val) == 0 {
return {}, false
}
key_name_wide := make([]u16, BUF_SIZE, context.temp_allocator)
val_name_wide := make([]u16, BUF_SIZE, context.temp_allocator)
utf16.encode_string(key_name_wide, subkey)
utf16.encode_string(val_name_wide, val)
when T == string {
result_wide := make([]u16, BUF_SIZE, context.temp_allocator)
result_size := sys.DWORD(BUF_SIZE * size_of(u16))
status := sys.RegGetValueW(
hkey,
&key_name_wide[0],
&val_name_wide[0],
sys.RRF_RT_REG_SZ,
nil,
raw_data(result_wide[:]),
&result_size,
)
if status != 0 {
// Couldn't retrieve string
return
}
// Result string will be allocated for the caller.
result_utf8 := make([]u8, BUF_SIZE * 4, context.temp_allocator)
utf16.decode_to_utf8(result_utf8, result_wide[:result_size])
return strings.clone_from_cstring(cstring(raw_data(result_utf8))), true
} else when T == i32 {
result_size := sys.DWORD(size_of(i32))
status := sys.RegGetValueW(
hkey,
&key_name_wide[0],
&val_name_wide[0],
sys.RRF_RT_REG_DWORD,
nil,
&res,
&result_size,
)
return res, status == 0
} else when T == i64 {
result_size := sys.DWORD(size_of(i64))
status := sys.RegGetValueW(
hkey,
&key_name_wide[0],
&val_name_wide[0],
sys.RRF_RT_REG_QWORD,
nil,
&res,
&result_size,
)
return res, status == 0
} else {
#assert(false, "Unhandled type for read_reg")
}
return
}

View File

@@ -0,0 +1,45 @@
package sysinfo
when !(ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 || ODIN_ARCH == .arm32 || ODIN_ARCH == .arm64) {
#assert(false, "This package is unsupported on this architecture.")
}
os_version: OS_Version
ram: RAM
gpus: []GPU
OS_Version_Platform :: enum {
Unknown,
Windows,
Linux,
MacOS,
iOS,
FreeBSD,
OpenBSD,
NetBSD,
}
OS_Version :: struct {
platform: OS_Version_Platform,
major: int,
minor: int,
patch: int,
build: [2]int,
version: string,
as_string: string,
}
RAM :: struct {
total_ram: int,
free_ram: int,
total_swap: int,
free_swap: int,
}
GPU :: struct {
vendor_name: string,
model_name: string,
total_ram: int,
}

View File

@@ -0,0 +1,7 @@
package unix
// FreeBSD 13 syscall numbers
// See: https://alfonsosiciliano.gitlab.io/posts/2021-01-02-freebsd-system-calls-table.html
SYS_uname : uintptr : 164
SYS_sysctl : uintptr : 202

View File

@@ -0,0 +1,6 @@
package unix
// OpenBSD 7.1 syscall numbers
// See: /usr/include/sys/syscall.h
SYS_sysctl : uintptr : 202

View File

@@ -0,0 +1,45 @@
//+build darwin
package unix
import "core:sys/darwin"
import "core:intrinsics"
_ :: darwin
sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) {
mib := mib
result_size := i64(size_of(T))
res := intrinsics.syscall(
darwin.unix_offset_syscall(.sysctl),
uintptr(raw_data(mib)), uintptr(len(mib)),
uintptr(val), uintptr(&result_size),
uintptr(0), uintptr(0),
)
return res == 0
}
// See sysctl.h for darwin for details
CTL_KERN :: 1
KERN_OSTYPE :: 1 // Darwin
KERN_OSRELEASE :: 2 // 21.5.0 for 12.4 Monterey
KERN_OSREV :: 3 // i32: system revision
KERN_VERSION :: 4 // Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:22 PDT 2022; root:darwin-8020.121.3~4/RELEASE_X86_64
KERN_OSRELDATE :: 26 // i32: OS release date
KERN_OSVERSION :: 65 // Build number, e.g. 21F79
CTL_VM :: 2
CTL_VFS :: 3
CTL_NET :: 4
CTL_DEBUG :: 5
CTL_HW :: 6
HW_MACHINE :: 1 // x86_64
HW_MODEL :: 2 // MacbookPro14,1
HW_NCPU :: 3 /* int: number of cpus */
HW_BYTEORDER :: 4 /* int: machine byte order */
HW_MACHINE_ARCH :: 12 /* string: machine architecture */
HW_VECTORUNIT :: 13 /* int: has HW vector unit? */
HW_MEMSIZE :: 24 // u64
HW_AVAILCPU :: 25 /* int: number of available CPUs */
CTL_MACHDEP :: 7
CTL_USER :: 8

View File

@@ -0,0 +1,44 @@
//+build freebsd
package unix
import "core:intrinsics"
sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) {
mib := mib
result_size := i64(size_of(T))
res := intrinsics.syscall(SYS_sysctl,
uintptr(raw_data(mib)), uintptr(len(mib)),
uintptr(val), uintptr(&result_size),
uintptr(0), uintptr(0),
)
return res == 0
}
// See /usr/include/sys/sysctl.h for details
CTL_SYSCTL :: 0
CTL_KERN :: 1
KERN_OSTYPE :: 1
KERN_OSRELEASE :: 2
KERN_OSREV :: 3
KERN_VERSION :: 4
CTL_VM :: 2
CTL_VFS :: 3
CTL_NET :: 4
CTL_DEBUG :: 5
CTL_HW :: 6
HW_MACHINE :: 1
HW_MODEL :: 2
HW_NCPU :: 3
HW_BYTEORDER :: 4
HW_PHYSMEM :: 5
HW_USERMEM :: 6
HW_PAGESIZE :: 7
HW_DISKNAMES :: 8
HW_DISKSTATS :: 9
HW_FLOATINGPT :: 10
HW_MACHINE_ARCH :: 11
HW_REALMEM :: 12
CTL_MACHDEP :: 7
CTL_USER :: 8
CTL_P1003_1B :: 9

View File

@@ -0,0 +1,49 @@
//+build openbsd
package unix
import "core:c"
foreign import libc "system:c"
@(default_calling_convention="c")
foreign libc {
@(link_name="sysctl") _unix_sysctl :: proc(name: [^]i32, namelen: u32, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> i32 ---
}
sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) {
mib := mib
result_size := c.size_t(size_of(T))
res := _unix_sysctl(raw_data(mib), u32(len(mib)), val, &result_size, nil, 0)
return res == 0
}
// See /usr/include/sys/sysctl.h for details
CTL_SYSCTL :: 0
CTL_KERN :: 1
KERN_OSTYPE :: 1
KERN_OSRELEASE :: 2
KERN_OSREV :: 3
KERN_VERSION :: 4
CTL_VM :: 2
CTL_FS :: 3
CTL_NET :: 4
CTL_DEBUG :: 5
CTL_HW :: 6
HW_MACHINE :: 1
HW_MODEL :: 2
HW_NCPU :: 3
HW_BYTEORDER :: 4
HW_PHYSMEM :: 5
HW_USERMEM :: 6
HW_PAGESIZE :: 7
HW_DISKNAMES :: 8
HW_DISKSTATS :: 9
HW_DISKCOUNT :: 10
HW_SENSORS :: 11
HW_CPUSPEED :: 12
HW_SETPERF :: 13
HW_VENDOR :: 14
HW_PRODUCT :: 15
HW_VERSION :: 16
HW_SERIALNO :: 17
HW_UUID :: 18
HW_PHYSMEM64 :: 19

View File

@@ -657,6 +657,13 @@ foreign kernel32 {
) -> BOOL ---
}
@(default_calling_convention="stdcall")
foreign kernel32 {
GlobalMemoryStatusEx :: proc(
lpBuffer: ^MEMORYSTATUSEX,
) -> BOOL ---
}
PBAD_MEMORY_CALLBACK_ROUTINE :: #type proc "stdcall" ()
@(default_calling_convention="stdcall")
@@ -800,5 +807,16 @@ foreign kernel32 {
) -> BOOL ---
}
@(default_calling_convention="stdcall")
foreign kernel32 {
GetProductInfo :: proc(
OSMajorVersion: DWORD,
OSMinorVersion: DWORD,
SpMajorVersion: DWORD,
SpMinorVersion: DWORD,
product_type: ^Windows_Product_Type,
) -> BOOL ---
}
HandlerRoutine :: proc "stdcall" (dwCtrlType: DWORD) -> BOOL
PHANDLER_ROUTINE :: HandlerRoutine

View File

@@ -17,6 +17,7 @@ size_t :: c.size_t
wchar_t :: c.wchar_t
DWORD :: c_ulong
DWORDLONG :: c.ulonglong
QWORD :: c.ulonglong
HANDLE :: distinct LPVOID
HINSTANCE :: HANDLE
@@ -3298,6 +3299,119 @@ IFileSaveDialogVtbl :: struct {
ApplyProperties: proc "stdcall" (this: ^IFileSaveDialog, psi: ^IShellItem, pStore: ^IPropertyStore, hwnd: HWND, pSink: ^IFileOperationProgressSink) -> HRESULT,
}
MEMORYSTATUSEX :: struct {
dwLength: DWORD,
dwMemoryLoad: DWORD,
ullTotalPhys: DWORDLONG,
ullAvailPhys: DWORDLONG,
ullTotalPageFil: DWORDLONG,
ullAvailPageFil: DWORDLONG,
ullTotalVirtual: DWORDLONG,
ullAvailVirtual: DWORDLONG,
ullAvailExtendedVirtual: DWORDLONG,
}
Windows_Product_Type :: enum DWORD {
BUSINESS = 0x00000006, // Business
BUSINESS_N = 0x00000010, // Business N
CLUSTER_SERVER = 0x00000012, // HPC Edition
CLUSTER_SERVER_V = 0x00000040, // Server Hyper Core V
CORE = 0x00000065, // Windows 10 Home
CORE_COUNTRYSPECIFIC = 0x00000063, // Windows 10 Home China
CORE_N = 0x00000062, // Windows 10 Home N
CORE_SINGLELANGUAGE = 0x00000064, // Windows 10 Home Single Language
DATACENTER_EVALUATION_SERVER = 0x00000050, // Server Datacenter (evaluation installation)
DATACENTER_A_SERVER_CORE = 0x00000091, // Server Datacenter, Semi-Annual Channel (core installation)
STANDARD_A_SERVER_CORE = 0x00000092, // Server Standard, Semi-Annual Channel (core installation)
DATACENTER_SERVER = 0x00000008, // Server Datacenter (full installation. For Server Core installations of Windows Server 2012 and later, use the method, Determining whether Server Core is running.)
DATACENTER_SERVER_CORE = 0x0000000C, // Server Datacenter (core installation, Windows Server 2008 R2 and earlier)
DATACENTER_SERVER_CORE_V = 0x00000027, // Server Datacenter without Hyper-V (core installation)
DATACENTER_SERVER_V = 0x00000025, // Server Datacenter without Hyper-V (full installation)
EDUCATION = 0x00000079, // Windows 10 Education
EDUCATION_N = 0x0000007A, // Windows 10 Education N
ENTERPRISE = 0x00000004, // Windows 10 Enterprise
ENTERPRISE_E = 0x00000046, // Windows 10 Enterprise E
ENTERPRISE_EVALUATION = 0x00000048, // Windows 10 Enterprise Evaluation
ENTERPRISE_N = 0x0000001B, // Windows 10 Enterprise N
ENTERPRISE_N_EVALUATION = 0x00000054, // Windows 10 Enterprise N Evaluation
ENTERPRISE_S = 0x0000007D, // Windows 10 Enterprise 2015 LTSB
ENTERPRISE_S_EVALUATION = 0x00000081, // Windows 10 Enterprise 2015 LTSB Evaluation
ENTERPRISE_S_N = 0x0000007E, // Windows 10 Enterprise 2015 LTSB N
ENTERPRISE_S_N_EVALUATION = 0x00000082, // Windows 10 Enterprise 2015 LTSB N Evaluation
ENTERPRISE_SERVER = 0x0000000A, // Server Enterprise (full installation)
ENTERPRISE_SERVER_CORE = 0x0000000E, // Server Enterprise (core installation)
ENTERPRISE_SERVER_CORE_V = 0x00000029, // Server Enterprise without Hyper-V (core installation)
ENTERPRISE_SERVER_IA64 = 0x0000000F, // Server Enterprise for Itanium-based Systems
ENTERPRISE_SERVER_V = 0x00000026, // Server Enterprise without Hyper-V (full installation)
ESSENTIALBUSINESS_SERVER_ADDL = 0x0000003C, // Windows Essential Server Solution Additional
ESSENTIALBUSINESS_SERVER_ADDLSVC = 0x0000003E, // Windows Essential Server Solution Additional SVC
ESSENTIALBUSINESS_SERVER_MGMT = 0x0000003B, // Windows Essential Server Solution Management
ESSENTIALBUSINESS_SERVER_MGMTSVC = 0x0000003D, // Windows Essential Server Solution Management SVC
HOME_BASIC = 0x00000002, // Home Basic
HOME_BASIC_E = 0x00000043, // Not supported
HOME_BASIC_N = 0x00000005, // Home Basic N
HOME_PREMIUM = 0x00000003, // Home Premium
HOME_PREMIUM_E = 0x00000044, // Not supported
HOME_PREMIUM_N = 0x0000001A, // Home Premium N
HOME_PREMIUM_SERVER = 0x00000022, // Windows Home Server 2011
HOME_SERVER = 0x00000013, // Windows Storage Server 2008 R2 Essentials
HYPERV = 0x0000002A, // Microsoft Hyper-V Server
IOTENTERPRISE = 0x000000BC, // Windows IoT Enterprise
IOTENTERPRISE_S = 0x000000BF, // Windows IoT Enterprise LTSC
IOTUAP = 0x0000007B, // Windows 10 IoT Core
IOTUAPCOMMERCIAL = 0x00000083, // Windows 10 IoT Core Commercial
MEDIUMBUSINESS_SERVER_MANAGEMENT = 0x0000001E, // Windows Essential Business Server Management Server
MEDIUMBUSINESS_SERVER_MESSAGING = 0x00000020, // Windows Essential Business Server Messaging Server
MEDIUMBUSINESS_SERVER_SECURITY = 0x0000001F, // Windows Essential Business Server Security Server
MOBILE_CORE = 0x00000068, // Windows 10 Mobile
MOBILE_ENTERPRISE = 0x00000085, // Windows 10 Mobile Enterprise
MULTIPOINT_PREMIUM_SERVER = 0x0000004D, // Windows MultiPoint Server Premium (full installation)
MULTIPOINT_STANDARD_SERVER = 0x0000004C, // Windows MultiPoint Server Standard (full installation)
PRO_WORKSTATION = 0x000000A1, // Windows 10 Pro for Workstations
PRO_WORKSTATION_N = 0x000000A2, // Windows 10 Pro for Workstations N
PROFESSIONAL = 0x00000030, // Windows 10 Pro
PROFESSIONAL_E = 0x00000045, // Not supported
PROFESSIONAL_N = 0x00000031, // Windows 10 Pro N
PROFESSIONAL_WMC = 0x00000067, // Professional with Media Center
SB_SOLUTION_SERVER = 0x00000032, // Windows Small Business Server 2011 Essentials
SB_SOLUTION_SERVER_EM = 0x00000036, // Server For SB Solutions EM
SERVER_FOR_SB_SOLUTIONS = 0x00000033, // Server For SB Solutions
SERVER_FOR_SB_SOLUTIONS_EM = 0x00000037, // Server For SB Solutions EM
SERVER_FOR_SMALLBUSINESS = 0x00000018, // Windows Server 2008 for Windows Essential Server Solutions
SERVER_FOR_SMALLBUSINESS_V = 0x00000023, // Windows Server 2008 without Hyper-V for Windows Essential Server Solutions
SERVER_FOUNDATION = 0x00000021, // Server Foundation
SMALLBUSINESS_SERVER = 0x00000009, // Windows Small Business Server
SMALLBUSINESS_SERVER_PREMIUM = 0x00000019, // Small Business Server Premium
SMALLBUSINESS_SERVER_PREMIUM_CORE = 0x0000003F, // Small Business Server Premium (core installation)
SOLUTION_EMBEDDEDSERVER = 0x00000038, // Windows MultiPoint Server
STANDARD_EVALUATION_SERVER = 0x0000004F, // Server Standard (evaluation installation)
STANDARD_SERVER = 0x00000007, // Server Standard (full installation. For Server Core installations of Windows Server 2012 and later, use the method, Determining whether Server Core is running.)
STANDARD_SERVER_CORE = 0x0000000D, // Server Standard (core installation, Windows Server 2008 R2 and earlier)
STANDARD_SERVER_CORE_V = 0x00000028, // Server Standard without Hyper-V (core installation)
STANDARD_SERVER_V = 0x00000024, // Server Standard without Hyper-V
STANDARD_SERVER_SOLUTIONS = 0x00000034, // Server Solutions Premium
STANDARD_SERVER_SOLUTIONS_CORE = 0x00000035, // Server Solutions Premium (core installation)
STARTER = 0x0000000B, // Starter
STARTER_E = 0x00000042, // Not supported
STARTER_N = 0x0000002F, // Starter N
STORAGE_ENTERPRISE_SERVER = 0x00000017, // Storage Server Enterprise
STORAGE_ENTERPRISE_SERVER_CORE = 0x0000002E, // Storage Server Enterprise (core installation)
STORAGE_EXPRESS_SERVER = 0x00000014, // Storage Server Express
STORAGE_EXPRESS_SERVER_CORE = 0x0000002B, // Storage Server Express (core installation)
STORAGE_STANDARD_EVALUATION_SERVER = 0x00000060, // Storage Server Standard (evaluation installation)
STORAGE_STANDARD_SERVER = 0x00000015, // Storage Server Standard
STORAGE_STANDARD_SERVER_CORE = 0x0000002C, // Storage Server Standard (core installation)
STORAGE_WORKGROUP_EVALUATION_SERVER = 0x0000005F, // Storage Server Workgroup (evaluation installation)
STORAGE_WORKGROUP_SERVER = 0x00000016, // Storage Server Workgroup
STORAGE_WORKGROUP_SERVER_CORE = 0x0000002D, // Storage Server Workgroup (core installation)
ULTIMATE = 0x00000001, // Ultimate
ULTIMATE_E = 0x00000047, // Not supported
ULTIMATE_N = 0x0000001C, // Ultimate N
UNDEFINED = 0x00000000, // An unknown product
WEB_SERVER = 0x00000011, // Web Server (full installation)
WEB_SERVER_CORE = 0x0000001D, // Web Server (core installation)
}
ENABLE_ECHO_INPUT : DWORD : 0x0004
ENABLE_INSERT_MODE : DWORD : 0x0020
ENABLE_LINE_INPUT : DWORD : 0x0002

View File

@@ -109,6 +109,8 @@ import i18n "core:text/i18n"
import thread "core:thread"
import time "core:time"
import sysinfo "core:sys/info"
import unicode "core:unicode"
import utf8 "core:unicode/utf8"
import utf8string "core:unicode/utf8/utf8string"
@@ -206,6 +208,7 @@ _ :: scanner
_ :: i18n
_ :: thread
_ :: time
_ :: sysinfo
_ :: unicode
_ :: utf8
_ :: utf8string

File diff suppressed because it is too large Load Diff

View File

@@ -590,8 +590,8 @@ void usage(String argv0) {
print_usage_line(1, "version print version");
print_usage_line(1, "report print information useful to reporting a bug");
print_usage_line(0, "");
print_usage_line(0, "For further details on a command, use -help after the command name");
print_usage_line(1, "e.g. odin build -help");
print_usage_line(0, "For further details on a command, invoke command help:");
print_usage_line(1, "e.g. `odin build -help` or `odin help build`");
}
enum BuildFlagKind {
@@ -1963,13 +1963,13 @@ void print_show_help(String const arg0, String const &command) {
print_usage_line(2, "Parse and type check .odin file(s) and then remove unneeded semicolons from the entire project");
}
bool doc = command == "doc";
bool build = command == "build";
bool run_or_build = command == "run" || command == "build" || command == "test";
bool test_only = command == "test";
bool doc = command == "doc";
bool build = command == "build";
bool run_or_build = command == "run" || command == "build" || command == "test";
bool test_only = command == "test";
bool strip_semicolon = command == "strip-semicolon";
bool check_only = command == "check" || strip_semicolon;
bool check = run_or_build || check_only;
bool check_only = command == "check" || strip_semicolon;
bool check = run_or_build || check_only;
print_usage_line(0, "");
print_usage_line(1, "Flags");
@@ -2085,7 +2085,7 @@ void print_show_help(String const arg0, String const &command) {
print_usage_line(3, "-build-mode:shared Build as a dynamically linked library");
print_usage_line(3, "-build-mode:obj Build as an object file");
print_usage_line(3, "-build-mode:object Build as an object file");
print_usage_line(3, "-build-mode:assembly Build as an object file");
print_usage_line(3, "-build-mode:assembly Build as an assembly file");
print_usage_line(3, "-build-mode:assembler Build as an assembly file");
print_usage_line(3, "-build-mode:asm Build as an assembly file");
print_usage_line(3, "-build-mode:llvm-ir Build as an LLVM IR file");
@@ -2701,6 +2701,14 @@ int main(int arg_count, char const **arg_ptr) {
build_context.command_kind = Command_bug_report;
print_bug_report_help();
return 0;
} else if (command == "help") {
if (args.count <= 2) {
usage(args[0]);
return 1;
} else {
print_show_help(args[0], args[2]);
return 0;
}
} else {
usage(args[0]);
return 1;
@@ -2727,7 +2735,12 @@ int main(int arg_count, char const **arg_ptr) {
if (!single_file_package) {
gb_printf_err("ERROR: `%.*s %.*s` takes a package as its first argument.\n", LIT(args[0]), LIT(command));
gb_printf_err("Did you mean `%.*s %.*s %.*s -file`?\n", LIT(args[0]), LIT(command), LIT(init_filename));
if (init_filename == "-file") {
gb_printf_err("Did you mean `%.*s %.*s <filename.odin> -file`?\n", LIT(args[0]), LIT(command));
} else {
gb_printf_err("Did you mean `%.*s %.*s %.*s -file`?\n", LIT(args[0]), LIT(command), LIT(init_filename));
}
gb_printf_err("The `-file` flag tells it to treat a file as a self-contained package.\n");
return 1;
} else {

View File

@@ -103,18 +103,7 @@ Window_alloc :: proc() -> ^Window {
@(objc_type=Window, objc_name="initWithContentRect")
Window_initWithContentRect :: proc (self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: bool) -> ^Window {
self := self
// HACK: due to a compiler bug, the generated calling code does not
// currently work for this message. Has to do with passing a struct along
// with other parameters, so we don't send the rect here.
// Omiting the rect argument here actually works, because of how the C
// calling conventions are defined.
self = msgSend(^Window, self, "initWithContentRect:styleMask:backing:defer:", styleMask, backing, doDefer)
// apply the contentRect now, since we did not pass it to the init call
msgSend(nil, self, "setContentSize:", contentRect.size)
msgSend(nil, self, "setFrameOrigin:", contentRect.origin)
return self
return msgSend(^Window, self, "initWithContentRect:styleMask:backing:defer:", contentRect, styleMask, backing, doDefer)
}
@(objc_type=Window, objc_name="contentView")
Window_contentView :: proc(self: ^Window) -> ^View {