summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2020-05-25 19:17:01 +0300
committerAqua-sama <aqua@iserlohn-fortress.net>2020-05-25 19:17:01 +0300
commit0f788c3fd76b25c1c6355756d62398d1e4236ccd (patch)
tree40e47ac1b96a217280c59b4f45c9f1c6cef465d9
parentInitial commit (diff)
downloadzrcc-0f788c3fd76b25c1c6355756d62398d1e4236ccd.tar.xz
Add dump subcommandHEADmaster
-rw-r--r--src/dump.zig109
-rw-r--r--src/main.zig53
2 files changed, 123 insertions, 39 deletions
diff --git a/src/dump.zig b/src/dump.zig
new file mode 100644
index 0000000..a41b2be
--- /dev/null
+++ b/src/dump.zig
@@ -0,0 +1,109 @@
+const std = @import("std");
+const adler32 = std.hash.Adler32;
+const openFlags = std.fs.File.OpenFlags{
+ .read = true,
+ .write = false,
+ .lock = std.fs.File.Lock.None,
+};
+const output_flags = std.fs.File.CreateFlags{
+ .read = false,
+ .truncate = true,
+ .exclusive = false,
+ .lock = std.fs.File.Lock.None,
+};
+
+fn help(args: [][]u8) u8 {
+ std.debug.warn(
+ \\Usage: {} {} [-h] [-o OUTPUT] input ...
+ \\
+ \\Optional arguments:
+ \\ -h, --help show this help message and exit
+ \\ -o, --output OUTPUT output header file (by default, stdout)
+ \\
+ \\Positional arguments:
+ \\ input one or more input files
+ \\
+ , .{ args[0], args[1] });
+ return if (args.len < 3) 255 else 0;
+}
+
+pub fn cmd(args: [][]u8) u8 {
+ if (args.len < 3) {
+ return help(args);
+ }
+
+ const State = enum {
+ Start,
+ OptionOutput,
+ };
+
+ var output_file: ?std.fs.File = null;
+ defer if (output_file != null) output_file.?.close();
+
+ var input_index: ?usize = null;
+ var state: State = State.Start;
+
+ parse_args: for (args[2..args.len]) |c, i| {
+ switch (state) {
+ State.Start => {
+ switch (adler32.hash(c)) {
+ adler32.hash("-h"), adler32.hash("--help") => return help(args),
+ adler32.hash("-o"), adler32.hash("--output") => state = State.OptionOutput,
+ else => {
+ if (input_index == null) {
+ input_index = i;
+ break :parse_args;
+ }
+ },
+ }
+ },
+ State.OptionOutput => {
+ output_file = switch (std.fs.path.isAbsolute(c)) {
+ true => std.fs.createFileAbsolute(c, output_flags) catch return 128,
+ false => std.fs.cwd().createFile(c, output_flags) catch return 128,
+ };
+ state = State.Start;
+ },
+ }
+ }
+
+ var output = (output_file orelse std.io.getStdOut()).outStream();
+
+ if (input_index == null)
+ return help(args);
+
+ for (args[2 + input_index.? .. args.len]) |path| {
+ output.print("// {}\n", .{path}) catch return 1;
+ hexdump(output, path, path) catch std.debug.warn("// Could not read file '{}'\n", .{path});
+ }
+
+ return 0;
+}
+
+fn hexdump(out: std.fs.File.OutStream, path: []const u8, name: []const u8) !void {
+ var file = switch (std.fs.path.isAbsolute(path)) {
+ true => try std.fs.openFileAbsolute(path, openFlags),
+ false => try std.fs.cwd().openFile(path, openFlags),
+ };
+ defer file.close();
+
+ var buffer: [16]u8 = undefined;
+ var r: u64 = undefined;
+ var l: u64 = 0;
+
+ try out.print("constexpr uint8_t {}_data[] = {{\n", .{name});
+ while (true) {
+ r = file.read(&buffer) catch break;
+ if (r <= 0)
+ break;
+
+ l += r;
+ try out.print(" ", .{});
+ for (buffer[0..r]) |c| {
+ try out.print("0x{x:2}, ", .{c});
+ }
+ try out.print("\n", .{});
+ }
+ try out.print("}};\n", .{});
+ try out.print("constexpr size_t {}_len = {};\n\n", .{ name, l });
+}
diff --git a/src/main.zig b/src/main.zig
index 1b8f702..c45cbed 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,43 +1,19 @@
const std = @import("std");
+const dump = @import("dump.zig");
const adler32 = std.hash.Adler32;
-const openFlags = std.fs.File.OpenFlags{
- .read = true,
- .write = false,
- .lock = std.fs.File.Lock.None,
-};
-
-fn dump(args: [][]u8) u8 {
- if (args.len < 3) {
- std.debug.warn("Usage: {} [subcommand] [options]\n", .{args[0]});
- return 255;
- }
-
- var file = std.fs.openFileAbsolute(args[2], openFlags) catch {
- std.debug.warn("Cannot open file {}\n", .{args[2]});
- return 255;
- };
- defer file.close();
-
- var buffer: [16]u8 = undefined;
- var r: u64 = undefined;
- while (true) {
- r = file.read(&buffer) catch {
- break;
- };
- if (r <= 0)
- break;
-
- for (buffer[0..r]) |c| {
- std.debug.warn("0x{x:2} ", .{c});
- }
- std.debug.warn(" -- {}\n", .{r});
- }
-
- return 0;
-}
fn help(args: [][]u8) u8 {
- std.debug.warn("Usage: {} [subcommand] [options]\n", .{args[0]});
+ std.debug.warn(
+ \\Usage: {} [subcommand] [options]
+ \\
+ \\Resource Compiler for C++
+ \\
+ \\Subcommands:
+ \\ dump [options] inputs hexdump the input files
+ \\
+ \\For a full list of subcommand options, use [subcommand] --help
+ \\
+ , .{args[0]});
return if (args.len < 2) 255 else 0;
}
@@ -45,15 +21,14 @@ pub fn main() anyerror!u8 {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
- std.debug.warn("All your codebase are belong to us.\n\n", .{});
-
const args = try std.process.argsAlloc(&arena.allocator);
if (args.len < 2) {
return help(args);
}
return switch (adler32.hash(args[1])) {
- adler32.hash("dump") => dump(args),
+ adler32.hash("dump") => dump.cmd(args),
+ adler32.hash("-h"), adler32.hash("--help") => help(args),
else => help(args),
};
}