All Projects → ronen25 → Libcmdf

ronen25 / Libcmdf

Single-header library for writing CLI applications in C/C++

Programming Languages

c
50402 projects - #5 most used programming language
cplusplus
227 projects

Projects that are alternatives of or similar to Libcmdf

Commander
🚀The framework to write type-safe and structured command line program easily in Swift.
Stars: ✭ 170 (+466.67%)
Mutual labels:  cli, command-line-parser
Terminal layout
The project help you to quickly build layouts in terminal,cross-platform(一个跨平台的命令行ui布局工具)
Stars: ✭ 98 (+226.67%)
Mutual labels:  cmd, cli
Sqlite Global Tool
SQLite .NET Core CLI tool that allows the user to manually enter and execute SQL statements with or without showing query result.
Stars: ✭ 37 (+23.33%)
Mutual labels:  cmd, cli
Spectre.cli
An extremely opinionated command-line parser.
Stars: ✭ 121 (+303.33%)
Mutual labels:  cli, command-line-parser
Argparse
Argparse for golang. Just because `flag` sucks
Stars: ✭ 294 (+880%)
Mutual labels:  cli, command-line-parser
Typin
Declarative framework for interactive CLI applications
Stars: ✭ 126 (+320%)
Mutual labels:  cli, command-line-parser
Pyinquirer
A Python module for common interactive command line user interfaces
Stars: ✭ 1,151 (+3736.67%)
Mutual labels:  cmd, cli
Crossline
A small, self-contained, zero-config, MIT licensed, cross-platform, readline and libedit replacement.
Stars: ✭ 53 (+76.67%)
Mutual labels:  cli, readline
Picocli
Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc.
Stars: ✭ 3,286 (+10853.33%)
Mutual labels:  cli, command-line-parser
Covid19 Tracker Cli
A curl-based command line tracker for Novel Coronavirus or COVID-19 pandemic. It Supports terminal for linux and macos, command prompt for windows, and termux for android with real-time updates.
Stars: ✭ 244 (+713.33%)
Mutual labels:  cmd, cli
Clikt
Multiplatform command line interface parsing for Kotlin
Stars: ✭ 1,658 (+5426.67%)
Mutual labels:  cli, command-line-parser
Argh
Argh! A minimalist argument handler.
Stars: ✭ 752 (+2406.67%)
Mutual labels:  cli, command-line-parser
Ppx deriving cmdliner
Ppx_deriving plugin for generating command line interfaces from types (Cmdliner.Term.t)
Stars: ✭ 78 (+160%)
Mutual labels:  cli, command-line-parser
Lua Resty Repl
Interactive console (REPL) for Openresty and luajit code
Stars: ✭ 165 (+450%)
Mutual labels:  cli, readline
Ishell
Library for creating interactive cli applications.
Stars: ✭ 1,127 (+3656.67%)
Mutual labels:  cli, readline
Ntutils
Various Command Line Utilities Ported to Windows NT
Stars: ✭ 58 (+93.33%)
Mutual labels:  cmd, cli
Jay
😎 Supercharged JavaScript REPL
Stars: ✭ 970 (+3133.33%)
Mutual labels:  cli, readline
Clii
Python 3.7+ function annotations -> CLI
Stars: ✭ 41 (+36.67%)
Mutual labels:  cli, command-line-parser
Commander
Test your command line interfaces on windows, linux and osx and nodes viá ssh and docker
Stars: ✭ 183 (+510%)
Mutual labels:  cmd, cli
Caporal.js
A full-featured framework for building command line applications (cli) with node.js
Stars: ✭ 3,279 (+10830%)
Mutual labels:  cli, command-line-parser

libcmdf.h

A simple library for writing command-line applications, inspired by Python's cmd module.


Latest version: v.1.3 (2020-27-11)


Features

  1. Written using 100% ANSI C
  2. Header only: no linkage! No separate compilation!
  3. Cross-platform
  4. GNU Readline support
  5. Can be used from C++ (without -fpermissive)

Requirements

  1. Any ANSI C/ISO C90-compliant compiler
    Tested on GCC 5.4+, clang 4.0+ and MSVC 14.0
  2. Linux/Windows
    Tested on Ubuntu 16.04 - 20.04, Fedora 26 - 30, and Windows 10 (all AMD64)
  3. GNU Readline development libraries (optional)
    Required for GNU Readline support, if enabled.

Usage

Being a header-only library, you don't need to do any complex linkage - just drop it in your project tree and you're done!

You will, however, need to define LIBCMDF_IMPL only once, and before you include the library, like this:

#define LIBCMDF_IMPL
#include <libcmdf.h>

...

API in a nutshell

First of all, you must initialize libcmdf by calling either cmdf_init_quick() or cmdf_init:

void cmdf_init(const char *prompt, const char *intro, const char *doc_header,
               const char *undoc_header, char ruler, int use_default_exit);
#define cmdf_init_quick() cmdf_init(NULL, NULL, NULL, NULL, 0, 1)

The two most important parameters are the prompt and the intro:

prompt - The prompt for every command.
intro - A text that is displayed to the user on program startup.

After initialization is done, you must then register some command callbacks. A command callback has a command name associated with it, and that can be executed by the user, which in turn will execute the associated command callback.

The command callback has the following format:

typedef CMDF_RETURN (* cmdf_command_callback)(cmdf_arglist *arglist);

CMDF_RETURN is a typedefd integer specifying a return code. arglist is a pointer to the arguments passed by the user along with the command, which libcmdf transperantly handles behind the scenes. It is destroyed by libcmdf when the command callback returns.

This simple structure contains two elements:

/* libcmdf command list and arglist */
typedef struct cmdf___arglist_s {
     char **args;                /* NULL-terminated string list */
     size_t count;               /* Argument list count */
} cmdf_arglist;

This way you can quickly iterate the command-line arguments and act accordingly.

After you have your command callback, simply register it using cmdf_register_command:

CMDF_RETURN cmdf_register_command(cmdf_command_callback callback, const char *cmdname,
                                  const char *help);

Note that you may provide an optional help message. If you do, the user will be able to see it when and if he will request it using the help command.

After that, initialization of the library is pretty much complete, so you can just call the main command loop:

cmdf_commandloop();

In any case you may refer to test.c for a working example.

Configuration

The library can be configured by #defineing any of the following definitions only once, before including the library:

Definition Description Default
CMDF_MAX_COMMANDS Maxmium amount of allowed commands. 24
CMDF_TAB_TO_SPACES If a tab is encountered in a command's help string, expand it to N spaces. 8
CMDF_READLINE_SUPPORT Enable/disable GNU readline support (Linux only, requires readline development libraries) (Disabled)
CMDF_FGETS A fgets()-like function, to be used for command-line input. fgets()
CMDF_MALLOC A malloc()-like function, to be used for memory allocations1. malloc()
CMDF_FREE A free()-like function, to be used for memory deallocations1. free()
CMDF_MAX_INPUT_BUFFER_LENGTH The maximum length of the input buffer used to get user input1. 256
CMDF_STDOUT A FILE * to be used as standard output. stdout
CMDF_STDIN A FILE * to be used as standard input. stdin

1 Note: GNU Readline will not use any custom memory allocation functions, but rather the standard library's malloc and free. Also, you may have to provide additional linker flags to link against readline.

To configure libcmdf simply define any configuration definitions once and before LIBCMDF_IMPL, like so:

#define CMDF_READLINE_SUPPORT   /* Enable readline support */
#define LIBCMDF_IMPL
#include <libcmdf.h>

...

Feedback

I tested the library to the best of my abilities, but there might still be some bugs.
If you do find them, please contact me or open an issue!

FAQ

Is the library thread-safe?

No, but it's just handling user input for CLI, so I honestly don't think it should be.

Why is cmdf_quit not implemented?

At the moment, the initialization routines don't allocate any memory, or perform any weird initialization tricks that require deinitalization.

This might change in the future, though, so make sure to call cmdf_quit when you're done with it!

Any plans to support Linenoise/anything else?

Yes! I'm planning to add support for it in the near future.

Any plans to implement a proper C++ API?

Yes! Near future, hopefully!

What's with the weird commit history?

I'm used to doing git with the command line, not with VSCode... sorry about that :-(


License

This software is dual-licensed to the public domain and under the following license: you are granted a perpetual, irrevocable license to copy, modify, publish and distribute this file as you see fit.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].