-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.zig
More file actions
110 lines (97 loc) · 4.03 KB
/
Copy pathmain.zig
File metadata and controls
110 lines (97 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! svd2zig CLI: read an SVD file, generate Zig bindings in the requested style,
//! write to a file (`-o`) or stdout.
const std = @import("std");
const svd2zig = @import("svd2zig");
const usage =
\\usage: svd2zig [--style conduit|regz|consts] <input.svd> [-o output.zig]
\\
\\ --style <s> output style (default: conduit)
\\ -o <path> write to file instead of stdout
\\ -h, --help show this help
\\
;
pub fn main(init: std.process.Init) void {
run(init) catch |err| {
report(init.io, err);
std.process.exit(1);
};
}
fn run(init: std.process.Init) !void {
const gpa = init.gpa;
const io = init.io;
var args = try std.process.Args.Iterator.initAllocator(init.minimal.args, gpa);
defer args.deinit();
_ = args.next(); // skip argv[0]
var style: svd2zig.Style = .conduit;
var input: ?[]const u8 = null;
var output: ?[]const u8 = null;
while (args.next()) |arg| {
if (std.mem.eql(u8, arg, "--style")) {
const v = args.next() orelse return fatal(io, "--style requires a value");
style = std.meta.stringToEnum(svd2zig.Style, v) orelse
return fatal(io, "unknown style (expected conduit, regz, or consts)");
} else if (std.mem.eql(u8, arg, "-o")) {
output = args.next() orelse return fatal(io, "-o requires a value");
} else if (std.mem.eql(u8, arg, "-h") or std.mem.eql(u8, arg, "--help")) {
try printStderr(io, usage);
return;
} else if (std.mem.startsWith(u8, arg, "-")) {
return fatal(io, "unknown flag");
} else if (input == null) {
input = arg;
} else {
return fatal(io, "unexpected extra argument");
}
}
const in_path = input orelse {
try printStderr(io, usage);
return error.MissingInput;
};
const bytes = try std.Io.Dir.cwd().readFileAlloc(io, in_path, gpa, .unlimited);
defer gpa.free(bytes);
var buf: [4096]u8 = undefined;
if (output) |out_path| {
var file = try std.Io.Dir.cwd().createFile(io, out_path, .{});
defer file.close(io);
var fw = file.writer(io, &buf);
try svd2zig.generate(gpa, bytes, style, &fw.interface);
try fw.interface.flush();
} else {
var sw = std.Io.File.stdout().writer(io, &buf);
try svd2zig.generate(gpa, bytes, style, &sw.interface);
try sw.interface.flush();
}
}
fn fatal(io: std.Io, msg: []const u8) error{InvalidArgs} {
printStderr(io, msg) catch {};
printStderr(io, "\n") catch {};
return error.InvalidArgs;
}
/// Print a clean one-line diagnostic for a failure (no stack trace). Argument
/// errors already printed their own message, so they are silent here.
fn report(io: std.Io, err: anyerror) void {
const msg: []const u8 = switch (err) {
error.InvalidArgs, error.MissingInput => return,
error.NoDeviceElement => "input is not a CMSIS-SVD <device> file",
error.MissingName => "an SVD element is missing its <name>",
error.MissingBaseAddress => "a peripheral is missing <baseAddress>",
error.UnknownDerivedFrom => "a derivedFrom target could not be found",
error.NameCollision => "two sibling names collide once converted to Zig identifiers",
error.BadBitRange => "a field has no valid bit range (bitOffset/bitWidth, lsb/msb, or bitRange)",
error.MalformedNumber => "a numeric SVD value could not be parsed",
error.MalformedAccess => "an <access> value was not recognized",
error.MalformedXml => "the input is not well-formed XML",
error.FileNotFound => "input file not found",
error.AccessDenied => "permission denied",
else => @errorName(err),
};
printStderr(io, "svd2zig: error: ") catch {};
printStderr(io, msg) catch {};
printStderr(io, "\n") catch {};
}
fn printStderr(io: std.Io, msg: []const u8) !void {
var buf: [256]u8 = undefined;
var sw = std.Io.File.stderr().writer(io, &buf);
try sw.interface.writeAll(msg);
try sw.interface.flush();
}