174 lines
4.3 KiB
Zig
174 lines
4.3 KiB
Zig
const std = @import("std");
|
|
|
|
pub const log_level: std.log.Level = .debug;
|
|
|
|
const ProgramOptions = struct {
|
|
outputFile: ?[]u8 = null,
|
|
inputFile: ?[]u8 = null,
|
|
allocator: std.mem.Allocator,
|
|
|
|
pub fn deinit(self: @This()) void {
|
|
if (self.outputFile) |f| {
|
|
self.allocator.free(f);
|
|
}
|
|
|
|
if (self.inputFile) |f| {
|
|
self.allocator.free(f);
|
|
}
|
|
}
|
|
|
|
fn matchArgOpt(arg: []const u8, long: []const u8, short: ?[]const u8) bool {
|
|
if (arg.len < 2) {
|
|
return false;
|
|
}
|
|
|
|
if (arg[0] == '-') {
|
|
if (arg[1] == '-') {
|
|
return std.mem.eql(u8, arg[2..], long);
|
|
} else if (short) |s| {
|
|
return arg[1] == s[0];
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
pub fn parseArgs(allocator: std.mem.Allocator) !@This() {
|
|
var rv: @This() = .{ .allocator = allocator };
|
|
|
|
const args = try std.process.argsAlloc(allocator);
|
|
defer std.process.argsFree(allocator, args);
|
|
|
|
var i: usize = 0;
|
|
while (i < args.len) : (i += 1) {
|
|
if (i <= 0) {
|
|
continue;
|
|
}
|
|
|
|
if (matchArgOpt(args[i], "input", "i")) {
|
|
i += 1;
|
|
rv.inputFile = try allocator.dupe(u8, args[i]);
|
|
} else if (matchArgOpt(args[i], "output", "o")) {
|
|
i += 1;
|
|
rv.outputFile = try allocator.dupe(u8, args[i]);
|
|
}
|
|
}
|
|
|
|
if (rv.outputFile == null) {
|
|
rv.outputFile = try allocator.dupe(u8, "imgui.zig");
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
};
|
|
|
|
// Parses out all of the cimgui functions and sorts them by calling type.
|
|
|
|
const ParserContext = struct {
|
|
arena: std.heap.ArenaAllocator,
|
|
backingAllocator: std.mem.Allocator,
|
|
opts: *const ProgramOptions,
|
|
|
|
read: []const u8 = undefined,
|
|
buffer: []const u8 = undefined,
|
|
|
|
state: enum {
|
|
Empty,
|
|
Label,
|
|
Struct,
|
|
Function,
|
|
} = .Empty,
|
|
|
|
pub fn create(allocator: std.mem.Allocator, options: *const ProgramOptions) !*@This() {
|
|
const self = try allocator.create(@This());
|
|
|
|
self.* = .{
|
|
.backingAllocator = allocator,
|
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
|
.opts = options,
|
|
};
|
|
|
|
return self;
|
|
}
|
|
|
|
const ParseResults = struct {};
|
|
|
|
pub fn getAllocator(self: *@This()) std.mem.Allocator {
|
|
return self.arena.allocator();
|
|
}
|
|
|
|
fn matchString(self: *@This(), str: []const u8) ?usize {
|
|
if (self.read.len < str.len) {
|
|
return null;
|
|
}
|
|
|
|
if (std.mem.eql(u8, self.read[0..str.len], str)) {
|
|
return str.len - 1;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
fn advanceEmpty(self: *@This()) !void {
|
|
if (self.matchString("struct")) |len| {
|
|
std.log.info("STRUCT FOUND! {s}", .{self.read[0 .. len + 1]});
|
|
self.advance(len);
|
|
}
|
|
}
|
|
|
|
inline fn next(self: *@This()) !void {
|
|
switch (self.state) {
|
|
.Empty => {
|
|
try self.advanceEmpty();
|
|
},
|
|
.Label => {},
|
|
.Struct => {},
|
|
.Function => {},
|
|
}
|
|
|
|
self.advance(1);
|
|
}
|
|
|
|
inline fn advance(self: *@This(), count: usize) void {
|
|
self.read = self.read[count..];
|
|
}
|
|
|
|
pub fn parseHeader(self: *@This()) !ParseResults {
|
|
var file = try std.fs.cwd().openFile(self.opts.inputFile.?, .{});
|
|
defer file.close();
|
|
|
|
self.buffer = try file.reader().readAllAlloc(self.getAllocator(), 1 * 1024 * 1024 * 1024);
|
|
self.read = self.buffer;
|
|
|
|
while (self.read.len > 0) {
|
|
try self.next();
|
|
}
|
|
|
|
return .{};
|
|
}
|
|
|
|
pub fn destroy(self: *@This()) void {
|
|
self.arena.deinit();
|
|
self.backingAllocator.destroy(self);
|
|
}
|
|
};
|
|
|
|
pub fn main() !void {
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
|
|
const allocator = gpa.allocator();
|
|
|
|
const opts = try ProgramOptions.parseArgs(allocator);
|
|
defer opts.deinit();
|
|
|
|
std.log.info("inputFile={?s}, outputFile={?s}", .{
|
|
opts.inputFile,
|
|
opts.outputFile,
|
|
});
|
|
|
|
const tokenizer = try Tokenizer.create(allocator, &opts);
|
|
defer tokenizer.destroy();
|
|
|
|
const tokenizeResults = try tokenizer.tokenize();
|
|
}
|