Open vertexmachina opened 6 years ago
Hey Austin, unfortunately this isn't possible in yuck as it stands. The way it registers the last sub-subcommand is a leaky abstraction over m4 which happens to allow to redefine macros.
As for a possible implementation: yuck lives on a union of common options and structs of subcommands. Adding another nesting this should read a union of unions of structs of sub-subcommands, structs of sub-commands and common options.
I was thinking of providing means to nest different yuck files somehow and in a meaningful way. For instance in the above case you'd have 3 yuck files, remote.yuck
, power yuck
and channel.yuck
each specifying just their immediate subcommands. Then in the C file with main()
you'd have something like
#include "remote.yucc"
#include "power.yucc"
#include "channel.yucc"
int main(int argc, char *argv[])
{
yuck_t remote[1];
yuck_parse(remote, argc, argv);
switch (remote->cmd) {
power_yuck_t power[1];
case REMOTE_CMD_POWER:
yuck_parse(power, argc, argv);
...
}
...
}
I imagine yuck gen
would be called with a --nest
or something to prefix the types with its own name to avoid symbol name clashes.
However, in either case it's currently unclear to me what to do about common options, the term unfolds into global common options and subcommand common options. In your example there's only nesting depth 0 and nesting depth 2 commands, but what if there was a
Usage: remote channel
Display current channel name.
Its options would/should be treated as common options to all remote channel
invocations. Actually that's more of a question than a statement.
Now, for a completely different idea: Observe how yuck gendsl
on your original file actually does see all subsubcommands. Instead of changing the current m4 script (which generates the C output from that), a second m4 script tailored to your use case could be implemented and you simply do a yuck gen --script=MY.m4 remote.yuck
. (Actually using multiple m4 scripts was the plan anyway to support different languages and stuff, I just happen to not use different languages a lot.)
Anyway, tell me what you think.
The tailored m4 script sounds like the best idea for now, or I may keep doing it how I have been which is remote power_on
, remote power_off
, remote channel_change
, etc.
I'd like to contribute to the project for use by others but I don't have any spare time in the foreseeable future.
Is it possible to have subcommands within subcommands?
I'd like the ability to do something like
remote channel change 5
, orremote channel read
, wherechannel
is the main subcommand andchange
andread
are subcommands that are part of thechannel
subcommand.I've attempted to do it with a yuck file like this:
Which generates the following:
As you can see, it seems to only register the last sub-subcommand (e.g.,
power off
andchannel read
) in the yuck file.Is this functionality already present and I'm doing it incorrectly? If it isn't present, would the current architecture allow for it to be easily added? I would be happy to contribute.