Skip to content

Commit

Permalink
split('||'), fix up tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dylan-conway authored and Jarred-Sumner committed Nov 7, 2023
1 parent bb5d6ff commit b5a0482
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 114 deletions.
5 changes: 4 additions & 1 deletion src/install/dependency.zig
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ pub fn parseWithTag(
input = input[1..];
}

const version = Semver.Query.parse(
const version = if (input.len > 0) Semver.Query.parse(
allocator,
input,
sliced.sub(input),
Expand All @@ -773,6 +773,9 @@ pub fn parseWithTag(
},
) catch unreachable;
return null;
} else Semver.Query.Group{
.allocator = allocator,
.input = input,
};

const result = Version{
Expand Down
170 changes: 92 additions & 78 deletions src/install/semver.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1858,7 +1858,6 @@ pub const Query = struct {
input: string,
sliced: SlicedString,
) !Group {
var i: usize = 0;
var list = Group{
.allocator = allocator,
.input = input,
Expand All @@ -1870,86 +1869,96 @@ pub const Query = struct {
var count: u8 = 0;
var skip_round = false;
var is_or = false;
var only_tagged_versions: ?bool = null;

while (i < input.len) {
skip_round = false;
var itr = strings.split(input, "||");

switch (input[i]) {
'>' => {
if (input.len > i + 1 and input[i + 1] == '=') {
token.tag = .gte;
i += 1;
} else {
token.tag = .gt;
}
while (itr.next()) |part| {
var i: usize = 0;
while (i < part.len and strings.containsChar(&std.ascii.whitespace, part[i])) : (i += 1) {}
if (i >= part.len) return Group{
.allocator = allocator,
.input = input,
};
if (i < part.len) {
skip_round = false;

switch (part[i]) {
'>' => {
if (part.len > i + 1 and part[i + 1] == '=') {
token.tag = .gte;
i += 1;
} else {
token.tag = .gt;
}

i += 1;
while (i < input.len and input[i] == ' ') : (i += 1) {}
},
'<' => {
if (input.len > i + 1 and input[i + 1] == '=') {
token.tag = .lte;
i += 1;
} else {
token.tag = .lt;
}
while (i < part.len and part[i] == ' ') : (i += 1) {}
},
'<' => {
if (part.len > i + 1 and part[i + 1] == '=') {
token.tag = .lte;
i += 1;
} else {
token.tag = .lt;
}

i += 1;
while (i < input.len and input[i] == ' ') : (i += 1) {}
},
'=', 'v' => {
token.tag = .version;
is_or = true;
i += 1;
while (i < input.len and input[i] == ' ') : (i += 1) {}
},
'~' => {
token.tag = .tilda;
i += 1;
i += 1;
while (i < part.len and part[i] == ' ') : (i += 1) {}
},
'=', 'v' => {
token.tag = .version;
is_or = true;
i += 1;
while (i < part.len and part[i] == ' ') : (i += 1) {}
},
'~' => {
token.tag = .tilda;
i += 1;

if (i < input.len and input[i] == '>') i += 1;
if (i < part.len and part[i] == '>') i += 1;

while (i < input.len and input[i] == ' ') : (i += 1) {}
},
'^' => {
token.tag = .caret;
i += 1;
while (i < input.len and input[i] == ' ') : (i += 1) {}
},
'0'...'9', 'X', 'x', '*' => {
token.tag = .version;
is_or = true;
},
'|' => {
i += 1;
while (i < part.len and part[i] == ' ') : (i += 1) {}
},
'^' => {
token.tag = .caret;
i += 1;
while (i < part.len and part[i] == ' ') : (i += 1) {}
},
'0'...'9', 'X', 'x', '*' => {
token.tag = .version;
is_or = true;
},
'|' => {
i += 1;

while (i < input.len and input[i] == '|') : (i += 1) {}
while (i < input.len and input[i] == ' ') : (i += 1) {}
is_or = true;
token.tag = Token.Tag.none;
skip_round = true;
},
'-' => {
i += 1;
while (i < input.len and input[i] == ' ') : (i += 1) {}
},
' ' => {
i += 1;
while (i < input.len and input[i] == ' ') : (i += 1) {}
skip_round = true;
},
else => {
i += 1;
token.tag = Token.Tag.none;
while (i < part.len and part[i] == '|') : (i += 1) {}
while (i < part.len and part[i] == ' ') : (i += 1) {}
is_or = true;
token.tag = Token.Tag.none;
continue;
},
'-' => {
i += 1;
while (i < part.len and part[i] == ' ') : (i += 1) {}
},
' ' => {
i += 1;
while (i < part.len and part[i] == ' ') : (i += 1) {}
continue;
},
else => {
i += 1;
token.tag = Token.Tag.none;

// skip tagged versions
while (i < input.len and input[i] != ' ' and input[i] != '|') : (i += 1) {}
skip_round = true;
},
}
// skip tagged versions
while (i < part.len and part[i] != ' ' and part[i] != '|') : (i += 1) {}
if (only_tagged_versions == null) only_tagged_versions = true;
continue;
},
}

if (!skip_round) {
const parse_result = Version.parse(sliced.sub(input[i..]));
const parse_result = Version.parse(sliced.sub(part[i..]));
const version = parse_result.version.fill();
if (version.tag.hasBuild()) list.flags.setValue(Group.Flags.build, true);
if (version.tag.hasPre()) list.flags.setValue(Group.Flags.pre, true);
Expand All @@ -1959,21 +1968,21 @@ pub const Query = struct {
i += parse_result.stopped_at;
const rollback = i;

const had_space = i < input.len and input[i] == ' ';
const had_space = i < part.len and part[i] == ' ';

// TODO: can we do this without rolling back?
const hyphenate: bool = had_space and possibly_hyphenate: {
i += 1;
while (i < input.len and input[i] == ' ') : (i += 1) {}
if (!(i < input.len and input[i] == '-')) break :possibly_hyphenate false;
while (i < part.len and part[i] == ' ') : (i += 1) {}
if (!(i < part.len and part[i] == '-')) break :possibly_hyphenate false;
i += 1;
if (!(i < input.len and input[i] == ' ')) break :possibly_hyphenate false;
if (!(i < part.len and part[i] == ' ')) break :possibly_hyphenate false;
i += 1;
while (i < input.len and switch (input[i]) {
while (i < part.len and switch (part[i]) {
' ', 'v', '=' => true,
else => false,
}) : (i += 1) {}
if (!(i < input.len and switch (input[i]) {
if (!(i < part.len and switch (part[i]) {
'0'...'9', 'X', 'x', '*' => true,
else => false,
})) break :possibly_hyphenate false;
Expand All @@ -1985,7 +1994,7 @@ pub const Query = struct {
i += @as(usize, @intFromBool(!hyphenate));

if (hyphenate) {
const second_parsed = Version.parse(sliced.sub(input[i..]));
const second_parsed = Version.parse(sliced.sub(part[i..]));
var second_version = second_parsed.version.fill();
if (second_version.tag.hasBuild()) list.flags.setValue(Group.Flags.build, true);
if (second_version.tag.hasPre()) list.flags.setValue(Group.Flags.pre, true);
Expand Down Expand Up @@ -2060,12 +2069,17 @@ pub const Query = struct {
}

is_or = false;
only_tagged_versions = false;
count += 1;
token.wildcard = .none;
prev_token.tag = token.tag;
}
}

if (count == 0 and only_tagged_versions != null and only_tagged_versions.?) {
return error.InvalidDependencyVersion;
}

return list;
}
};
Expand Down
Loading

0 comments on commit b5a0482

Please sign in to comment.