├── .gitignore ├── LICENSE ├── README.md ├── build.zig ├── build.zig.zon └── src └── mini_parser.zig /.gitignore: -------------------------------------------------------------------------------- 1 | /.zig-cache 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025, Operachi 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mini-parser 2 | mini-parser is a very-minimal parser for [Zig](https://ziglang.org) language. 3 | 4 | ## Example 5 | ```zig 6 | const std = @import("std"); 7 | const mini_parser = @import("mini_parser"); 8 | const debug = std.debug; 9 | const posix = std.posix; 10 | 11 | const usage = 12 | \\Usage: example 13 | \\ 14 | \\Options: 15 | \\ --help -h Display help list. 16 | \\ --text -t Print the text. 17 | \\ --bool -b Enable the boolean. 18 | \\ 19 | ; 20 | 21 | pub fn main() !void { 22 | const argv = std.os.argv[0..]; 23 | 24 | var i: usize = 0; 25 | while (argv.len > i) : (i += 1) { 26 | const parser = try mini_parser.init(argv[i], &.{ 27 | .{ .name = "help", .short_name = 'h', .type = .boolean }, // 1 28 | .{ .name = "text", .short_name = 't', .type = .argument }, // 2 29 | .{ .name = "bool", .short_name = 'b', .type = .boolean }, // 3 30 | }); 31 | 32 | switch (parser.argument) { 33 | 0 => { 34 | debug.print("no argument was given.\n", .{}); 35 | posix.exit(0); 36 | }, 37 | 1 => { // 1 38 | debug.print("{s}\n", .{usage}); 39 | posix.exit(0); 40 | }, 41 | 2 => debug.print("Text: {s}\n", .{parser.value}), // 2 42 | 3 => debug.print("Enabled boolean!\n", .{}), // 3 43 | 4 => { 44 | debug.print("argument '{s}' does not exist.\n", .{argv[i]}); 45 | posix.exit(0); 46 | }, 47 | else => {}, 48 | } 49 | } 50 | } 51 | ``` 52 | 53 | ## Installation 54 | 55 | Fetch mini-parser package to `build.zig.zon`: 56 | ```sh 57 | zig fetch --save git+https://github.com/Operachi061/mini-parser 58 | ``` 59 | 60 | Then add following to `build.zig`: 61 | ```zig 62 | const mini_parser = b.dependency("mini_parser", .{}); 63 | exe.root_module.addImport("mini_parser", mini_parser.module("mini_parser")); 64 | ``` 65 | 66 | After building, test it via: 67 | ```sh 68 | ./example --bool --text foo -h 69 | ``` 70 | 71 | ## License 72 | This project is based on the BSD 3-Clause license. 73 | -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn build(b: *std.Build) void { 4 | _ = b.addModule("mini_parser", .{ 5 | .root_source_file = b.path("src/mini_parser.zig"), 6 | }); 7 | } 8 | -------------------------------------------------------------------------------- /build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .mini_parser, 3 | 4 | .version = "0.0.0", 5 | .minimum_zig_version = "0.15.0-dev.208+8acedfd5b", 6 | 7 | .paths = .{ 8 | "build.zig", 9 | "build.zig.zon", 10 | "src", 11 | }, 12 | .fingerprint = 0xcddd5f41eb6a7a8c, 13 | } 14 | -------------------------------------------------------------------------------- /src/mini_parser.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const mem = std.mem; 3 | 4 | pub const Table = struct { 5 | name: []const u8, 6 | short_name: u8, 7 | type: enum { argument, boolean }, 8 | }; 9 | 10 | const ArgumentData = struct { 11 | argument: usize, 12 | value: []const u8, 13 | }; 14 | 15 | pub fn init(Arg: [*:0]u8, comptime table: []const Table) !ArgumentData { 16 | const args = mem.sliceTo(Arg, 0); 17 | const argv = std.os.argv; 18 | 19 | if (argv.len == 1) return .{ .argument = 0, .value = "" }; 20 | 21 | var i: usize = 1; 22 | while (table.len > i) : (i += 1) { 23 | inline for (table, 1..table.len + 1) |flag, arg| { 24 | const argument = mem.eql(u8, "--" ++ flag.name, args); 25 | const short_argument = mem.eql(u8, &[_]u8{ '-', flag.short_name }, args); 26 | 27 | if (argument or short_argument) return switch (flag.type) { 28 | .boolean => .{ .argument = arg, .value = "" }, 29 | .argument => .{ .argument = arg, .value = mem.sliceTo(Arg[args.len + 1 ..], 0) }, 30 | }; 31 | } 32 | if (mem.eql(u8, args[0..1], "--") or args[0] == '-') return .{ .argument = table.len + 1, .value = "" }; 33 | } 34 | 35 | return .{ .argument = table.len + 2, .value = "" }; 36 | } 37 | --------------------------------------------------------------------------------