Skip to content

Commit 53431d6

Browse files
authored
Update main.zig
1 parent 07369d6 commit 53431d6

File tree

1 file changed

+48
-51
lines changed

1 file changed

+48
-51
lines changed

hacker-parser/main.zig

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,29 @@
11
const std = @import("std");
2-
32
const HACKER_DIR_SUFFIX = "/.hackeros/hacker-lang";
4-
53
fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbose: bool) !struct {
6-
deps: std.StringHashSet,
7-
libs: std.StringHashSet,
4+
deps: std.StringHashMap(void),
5+
libs: std.StringHashMap(void),
86
vars_dict: std.StringHashMap([]const u8),
97
cmds: std.ArrayList([]const u8),
108
includes: std.ArrayList([]const u8),
119
binaries: std.ArrayList([]const u8),
1210
errors: std.ArrayList([]const u8),
1311
config_data: std.StringHashMap([]const u8),
1412
} {
15-
var deps = std.StringHashSet.init(allocator);
16-
var libs = std.StringHashSet.init(allocator);
13+
var deps = std.StringHashMap(void).init(allocator);
14+
var libs = std.StringHashMap(void).init(allocator);
1715
var vars_dict = std.StringHashMap([]const u8).init(allocator);
1816
var cmds = std.ArrayList([]const u8).init(allocator);
1917
var includes = std.ArrayList([]const u8).init(allocator);
2018
var binaries = std.ArrayList([]const u8).init(allocator);
2119
var errors = std.ArrayList([]const u8).init(allocator);
2220
var config_data = std.StringHashMap([]const u8).init(allocator);
23-
2421
var in_config = false;
2522
var line_num: u32 = 0;
26-
27-
const home = std.os.getenv("HOME") orelse "";
23+
const home = std.posix.getenv("HOME") orelse "";
2824
const hacker_dir = try std.fs.path.join(allocator, &.{ home, HACKER_DIR_SUFFIX });
2925
defer allocator.free(hacker_dir);
30-
3126
const console = std.io.getStdOut().writer();
32-
3327
const file = std.fs.cwd().openFile(file_path, .{}) catch |err| {
3428
if (err == error.FileNotFound) {
3529
if (verbose) try console.print("File {s} not found\n", .{file_path});
@@ -48,18 +42,14 @@ fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbos
4842
return err;
4943
};
5044
defer file.close();
51-
5245
const reader = file.reader();
5346
var line_buf: [4096]u8 = undefined;
54-
5547
while (reader.readUntilDelimiterOrEof(&line_buf, '\n') catch null) |line_slice| {
5648
line_num += 1;
57-
const line_trimmed = std.mem.trim(u8, line_slice orelse break, " \t\r\n");
49+
const line_trimmed = std.mem.trim(u8, line_slice, " \t\r\n");
5850
if (line_trimmed.len == 0) continue;
59-
6051
const line = try allocator.dupe(u8, line_trimmed);
6152
defer allocator.free(line);
62-
6353
if (std.mem.eql(u8, line, "[")) {
6454
if (in_config) {
6555
try errors.append(try std.fmt.allocPrint(allocator, "Line {d}: Nested config section", .{line_num}));
@@ -73,7 +63,6 @@ fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbos
7363
in_config = false;
7464
continue;
7565
}
76-
7766
if (in_config) {
7867
if (std.mem.indexOfScalar(u8, line, '=')) |eq_pos| {
7968
const key = std.mem.trim(u8, line[0..eq_pos], " \t");
@@ -82,11 +71,10 @@ fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbos
8271
}
8372
continue;
8473
}
85-
8674
if (std.mem.startsWith(u8, line, "//")) {
8775
const dep = std.mem.trim(u8, line[2..], " \t");
8876
if (dep.len > 0) {
89-
_ = try deps.insert(try allocator.dupe(u8, dep));
77+
_ = try deps.put(try allocator.dupe(u8, dep), {});
9078
} else {
9179
try errors.append(try std.fmt.allocPrint(allocator, "Line {d}: Empty system dependency", .{line_num}));
9280
}
@@ -95,26 +83,27 @@ fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbos
9583
if (lib.len > 0) {
9684
const lib_dir = try std.fs.path.join(allocator, &.{ hacker_dir, "libs", lib });
9785
defer allocator.free(lib_dir);
98-
9986
const lib_hacker_path = try std.fs.path.join(allocator, &.{ lib_dir, "main.hacker" });
10087
defer allocator.free(lib_hacker_path);
101-
10288
const lib_bin_path = try std.fs.path.join(allocator, &.{ hacker_dir, "libs", lib });
10389
defer allocator.free(lib_bin_path);
104-
10590
if (std.fs.cwd().access(lib_hacker_path, .{})) |_| {
10691
try includes.append(try allocator.dupe(u8, lib));
107-
const sub = try parse_hacker_file(allocator, lib_hacker_path, verbose);
108-
for (sub.deps.keys()) |sub_dep| {
109-
_ = try deps.insert(sub_dep);
92+
var sub = try parse_hacker_file(allocator, lib_hacker_path, verbose);
93+
var dep_it = sub.deps.keyIterator();
94+
while (dep_it.next()) |sub_dep_ptr| {
95+
const sub_dep = sub_dep_ptr.*;
96+
_ = try deps.put(try allocator.dupe(u8, sub_dep), {});
11097
}
111-
for (sub.libs.keys()) |sub_lib| {
112-
_ = try libs.insert(sub_lib);
98+
var lib_it = sub.libs.keyIterator();
99+
while (lib_it.next()) |sub_lib_ptr| {
100+
const sub_lib = sub_lib_ptr.*;
101+
_ = try libs.put(try allocator.dupe(u8, sub_lib), {});
113102
}
114103
{
115104
var sub_it = sub.vars_dict.iterator();
116105
while (sub_it.next()) |entry| {
117-
try vars_dict.put(entry.key_ptr.*, entry.value_ptr.*);
106+
try vars_dict.put(try allocator.dupe(u8, entry.key_ptr.*), try allocator.dupe(u8, entry.value_ptr.*));
118107
}
119108
}
120109
try cmds.appendSlice(sub.cmds.items);
@@ -133,11 +122,10 @@ fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbos
133122
sub.errors.deinit();
134123
sub.config_data.deinit();
135124
} else |_| {} // ignore access error for now
136-
137-
if (std.fs.cwd().access(lib_bin_path, .{ .mode = .execute })) |_| {
125+
if (std.posix.access(lib_bin_path, std.posix.X_OK)) |_| {
138126
try binaries.append(try allocator.dupe(u8, lib_bin_path));
139127
} else |_| {
140-
_ = try libs.insert(try allocator.dupe(u8, lib));
128+
_ = try libs.put(try allocator.dupe(u8, lib), {});
141129
}
142130
} else {
143131
try errors.append(try std.fmt.allocPrint(allocator, "Line {d}: Empty library/include", .{line_num}));
@@ -211,24 +199,37 @@ fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbos
211199
try errors.append(try std.fmt.allocPrint(allocator, "Line {d}: Invalid syntax", .{line_num}));
212200
}
213201
}
214-
215202
if (in_config) {
216203
try errors.append(try allocator.dupe(u8, "Unclosed config section"));
217204
}
218-
219205
if (verbose) {
220-
try console.print("System Deps: {any}\n", .{deps.keys()});
221-
try console.print("Custom Libs: {any}\n", .{libs.keys()});
222-
try console.print("Vars: {any}\n", .{vars_dict.unmanaged});
206+
var dep_keys = try allocator.alloc([]const u8, deps.count());
207+
defer allocator.free(dep_keys);
208+
var i: usize = 0;
209+
var dep_it = deps.keyIterator();
210+
while (dep_it.next()) |key| {
211+
dep_keys[i] = key.*;
212+
i += 1;
213+
}
214+
try console.print("System Deps: {any}\n", .{dep_keys});
215+
var lib_keys = try allocator.alloc([]const u8, libs.count());
216+
defer allocator.free(lib_keys);
217+
i = 0;
218+
var lib_it = libs.keyIterator();
219+
while (lib_it.next()) |key| {
220+
lib_keys[i] = key.*;
221+
i += 1;
222+
}
223+
try console.print("Custom Libs: {any}\n", .{lib_keys});
224+
try console.print("Vars: {any}\n", .{vars_dict});
223225
try console.print("Cmds: {any}\n", .{cmds.items});
224226
try console.print("Includes: {any}\n", .{includes.items});
225227
try console.print("Binaries: {any}\n", .{binaries.items});
226-
try console.print("Config: {any}\n", .{config_data.unmanaged});
228+
try console.print("Config: {any}\n", .{config_data});
227229
if (errors.items.len > 0) {
228230
try console.print("Errors: {any}\n", .{errors.items});
229231
}
230232
}
231-
232233
return .{
233234
.deps = deps,
234235
.libs = libs,
@@ -240,15 +241,12 @@ fn parse_hacker_file(allocator: std.mem.Allocator, file_path: []const u8, verbos
240241
.config_data = config_data,
241242
};
242243
}
243-
244244
pub fn main() !void {
245245
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
246246
defer _ = gpa.deinit();
247247
const allocator = gpa.allocator();
248-
249248
var verbose = false;
250249
var file_path: ?[]const u8 = null;
251-
252250
for (std.os.argv[1..]) |arg_ptr| {
253251
const arg = std.mem.span(arg_ptr);
254252
if (std.mem.eql(u8, arg, "--verbose")) {
@@ -260,14 +258,11 @@ pub fn main() !void {
260258
std.process.exit(1);
261259
}
262260
}
263-
264261
if (file_path == null) {
265262
try std.io.getStdErr().writer().print("Usage: hacker-parser [--verbose] <file>\n", .{});
266263
std.process.exit(1);
267264
}
268-
269-
const res = try parse_hacker_file(allocator, file_path.?, verbose);
270-
265+
var res = try parse_hacker_file(allocator, file_path.?, verbose);
271266
defer res.deps.deinit();
272267
defer res.libs.deinit();
273268
defer res.vars_dict.deinit();
@@ -276,17 +271,19 @@ pub fn main() !void {
276271
defer res.binaries.deinit();
277272
defer res.errors.deinit();
278273
defer res.config_data.deinit();
279-
280274
var deps_list = std.ArrayList([]const u8).init(allocator);
281275
defer deps_list.deinit();
282-
for (res.deps.keys()) |d| try deps_list.append(d);
283-
276+
var dep_it = res.deps.keyIterator();
277+
while (dep_it.next()) |key| {
278+
try deps_list.append(key.*);
279+
}
284280
var libs_list = std.ArrayList([]const u8).init(allocator);
285281
defer libs_list.deinit();
286-
for (res.libs.keys()) |l| try libs_list.append(l);
287-
282+
var lib_it = res.libs.keyIterator();
283+
while (lib_it.next()) |key| {
284+
try libs_list.append(key.*);
285+
}
288286
const stdout = std.io.getStdOut().writer();
289-
290287
try stdout.print("{{", .{});
291288
try stdout.print("\"deps\":[", .{});
292289
var first = true;

0 commit comments

Comments
 (0)