{"id":25300136,"url":"https://github.com/deftio/xelp","last_synced_at":"2026-05-16T07:15:00.155Z","repository":{"id":148290412,"uuid":"584928216","full_name":"deftio/xelp","owner":"deftio","description":"xelp is a tiny cli for embedded processors in pure C with no dependancies.  It supports programmer provided functions and is ROM-able and scriptable and has built-in help.","archived":false,"fork":false,"pushed_at":"2026-05-11T11:27:41.000Z","size":834,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-05-11T13:32:11.587Z","etag":null,"topics":["arduino","arm","cli","embedded-systems","msp430","x86"],"latest_commit_sha":null,"homepage":"https://deftio.github.io/xelp/pages/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deftio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2023-01-03T21:59:26.000Z","updated_at":"2026-05-11T11:26:14.000Z","dependencies_parsed_at":"2023-05-19T15:45:50.375Z","dependency_job_id":null,"html_url":"https://github.com/deftio/xelp","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/deftio/xelp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deftio%2Fxelp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deftio%2Fxelp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deftio%2Fxelp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deftio%2Fxelp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deftio","download_url":"https://codeload.github.com/deftio/xelp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deftio%2Fxelp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33093848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","arm","cli","embedded-systems","msp430","x86"],"created_at":"2025-02-13T05:38:31.547Z","updated_at":"2026-05-16T07:15:00.148Z","avatar_url":"https://github.com/deftio.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://deftio.github.io/xelp/pages/\"\u003e\u003cimg src=\"https://deftio.github.io/xelp/img/xelp-prompt-med.png\" width=\"30%\"\u003e\u003c/img\u003e\u003c/a\u003e\n\n![Version](https://img.shields.io/badge/version-0.3.3-blue.svg)\n[![License](https://img.shields.io/badge/License-BSD%202--Clause-blue.svg)](https://opensource.org/licenses/BSD-2-Clause)\n[![CI](https://github.com/deftio/xelp/actions/workflows/ci.yml/badge.svg)](https://github.com/deftio/xelp/actions/workflows/ci.yml)\n![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen.svg)  \n[![PlatformIO](https://img.shields.io/badge/PlatformIO-library-teal.svg)](https://registry.platformio.org/libraries/deftio/xelp)\n[![Arduino](https://img.shields.io/badge/Arduino-library-teal.svg)](https://github.com/deftio/xelp)\n[![ESP Component](https://img.shields.io/badge/ESP--IDF-component-teal.svg)](https://components.espressif.com/components/deftio/xelp)\n\n# xelp\n\nA tiny extensible command interpreter with scripting support for embedded systems. \nAdd an interactive serial CLI, single-key menus, or scripted command sequences to any microcontroller --\nfrom an 8-bit ATtiny85 to a 64-bit ARM Cortex-A. Pure C, no malloc, no OS,\nunder 3-5 KB fully featured on 32-bit targets (larger on 8/16-bit).\n\nXelp is instance based so it's possible to run distinct copies on different ports and it can be run inside interrupts (pending your own functions are safe).\n\n\u003cimg src=\"https://deftio.github.io/xelp/img/xelp-cli-demo.png\" width=\"70%\" alt=\"xelp CLI demo session\"\u003e\n\n## Why xelp\n\nMany embedded projects end up with an ad-hoc `if (char == 'x')` debug\nconsole. xelp replaces that with a proper CLI that:\n\n- Compiles on 8-bit to 64-bit targets with any C89 or later compiler\n- Fits in ~1 KB (key dispatch only) to ~5 KB (full CLI with line editing)\n- Uses zero dynamic memory -- no malloc, no heap, safe for ISRs\n- Supports multiple independent instances -- one per UART, no globals\n- Multiple commands can be saved as strings (scripts) and run from C or from the CLI.\n- Scripts are ROM-able const strings -- the parser never modifies its input (e.g. no strtok style processing)\n- Function dispatch tables make any C/C++ function callable from the CLI\n- Live help listing (optional, compile-time removable), commands can have run time assistance\n- CLI commands can be called from C or C functions can be called from the CLI.\n- A cpp wrapper is provided with identical functionality and some syntactic sugar for ease of use (still no memory allocation)\n\n## History\nXelp was first built for some embedded projects in the late 90s (though under different names) and then made more uniform in the late 2000s.\n\n\n## Build Profiles\n\nxelp is modular -- enable only what you need. Three profiles cover most use cases.\n\n### KEY only (~1 KB)\n\nSingle-keypress dispatch: each key triggers a function immediately, no\nENTER needed. Ideal for debug menus and hardware test jigs.\n\n```c\n#define XELP_ENABLE_KEY  1\n```\n\n### CLI Lean (~1.4 KB)\n\nAppend-only command line with tokenizer, scripting, and command dispatch.\nNo line editing, no cursor movement, no help listing. Ideal for the\nmost size-constrained targets that still need a CLI.\n\n```c\n#define XELP_ENABLE_CLI  1\n```\n\n### CLI (~3-5 KB)\n\nLine-buffered command prompt with cursor movement, line editing, multi-byte\nANSI key recognition, tokenizer, scripting, and help. This is the typical\ninteractive configuration.\n\n```c\n#define XELP_ENABLE_CLI        1\n#define XELP_ENABLE_LINE_EDIT  1\n#define XELP_ENABLE_KEY        1\n#define XELP_ENABLE_HELP       1\n```\n\nOptional: add `XELP_ENABLE_HISTORY` for UP/DOWN arrow command recall\n(~420 bytes, requires `XELP_ENABLE_LINE_EDIT`).\n\n### Full (~3-6 KB)\n\nAdds THR pass-through mode (~50-125 bytes more) for forwarding all\nkeystrokes to another peripheral such as a modem or radio module. This enables \nthe cli to flip in to a mode where one can send raw commands (such AT commands) to another device.  \n\n```c\n#define XELP_ENABLE_FULL  1\n```\n\nEvery flag is independent -- mix and match. For the full reference see\n[Build Profiles \u0026 Configuration Guide](docs/build-profiles.md).\n\n## Quick Start (Pure C)\n\nSee examples for simpler C++ version.\n\nAdd these three files to your project: `xelp.c`, `xelp.h`, `xelpcfg.h`.\n\n```c\n#include \"xelpcfg.h\"\n#include \"xelp.h\"\n\n/* Your output function -- write one char to UART, LCD, etc. */\nvoid uart_putc(char c) { UART_TX = c; }\n\n/* Your destructive backspace function - customize for your OS */\nvoid uart_bksp(void)   { uart_putc('\\b'); uart_putc(' '); uart_putc('\\b'); }\n\n/* Commands -- any C function with this signature */\nXELPRESULT cmd_hello(XELP *ths, const char *args, int len) {\n    XelpOut(ths, \"Hello!\\n\", 0);\n    return XELP_S_OK;\n}\n\nXELPRESULT cmd_led(XELP *ths, const char *args, int len) {\n    XelpArgs a;\n    int val;\n    XelpArgsInit(\u0026a, args, len);\n    XelpNextTok(\u0026a, 0);                      /* skip command name */\n    XelpNextInt(\u0026a, \u0026val);\n    LED_PORT = val;\n    return XELP_S_OK;\n}\n\n/* Command table */\nXELPCLIFuncMapEntry commands[] = {\n    { \u0026cmd_hello, \"hello\", \"say hello\"  },\n    { \u0026cmd_led,   \"led\",   \"led \u003c0|1\u003e\"  },\n    XELP_FUNC_ENTRY_LAST\n};\n\nXELP cli;\n\nvoid main(void) {\n    XelpInit(\u0026cli, \"My Device v1.0\");\n    XELP_SET_FN_OUT(cli, \u0026uart_putc);\n    XELP_SET_FN_BKSP(cli, \u0026uart_bksp);\n    XELP_SET_FN_CLI(cli, commands);\n\n    for (;;) {\n        if (uart_rx_ready())\n            XelpParseKey(\u0026cli, uart_getc());\n    }\n}\n```\n\nAt the prompt:\n\n```\nxelp\u003e hello\nHello!\nxelp\u003e led 1\nxelp\u003e\n```\n\nThe prompt string is settable per instance:\n\n```c\nXELP_SET_VAL_CLI_PROMPT(cli, \"mydev\u003e\");\n```\n\nThe prompt is stored by pointer, not copied. It must be a null-terminated\nstring that remains valid for the life of the instance (string literal,\nstatic, or global -- not a stack buffer that goes out of scope).\n\nPrompts can be global (all instances share a prompt), or per-instance (each peripheral gets its own prompt)\n\n## Scripting\n\nAnything typed at the CLI can be run as a script. Scripts are const strings\nparsed without modification -- they can live in ROM:\n\n```c\nconst char *startup_script = \"hello; led 1\";   /* cli functions that are available plus mode switch imperatives are allowed */\nXelpParse(\u0026cli, startup_script, XelpStrLen(startup_script));\n```\n\nScripts support semicolons (`;`), newlines, `#` comments, quoted strings\n(`\"...\"`), and escape characters (backtick at CLI, backslash in quotes).\n\n## Three Modes\n\n```\n         CTRL-P           ESC            CTRL-T\nCLI mode -------\u003e KEY mode -----\u003e THR mode\n   ^                                |\n   +--------------------------------+\n              mode switch keys\n```\n\n- **CLI**: Line-buffered input with prompt. Type commands, press ENTER.\n- **KEY**: Each keypress triggers a command immediately. For menus.\n- **THR**: All keys pass through to another peripheral. For debugging modems, serial devices.\n\nMode switch keys are configurable in `xelpcfg.h`.  If any mode is not enabled then the mode switch skips that mode\n\n## Building and Testing\n\n### Local development (fast, no Docker)\n\n```bash\nmake validate       # build + run tests + build all examples (the everyday check)\nmake tests          # unit tests + coverage only\nmake examples       # build all examples (no interactive launch)\nmake example        # build and run the posix ncurses demo (interactive)\nmake coverage       # tests + coverage summary\nmake fuzz           # fuzz testing with libFuzzer (requires clang)\nmake funcsizes      # per-function compiled sizes (x86-32, ARM32)\nmake sizes          # print compiled sizes for all feature profiles\nmake clean          # remove test build artifacts\nmake clean-all      # clean tests + all examples\n```\n\n50 test units, 693 test cases, 100% line coverage of `xelp.c`.\n\nFeature profile sizes: `dev/size_profiles.sh` (uses Docker for ARM Cortex-M0, falls back to host GCC).\n\n### Pre-release (validates + updates size tables)\n\n```bash\nmake prerelease     # tests + examples + Docker cross-compile + update README size tables\n```\n\nRuns `make validate`, then `tools/crossbuild.sh` (Docker), then\n`tools/update_sizes.sh` to patch the compiled-size tables in README.md\nand pages/index.html. Does not tag, push, or publish.\n\n### Full release\n\n```bash\nbash tools/make_release.sh             # full guided release (includes Docker cross-build)\nbash tools/make_release.sh --validate  # local validation only (no git, no push)\n```\n\nThe release script handles everything end-to-end: validation (tests +\nexamples), manifest sync, badge update, Docker cross-compilation, size\ntable update, push, PR, CI, merge, tag, and publish. The Docker\ncross-build step is skipped if Docker is not installed. Day-to-day\ndevelopment uses `make validate` which takes seconds.\n\n## Compiled Sizes\n\nCompiled `.text` section sizes with `-Os`. Three configurations: KEY\n(single-key dispatch only), CLI (typical interactive use), FULL (all\nfeatures including history, argv, and THR). Even the largest full build\nis under 12 KB.\n\n\u003c!-- Build Size Table --\u003e\n| CPU | Width | Compiler | KEY (bytes) | CLI (bytes) | FULL (bytes) |\n|-----|------:|----------|------------:|------------:|-------------:|\n| AVR (ATtiny85) | 8 | avr-gcc | 990 | 4302 | 5697 |\n| AVR (ATmega328P) | 8 | avr-gcc | 998 | 4402 | 5811 |\n| Z80 | 8 | SDCC | 1969 | 7378 | 9354 |\n| 6800 (HC08) | 8 | SDCC | 2095 | 8648 | 11170 |\n| MSP430 | 16 | msp430-gcc | 782 | 3532 | 4726 |\n| 68HC11 | 16 | m68hc11-gcc | 2169 | 6918 | 9902 |\n| ARM Thumb | 32 | arm-none-eabi-gcc | 600 | 2630 | 3463 |\n| Xtensa LX7 (ESP32-S3) | 32 | xtensa-esp-elf-gcc | 620 | 2652 | 3553 |\n| m68k | 32 | m68k-linux-gnu-gcc | 746 | 3372 | 4543 |\n| RISC-V (rv32) | 32 | riscv64-unknown-elf-gcc | 746 | 3140 | 4182 |\n| Xtensa LX106 (ESP8266) | 32 | xtensa-lx106-elf-gcc | 747 | 3003 | 3968 |\n| ARM32 | 32 | arm-none-eabi-gcc | 1008 | 4006 | 5327 |\n| x86-32 | 32 | GCC | 1099 | 4985 | 6349 |\n| MIPS32 | 32 | mipsel-linux-gnu-gcc | 1312 | 5288 | 6832 |\n| PowerPC | 32 | powerpc-linux-gnu-gcc | 1536 | 6146 | 7799 |\n| RISC-V (rv64) | 64 | riscv64-linux-gnu-gcc | 780 | 3594 | 4684 |\n| x86-64 | 64 | Clang | 1069 | 5355 | 7212 |\n| x86-64 | 64 | GCC | 1084 | 5183 | 6544 |\n| AArch64 (ARM64) | 64 | aarch64-linux-gnu-gcc | 1336 | 5626 | 6987 |\n| MIPS64 | 64 | mips64el-linux-gnuabi64-gcc | 1376 | 5928 | 7744 |\n\u003c!-- Build Size Table --\u003e\n\nx86-64 GCC row is measured directly; others from cross-compilation via\n`tools/Dockerfile.crossbuild`.  This is for size tracking, older versions / cousins of xelp were compiled and run on several (but not all of the above platforms)\n\n## Configuration\n\nAll compile-time options (buffer size, key mappings, prompt, escape\ncharacters, register count) are controlled via `#define` flags in\n`src/xelpcfg.h`. See the\n[Build Profiles \u0026 Configuration Guide](docs/build-profiles.md).\n\n## Porting\n\nxelp compiles on anything with a C89 compiler. To port:\n\n1. Add `xelp.c`, `xelp.h`, `xelpcfg.h` to your build\n2. Write a `void putc(char c)` function for your output hardware\n3. Call `XELP_SET_FN_OUT()` and `XelpParseKey()` -- that's it\n\nNo assembly. No platform `#ifdefs` (except optional SDCC `__reentrant`).\nSee [Porting Guide](docs/porting.md).\n\n## Architecture Support\n\nThe following toolchains compile xelp with zero warnings. Verified via\nDocker cross-compilation (`tools/Dockerfile.crossbuild`):\n\n| Architecture | Compiler | Word Size |\n|-------------|----------|-----------|\n| x86-64 | GCC, Clang | 64-bit |\n| x86-32 | GCC, Clang | 32-bit |\n| ARM64 | aarch64-linux-gnu-gcc | 64-bit |\n| ARM32 / Thumb | arm-none-eabi-gcc | 32-bit |\n| RISC-V (rv64) | riscv64-linux-gnu-gcc | 64-bit |\n| RISC-V (rv32) | riscv64-unknown-elf-gcc | 32-bit |\n| Xtensa LX106 (ESP8266) | xtensa-lx106-elf-gcc | 32-bit |\n| Xtensa LX7 (ESP32-S3) | xtensa-esp-elf-gcc | 32-bit |\n| MSP430 | msp430-gcc | 16-bit |\n| m68k (68000) | m68k-linux-gnu-gcc | 32-bit |\n| AVR (ATmega, ATtiny) | avr-gcc | 8-bit |\n| 8051 | SDCC | 8-bit (compiles, not in size table) |\n| 68HC11/12 | m68hc11-gcc | 16-bit |\n| PowerPC | powerpc-linux-gnu-gcc | 32-bit |\n\n## Repository Structure\n\n```\nxelp/\n  src/            xelp.c, xelp.h, xelpcfg.h (the library -- add these to your project)\n  tests/          unit tests (jumpbug framework), fuzz harnesses, 100% coverage\n  examples/       POSIX ncurses, Arduino, C++ wrapper, bare-metal, scripting, ESP32 Wi-Fi/BLE, Pico\n  tools/          cross-build scripts, release script, banner generator\n  docs/           API reference, configuration guide, porting guide\n  pages/          GitHub Pages site\n  dev/            design notes, planning docs, size profiling tools\n  .github/        CI workflows (build, test, fuzz, PlatformIO)\n```\n\n## Contributing\n\nPRs welcome. `master` is protected -- all changes go through pull requests.\nCI must pass (zero warnings, all tests, coverage) before merge.  Please note that \nPRs which affect multi-instance support or require dynamic memory may not be accepted.\n\n```bash\ngit checkout -b dev-my-feature master\n# make changes...\nmake clean \u0026\u0026 make tests    # must pass, zero warnings\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines: coding standards,\nwhat we welcome, branch model, and the release process.\n\n## Documentation\n\n- [Tutorial](docs/tutorial.md) -- step-by-step introduction to xelp\n- [Examples](docs/examples.md) -- annotated code for various platforms\n- [API Reference](docs/api-reference.md) -- all public functions, macros, types\n- [Build Profiles \u0026 Configuration Guide](docs/build-profiles.md) -- feature system and compile-time options\n- [Configuration Quick Reference](docs/configuration.md) -- all `#define` flags at a glance\n- [Porting Guide](docs/porting.md) -- bringing up xelp on a new platform\n- [Release Management](release_management.md) -- versioning, CI, release workflow\n- [Tools](tools/README_TOOLS.md) -- build utilities and code generators\n- [Contributing](CONTRIBUTING.md) -- how to contribute\n\n## AI / LLM Integration\n\nIf you use AI coding agents (Claude Code, Cursor, Copilot, etc.), xelp\nprovides machine-readable context files for accurate code generation:\n\n- [AGENTS.md](AGENTS.md) -- comprehensive coding reference: architecture, function signatures, parser internals, setup patterns, testing, common mistakes\n- [llms.txt](llms.txt) -- project overview and full documentation index ([llmstxt.org](https://llmstxt.org) format)\n\n## License\n\nBSD 2-Clause. See [LICENSE.txt](LICENSE.txt).\n\nCopyright (c) 2011-2026, M. A. Chatterjee\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeftio%2Fxelp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeftio%2Fxelp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeftio%2Fxelp/lists"}