torque 5f0d7b34d7
parser: shove an arena allocator in there
Stay a while and listen to my story.

Due to the design of the parser execution flow, the only reasonable way
to avoid leaking memory in the parser is to use an arena allocator
because the parser itself doesn't have direct access to everything it
allocates, and everything it allocates needs to live for the duration
of whatever callbacks are called.

Now, you might say, if the items it allocates are stored for the
lifetime of whatever callbacks, then that means that the items it
allocates stay allocated for effectively the entire life of the
program. In which case there's really not much point in freeing them
at all, as it's just extra work on exit that the OS should normally
clean up. And you'd be right, except for two details: if the user uses
the current GeneralPurposeAllocator, it will complain about leaks when
deinitialized, which simply isn't groovy. The other detail is that
technically the user can run any code they want after the parser
execution finishes, so forcing the user to leak memory by having an
incomplete API is rude.

The other option would be, as before, forcing the user to supply their
own arena allocator if they don't want to leak, but that's kind of a
rude thing to do and goes against the "all allocators look the same"
design of the standard library, which is what makes it so easy to use
and create allocators with advanced functionality. That seems like an
ugly thing to do, so, instead, each parser gets to eat the memory cost
of storing a pointer to its arena allocator (and the heap cost of the
arena allocator itself).

In theory, subcommands could borrow the arena allocator of their parent
command to save a bit of heap space, but that would make a variety of
creation and cleanup-related tasks less isomorphic between the parents
and the subcommands. I like the current design where commands and
subcommands are the same thing, and I'm not in a rush to disturb that.
I don't think the overhead cost of the arena allocator itself, which
can be measured in double digit bytes, is a particularly steep price
to pay.
2023-07-20 23:15:37 -07:00
2022-11-20 12:54:42 -08:00
2023-06-01 23:58:00 -07:00
2022-11-20 12:54:42 -08:00
2023-04-07 00:22:57 -07:00

== nearly obvious command line interface parser

A zig library for composing declarative command-line interfaces. Heavily
inspired by https://click.palletsprojects.com/[click] for Python.

== Extemporaneous Bloviation

[quote, George "Albert Einstein" Washington]
____
The alarm rings, and expletives spill from my mouth—instinctively, before any
neuron has a chance to fire. You'd think this would get easier, having done it
at least 12000 times, but I guess it just goes to show that practice does not
necessarily converge on perfection, no matter what infinite limit t approaches.
Eyes clamped shut against the encroaching underglow spilling from the curtains,
I stretch my arms straight out from my sides and proceed to lose my balance,
flying horizontally off of the mattress. An attempt at attitude control fails
vigorously and I begin cartwheeling through open space, asserting a lopsided
trajectory that intersects with the roof of the house. Passing through it
unencumbered, I careen skyward and watch the ground recede into the distance,
as the features of the landscape shrink and pop out of existence.
____

== Hello

Requires a pre-release version of Zig `0.11.0`. `0.11.0-dev.1844+75ff34db9` is the
oldest version specifically known to me to work.

=== Features

WARNING: NOCLIP is usable but not currently mature or well-tested. Unfinished features
and bugs likely exist.

* highly configurable short/long option and argument specification
  ** named options can be associated with an environment variable
  ** named flags, which take no value and can be biased `true` or `false`
  ** multiple specification options, which can be provided many times to the CLI
  ** overridable built-in conversion functions for standard types
  ** required options that must be specified by the user
  ** default values for options
* arbitrarily nestable subcommands for building sophisticated tools
* parser that supports many conventional CLI behaviors
  ** congealed short flags (e.g. `-abc` is the same as `-a -b -c`)
  ** `--` to force early of argument parsing
  ** both `--long value` and `--long=value` styles are supported
* option values are converted into rich native types using conversion callback functions
  ** integers
  ** basic tuple values
  ** strings
  ** enumerations as named choice sets
  ** more to come
* automatic help text generation and formatting
* CLI specification and parser are built at compile time

=== Use

`zig build demo` for a demo. Otherwise just copy the file or use a submodule or
something.

----
Usage: noclip-demo [options...] <arg> <subcommand ...>

  The definitive noclip demonstration utility

  This command demonstrates the functionality of the noclip library. cool!

Arguments:
  arg                         This is an argument that doesn't really do anything, but it's very
                              important.

Options:
  -t, --test <int> <int>      multi-value test option (env: NOCLIP_TEST)
  -c, --choice <choice>       enum choice option (env: NOCLIP_CHOICE) (default: demo.Choice.second)
  -d, --default <uint>        default value integer option (env: NOCLIP_DEFAULT) (default: 100)
  -m, --multi <u8>            multiple specification test option
  -f, --flag / -F, --no-flag  boolean flag (env: NOCLIP_FLAG)
  -M                          multiple specification test flag

Environment variables:
  NOCLIP_ENVIRON              environment variable only option

Subcommands:
  verb                        Perform some sort of work
----

== LICENSE

INTERNET SOFTWARE CONSORTIUM LICENSE

Description
Zig library for declaratively creating command-line interfaces
Readme 336 KiB
Languages
Zig 100%