Zarg
The minimalistic, Zig command line argument parser. Following (or making it easier to follow) the CLIG guidelines
24 Replies
Here is the banner that will be going up on the repo
Here are the xcf files for these
Both of these can be cleaned up and @earth's penguin mentioned using something like inkscape to convert the logo into a vector. Which would clean up all the finer details. I also think the text could be cleaned up, maybe with a different font, or rounding the edges.
I have messed with this project quite a lot, about 8 different tests and such. I think this will be the last time I'll have to keep doing continued rewriting. I will be planning out things very extensively in this channel. If not here, then likely on a notion page (which I would send here for your viewing).
The goal is to follow (or making it easier to follow) the CLIG guidelines. I won't bend over back too far to make every single thing adhere. I plan on making a list of things that will be supported and (for the time being) what wont.
Command Line Interface Guidelines
An open-source guide to help you write better command-line programs, taking traditional UNIX principles and updating them for the modern day.
I plan on using this library for all argument parsing done with #Hexdump
This list is going to be quite verbose, listing out every single feature mentioned in CLIG. If you want more detail on a feature refer back to CLIG. I have marked some things with (optional), meaning they can be done but aren't required to be done. Anything marked as optional likely means it's something in the API that can be set, not something Zarg is expected to have or do.
This list is just stuff from CLIG, Zarg will have other features too that aren't mentioned in this message!
SUPPORTED
HELP
- Return zero exit code on success, non-zero on failure
- Send output to stdout.
- Send messaging to stderr.
- Display help text when passed no options.
- Display a concise help text by default.
- A description of what your program does. (optional)
- One or two example invocations. (optional)
- Show full help when -h and --help is passed.
- Provide a support path for feedback and issues. (optional)
- In help text, link to the web version of the documentation. (optional)
- Use formatting in your help text.
- If the user did something wrong and you can guess what they meant, suggest it.
- If your command is expecting to have something piped to it and stdin is an interactive terminal, display help immediately and quit.
DOCUMENTATION
- Consider auto-generating man pages.
This isn't something in CLIG, just rather my own idea. I'm on the fence about it just because of simplicity.
OUTPUT
This entire section for now will be skipped. Output is done the the developer, not Zarg. Do follow CLIG's guidelines for output though...
ERRORS
- Catch errors and rewrite them for humans.
- If there is an unexpected or unexplainable error, provide debug and traceback information, and instructions on how to submit a bug.
- Make it effortless to submit bug reports.
All of these are done for Zarg itself, but this is expected to be done by the developer themselves.
FLAGS AND ARGUMENTS
- If a flag can accept an optional value, allow a special word like “none.”
- If possible, make arguments, flags and subcommands order-independent.
Robustness
- Responsive is more important than fast.
- Do stuff in parallel where you can, but be thoughtful about it.
UNSUPPORTED
- Display the most common flags and commands at the start of the help text.
this should just be done by the developer, not zarg as to keep it minimal
What language are you going to write this in? I assume it's Zig judging by the name
That's correct
Yes, I will be using Zig
Unlike the SUPPORTED and UNSUPPORTED sections, here is a hard list of features Zarg plans to or has implemented. This list differs from the prior one mentioned as we're no longer in the realm of philosophy (which is up to different peoples interpretation) but now to cold hard facts of features.
This list will be pinned and updated as time goes on, (and at some point) tagging features with emojis for their status:
✅ : implemented & tested
☑️ : implemented but haven't been tested
⚠️ : implemented but failed testing
🧪 : working on implementation
❌ : not implemented
PLANNED FEATURES
not a complete list due to my laziness
- ❌ | Flags
- 🧪 | Short flags
-s
- 🧪 | Long flags --long
- ❌ | Chaining flags like -abc
(where a
and b
do not take values)
- ❌ | Passing values using spaces or =
(-a 100
, -a=100
)
You could also infer this from Zarg's logo and or banner, where the Ziglang logo is used
Created a Github repo, nothing on it yet. Just a novelty for right nowFor speed reasons I'll be dropping some features
Namely:
1. auto-generating help menu
2. Tab completion of flags (maybe?)
3. Validating flags at comptime or runtime (maybe?)
4. Abstracting the underlying cast, meaning the developer gets positions and flag values as
[]const u8
Why?
1. Although this could all be done at comptime, it would require a very verbose "magic" api. It wouldn't keep much of it's "low levelness"
2. Same reason as #1
3. Requires allocating space for all args, or searching for them at runtime
4. Makes Zarg seem more like magic, not a low level argument parser
TL;DR
Although this message was not long... like at all. Here are my final words and goal of Zarg as of now. Zarg shouldn't look like magic, following Zigs lead, nothing is magic, everything being written out. Explicitly, making the control flow of the code much more obvious.
Example API Going Forward
Here is the pseudo code idea for the API I strive for:
The Old API
Here is the old API just for fun, this was my original concept and testing API:
In my opinion the new API is just better. It also solves many issues and allows Zarg to parse arguments in just a few microseconds
While the old API takes around 5-7 milliseconds, and is just a bit messier in my opinion. Although not shown in the example it could also have a autogenerating help menu, along with flag autocomplete (thanks to having to explicitly define the flags taken)
I would like to hear what you think about this @earth's penguin, as you're the one who is going to be using it.
Zarg will be using a state machine to parse the command line arguments@earth's bird how would I get certain arguments later in the code. is it using the switch statement with just one case?
I'd say you'd just setup a switch like so
This would be a somewhat downside to this, as unlike the old API not everything is provided under one struct and accessible at any point.
is it using the switch statement with just one case?I'm pretty sure you meant something like this https://discord.com/channels/728958932210679869/1199401594630963221/1200888484949397684. If that was the case, then yeah Be sure to let me know how you feel about it, after all Zarg is really just designed for Hexdump Seeing as you wanted Zarg to be fast fast I've been messing around with the API to get it to be fast. This was my solution but I'm open to rethinking it Working just on Linux support for the time being Why is it not just cross platform already you say? Well Windows needs allocations, Linux doesn't. Allocating uses a (likely many) syscall, syscalls are slow. Hopefully you see my dilemma, so I must break Zarg into a Windows and then Unix section. Thankfully all that really changes is the
init
function, but now I must manage an allocator safely.
Here is the init function currentlyAs you can see I do a quick switch on the
os.tag
This makes Zarg very fast on Linux, but slower on Windows thanks to the pesky unavoidable allocations
I'm trying to think of how I could write my own allocator that would be smarter about allocating memory for command line arguments
Hence this is the reason I am "Working just on Linux support for the time being"
the other option is just to allocate on both platforms, but no, no. Not happening
I have created the tokenizer, which was the most annnoying task, jeez.
Here is the test I ran if anyone would like to know
I'll run a quick test on speed here
I'm a bit concerned as I want to majorly optimise every little thing, why? Just because
If the tokenizing takes over a milisecond I will be sad@earth's bird how long does it take
Too long
:(
ouch
Way more then I want
Yeah well I ditched the system I told you last night
I keep changing everything because I find issues with it
Tokenizing like this fixes a lot, but as it's no longer abstract it still takes a hot minute. This is the longest task Zarg will have to do though.
Throwing my code onto my Linux machine to do some profiling
How would an auto generated help menu require a "magic API"
because auto generating the help menu requires it to now what options there are
if the options are handled by a switch statement as done without the magic api, the program doesnt know what arguments there are
thats a shitty way to explain it tho, @earth's bird can probably explain better
Magic just meaning you don't understand what it's doing, it seems like magic because you have no clue what is actually happening under the hood. Maybe for a high level language this isn't an issue, but for Zig it is. Regardless as @earth's penguin mentioned it would require me to know what arguments and flags the program wants to accept and their descriptions before hand
There is now tons of overhead that was never required before
Currently Zarg doesn't care what you want or what you don't want. What flags take values and what don't. It tokenizes the command line arguments and then gives a low level api for working with the tokens
That's what this is
Example API Going Forward Here is the pseudo code idea for the API I strive for: