I’m trying to list put gnupg groups into hash maps with the group names as keys and values being the Key IDs from the groups. However when returning a StringArrayHashmap from my function the key name appears as a function when iterating over the key values. Does StringArrayHashmap only allocate memory for its values and not keys? You can find the function I’ve written below:
/// Returns a HashMap of all GNUPG groups and their KeyIDs
fn getGPGGroups(allocator: std.mem.Allocator) !std.StringArrayHashMap([]const []const u8) {
var groups = std.StringArrayHashMap([]const []const u8).init(allocator);
const res = try std.ChildProcess.run(.{
.allocator = allocator,
.argv = &.{ "gpg", "--list-config", "--with-colons" },
.cwd = null,
.cwd_dir = null,
});
defer {
allocator.free(res.stderr);
allocator.free(res.stdout);
}
var stream = std.io.fixedBufferStream(res.stdout);
const reader = stream.reader();
var line = std.ArrayList(u8).init(allocator);
var ids = std.ArrayList([]const u8).init(allocator);
defer {
line.deinit();
ids.deinit();
}
const writer = line.writer();
while (reader.streamUntilDelimiter(writer, '\n', null)) {
// Clear the line so we can reuse it.
defer {
ids.clearRetainingCapacity();
line.clearRetainingCapacity();
}
if (!std.mem.startsWith(u8, line.items, "cfg:group")) continue;
if (line.items[line.items.len - 1] == '\r') _ = line.pop();
var line_iter = std.mem.splitScalar(u8, line.items, ':');
_ = line_iter.first(); // cfg
_ = line_iter.next(); // group
const group_name = line_iter.next().?;
const keyIds = line_iter.next().?;
var id_iter = std.mem.splitScalar(u8, keyIds, ';');
while (id_iter.next()) |id| {
try ids.append(id);
}
std.debug.print("{s}\n", .{group_name});
try groups.put(group_name, ids.items);
} else |err| switch (err) {
error.EndOfStream => {}, // Continue on
else => return err, // Propagate error
}
return groups;
}
Any help here would be greatly appreciated!
I use the test below, I have one group that I called ‘helo’ just to test.
But get a segmentation fault when performing the test outside of the function.
test "getGPGGroups" {
const alloc = std.testing.allocator;
var groups = try getGPGGroups(alloc);
defer groups.deinit();
try std.testing.expect(groups.contains("helo"));
}
Edit
I realize I didn’t include any test data, The group line for my group ‘helo’ looks like this.
cfg:group:helo:AFEC18BD8EDE74098290EB125D93694E918198B9;8071489F45AB0284A6AE258F04934E5882A67089