A library for interactive command line interfaces in modern C++

Related tags

CLI cli
Overview

C/C++ CI of Cli

cli

A cross-platform header only C++14 library for interactive command line interfaces (Cisco style)

demo_local_session

demo_telnet_session

C/C++ CI of Cli

Features

  • Header only
  • Cross-platform (linux and windows)
  • Menus and submenus
  • Remote sessions (telnet)
  • Persistent history (navigation with arrow keys)
  • Autocompletion (with TAB key)
  • Async interface
  • Colors

How to get CLI library

Dependencies

The library depends on asio (either the standalone version or the boost version) only to provide telnet server. Therefore, the library has no dependencies if you don't need remote sessions.

Installation

The library is header-only: it consists entirely of header files containing templates and inline functions, and require no separately-compiled library binaries or special treatment when linking.

Extract the archive wherever you want.

Now you must only remember to specify the cli (and optionally asio or boost) paths when compiling your source code.

If you fancy it, a Cmake script is provided. To install you can use:

mkdir build && cd build
cmake ..
sudo make install

and, if you want to specify the installation path:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX:PATH=<cli_install_location>
make install

Compilation of the examples

You can find some examples in the directory "examples". Each .cpp file corresponds to an executable. You can compile each example by including cli (and optionally asio/boost header files) and linking pthread on linux (and optionally boost system).

To compile the examples using cmake, use:

mkdir build
cd build
cmake .. -DCLI_BuildExamples=ON
# or: cmake .. -DCLI_BuildExamples=ON -DBOOST_INCLUDEDIR=<boost_include_directory>
make all
# or: cmake --build .

In the same directory you can also find:

  • a GNU make file (Makefile)
  • a Windows nmake file (makefile.win)
  • a Visual Studio solution

You can specify boost library path in the following ways:

GNU Make

make CXXFLAGS="-isystem <boost_include>" LDFLAGS="-L<boost_lib>"

example:

make CXXFLAGS="-isystem /opt/boost_1_66_0/install/x86/include" LDFLAGS="-L/opt/boost_1_66_0/install/x86/lib"

(if you want to use clang instead of gcc, you can set the variable CXX=clang++)

Windows nmake

Optionally set the environment variable ASIO or BOOST to provide the library path. Then, from a visual studio console, start nmake passing one of the makefile.*.win files.

E.g., from a visual studio console, use one of the following commands:

# only compile examples that do not require asio
nmake /f makefile.noasio.win
# compile examples using boost asio
set BOOST=<path of boost libraries>
nmake /f makefile.boostasio.win
# compile examples using standalone asio
set ASIO=<path of asio library>
nmake /f makefile.standaloneasio.win

Visual Studio solution

Set the environment variable BOOST. Then, open the file cli/examples/examples.sln

CLI usage

The cli interpreter can manage correctly sentences using quote (') and double quote ("). Any character (spaces too) comprises between quotes or double quotes are considered as a single parameter of a command. The characters ' and " can be used inside a command parameter by escaping them with a backslash.

Some example:

cli> echo "this is a single parameter"
this is a single parameter
cli> echo 'this too is a single parameter'
this too is a single parameter
cli> echo "you can use 'single quotes' inside double quoted parameters"
you can use 'single quotes' inside double quoted parameters
cli> echo 'you can use "double quotes" inside single quoted parameters'
you can use "double quotes" inside single quoted parameters
cli> echo "you can escape \"quotes\" inside a parameter"               
you can escape "quotes" inside a parameter
cli> echo 'you can escape \'single quotes\' inside a parameter'
you can escape 'single quotes' inside a parameter
cli> echo "you can also show backslash \\ ... "                
you can also show backslash \ ... 

License

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Contact

Please report issues here: http://github.com/daniele77/cli/issues

and questions, feature requests, ideas, anything else here: http://github.com/daniele77/cli/discussions

You can always contact me via twitter at @DPallastrelli


Contributing (We Need Your Help!)

Any feedback from users and stakeholders, even simple questions about how things work or why they were done a certain way, carries value and can be used to improve the library.

Even if you just have questions, asking them in GitHub Discussions provides valuable information that can be used to improve the library - do not hesitate, no question is insignificant or unimportant!

If you or your company uses cli library, please consider becoming a sponsor to keep the project strong and dependable.

Comments
  • Initial support for Cmake

    Initial support for Cmake

    It may not be much but it is a start.

    I am mostly familiar with best practices consuming libraries but when it comes to creating them my knoledge could be improve.

    I will do some resaerch now but this is enoguh code so that others can take a look at it.

    Feedback is welcomed.

    #23 Is related

    opened by tete17 33
  • Support commands with variable number of arguments.

    Support commands with variable number of arguments.

    Using this we can now use lambdas that accept std::vector<std::string> in order to get the raw command into my lambda. This helps for situations when there's a few optional arguments that I need to have for my command.

    enhancement 
    opened by sakshamsharma 8
  • Bug instantiating Local terminal sessions in multiple threads

    Bug instantiating Local terminal sessions in multiple threads

    Discussed in https://github.com/daniele77/cli/discussions/131

    Originally posted by kalowery October 23, 2021 Hi - I'm using cli and really like it. It's going to save me huge amounts of time. I'm working on a tool that presents a cli on different threads at different times in a multi-threaded application. There's a segfault bug in linuxkeyboard.h when doing this. It has to do with the detached thread reading keyboard input (i.e. std::getchar) which is still alive after tearing down the session (it's blocking in getchar). The next time the user presses a key the detached thread returns from getchar (in Read()) but the reference to the scheduler is now invalid and the call to Post crashes with a segfault because the vtable is gone.

    I got it to quit crashing by having LinuxKeyboard check the "run" boolean member variable before calling notify. It still eats the first key stroke that would have gone to a new local session instance, which is annoying but it's better than crashing. I'm using the LoopScheduler and calling Stop() in my ExitAction. I'm open to the idea that I'm tearing things down improperly, but I really think it's an artifact of the detached thread being stuck in a blocking call to getchar() when the session is torn down.

    bug 
    opened by kalowery 6
  • Linker error when building examples using cmake in Visual Studio 2019

    Linker error when building examples using cmake in Visual Studio 2019

    Hey,

    I am trying to build the project in Visual Studio 2019, building it as a CMake project. I get the linker error:

    "fatal error LNK1104: cannot open file 'libboost_date_time-vc142-mt-gd-x64-1_70.lib'"

    I just dont understand where the dependancy on boosts date_time comes into play. Another curious thing is that it is only building complete.cpp and pluginmanager.cpp that fails. The exe files to filesession.cpp and simplelocalsession.cpp are building correctly without errors. Hope you could shed some light on this issue.

    If any other information is needed, please let me know

    help wanted 
    opened by chrisabr 6
  • Redesigned the function handle template for Menu::Add() to allow for arbitrary arguments

    Redesigned the function handle template for Menu::Add() to allow for arbitrary arguments

    The existing code had separate implementations of the FuncCmd wrapper that could handle 0 to 4 arguments passed from the command parser into the handler. This mechanism has been replaced with some relatively simple TMP based on a template parameter pack.

    You can now specify a command handler callable that takes any number of arguments. It's also easier to customize the display of help text for these arguments. The following pattern implemented before the menu items are instantiated will allow custom prompt text to be displayed even if the arguments are the same base type.

    namespace cli {
    	namespace argtypes {
    		struct device : public std::string {};
    		struct filename : public std::string {};
    	}
    	template <> struct TypeDesc<argtypes::device> { static const char* Name() { return "<device>"; } };
    	template <> struct TypeDesc<argtypes::filename> { static const char* Name() { return "<filename>"; } };
    }
    
    rootMenu->Add("do-something",
    	[service](std::ostream & out, cli::argtypes::device identifier){ performAction(identifier, "", out); });
    rootMenu->Add("do-something",
    	[service](std::ostream & out, cli::argtypes::device identifier, cli::argtypes::filename filename){ performAction(identifier, filename, out); },
    	"Perform the action on the device with the file");
    

    You'll get the following help text:

     - do-something <device>
     - do-something <device> <filename>
    	Perform the action on the device with the file
    

    The implementation relies on std::apply() as specified by C++17 so I've relicensed a portion of my C++17 compatibility layer and included it for configurations where std::experimental::apply() isn't available.

    The reordering of the arguments in the command handler declaration, with the ostream parameter coming first is intentional. This is necessary to reduce ambiguity with the variadic arguments. If the description field is an empty string, an empty newline is not printed for that command. This makes it cleaner to specify overloads of command names that take slightly different arguments.

    opened by ghost 6
  • Backspace is not working in MobaXterm

    Backspace is not working in MobaXterm

    In putty the backspace int value is 127 but in MobaXterm (https://mobaxterm.mobatek.net/) the value is 8. Hence, the cli apps are not usable in MobaXterm.

    bug 
    opened by paulsubrata55 5
  • Replaced Boost.Asio with Asio (much smaller library)

    Replaced Boost.Asio with Asio (much smaller library)

    This was much easier than I expected. I basically just messed with the namespaces to rearrange things to depend on Asio instead of Boost. I had to change boost::system::error_code to std::error_code in a few places, but that's consistent with the other differences of Boost-less Asio. More info on that: https://think-async.com/Asio/AsioAndBoostAsio.html

    I wasn't able to get tests working immediately because I had some issues with my local Boost library. I did try the Windows examples, though, and they all worked!

    opened by connorjak 5
  • Examples fail to build with Boost 1.74

    Examples fail to build with Boost 1.74

    It looks like v1.2.0 is not compatible with ASIO that comes with Boost 1.74, or is there any flags that should be set when configuring ?

    In file included from /home/debionne/dev/boost/boost_1_74_0/boost/asio/executor.hpp:342,
                     from /home/debionne/dev/boost/boost_1_74_0/boost/asio.hpp:86,
                     from /home/debionne/dev/cli/include/cli/detail/newboostasio.h:33,
                     from /home/debionne/dev/cli/include/cli/detail/boostasio.h:43,
                     from /home/debionne/dev/cli/include/cli/cliasyncsession.h:34,
                     from /home/debionne/dev/cli/examples/asyncsession.cpp:30:
    /home/debionne/dev/boost/boost_1_74_0/boost/asio/impl/executor.hpp: In instantiation of ‘void boost::asio::executor::impl<...> >’ has no member named ‘on_work_started’
         executor_.on_work_started();
         ~~~~~~~~~~^~~~~~~~~~~~~~~
    
    bug help wanted 
    opened by sdebionne 5
  • Persistent history

    Persistent history

    It would be useful to (optionally) make persistent the cli history.

    The local session and each remote session should maintain its own history. But how to identify remote sessions? According to the client IP address? Or more simply by providing one history for the local session and just one for all the remote sessions? In this case, what happens when more than one client is connected simultaneously?

    Maybe we could start by providing persistent history just for the local session.

    enhancement 
    opened by daniele77 5
  • vcpkg does not have telnet server include files

    vcpkg does not have telnet server include files

    First off, thanks for the library.

    Looking at Github and what's installed as part of vcpkg shows that telnet server support is not included in vcpkg. May request for updated package with telnet support?

    suspended 
    opened by tukotech 4
  • Default input handler without specifying a command

    Default input handler without specifying a command

    Like the switch grammar, how about register a default handler for input? For example: just input three integers after the prompt, and then call the Add command by default.

    cli> 1 2 3 6 cli>

    It would be nice when a single command is massively used.

    BTW, cli now supports Insert a command name of std::string(""), but it seems this command would never be called.

    opened by wangxuw 4
  • Feature EnterAction

    Feature EnterAction

    We can register a function to ExitAction() to do some of the things we want to do when the session exits

    So correspondingly, can we add an EnterAction() hook to do something we want to do when the session is first entered?

    For example, output a welcome message, a help message, etc.

    opened by Dup4 0
  • Coredump in `cli::detail::Session::Disconnect()`

    Coredump in `cli::detail::Session::Disconnect()`

    • cli: v2.0.2
    • boost: 1.78.0

    I used the above configuration with cli, but a coredump occurred at runtime with the following stack information, some sensitive information has been handled.

    #0  (inline)0x1f0a1f3 in cpputil::backtrace::(anonymous namespace)::signalHandler(int, siginfo_t*, void*) at /opt/tiger/bazel-buildfarm/default/operations/8d379db2-4128-4fb1-9dc4-bc4a80c55ac9/cpputil/backtrace/SignalHandler.cpp:127
    #1  0x0 in (unknown) at :0
    #2  0x34ec0 in gsignal at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/glibc/signal/../sysdeps/unix/sysv/linux/raise.c:51
    #3  0x36030 in abort at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/glibc/stdlib/abort.c:79
    #4  0x94972 in __gnu_cxx::__verbose_terminate_handler() [clone .cold.1] at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/gcc/libstdc++-v3/libsupc++/vterminate.cc:95
    #5  0x9a8d5 in __cxxabiv1::__terminate(void (*)()) at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:47
    #6  0x9a910 in std::terminate() at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:57
    #7  0x9ab42 in __cxa_throw at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc:95
    #8  0x3215357 in void boost::throw_exception<boost::system::system_error>(boost::system::system_error const&) at /opt/tiger/bazel-buildfarm/default/operations/f959d280-2dd3-47c4-a9ff-693ae49b2567/cpp3rdlib/boost/include/boost/throw_exception.hpp:162
    #9  0x33c0deb in boost::asio::detail::do_throw_error(boost::system::error_code const&, char const*) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/impl/throw_error.ipp:38
    #10  (inline)0x33c0deb in boost::asio::detail::throw_error(boost::system::error_code const&, char const*) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/throw_error.hpp:42
    #11  (inline)0x33c0deb in boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>::shutdown(boost::asio::socket_base::shutdown_type) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/basic_socket.hpp:1676
    #12  0x33bfe79 in cli::detail::Session::Disconnect() at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/cli/include/cli/detail/server.h:57
    #13  0x33b1db5 in std::function<void (std::ostream&)>::operator()(std::ostream&) const at /opt/tiger/typhoon-blade/gccs/x86_64-x86_64-gcc-830/lib/gcc/x86_64-linux-gnu/8.3.0/../../../../include/c++/8.3.0/bits/std_function.h:687
    #14  (inline)0x33b1db5 in cli::CliSession::Exit() at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/cli/include/cli/cli.h:303
    #15  0x33b2a8b in cli::detail::InputHandler::Keypressed(std::pair<cli::detail::KeyType, char>) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/cli/include/cli/detail/inputhandler.h:60
    #16  (inline)0x33b2a8b in operator()<std::pair<cli::detail::KeyType, char> > at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/cli/include/cli/detail/inputhandler.h:52
    #17  (inline)0x33b2a8b in std::_Function_handler<void (std::pair<cli::detail::KeyType, char>), cli::detail::InputHandler::InputHandler(cli::CliSession&, cli::detail::InputDevice&)::{lambda(auto:1)#1}>::_M_invoke(std::_Any_data const&, std::pair<cli::detail::KeyType, char>&&) at /opt/tiger/typhoon-blade/gccs/x86_64-x86_64-gcc-830/lib/gcc/x86_64-linux-gnu/8.3.0/../../../../include/c++/8.3.0/bits/std_function.h:297
    #18  0x33b29e7 in std::function<void (std::pair<cli::detail::KeyType, char>)>::operator()(std::pair<cli::detail::KeyType, char>) const at /opt/tiger/typhoon-blade/gccs/x86_64-x86_64-gcc-830/lib/gcc/x86_64-linux-gnu/8.3.0/../../../../include/c++/8.3.0/bits/std_function.h:687
    #19  (inline)0x33b29e7 in operator() at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/cli/include/cli/detail/inputdevice.h:59
    #20  (inline)0x33b29e7 in std::_Function_handler<void (), cli::detail::InputDevice::Notify(std::pair<cli::detail::KeyType, char>)::{lambda()#1}>::_M_invoke(std::_Any_data const&) at /opt/tiger/typhoon-blade/gccs/x86_64-x86_64-gcc-830/lib/gcc/x86_64-linux-gnu/8.3.0/../../../../include/c++/8.3.0/bits/std_function.h:297
    #21  0x33bab7b in std::function<void ()>::operator()() const at /opt/tiger/typhoon-blade/gccs/x86_64-x86_64-gcc-830/lib/gcc/x86_64-linux-gnu/8.3.0/../../../../include/c++/8.3.0/bits/std_function.h:687
    #22  (inline)0x33bab7b in boost::asio::detail::binder0<std::function<void ()> >::operator()() at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/bind_handler.hpp:60
    #23  (inline)0x33bab7b in void boost::asio::asio_handler_invoke<boost::asio::detail::binder0<std::function<void ()> > >(boost::asio::detail::binder0<std::function<void ()> >&, ...) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/handler_invoke_hook.hpp:88
    #24  (inline)0x33bab7b in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder0<std::function<void ()> >, std::function<void ()> >(boost::asio::detail::binder0<std::function<void ()> >&, std::function<void ()>&) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:54
    #25  (inline)0x33bab7b in void boost::asio::detail::asio_handler_invoke<boost::asio::detail::binder0<std::function<void ()> >, std::function<void ()> >(boost::asio::detail::binder0<std::function<void ()> >&, boost::asio::detail::binder0<std::function<void ()> >*) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/bind_handler.hpp:111
    #26  (inline)0x33bab7b in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder0<std::function<void ()> >, boost::asio::detail::binder0<std::function<void ()> > >(boost::asio::detail::binder0<std::function<void ()> >&, boost::asio::detail::binder0<std::function<void ()> >&) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:54
    #27  (inline)0x33bab7b in void boost::asio::detail::executor_function::complete<boost::asio::detail::binder0<std::function<void ()> >, std::allocator<void> >(boost::asio::detail::executor_function::impl_base*, bool) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/executor_function.hpp:116
    #28  0x33b8ceb in boost::asio::detail::executor_function::operator()() at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/executor_function.hpp:64
    #29  (inline)0x33b8ceb in void boost::asio::asio_handler_invoke<boost::asio::detail::executor_function>(boost::asio::detail::executor_function&, ...) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/handler_invoke_hook.hpp:88
    #30  (inline)0x33b8ceb in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::executor_function, boost::asio::detail::executor_function>(boost::asio::detail::executor_function&, boost::asio::detail::executor_function&) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:54
    #31  (inline)0x33b8ceb in boost::asio::detail::executor_op<boost::asio::detail::executor_function, std::allocator<void>, boost::asio::detail::scheduler_operation>::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/detail/executor_op.hpp:70
    #32  0x3218565 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) at /opt/tiger/bazel-buildfarm/default/operations/f959d280-2dd3-47c4-a9ff-693ae49b2567/cpp3rdlib/boost/include/boost/asio/detail/scheduler_operation.hpp:40
    #33  (inline)0x3218565 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) at /opt/tiger/bazel-buildfarm/default/operations/f959d280-2dd3-47c4-a9ff-693ae49b2567/cpp3rdlib/boost/include/boost/asio/detail/impl/scheduler.ipp:492
    #34  0x3218033 in boost::asio::detail::scheduler::run(boost::system::error_code&) at /opt/tiger/bazel-buildfarm/default/operations/f959d280-2dd3-47c4-a9ff-693ae49b2567/cpp3rdlib/boost/include/boost/asio/detail/impl/scheduler.ipp:210
    #35  0x33aef46 in boost::asio::io_context::run() at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/cpp3rdlib/boost/include/boost/asio/impl/io_context.ipp:63
    #36  0x33adb3d in xxx::xxxxx::cli::CLI::run() at /opt/tiger/bazel-buildfarm/default/operations/bc3b4bc4-b87c-40d8-a522-443120f95bab/xxx/src/xxx/cli/cli.cpp:54
    #37  0xc3a6e in execute_native_thread_routine at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/gcc/libstdc++-v3/src/c++11/thread.cc:80
    #38  0x7ca8 in start_thread at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/glibc/nptl/pthread_create.c:486
    #39  0xf276e in clone at /data00/jenkins_dir/workspace/toolchain/gcc8_x86_64/src/glibc/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95
    

    I can roughly deduce that when cli::detail::Session::Disconnect() was executed, boost threw an exception, but it was not caught, so a core dump occurred.

    https://github.com/daniele77/cli/blob/8ccd7bdcbd7824d56830e2bbbdb9636647dc0632/include/cli/detail/server.h#L55-L59

    So have we considered adding a try statement to cli::detail::Session::Disconnect()?

    opened by Dup4 1
  • get the help message of a sub menu by just calling <submenu name> + help

    get the help message of a sub menu by just calling + help

    Discussed in https://github.com/daniele77/cli/discussions/165

    Originally posted by fadytalat268 October 27, 2022 get the help message of a sub menu by just calling "submenu name" + help from the main menu

    opened by daniele77 0
  • Parameter of type

    Parameter of type "file" (or "directory") with autocompletion

    It would be nice to add the support for parameters of type std::filesystem::path, with auto-completion listing the files on the filesystem (bash style). This issue partially overlaps with #69 .

    enhancement 
    opened by daniele77 0
  • Add new keystroke / shortcut bash style

    Add new keystroke / shortcut bash style

    (From discussion #151 )

    Some examples:

    C-a Move to the start of the line.
    C-e Move to the end of the line.
    M-f Move forward a word, where a word is composed of letters and digits.
    M-b Move backward a word.
    C-l Clear the screen, reprinting the current line at the top.
    C-k Kill the text from the current cursor position to the end of the line.
    C-u Kill the text from the current cursor position to the beginning of the line.
    C-r search on the history
    C-d Exit.
    
    enhancement 
    opened by daniele77 0
Releases(v2.0.2)
  • v2.0.2(Aug 18, 2022)

  • v2.0.1(Apr 19, 2022)

    • Add a non-blocking exec method to schedulers (issue #127)
    • Add a Menu::Insert method working with free functions as handler
    • Cli::cout() returns a class derived from std::ostream
    • Fix address sanitizer issue with GenericAsioScheduler dtor
    • Fix teardown problem with linux (issue #132)
    • Fix teardown problem with windows
    • The prompt is no more shown after exit
    • Telnet server now works on MobaXTerm
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Aug 25, 2021)

    • Remove boost dependency for local only sessions (issue #83)
    • Now you can use standalone asio library instead of boost asio for remote sessions (issue #41)
    • Fix missing echo after ctrl-v paste of command (issue #72)
    • Remove the symbol BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT (issue #89)
    • Fix unused parameters warning in release mode (issue #90)
    • Cli constructor revision (issue #75)
    • Special keys not recognized behaves like backspace in windows (issue #111)
    • Fix cmake install dependencies (issue #117)
    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(Aug 27, 2020)

  • v1.2.0(Jun 27, 2020)

    • History persistence (issue #39)
    • Escaping and sentence support with quote and double quote
    • Remove boost dependency from cli.h: now, if you just use CliFileSession you don't need boost anymore
    • Support commands with a variable number of arguments through vector<string>
    • Handle CTRL-D (EOF) on linux
    • Handle CTRL-D, CTRL-Z and CTRL-C on windows
    • Consecutive identical commands are not stored in the history (issue #55)
    • Change message in case of wrong command
    • Fix Backspace from a remote terminal (issue #52)
    • Fix duplicate autocompletion (issue #67)
    • Add a namespace and folder "detail" (issue #17)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Sep 16, 2019)

    • Specify binding IP address in CliTelnetServer (issue #44)
    • Fix compilation with boost v. 1.70.0 (issue #40)
    • Fix assertion in History::Next() when buffer is empty (issue #47)
    • Fix compilation with older boost versions (< 1.66.0)
    • CMake generates cli.pc configuration file for pkg-config
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Apr 14, 2019)

    • Dynamically Remove/Disable/Enable commands and submenus (issue #15)
    • New variadic template method to add commands and menu (makes Add() deprecated)
    • Optionally delimitate string parameters by " (issue #38)
    • Explicitly set the names of parameters in help description
    • Unit tests
    • CMake support
    • Vcpkg support
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Feb 16, 2019)

    • Fix Clang 3.6 - 7.0 undefined reference bug
    • Fix infinite loop on EoF
    • Fix issue #27 (odd history behaviour): the history now works like in bash
    • Fix issue #28 (check for invalid stream in CliFileSession class)
    • Add doxygen basic configuration
    • Add session recordings in README file
    • Add CHANGELOG.md, CODE_OF_CONDUCT.md, CONTRIBUTING.md files
    Source code(tar.gz)
    Source code(zip)
Owner
Daniele Pallastrelli
Follow me on twitter at: @DPallastrelli
Daniele Pallastrelli
easy to use, powerful & expressive command line argument parsing for modern C++ / single header / usage & doc generation

clipp - command line interfaces for modern C++ Easy to use, powerful and expressive command line argument handling for C++11/14/17 contained in a sing

André Müller 977 Dec 29, 2022
A single header C++ library for parsing command line arguments and options with minimal amount of code

Quick Arg Parser Tired of unwieldy tools like getopt or argp? Quick Arg Parser is a single header C++ library for parsing command line arguments

null 47 Dec 21, 2022
null 77 Dec 27, 2022
C++ Library for pulling system and hardware information, without hitting the command line.

infoware C++ Library for pulling system and hardware information, without hitting the command line. Requirements No non-built-in ones by default. Some

The Phantom Derpstorm 323 Dec 23, 2022
A simple to use, composable, command line parser for C++ 11 and beyond

Clara v1.1.5 !! This repository is unmaintained. Go here for a fork that is somewhat maintained. !! A simple to use, composable, command line parser f

Catch Org 648 Dec 27, 2022
CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.

CLI11: Command line parser for C++11 What's new • Documentation • API Reference CLI11 is a command line parser for C++11 and beyond that provides a ri

null 2.4k Dec 30, 2022
Lightweight C++ command line option parser

Release versions Note that master is generally a work in progress, and you probably want to use a tagged release version. Version 3 breaking changes I

null 3.3k Dec 30, 2022
A simple to use, composable, command line parser for C++ 11 and beyond

Lyra A simple to use, composing, header only, command line arguments parser for C++ 11 and beyond. Obtain License Standards Stats Tests License Distri

Build Frameworks Group 388 Dec 22, 2022
CLIp is a clipboard emulator for a command line interface written in 100% standard C only. Pipe to it to copy, pipe from it to paste.

CLIp v2 About CLIp is a powerful yet easy to use and minimal clipboard manager for a command line environment, with no dependencies or bloat. Usage Sy

A.P. Jo. 12 Sep 18, 2021
pbr2gltf2 is a command line tool for converting PBR images to a glTF 2.0 material.

pbr2gltf2 is a command line tool for converting PBR images to a glTF 2.0 material. The tool is detecting depending on the filename, which PBR information is stored. It swizzles the images and does reassign the channels to a glTF 2.0 image. The tool stores the images plus a minimal, valid glTF 2.0 file containing the required material, textures and images.

UX3D GmbH 23 Jul 31, 2022
A command-line tool to display colorful distro information.

sjfetch A command-line tool to display colorful distro information.

Fikret Musk 6 Apr 6, 2022
LwSHELL is lightweight, platform independent, command line shell for embedded systems.

LwSHELL is lightweight, platform independent, command line shell for embedded systems. It targets communication with embedded systems from remote terminal to quickly send commands and the retrieve data from the device.

Tilen Majerle 80 Dec 25, 2022
Toybox: all-in-one Linux command line.

Toybox: all-in-one Linux command line.

Rob Landley 1.8k Dec 27, 2022
Simple command line tool that processes image files using the FidelityFX Super Resolution (FSR) or Contrast Adaptive Sharpening (CAS) shader systems.

Simple command line tool that processes image files using the FidelityFX Super Resolution (FSR) or Contrast Adaptive Sharpening (CAS) shader systems.

GPUOpen Effects 190 Dec 12, 2022
Command-line flag parsing in C

flag.h Inspired by Go's flag module: https://pkg.go.dev/flag WARNING! The design of the library is not finished and may be a subject to change. Quick

Tsoding 41 Nov 10, 2022
A command line tool with no external dependencies to print information about an X server instance.

xinfo A command line tool with no external dependencies to print information about an X server instance. Building and running To build the code in thi

Jean-Michel Gorius 6 Jan 13, 2022
Windows command line program for Spleeter, written in pure C, no need of Python.

SpleeterMsvcExe is a Windows command line program for Spleeter, which can be used directly. It is written in pure C language, using ffmpeg to read and write audio files, and using Tensorflow C API to make use of Spleeter models. No need to install Python environment, and it does not contain anything related to Python.

Wudi 181 Dec 5, 2022
Parse command line arguments by defining a struct

Parse command line arguments by defining a struct Quick Start #include <structopt/app.hpp> struct Options { // positional argument // e.g., .

Pranav 420 Dec 20, 2022
Rizin - UNIX-like reverse engineering framework and command-line toolset.

Rizin - UNIX-like reverse engineering framework and command-line toolset.

Rizin Organization 1.7k Dec 30, 2022