Skip to content

dstroy0/InputHandler

Repository files navigation

Alt text

InputHandler README

It's easy to start using

Check out the examples for different use cases.

This library is meant to assist in interfacing with your hardware, either through a uint8_t buffer, or a Stream, such as a Serial interface object.

Class output is enabled by defining a buffer, the class methods format the buffer into useful human readable information. ih::Input (the input parser) will function as normal without an output buffer.

Command length has no restrictions, any printable char or control char that is not your end of line character, token delimiter, or c-string delimiter is a valid commandString. You can have up to config.h:IH_MAX_ARGS_PER_COMMAND number of arguments. At runtime, ih::Input:addCommand() scans ih::Parameters and determines the maximum number of arguments you intend to use, it then allocates a dynamically sized array of flags (bit flags in a future feature) which lives for the duration of the process (one allocation per invocation of ih::Input::begin())

User-defined commands have a general tree structure, each command has its own ih::Parameters struct which is stored in non-volatile program memory (PROGMEM on Arduino platforms).

Individual commands that do not contain a wildcard character (each call to ih::Command) use 8 bytes of RAM (on avr). Commands that contain wildcards use more, how much they use depends on the placement of the wildcard characters, and the command length.

The ih::Command ih::Parameters target function will not execute if the input does not match the ih::Command ih::Parameters ih::Parameters::command, if any arguments are type-invalid, or if an unexpected amount of arguments are received.

To make input matching more performant, ih::Parameters::command that contain one or more ih::WildcardChar have their memcmp ranges computed at runtime for each command containing a wildcard char, each memcmp range that needs to be remembered uses ((1 + (1 + 1*n_wcc_containing_prm) + 1) + n_memcmp_ranges*2) bytes. ****, 8***, *8**, **8*, ***8 would compute one memcmp range 8**8 computes as two, 8888 doesn't have any wcc, so it would undergo "length of input" memcmp. Memcmp ranges are command-wide, if you have a nested command it will only have one associated ih::CommandRuntimeCalc struct.

InputHandler uses C++11 Aggregate initialization for ih::Parameters and ih::InputParameters structs.

Class output is enabled by defining a buffer, the class methods format the buffer into useful human readable information.

Default InputHandler Input constructor initialization with no output:

/*
  InputHandler default Input constructor uses InputParameters variables defined in the namespace ihc src/config/utility/namespace.h
*/
#include <InputHandler.h>
using namespace ih;

Input inputHandler;

Default InputHandler Input constructor initialization with output buffer:

/*
  InputHandler default Input constructor uses InputParameters variables defined in the namespace ihc src/config/utility/namespace.h
  This constructor will output messages into `output_buffer`, you can check to see if there's a message with ih::Input::isOutputAvailable()
*/
#include <InputHandler.h>
using namespace ih;
char output_buffer[512] = {'\0'}; //  output buffer
Input inputHandler(output_buffer, buffsz(output_buffer)); // Input constructor with output buffer and buffer length

Many aspects of InputParameters are customizable:

#include <InputHandler.h>
using namespace ih;

// char array typdef aliases
const PROGMEM ProcessName process_name = "_test_"; // process name
const PROGMEM EndOfLineChar process_eol = "\r\n";  // end of line characters
const PROGMEM ControlCharSeq process_ccseq = "##"; // input control character sequence
const PROGMEM WildcardChar process_wcc = "*";      // process wildcard character

// ih_auto::size_t, {ih_auto::size_t,...}, {ih_auto::char_array,...}
const PROGMEM DelimiterSequences process_delimseq = {
  1,    // number of delimiter sequences
  {1},  // delimiter sequence lens
  {" "} // delimiter sequences
};

// ih_auto::size_t, {ih_auto::size_t,...}, {ih_auto::char_array,...}
const PROGMEM StartStopSequences process_ststpseq = {
  1,           // num start stop sequence pairs
  {1, 1},      // start stop sequence lens
  {"\"", "\""} // start stop sequence pairs
};

const PROGMEM InputParameters input_prm[1] = {
  &process_name,
  &process_eol,
  &process_ccseq,
  &process_wcc,
  &process_delimseq,
  &process_ststpseq
};

char output_buffer[512] = {'\0'}; //  output buffer
Input inputHandler(input_prm, output_buffer, buffsz(output_buffer)); // Input constructor

A valid command string would look like this with the above InputParameters:

your_command arg_1 arg_2 arg... "arguments enclosed with start/stop delimiter sequences can have any char value 0-255, you can memcpy these argument types directly into a recipient struct (size - 1 to remove the null terminator) as uint8_t"
your_command subcommand_1 subcommand_2 ... subcommand_N subcommand_N_arg1 subcommand_N_arg2 ...
y*ur_co***** ...

ih::Input's input methods are:

void getCommandFromStream(Stream &stream, size_t rx_buffer_size = IH_MAX_PROC_INPUT_LEN);

Or, if you don't want to use a Stream object use this method instead:

void readCommandFromBuffer(uint8_t *data, size_t len);

This method will output to any initialized stream (hardware or software Serial):

void ih::Input::outputToStream(Stream &stream);

or, you can check to see if ihout output is available with:

bool ih::Input::outputIsAvailable();

and then when you are done with the output buffer, it needs to be reinitialized with:

void ih::Input::clearOutputBuffer();

Bug Reporting

Please report any bugs in InputHandler/src/ using bug_report.md at InputHandler/src/ bug report forum

Library Build Status

Adafruit platforms
Arduino platforms
ESP32 platforms
ESP8266 platforms
RPi platforms
Teensyduino platforms

Docs Build Status

Docs CI

Source Format Conformity

src-cpp-linter CI

Prebuilt cli_gen_tool Binaries

Made with PyInstaller

Download for linuxbuild linux binary

Download for macosbuild macos binary

Download for windowsbuild windows binary

Design Goals

Ease of use.
Implementation and platform flexibility.
Feature rich.
Low memory use.
Parse uint8_t, any value 0-255 char array.
Inter equipment interfacing.
Construct complex commands with subcommands, and enforce the input type.
Nested commands with no wildcards use 8 bytes or less of sram (avr).

News

See the releases' descriptions on the library's release page for a list of changes.

Supported Platforms

Not supported:
ATTiny85 -- memory/flash
ATMegaNG -- flash
adafruit:samd:adafruit_neotrinkey_m0 -- doesn't build
adafruit:samd:adafruit_pybadge_airlift_m4 -- doesn't build
arduino:samd:nano_33_iot -- doesn't build

If your board is not listed as not supported open an issue if you'd like it added to build coverage.

NOTE: vsnprintf and dtostrf implemented on the following platforms:
(see: src/config/noedit.h for your platform's implementation)
SAMD,
MBED,
arduino DUE

Build coverage:
Arduino
platformIO

InputHandler library documentation note

The docs use a feature not supported by every browser to jump to C++ source text. Source links will still take you to the source file, but to take advantage of url-scroll-to-text-fragment you need to use a supported browser, like chrome. Alternatively you can install an addon into firefox auto find text fragment to enable the functionality.        

Changelog

Generated by auto-changelog.

v0.0.12 - 2023-11-03

Commits

  • ci(version): library version d33e0e9
  • README.md v0.0.11 a4e877d
  • ci(version): library version de55c84
  • README.md 2289102
  • ci(version): library version bd7c4a1
  • README.md v0.0.9 89d16e7
  • chore(changelog): remove vestigial changelog 4dd1c60
  • README.md v0.0.8 a073c78
  • ci(changelog): fix changelog template path 8d221a2
  • ci(library.json): fix wrong path 7d0d097
  • ci(docs.yml): remove unnecessary trigger 6cf604d
  • ci(generate_changelog.yml): terminal command order 7ca42e8
  • feat(docs): add changelog to end of readme 1f790b4
  • generate changelog 8def221
  • ci(version bump automation): auto-changelog opts 365f8d9
  • generate changelog 39e7eec
  • fix(generate_changelog.yml): fetch main branch 09c6246
  • generate changelog 417009c
  • fix(generate_changelog.yml): fetch main branch 056bdf3
  • generate changelog da81b57
  • chore(update library.json): add auto-changelog opts 4806767
  • generate changelog 1f5959b
  • fix(generate_changelog.yml): change commands 90792d6
  • generate changelog f0e659d
  • fix(generate_changelog.yml): change commands 3c44528
  • fix(generate_changelog.yml): change commands 895ac2a
  • fix(generate_changelog.yml): change commands f7078b1
  • fix(generate_changelog.yml): change commands 22bc0ae
  • fix(generate_changelog.yml): change commands b451ad7
  • fix(generate_changelog.yml): change commands 5e53f49
  • fix(generate_changelog.yml): change commands 264b563
  • fix(generate_changelog.yml): remove symlink cmd 70ebdb9
  • feat(docs.yml): build docs if changelog altered 3e15aa8
  • autogenerated changelog 21b36dc
  • fix(generate_changelog.yml): testing symlink 69bdb22
  • autogenerated changelog 9072774
  • fix(generate_changelog.yml): add --no-git-tag-version opt 8c4efd8
  • feat(auto version bump): bump library.json version 6cf0974
  • feat(docs changelog): add changelog to docs 9d2f2c1
  • fix(workflow): docs build requirements cadcf6a
  • autogenerated changelog b2c22ff
  • add changelog to docs 440a70e
  • autogenerated changelog 52ea0d8
  • auto changelog workflow 63fa1d3
  • auto changelog workflow 43642b7
  • auto changelog workflow 25ec2da
  • auto changelog workflow a08b99c
  • fix(generate_changelog): workflow testing 2462937
  • fix(generate_changelog): workflow testing 4d0856c
  • fix(generate_changelog): workflow testing 2531183
  • fix(generate_changelog): workflow testing fb08dce
  • fix(generate_changelog): workflow testing 3d6150a
  • fix(generate_changelog): workflow testing 0aba2b1
  • fix(generate_changelog): workflow testing 150f3dd
  • fix(generate_changelog): workflow testing e3169f2
  • fix(generate_changelog): workflow testing 8569029
  • fix(generate_changelog): workflow testing 21cb6c4
  • fix(generate_changelog): workflow testing ee02127
  • fix(generate_changelog): workflow testing 7266b33
  • fix(generate_changelog): workflow testing 8a1a212
  • fix(generate_changelog): workflow testing e51a49f
  • fix(generate_changelog): workflow testing 315ea90
  • fix(generate_changelog): workflow testing 115838c
  • fix(generate_changelog): workflow testing fc67bef
  • feat(library): changelog generator testing 849fbe0
  • refactor(cli_gen_tool): use f string literals instead of string concatenation 72ea79a
  • refactor(commandParamtersDialog): refine layout, move ui files into tool src ccf1c8c
  • feat(tool_cli): script cli improvements 6697063
  • feat(tool_cli): add new arguments 5b2bcd2
  • style(cli_gen_tool src): PEP-8 formatting 3b04c5f
  • docs(library): conformity d7e65f1
  • refactor(library): refactor config parser 99d95b5
  • fix app exit errors 5719d6c
  • refactor, consolidate widgets 46a902f
  • gui launching w/o errors, gui closes w/ errors fffa68b
  • fix invalid return from MainWindow.eventFilter a42b01d
  • refactor, gui is launching with many errors 2981a8e
  • file generation/manipulation 3b3f462
  • refactor 0761161
  • refactor, remove Qt from file manipulation 0067547
  • format, read/write consolidation aa5c9af
  • checkpoint e691d11
  • Move cli_gen_tool cli to separate file 28c95f6
  • contrib checkpoints 033f47c
  • format 7a8d03d
  • build workflow syntax dc9361d
  • build workflow syntax error b0d9a2e
  • build workflow syntax error 3149afb
  • format, linting workflows 94b88f8
  • src lint workflow be291f3
  • src lint workflow a77f6e8
  • src lint workflow 0ac9230
  • src lint workflow 19fca91
  • src lint workflow 025d809
  • src lint workflow 4e5c079
  • src lint workflow 5a7e526
  • src lint workflow f4cc103