mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
Merge pull request #6649 from Rocknest/verparse
make Version.parse less strict
This commit is contained in:
parent
8af0a1987b
commit
50269f2315
@ -490,11 +490,26 @@ pub const Version = struct {
|
||||
}
|
||||
|
||||
pub fn parse(text: []const u8) !Version {
|
||||
var it = std.mem.split(text, ".");
|
||||
var end: usize = 0;
|
||||
while (end < text.len) : (end += 1) {
|
||||
const c = text[end];
|
||||
if (!std.ascii.isDigit(c) and c != '.') break;
|
||||
}
|
||||
// found no digits or '.' before unexpected character
|
||||
if (end == 0) return error.InvalidVersion;
|
||||
|
||||
var it = std.mem.split(text[0..end], ".");
|
||||
// substring is not empty, first call will succeed
|
||||
const major = it.next().?;
|
||||
if (major.len == 0) return error.InvalidVersion;
|
||||
const minor = it.next() orelse "0";
|
||||
// ignore 'patch' if 'minor' is invalid
|
||||
const patch = if (minor.len == 0) "0" else (it.next() orelse "0");
|
||||
|
||||
return Version{
|
||||
.major = try std.fmt.parseInt(u32, it.next() orelse return error.InvalidVersion, 10),
|
||||
.minor = try std.fmt.parseInt(u32, it.next() orelse "0", 10),
|
||||
.patch = try std.fmt.parseInt(u32, it.next() orelse "0", 10),
|
||||
.major = try std.fmt.parseUnsigned(u32, major, 10),
|
||||
.minor = try std.fmt.parseUnsigned(u32, if (minor.len == 0) "0" else minor, 10),
|
||||
.patch = try std.fmt.parseUnsigned(u32, if (patch.len == 0) "0" else patch, 10),
|
||||
};
|
||||
}
|
||||
|
||||
@ -520,6 +535,56 @@ pub const Version = struct {
|
||||
}
|
||||
};
|
||||
|
||||
test "Version.parse" {
|
||||
@setEvalBranchQuota(3000);
|
||||
try testVersionParse();
|
||||
comptime (try testVersionParse());
|
||||
}
|
||||
|
||||
pub fn testVersionParse() !void {
|
||||
const f = struct {
|
||||
fn eql(text: []const u8, v1: u32, v2: u32, v3: u32) !void {
|
||||
const v = try Version.parse(text);
|
||||
std.testing.expect(v.major == v1 and v.minor == v2 and v.patch == v3);
|
||||
}
|
||||
|
||||
fn err(text: []const u8, expected_err: anyerror) !void {
|
||||
_ = Version.parse(text) catch |actual_err| {
|
||||
if (actual_err == expected_err) return;
|
||||
return actual_err;
|
||||
};
|
||||
return error.Unreachable;
|
||||
}
|
||||
};
|
||||
|
||||
try f.eql("2.6.32.11-svn21605", 2, 6, 32); // Debian PPC
|
||||
try f.eql("2.11.2(0.329/5/3)", 2, 11, 2); // MinGW
|
||||
try f.eql("5.4.0-1018-raspi", 5, 4, 0); // Ubuntu
|
||||
try f.eql("5.7.12_3", 5, 7, 12); // Void
|
||||
try f.eql("2.13-DEVELOPMENT", 2, 13, 0); // DragonFly
|
||||
try f.eql("2.3-35", 2, 3, 0);
|
||||
try f.eql("1a.4", 1, 0, 0);
|
||||
try f.eql("3.b1.0", 3, 0, 0);
|
||||
try f.eql("1.4beta", 1, 4, 0);
|
||||
try f.eql("2.7.pre", 2, 7, 0);
|
||||
try f.eql("0..3", 0, 0, 0);
|
||||
try f.eql("8.008.", 8, 8, 0);
|
||||
try f.eql("01...", 1, 0, 0);
|
||||
try f.eql("55", 55, 0, 0);
|
||||
try f.eql("4294967295.0.1", 4294967295, 0, 1);
|
||||
try f.eql("429496729_6", 429496729, 0, 0);
|
||||
|
||||
try f.err("foobar", error.InvalidVersion);
|
||||
try f.err("", error.InvalidVersion);
|
||||
try f.err("-1", error.InvalidVersion);
|
||||
try f.err("+4", error.InvalidVersion);
|
||||
try f.err(".", error.InvalidVersion);
|
||||
try f.err("....3", error.InvalidVersion);
|
||||
try f.err("4294967296", error.Overflow);
|
||||
try f.err("5000877755", error.Overflow);
|
||||
// error.InvalidCharacter is not possible anymore
|
||||
}
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const CallOptions = struct {
|
||||
|
||||
@ -211,16 +211,9 @@ pub const NativeTargetInfo = struct {
|
||||
.linux => {
|
||||
const uts = std.os.uname();
|
||||
const release = mem.spanZ(&uts.release);
|
||||
// The release field may have several other fields after the
|
||||
// kernel version
|
||||
const kernel_version = if (mem.indexOfScalar(u8, release, '-')) |pos|
|
||||
release[0..pos]
|
||||
else if (mem.indexOfScalar(u8, release, '_')) |pos|
|
||||
release[0..pos]
|
||||
else
|
||||
release;
|
||||
|
||||
if (std.builtin.Version.parse(kernel_version)) |ver| {
|
||||
// The release field sometimes has a weird format,
|
||||
// `Version.parse` will attempt to find some meaningful interpretation.
|
||||
if (std.builtin.Version.parse(release)) |ver| {
|
||||
os.version_range.linux.range.min = ver;
|
||||
os.version_range.linux.range.max = ver;
|
||||
} else |err| switch (err) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user