Continuing the discussion from OTP whitelabel options for RP2350 boards:
A few items for discussion:
- Command reorganization
- Hierarchical command definition
- Common parsing of command line parameter types
- Simpler extension with new sub-commands
- Tab-completion … in long-term managable form (no per-command work)
Example using (global) OTP commands
Given the desire to add the following permitted commands:
otp dir [entryTypeId]
otp dump 3xbytes (startRow) [rowCount] [--show-votes]
otp dump n_of_m (startRow) (rowCount) N [--show-votes]
otp dump raw (startRow) [rowCount] [-q|--quiet]
otp dump ecc (startRow) [rowCount] [-q|--quiet]
otp dump auto (startRow) [rowCount] [-q|--quiet]
At root level, would add otp
as a string to the global (1st-level) table, which points to an OTP-specific 2nd-level table (same structure as the 1st-level table). This OTP entry would indicate the command(s) is globally available (should be parsed regardless of mode).
The 2nd-level OTP table would have two entries: One for dir
(otp dir
if parsing the whole hierarchy), which points to a command structure with options.
One for dump
, which points to a 3rd-level table (again, same structure as 1st/2nd levels).
The 3rd-level otp dump
table would have five entries, each pointing to a command structure with options for the corresponding variant.
A command structure would support listing mandatory and optional parameters, provide help for each parameter, examples for the command, etc.
Example for a specific mode
Given the desire to add the following permitted commands:
mode irplank [--use_prior_values]
mode irplank [--show_prior_values]
mode irplank [--tx_hertz N] [--tx_hertz N] ...
This indicates that there’s a mode supporting buspirate scripting.
Adding a mode would NOT modify the global command table, but only modify the mode
2nd-level table, by add an entry for the command irplank
(with its unique options to configure that mode).
Note that doing this would remove the overhead of having all the prompting for settings. The help text for each option would define what those options do. The --use_prior_values
and --show_prior_values
can be common code for all modes, reducing complexity of adding things further.
Common Parsing reduces per-addition overhead
Some default parsing becomes possible for each hierarchy. For the mode, the display / setting / saving of parameters can become automatic (with opt-out).
For all commands, a -h
/ --help
switch can parse the same structures and display the help that was defined … right next to its implementation.
Optional parameter? Parameter with optional / required arguments? Flags to permit arguments to be integer / hex / binary / bpscript token(s) / etc.? 90% declarative, and thus self-documenting.
As another example, for modes, it becomes possible to automatically document which bpscript tokens have meaning. Which modes ignore / implement:
protocol_start
protocol_start_alt
protocol_dath
(“set data line high”)protocol_write
protocol_read
protocol_datl
protocol_dath
protocol_dats
protocol_periodic
protocol_...
etc.
The information is already in the configuration structure (note: I would have the configuration using nullptr
to select a do-nothing option, adjusted to the default do-nothing function when the mode is entered). In other words, this can help to automatically document a substantial portion of the various modes, AND tab completion would become way more powerful by excluding options that the current mode doesn’t actually support.
Tab completion
Basically, processes each character of terminal input (not line-by-line). While at the CLI, it uses the command tables to discover the valid token(s) that might complete the current partial user-input-line. When tab key is pressed, if only one valid option to complete the partial line exists, it completes the entry, and adjusts the “current” table it looks at to that next-level table. If multiple entries could complete them, it displays those options (compactly).
While inputing bpscript, this would be a distinct tab completion process. First, it could be dependent on the mode’s configuration, such as to exclude from the list of allowed tokens those that the current mode does not support.
If this is pulled off, it will add a level of polish and shine to the CLI that reflects a much more mature (and expensive) product … with only a one-time-engineering cost.
I love the project. I see limitations and trouble coming for the CLI.
How can we make the CLI much more powerful and usable, while making it easier to add new commands / subcommands?
Should there be a way to mark a command / tree of commands as tied to a specific type of plank attached? (IR, smart card, etc. … each of which relies on hardware on the plank to do more)
[Edit – Add this para] Perhaps the structure listing the commands is universal, with a flag indicating if the command is available. e.g., OTP function availability would return false
if running on RP2040. Why? Less #ifdef
mess outside of the implementation (where it is unavoidable).
All the above is described in concept form … actual code comes after defining how it should work to be pleasant and user-friendly.
Oh, and that whole tab-completion thing has zero runtime overhead when not using tab. Winning!