Skip to content

A simple header-only C++ command interpreter library

License

Notifications You must be signed in to change notification settings

remysalim/cppcmd

Repository files navigation

cppcmd

Build Status

A lightweight and simple C++ command interpreter for your command interpreting needs.

Quick start

Minimal working sample

#include <iostream>
#include <cppcmd/CommandInterpreter.hpp>

using namespace cppcmd;
int main() {
    auto cli = CommandInterpreter(
        std::cin,  // input stream
        std::cout, // output stream
        std::cout  // prompt stream (optional)
    );

    cli.registerCommand("foo", [](const auto& args, auto& os) {
        os << "Hello from foo!\n";
        if (args.size()) {
            os << "got args: ";
            for (const auto& arg : args) os << arg << ' ';
            os << '\n';
        }
    });

    cli.run();
}

Parsing arguments

Arguments can be easily parsed from a string using cppcmd::as<T> in a command callback.

int value = 0;
cli.registerCommand("foo", [](const auto& args, auto& os) {
    value = as<int>(args[0]);

    // below is valid if Args == cppcmd::values::ValueString (default)
    value = args[0].as<int>();
});

Exceptions

Unexpected parsing errors yield cppcmd::parse_error exceptions, that extends std::exception .

i.e:

// bool regex mismatch throws
as<bool>("foobar");

// out of bound throws
as<uint8_t>("0xffff");

// trying to hold a signed value into an unsigned type throws
as<unsigned int>("-1");

// invalid string conversion throws
as<float>("number");

Overriding defaults

Default is described as follows:

  • A Command is a std::string
  • Args are stored in a std::vector of cppcmd::values::ValueString
  • Callback signature is a std::function<void(Args, OutputStream&)>

Defining a custom 'Expression'

An Expression defines the type of a Command , the separator character in between arguments, and the container in which the arguments are contained.

i.e:

using DefaultExpression = Expression<string, vector<values::ValueString>, ' '>;

Note:
values::ValueString is merely a std::string wrapper that implicitly converts to and from std::string and exposes values::ValueString::at<T>() to facilitate value parsing.

Setting the line-end character

Line-end is specialized along with Expression definition:

auto cli = CommandLine<DefaultExpression, '\n'>(is, os, tty);

Changing prompt string

You can override the default >>> prompt string (equivalent to PS1 under bash) as needed.

auto cli = CommandLine(is, os, tty, "$ ");

// if no prompt is expected, omit the prompt stream parameter
auto cli = CommandLine(is, os);

More

Additional samples and usage can be found in tests sources and in cppcmd-demo app:

Building and running tests

$ mkdir build && cd build

# test dependencies are resolved using Conan
$ conan install ..

$ cmake ..
$ cmake --build . --target cppcmd-test
$ ctest

Contributing

TO DO:

  • Handle arrow keys, del, backspace input
  • Add history
  • Allow specialization of callback signature