Skip to content

koeir/zig-flag

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

253 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zig-flag

A simple flag parser for Zig programs.

API documentation can be found here or made with zig build docs. If fetching from master, it is recommended do use zig build docs as the GitHub pages might not be updated.

Features

Config Options

Parse Config

See Type.ParseConfig

  • allowDups: Don't error when duplicate flags are set. Default is false.
  • verbose: Print out error messages when errors occur. Default is false.
  • writer: Required when using verbose option. Doesn't really do anything without it. Default is null.
  • prefix: Print out a custom string for verbose messages. Default is null.
  • allowDashInput: Allow input type flags to hold strings that begin with "-". Default is true.
  • errOnNoArgs: Outputs an error if there are no arguments except argv[0]. Default is false.
  • exitFirstErr: Exit on first error found. Default is true.

Print Formatting

See examples/formatting.md

Usage

  1. Fetch with zig and add as module in build.zig
// Specific tag
zig fetch --save https://github.com/koeir/zigflag/archive/refs/tags/v0.x.x.tar.gz

// Or master branch
zig fetch --save git+https://github.com/koeir/zigflag
    // build.zig
    const zigflag = b.dependency("zigflag", .{
        .target = target,
        .optimize = optimize,
    });

    const exe = b.addExecutable(.{...});
    exe.root_module.addImport("zigflag", zigflag.module("zigflag"));
  1. Initialize flags
const zigflag = @import("zigflag");

const SwitchFlag = zigflag.Type.SwitchFlag; // bool
const InputFlag = zigflag.Type.InputFlag;   // ?[][:0]const u8

const Flags = zigflag.Type.Flags;
const Flag = zigflag.Type.Flag;

// Initialize flags and their default values
// name doesn't really matter as long as the
// members are all of type zigflag
pub const defaults: Flags = .{
    .list = &[_]Flag
    {
        .{
            .name = "recursive",
            .tag = "Switches",
            .long = "recursive",
            .short = 'r',
            .value = SwitchFlag,
            .desc = "Recurse into directories",
        },
        .{
            .name = "force",
            .tag = "Switches",
            .long = "force",
            .short = 'f',
            .vanity = "-[n|f], --[no-]force",
            .value = SwitchFlag,
            .desc = "Skip confirmation prompts",
        },
        .{  // by default, untagged flags will not be printed
            .name = "no-force",
            .long = "no-force",
            .short = 'n',
            .value = SwitchFlag,
            .desc = "Do not skip confirmation prompts",
        },
        // Arguments will accept the next argv
        // e.g. -prf noob
        // "noob" will be accepted as the file
        .{
            .name = "file",
            .tag = "Input",
            .long = "path",
            .short = 'p',
            .value = InputFlag,
            .desc = "Path to file",
        },
    }
};

Input takes always takes the next argument after it, optionally erring if the next arg has flag syntax. Input supports storing multiple arguments by default, but can be avoided setting allowDups to false or just checking the array len.

  1. Parse flags
const defaults = @import("./init_flags.zig").defaults;
const Flags = zigflag.StructFlags(defaults);

pub fn main(init: std.process.Init) !void {
    ...
    // Make config
    const parsecfg: zigflag.Type.ParseConfig = .{
        .allowDashInput = true,
        .allowDups = true,
        .verbose = true,
        .writer = stderr,
        .prefix = "my-program: "
    };
    
    // points to erred flag
    var errptr: ?[]const u8 = null;
    // actual parse, returns a tuple of Flags and resulting args
    const result = try zigflag.parse(init.gpa, min.args, defaults, &errptr, parsecfg);
    defer result.deinit();

    // retrieving values
    const flags: Flags = result.flags;
    const argv: [][:0]const u8 = result.argv;
    ...
}

The flags are stored in a struct in which the fields are names of the flags. Each field will have their corresponding values (Switch/bool, Input/?[][:0]const u8). The struct also holds the allocator, inner arrays, and necessary components for deinit. gpa is used here, but it might be more convenient to use arena allocators.

  1. Use
const defaults = @import("./init_flags.zig").defaults;
const Flags = zigflag.StructFlags(defaults);

pub fn main(init: std.process.Init) !void {
    ...
    const parsed: Flags = result.flags;
    // arg list that has flags removed;
    // also removes values that were taken in by flags
    const flagless_args: [][:0]const u8 = result.args;

    if (parsed.force) // whatever

    const recursive: bool = parsed.recursive;
    const files: ?[][:0]const u8 = parsed.files;

    if (!recursive) //whatever

    for (files orelse &.{}) |file| {
        // whatever
    }
    ...
}
  1. Optionally customize
    // warning:
    //
    // center padding is calculated by
    // value - n of chars in "-<s>, --<long>"
    // so make sure the padding is enough
    zigflag.Type.Flag.fmt = .{
        .padding = .{
            .left = 5,
            .center = 30,
        },
        .greyOutFiller = true,
        .fillerStyle = '.',
    };
  Switches:
     -r, --recursive.............. Recurse into directories
     -[n|f], --[no-]force......... Skip confirmation prompts

  Input:
     -p <file>, --path <file>..... Path to file

Errors

pub const FlagErrs = error {
    NoArgs,             // argc < 2
    NoSuchFlag,         // unrecognized flag in arg list
    FlagNotSwitch,      // non-switch/non-bool Flag treated as a switch/bool
    FlagNotArg,         // non-input type flag treated as an input type
    DuplicateFlag,      // flag appears twice in arg list; can be ignored with config
    ArgNoArg,           // no argument given to input type flag
    NoWriter,           // no writer given when verbose is true
    TypeMismatch,       // a more general FlagNotSwitch/FlagNotArg
}

About

Actually simple flag parser for CLI Zig programs.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages