Awesome
no-cli
Cheesy command line interpreter designed for tiny memory-constrained systems. Minimal dependencies: just string.h.
Features
-
low footprint; the library is ~600 bytes
.text
(~335 bytes under minimal configuration), and uses a (configurable) 128 byte buffer (.bss
) and 24 byte (.data
) context structure.❯ arm-none-eabi-gcc -DNOCLI_RUNTIME_ECHO_CONTROL=0 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Os -Itest -c nocli.c -o nocli.o ❯ arm-none-eabi-size nocli.o text data bss dec hex filename 562 0 0 562 232 nocli.o
-
incremental parsing of input stream
-
static memory usage
-
supports doubly- and singly- quoted args (can be disabled to save ~100 bytes)
-
100% test coverage
-
fuzz tested via LibFuzzer
Possible future features, if I need them:
- UNIMPLEMENTED optional tab completion or history?
Usage
Example
See test/example.c
for an example that runs on host.
You can try the example by building it and running it:
# build
❯ make -f test/Makefile
Compiling nocli.c
Compiling test/example.c
Linking build/example/example
# run
❯ ./build/example/example
nocli$ help
?
help
count-args print number of args passed
change-prompt set prompt to new string
nocli$ count-args 1 2 3
Arg count: 3
nocli$
Integration
API is documented in nocli.h
. There's only two functions used:
- initialize the library:
void Nocli_Init(struct Nocli *nocli);
this includes a callback for outputting data and the table of commands.
- pass any amount of data:
void Nocli_Feed(struct Nocli *nocli, const char *input, size_t length);
commands are executed within this function, so be sure to call it in a safe context
libfuzzer crashes
Run libfuzzer with make -f test/Makefile fuzz
; it will run continuously until
a crash occurs (AddressSanitizer
and UndefinedBehaviorSanitizer
are enabled
on the fuzz build)
Crashes that libfuzzer finds are saved in test/corpus, which are run through the library in ci to catch regressions.
License
WTFPL (http://www.wtfpl.net/) or public domain, whichever you prefer.
Alternatives!
This library conflates two operations:
- line editing
- command line argument parsing
There are a LOT of alternatives. Here's some commonly used ones:
Line editing
- readline
- linenoise
Argument parsing
- getopt
- argp
- argparse3