summaryrefslogtreecommitdiff
path: root/src/data.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.zig')
-rw-r--r--src/data.zig162
1 files changed, 97 insertions, 65 deletions
diff --git a/src/data.zig b/src/data.zig
index f2ee9d9..824d36c 100644
--- a/src/data.zig
+++ b/src/data.zig
@@ -88,6 +88,22 @@ fn search(list: []Section, name: []const u8) !usize {
}
// TODO return last match instead?
+const CommandType = enum { start, add, end, ref, none };
+
+fn command_type(line: []const u8) CommandType {
+ if (std.mem.startsWith(u8, line, k_start)) {
+ return .start;
+ } else if (std.mem.startsWith(u8, line, k_add)) {
+ return .add;
+ } else if (std.mem.eql(u8, line, k_end)) {
+ return .end;
+ } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
+ return .ref;
+ } else {
+ return .none;
+ }
+}
+
pub fn parse(lines: [][]const u8, alloc: Allocator) ![]Section {
var sections = std.ArrayList(Section).init(alloc);
defer sections.deinit();
@@ -95,32 +111,37 @@ pub fn parse(lines: [][]const u8, alloc: Allocator) ![]Section {
var i: u32 = 0;
while (i < lines.len) {
const line = lines[i];
- if (std.mem.startsWith(u8, line, k_start)) {
- const name = line[(k_start.len)..];
- log(.debug, "({d}) starting section '{s}'", .{ i + 1, name });
-
- const section = try parse_code(lines, i + 1, alloc);
- try sections.append(.{ .name = name, .content = section.content });
-
- log(.debug, "({d}) ending section '{s}'", .{ section.index, name });
- i = section.index;
- } else if (std.mem.startsWith(u8, line, k_add)) {
- const name = line[(k_add.len)..];
- log(.debug, "({d}) appending to section '{s}'", .{ i + 1, name });
-
- const section = try parse_code(lines, i + 1, alloc);
- const index = try search(sections.items, name);
- const old = &sections.items[index];
- const new = try std.mem.concat(alloc, Content, &[_][]const Content{ old.*.content, section.content });
- old.*.content = new;
-
- log(.debug, "({d}) ending section '{s}'", .{ section.index, name });
- i = section.index;
- } else if (std.mem.eql(u8, line, k_end)) {
- log(.err, "line {d}: unexpected section end", .{i + 1});
- return error.UnexpectedEnd;
- } else {
- i += 1;
+ switch (command_type(line)) {
+ .start => {
+ const name = line[(k_start.len)..];
+ log(.debug, "({d}) starting section '{s}'", .{ i + 1, name });
+
+ const section = try parse_code(lines, i + 1, alloc);
+ try sections.append(.{ .name = name, .content = section.content });
+
+ log(.debug, "({d}) ending section '{s}'", .{ section.index, name });
+ i = section.index;
+ },
+ .add => {
+ const name = line[(k_add.len)..];
+ log(.debug, "({d}) appending to section '{s}'", .{ i + 1, name });
+
+ const section = try parse_code(lines, i + 1, alloc);
+ const index = try search(sections.items, name);
+ const old = &sections.items[index];
+ const new = try std.mem.concat(alloc, Content, &[_][]const Content{ old.*.content, section.content });
+ old.*.content = new;
+
+ log(.debug, "({d}) ending section '{s}'", .{ section.index, name });
+ i = section.index;
+ },
+ .end => {
+ log(.err, "line {d}: unexpected section end", .{i + 1});
+ return error.UnexpectedEnd;
+ },
+ else => {
+ i += 1;
+ },
}
}
@@ -134,32 +155,37 @@ fn parse_code(lines: [][]const u8, index: u32, alloc: Allocator) !CodeReturn {
var i = index;
while (i < lines.len) {
const line = lines[i];
- if (std.mem.startsWith(u8, line, k_start) or std.mem.startsWith(u8, line, k_add)) {
- log(.err, "line {d}: unexpected section start", .{i + 1});
- return error.UnexpectedStart;
- } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
- const ref_name = std.mem.trimLeft(u8, line, " \t")[(k_ref.len)..];
- try content.append(.{ .reference = ref_name });
- log(.debug, "({d}) \tappended reference '{s}'", .{ i + 1, ref_name });
- i += 1;
- } else if (std.mem.eql(u8, line, k_end)) {
- break;
- } else {
- if (content.items.len > 0) {
- switch (content.items[content.items.len - 1]) {
- .literal => |*range| {
- range.*.end = i;
- },
- .reference => {
- try content.append(.{ .literal = .{ .start = i, .end = i } });
- log(.debug, "({d}) \tappending literal", .{i + 1});
- },
+ switch (command_type(line)) {
+ .start, .add => {
+ log(.err, "line {d}: unexpected section start", .{i + 1});
+ return error.UnexpectedStart;
+ },
+ .ref => {
+ const ref_name = std.mem.trimLeft(u8, line, " \t")[(k_ref.len)..];
+ try content.append(.{ .reference = ref_name });
+ log(.debug, "({d}) \tappended reference '{s}'", .{ i + 1, ref_name });
+ i += 1;
+ },
+ .end => {
+ break;
+ },
+ else => {
+ if (content.items.len > 0) {
+ switch (content.items[content.items.len - 1]) {
+ .literal => |*range| {
+ range.*.end = i;
+ },
+ .reference => {
+ try content.append(.{ .literal = .{ .start = i, .end = i } });
+ log(.debug, "({d}) \tappending literal", .{i + 1});
+ },
+ }
+ } else {
+ try content.append(.{ .literal = .{ .start = i, .end = i } });
+ log(.debug, "({d}) \tappending literal", .{i + 1});
}
- } else {
- try content.append(.{ .literal = .{ .start = i, .end = i } });
- log(.debug, "({d}) \tappending literal", .{i + 1});
- }
- i += 1;
+ i += 1;
+ },
}
}
@@ -214,20 +240,26 @@ pub fn textgen(lines: [][]const u8, alloc: Allocator) ![][]const u8 {
for (lines) |line| {
if (std.mem.startsWith(u8, line, kc_start) or std.mem.startsWith(u8, line, kc_add) or std.mem.startsWith(u8, line, kc_end) or std.mem.startsWith(u8, line, kc_ref)) {
continue;
- } else if (std.mem.startsWith(u8, line, k_start)) {
- current_name = line[(k_start.len)..];
- try buffer.append(try std.mem.join(alloc, current_name, conf_start));
- } else if (std.mem.startsWith(u8, line, k_add)) {
- current_name = line[(k_add.len)..];
- try buffer.append(try std.mem.join(alloc, current_name, conf_add));
- } else if (std.mem.startsWith(u8, line, k_end)) {
- try buffer.append(try std.mem.join(alloc, current_name, conf_end));
- } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
- const start = std.mem.indexOf(u8, line, k_ref).?;
- const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref);
- try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref }));
- } else {
- try buffer.append(line);
+ } else switch (command_type(line)) {
+ .start => {
+ current_name = line[(k_start.len)..];
+ try buffer.append(try std.mem.join(alloc, current_name, conf_start));
+ },
+ .add => {
+ current_name = line[(k_add.len)..];
+ try buffer.append(try std.mem.join(alloc, current_name, conf_add));
+ },
+ .ref => {
+ const start = std.mem.indexOf(u8, line, k_ref).?;
+ const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref);
+ try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref }));
+ },
+ .end => {
+ try buffer.append(try std.mem.join(alloc, current_name, conf_end));
+ },
+ else => {
+ try buffer.append(line);
+ },
}
}