Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/std/Target/Query.zig
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
/// Similar to `SemanticVersion.parse`, but with following changes:
/// * Leading zeroes are allowed.
/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
/// * Prerelease and build components are disallowed.
pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
const parseVersionComponentFn = (struct {
fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
Expand All @@ -348,11 +349,14 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
};
}
}).parseVersionComponentInner;

var version_components = mem.splitScalar(u8, ver, '.');

const major = version_components.first();
const minor = version_components.next() orelse return error.InvalidVersion;
const patch = version_components.next() orelse "0";
if (version_components.next() != null) return error.InvalidVersion;

return .{
.major = try parseVersionComponentFn(major),
.minor = try parseVersionComponentFn(minor),
Expand All @@ -361,10 +365,12 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
}

test parseVersion {
try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));

try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3-dev"));
}

pub fn isNativeCpu(self: Query) bool {
Expand Down
34 changes: 11 additions & 23 deletions lib/std/zig/system.zig
Original file line number Diff line number Diff line change
Expand Up @@ -215,25 +215,17 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi);
if (query.os_tag == null) {
switch (builtin.target.os.tag) {
.linux => {
.linux, .illumos => {
const uts = posix.uname();
const release = mem.sliceTo(&uts.release, 0);
// The release field sometimes has a weird format,
// `Version.parse` will attempt to find some meaningful interpretation.
if (std.SemanticVersion.parse(release)) |ver| {
os.version_range.linux.range.min = ver;
os.version_range.linux.range.max = ver;
} else |err| switch (err) {
error.Overflow => {},
error.InvalidVersion => {},
}
},
.illumos => {
const uts = posix.uname();
const release = mem.sliceTo(&uts.release, 0);
if (std.SemanticVersion.parse(release)) |ver| {
os.version_range.semver.min = ver;
os.version_range.semver.max = ver;
var stripped = ver;
stripped.pre = null;
stripped.build = null;
os.version_range.linux.range.min = stripped;
os.version_range.linux.range.max = stripped;
} else |err| switch (err) {
error.Overflow => {},
error.InvalidVersion => {},
Expand Down Expand Up @@ -307,10 +299,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
posix.CTL.KERN,
posix.KERN.OSRELEASE,
};
var buf: [64]u8 = undefined;
var buf: [64:0]u8 = undefined;
// consider that sysctl result includes null-termination
// reserve 1 byte to ensure we never overflow when appending ".0"
var len: usize = buf.len - 1;
var len: usize = buf.len + 1;

posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
error.NameTooLong => unreachable, // constant, known good value
Expand All @@ -320,12 +311,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
error.Unexpected => return error.OSVersionDetectionFail,
};

// append ".0" to satisfy semver
buf[len - 1] = '.';
buf[len] = '0';
len += 1;

if (std.SemanticVersion.parse(buf[0..len])) |ver| {
if (Target.Query.parseVersion(buf[0..len :0])) |ver| {
assert(ver.build == null);
assert(ver.pre == null);
os.version_range.semver.min = ver;
os.version_range.semver.max = ver;
} else |_| {
Expand Down
2 changes: 2 additions & 0 deletions lib/std/zig/system/darwin/macos.zig
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub fn detect(target_os: *Target.Os) !void {
if (parseSystemVersion(bytes)) |ver| {
// never return non-canonical `10.(16+)`
if (!(ver.major == 10 and ver.minor >= 16)) {
assert(ver.pre == null);
assert(ver.build == null);
target_os.version_range.semver.min = ver;
target_os.version_range.semver.max = ver;
return;
Expand Down
Loading