Skip to content

Instantly share code, notes, and snippets.

@Tetralux
Last active October 21, 2023 02:03
Show Gist options
  • Save Tetralux/c0e2439d560441f313b5cd314987bcae to your computer and use it in GitHub Desktop.
Save Tetralux/c0e2439d560441f313b5cd314987bcae to your computer and use it in GitHub Desktop.
Rudimentary INI parser in Zig
const std = @import("std");
const string = []const u8;
const Allocator = std.mem.Allocator;
/// Given an entire INI string, parses it into a map of key-value pairs.
/// The pairs are all freed by a call to `Parser.deinit`, and retrieved via `Parser.get`.
/// If you need them to live beyond that, use `some_other_allocator.dupe(u8, value)`.
pub const Parser = struct {
data: std.StringArrayHashMap(string),
arena: std.heap.ArenaAllocator,
/// Parses an entire INI string into a map of key-value pairs.
/// See `Parser.get` and `Parser.deinit`.
pub fn parse(input: string, ally: Allocator) !Parser {
var p = Parser {
.data = undefined,
.arena = std.heap.ArenaAllocator.init(ally),
};
p.data = std.StringArrayHashMap(string).init(p.arena.allocator());
try p.data.ensureTotalCapacity(32);
errdefer p.deinit();
var stream = std.io.fixedBufferStream(input);
const r = stream.reader();
while (try r.readUntilDelimiterOrEofAlloc(p.arena.allocator(), '\n', std.math.maxInt(u32))) |line| {
const trimmed_line = std.mem.trim(u8, line, "\r\n\t");
if (trimmed_line.len == 0) continue;
if (trimmed_line[0] == '#') continue;
if (std.mem.indexOfScalar(u8, trimmed_line, '=')) |i| {
const key = std.mem.trim(u8, trimmed_line[0..i-1], "\r\t ");
const value = std.mem.trim(u8, trimmed_line[i+1..], "\r\t ");
try p.data.put(key, value);
}
}
return p;
}
/// Frees all key-value pairs that were allocated by `Parser.parse`.
pub fn deinit(p: *Parser) void {
p.arena.deinit();
p.* = undefined;
}
/// Lookup a key.
///
/// The string returned by this function is freed by `Parser.deinit`.
/// If you need it to live beyond that, use `some_other_allocator.dupe(u8, value)`.
pub fn get(p: *Parser, key: string) ?string {
return p.data.get(key);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment