@@ 41,7 41,7 @@ fn IniTok(comptime T: type) type {
line.* += 1;
if (try self.reader.readUntilDelimiterOrEof(&self.stack_buffer, '\n')) |__buf| {
if (__buf.len == 1) {
- if (__buf[0] == '\n') {
+ if (__buf[0] == '#') {
continue;
} else {
return error.InvalidLine;
@@ 69,28 69,39 @@ fn IniTok(comptime T: type) type {
}
// Is this line an assignment?
- var it = mem.tokenize(u8, buf, "=");
- const variable = blk: {
- const _variable = mem.trim(u8, it.next() orelse return error.InvalidLine, &ascii.spaces);
- if (_variable.len == 0) return error.InvalidLine;
- break :blk _variable;
- };
- const value = blk: {
- const _value = mem.trim(u8, it.next() orelse return error.InvalidLine, &ascii.spaces);
- if (_value.len < 2 or _value[_value.len - 1] != ';') return error.InvalidLine;
- // TODO[zig] should be inline, but that crashes the zig compiler right now
- for ([_]u8{ '\'', '"' }) |q| {
- if (_value[0] == q) {
- if (_value[_value.len - 2] == q and _value.len > 3) {
- break :blk _value[1 .. _value.len - 2];
- } else {
- return error.InvalidLine;
- }
+ var eq_pos = blk: {
+ for (buf) |char, i| {
+ if (char == '=') {
+ if (i == buf.len - 1) return error.InvalidLine;
+ break :blk i;
}
}
- break :blk _value[0 .. _value.len - 1];
+ return error.InvalidLine;
+ };
+ return Content{
+ .assign = .{
+ .variable = blk: {
+ const variable = mem.trim(u8, buf[0..eq_pos], &ascii.spaces);
+ if (variable.len == 0) return error.InvalidLine;
+ break :blk variable;
+ },
+ .value = blk: {
+ const value = mem.trim(u8, buf[eq_pos + 1 ..], &ascii.spaces);
+ if (value.len < 2 or value[value.len - 1] != ';') return error.InvalidLine;
+ // TODO[zig] should be inline, but that crashes the zig compiler right now
+ for ([_]u8{ '\'', '"' }) |q| {
+ if (value[0] == q) {
+ if (value[value.len - 2] == q and value.len > 3) {
+ break :blk value[1 .. value.len - 2];
+ } else {
+ return error.InvalidLine;
+ }
+ }
+ }
+ break :blk value[0 .. value.len - 1];
+ },
+ },
};
- return Content{ .assign = .{ .variable = variable, .value = value } };
} else {
return null;
}
@@ 115,6 126,11 @@ test "ini tokenizer good input" {
\\
\\[header2]
\\[header3]
+ \\#
+ \\
+ \\hello = this has spaces;
+ \\hello = this one; is weird;
+ \\hello = test=test;
\\
).reader();
@@ 172,28 188,95 @@ test "ini tokenizer good input" {
unreachable;
}
- try std.testing.expect((try it.next(&line)) == null);
-}
-
-test "ini tokenizer bad input" {
- const reader = io.fixedBufferStream(
- \\[header]
- \\
- \\a = b # missing semicolon
- \\
- ).reader();
+ if (try it.next(&line)) |a| {
+ try std.testing.expect(a == .assign);
+ try std.testing.expectEqualSlices(u8, "hello", a.assign.variable);
+ try std.testing.expectEqualSlices(u8, "this has spaces", a.assign.value);
+ try std.testing.expect(line == 11);
+ } else {
+ unreachable;
+ }
- var it = tokenize(reader);
- var line: usize = 0;
+ if (try it.next(&line)) |a| {
+ try std.testing.expect(a == .assign);
+ try std.testing.expectEqualSlices(u8, "hello", a.assign.variable);
+ try std.testing.expectEqualSlices(u8, "this one; is weird", a.assign.value);
+ try std.testing.expect(line == 12);
+ } else {
+ unreachable;
+ }
if (try it.next(&line)) |a| {
- try std.testing.expect(a == .section);
- try std.testing.expectEqualSlices(u8, "header", a.section);
- try std.testing.expect(line == 1);
+ try std.testing.expect(a == .assign);
+ try std.testing.expectEqualSlices(u8, "hello", a.assign.variable);
+ try std.testing.expectEqualSlices(u8, "test=test", a.assign.value);
+ try std.testing.expect(line == 13);
} else {
unreachable;
}
- try std.testing.expectError(error.InvalidLine, it.next(&line));
- try std.testing.expect(line == 3);
+ try std.testing.expect((try it.next(&line)) == null);
+}
+
+test "ini tokenizer bad input" {
+ {
+ const reader = io.fixedBufferStream(
+ \\[section
+ \\
+ ).reader();
+ var it = tokenize(reader);
+ var line: usize = 0;
+ try std.testing.expectError(error.InvalidLine, it.next(&line));
+ try std.testing.expect(line == 1);
+ }
+ {
+ const reader = io.fixedBufferStream(
+ \\section]
+ \\
+ ).reader();
+ var it = tokenize(reader);
+ var line: usize = 0;
+ try std.testing.expectError(error.InvalidLine, it.next(&line));
+ try std.testing.expect(line == 1);
+ }
+ {
+ const reader = io.fixedBufferStream(
+ \\[]
+ \\
+ ).reader();
+ var it = tokenize(reader);
+ var line: usize = 0;
+ try std.testing.expectError(error.InvalidLine, it.next(&line));
+ try std.testing.expect(line == 1);
+ }
+ {
+ const reader = io.fixedBufferStream(
+ \\ =B;
+ \\
+ ).reader();
+ var it = tokenize(reader);
+ var line: usize = 0;
+ try std.testing.expectError(error.InvalidLine, it.next(&line));
+ try std.testing.expect(line == 1);
+ }
+ {
+ const reader = io.fixedBufferStream(
+ \\a =
+ \\
+ ).reader();
+ var it = tokenize(reader);
+ var line: usize = 0;
+ try std.testing.expectError(error.InvalidLine, it.next(&line));
+ try std.testing.expect(line == 1);
+ }
+ {
+ const reader = io.fixedBufferStream(
+ \\a = ;
+ \\
+ ).reader();
+ var it = tokenize(reader);
+ var line: usize = 0;
+ try std.testing.expectError(error.InvalidLine, it.next(&line));
+ try std.testing.expect(line == 1);
+ }
}