This is a simple CLI interface helper library for C.

LIBCCLI

This is a very simple shell like interface for CLI activities.

More will be added to this, but for now, this is the basic idea:

", STDIN_FILENO, STDOUT_FILENO); ccli_register_command(ccli, "hello", say_hello, this_data); ccli_register_completion(ccli, "hello", hello_completion); ccli_loop(ccli); ccli_free(ccli); return 0; }">
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ccli.h>

static int say_hello(struct ccli *ccli, const char *command,
		     const char *line, void *data,
		     int argc, char **argv)
{
	char *this = (char *)data;
	int i;

	/* command matches argv[0] */
	/* line is the full line that was typed */
	/* argc is the number of words in the line */
	/* argv is the individual words */

	ccli_printf(ccli, "You typed %s\n", line);
	ccli_printf(ccli, "which is broken up into:\n");
	for (i = 0; i < argc; i++)
		ccli_printf(ccli, "word %d:\t%s\n", i, argv[i]);

	ccli_printf(ccli, "And this is passed %s\n", this);

	ccli_printf(ccli, "Type 'exit' to quit\n");

	/* returning anything but zero will exit the loop */
	/* By default, ccli will add the "exit" command to exit the loop */
	return 0;
}

#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))

static int hello_completion(struct ccli *ccli, const char *command,
			    const char *line, int word, const char *match,
			    char ***list, void *data)
{
	const char *word1[] = {
		"Sir", "Madam", "you", "kitty", "is", "for", "my",
		"good", "Mr." };
	const char *word2[] = {
		"Darling", "there", "now", "Hunk", "Bond" };
	const char *word3[] = { "anybody", "I" };
	const char *word4[] = { "out", "want" };
	const char *word5[] = { "there", "you" };
	const char **words;
	char **l;
	int len;
	int i;

	switch(word) {
	case 1:
		words = word1;
		len = ARRAY_SIZE(word1);
		break;
	case 2:
		words = word2;
		len = ARRAY_SIZE(word2);
		break;
	case 3:
		words = word3;
		len = ARRAY_SIZE(word3);
		break;
	case 4:
		words = word4;
		len = ARRAY_SIZE(word4);
		break;
	case 5:
		words = word5;
		len = ARRAY_SIZE(word5);
		break;
	default:
		return -1;
	}

	/*
	 * We do not worry about matching, the caller will only display
	 * words that do match "match".
	 */
	l = calloc(len, sizeof(char *));
	if (!l)
		return -1;

	for (i = 0; i < len; i++) {
		l[i] = strdup(words[i]);
		/*
		 * If the above fails to alloc, the caller will just
		 * ignore this field. It will be treated as a non-match.
		 * This may be an issues for the user, but if there's
		 * memory allocation issues, the user probably has more
		 * to worry about.
		 */
	}

	*list = l;
	return len;
}

int main(int argc, char **argv)
{
	struct ccli *ccli;
	char *this_data = "something here";

	ccli = ccli_alloc("myprompt> ", STDIN_FILENO, STDOUT_FILENO);

	ccli_register_command(ccli, "hello", say_hello, this_data);

	ccli_register_completion(ccli, "hello", hello_completion);

	ccli_loop(ccli);

	ccli_free(ccli);

	return 0;
}

To build:

  make

To build the sample file(s)

  make samples

The samples will be placed in a local bin directory. One that you may find useful is the read-file sample.

 bin/read-file binary-file

This will give you a command line interface that can read the binary file:

-----------------------------------------------------------------------------
 $ bin/read-file trace.dat
Reading file /tmp/trace.dat
rfile> read 8
0000000000000000: 0x6963617274440817
rfile> goto 0x100
rfile> dump 256
0000000000000100: cd 00 00 00 00 00 00 00  23 20 63 6f 6d 70 72 65  |........# compre|
0000000000000110: 73 73 65 64 20 65 6e 74  72 79 20 68 65 61 64 65  |ssed entry heade|
0000000000000120: 72 0a 09 74 79 70 65 5f  6c 65 6e 20 20 20 20 3a  |r..type_len    :|
0000000000000130: 20 20 20 20 35 20 62 69  74 73 0a 09 74 69 6d 65  |    5 bits..time|
0000000000000140: 5f 64 65 6c 74 61 20 20  3a 20 20 20 32 37 20 62  |_delta  :   27 b|
0000000000000150: 69 74 73 0a 09 61 72 72  61 79 20 20 20 20 20 20  |its..array      |
0000000000000160: 20 3a 20 20 20 33 32 20  62 69 74 73 0a 0a 09 70  | :   32 bits...p|
0000000000000170: 61 64 64 69 6e 67 20 20  20 20 20 3a 20 74 79 70  |adding     : typ|
0000000000000180: 65 20 3d 3d 20 32 39 0a  09 74 69 6d 65 5f 65 78  |e == 29..time_ex|
0000000000000190: 74 65 6e 64 20 3a 20 74  79 70 65 20 3d 3d 20 33  |tend : type == 3|
00000000000001a0: 30 0a 09 74 69 6d 65 5f  73 74 61 6d 70 20 3a 20  |0..time_stamp : |
00000000000001b0: 74 79 70 65 20 3d 3d 20  33 31 0a 09 64 61 74 61  |type == 31..data|
00000000000001c0: 20 6d 61 78 20 74 79 70  65 5f 6c 65 6e 20 20 3d  | max type_len  =|
00000000000001d0: 3d 20 32 38 0a 12 00 00  00 55 03 00 00 00 00 00  |= 28.....U......|
00000000000001e0: 00 6e 61 6d 65 3a 20 77  61 6b 65 75 70 0a 49 44  |.name: wakeup.ID|
00000000000001f0: 3a 20 33 0a 66 6f 72 6d  61 74 3a 0a 09 66 69 65  |: 3.format:..fie|
rfile> goto + 8
rfile> read string
0000000000000108: '# compressed entry header
        type_len    :    5 bits
        time_delta  :   27 bits
        array       :   32 bits

        padding     : type == 29
        time_extend : type == 30
        time_stamp : type == 31
        data max type_len  == 28
'
rfile> help
'read' command:
 To read the current address:
  type '1' or 'x8' for a byte in hex
       'u8' for on unsigned byte
       's8' for a signed byte
  type '2' or 'x16' for short in hex
       'u16' for on unsigned short
       's16' for a signed short
  type '4' or 'x32' for int in hex
       'u32' for on unsigned int
       's32' for a signed int
  type '8' or 'x64' for long long in hex
       'u64' for on unsigned long long
       's64' for a signed long long
  type 'string' followed by optional length
     This will write the string at the location

'dump' command:
 To dump the current location:
  By default, will dump 512 bytes, but if you add
  a length after the command, it will dump that many bytes

'goto' command:
 To goto a location in the file:
  type a value to set the offset into the file.
   Add a '+' to add the current position
   Add a '-' to subtract the current position
rfile> quit
Goodbye!
-----------------------------------------------------------------------------

This gives you a command line interface to browse a binary file and walk through its contents.

Requirements to build tests:

* CUnit-devel (CentOS)
* libcunit1-dev (Ubuntu/Debian)
* cunit-devel (OpenSUSE)
Owner
Comments
  • fix: handle offset below zero

    fix: handle offset below zero

    "offset" is size_t, so the check offset < 0 is invalid

    Currently it's not actually causing a problem, but the error message is incorrect:

    $ ./bin/read-file bin/read-file 
    Reading file bin/read-file
    rfile> goto -8  
    Size fffffffffffffff8 (-8) is greater than the size of the file (50832)
    rfile> dump 32  
    0000000000000000: 7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
    0000000000000010: 03 00 3e 00 01 00 00 00  60 14 00 00 00 00 00 00  |..>.....`.......|
    
  • Clarify the need of CUnit-devel pkg for developers

    Clarify the need of CUnit-devel pkg for developers

    Developers must install the CUnit-devel package that contains the header files and libraries for use with CUnit package. Otherwise the make test command will not work

    Signed-off-by: VictorRodriguez [email protected]

  • [PATCH v3 0/3] Cleanup and fix potential undefined behavior

    [PATCH v3 0/3] Cleanup and fix potential undefined behavior

    From 5610478a9fc8653231a7c1b7e4b66d0f6aef98ac Mon Sep 17 00:00:00 2001
    From: Ammar Faizi <[email protected]>
    Date: Mon, 17 Jan 2022 00:43:45 +0700
    Subject: [PATCH v3 0/3] Cleanup and fix potential undefined behavior
    
    Hi Steven,
    
    There are 3 patches in this series.
    
      - PATCH 1/3 is just a trivial cleanup.
      - PATCH 2/3 adds *.patch file to .gitignore.
      - PATCH 3/3 fixes potential undefined behavior of ctype functions.
    
    Please review...
    
    v3:
      - Commit message in patch 2/3 used ".gitignore:" as a prefix,
        change it to "ccli:".
    
    v2:
      - Fix commit message in patch 3/3.
    
    Link v2: https://github.com/rostedt/libccli/pull/3
    Link v1: https://github.com/rostedt/libccli/pull/2
    
    ---
    Ammar Faizi (3):
      ccli: Remove unused semicolon
      ccli: Add `*.patch` file to .gitignore
      ccli: Cast argument of ctype functions to unsigned char
    
     .gitignore |  1 +
     src/ccli.c | 12 ++++++------
     2 files changed, 7 insertions(+), 6 deletions(-)
    
    
    base-commit: 37bfea9cfb117bcb2a408e23b0ab2fab1c043509
    -- 
    2.32.0
    
  • [RFC] ccli: Enable execute more than one command at the same line

    [RFC] ccli: Enable execute more than one command at the same line

    Hi,

    This PR is just to get feedback from you, supposing you would implement/allow this functionality. This PR enables, eg: goto 2 && dump 32 && read string

    I'm not a C developer, so there are probably lots of room for improvement.

    One current problem of this approach is that && might be an argument to some command. Maybe one way to handle that is to check if the next word is a command or not.

  • ccli: Add filetype to README.md sections

    ccli: Add filetype to README.md sections

    This enables code highlight.

    You can take a look here to see how it will look like: https://github.com/tivrfoa/libccli/tree/add-filetype-to-readme-sections

  • [PATCH v5 0/3] Cleanup and fix potential undefined behavior

    [PATCH v5 0/3] Cleanup and fix potential undefined behavior

    From 35c7ecdc3dbfe6444e4f39c095335cd4fbcfa3cd Mon Sep 17 00:00:00 2001
    From: Ammar Faizi <[email protected]>
    Date: Mon, 17 Jan 2022 05:20:33 +0700
    Subject: [PATCH v5 0/3] Cleanup and fix potential undefined behavior
    
    Hi Steven,
    
    There are 3 patches in this series.
    
      - PATCH 1/3 is just a trivial cleanup.
      - PATCH 2/3 adds *.patch file to .gitignore.
      - PATCH 3/3 fixes potential undefined behavior of ctype functions.
    
    Please review...
    
    v5:
      - Rebase the work due to conflict, now it is on top of commit
        dab75c8 ("ccli: Clean up termios at ccli_free() not atexit()").
    
    v4:
      - Addressed comment to add a new macro ISSPACE() instead of
        having `(unsigned char)` cast all over the place.
    
    v3:
      - Commit message in patch 2/3 used ".gitignore:" as a prefix,
        change it to "ccli:".
    
    v2:
      - Fix commit message in patch 3/3.
    
    Link v4: https://github.com/rostedt/libccli/pull/5
    Link v3: https://github.com/rostedt/libccli/pull/4
    Link v2: https://github.com/rostedt/libccli/pull/3
    Link v1: https://github.com/rostedt/libccli/pull/2
    
    Ammar Faizi (3):
      ccli: Add `*.patch` file to .gitignore
      ccli: Remove unused semicolon
      ccli: Add a new macro ISSPACE() and replace isspace() calls with it
    
     .gitignore       | 1 +
     src/ccli-local.h | 2 ++
     src/ccli.c       | 8 ++++----
     src/line.c       | 4 ++--
     4 files changed, 9 insertions(+), 6 deletions(-)
    
    
    base-commit: dab75c88ba8fe6c7e338937c673ba67058ddc03d
    -- 
    2.32.0
    
  • [PATCH v4 0/3] Cleanup and fix potential undefined behavior

    [PATCH v4 0/3] Cleanup and fix potential undefined behavior

    From 45fdfda84d799d2bd62cec62ba0a4c1fd684fa4e Mon Sep 17 00:00:00 2001
    From: Ammar Faizi <[email protected]>
    Date: Mon, 17 Jan 2022 05:08:03 +0700
    Subject: [PATCH v4 0/3] Cleanup and fix potential undefined behavior
    
    Hi Steven,
    
    There are 3 patches in this series.
    
      - PATCH 1/3 is just a trivial cleanup.
      - PATCH 2/3 adds *.patch file to .gitignore.
      - PATCH 3/3 fixes potential undefined behavior of ctype functions.
    
    Please review...
    
    v4:
      - Addressed comment to add a new macro ISSPACE() instead of
        having `(unsigned char)` cast all over the place.
    
    v3:
      - Commit message in patch 2/3 used ".gitignore:" as a prefix,
        change it to "ccli:".
    
    v2:
      - Fix commit message in patch 3/3.
    
    Link v3: https://github.com/rostedt/libccli/pull/4
    Link v2: https://github.com/rostedt/libccli/pull/3
    Link v1: https://github.com/rostedt/libccli/pull/2
    
    ---
    Ammar Faizi (3):
      ccli: Add `*.patch` file to .gitignore
      ccli: Remove unused semicolon
      ccli: Add a new macro ISSPACE() and replace isspace() calls with it
    
     .gitignore       | 1 +
     src/ccli-local.h | 2 ++
     src/ccli.c       | 8 ++++----
     src/line.c       | 4 ++--
     4 files changed, 9 insertions(+), 6 deletions(-)
    
    
    base-commit: 294f8b5064253190ed44ca245edb0abf3a0dcbe9
    -- 
    2.32.0
    
  • [PATCH v2 0/3] Cleanup and fix potential undefined behavior

    [PATCH v2 0/3] Cleanup and fix potential undefined behavior

    From be0a4739e1daec249aa12dc8f923dbec81820019 Mon Sep 17 00:00:00 2001
    From: Ammar Faizi <[email protected]>
    Date: Mon, 17 Jan 2022 00:31:00 +0700
    Subject: [PATCH v2 0/3] Cleanup and fix potential undefined behavior
    
    Hi Steven,
    
    There are 3 patches in this series.
    
      - PATCH 1/3 is just a trivial cleanup.
      - PATCH 2/3 adds *.patch file to .gitignore.
      - PATCH 3/3 fixes potential undefined behavior of ctype functions.
    
    Please review...
    
    v2:
      - Fix commit message in patch 3/3.
    
    Link v1: https://github.com/rostedt/libccli/pull/2
    ---
    Ammar Faizi (3):
      ccli: Remove unused semicolon
      .gitignore: Add `*.patch` file to .gitignore
      ccli: Cast argument of ctype functions to unsigned char
    
     .gitignore |  1 +
     src/ccli.c | 12 ++++++------
     2 files changed, 7 insertions(+), 6 deletions(-)
    
    
    base-commit: 37bfea9cfb117bcb2a408e23b0ab2fab1c043509
    -- 
    2.32.0
    
  • [PATCH v1 0/3] Cleanup and fix potential undefined behavior

    [PATCH v1 0/3] Cleanup and fix potential undefined behavior

    From 0536c89ea21de9969037782070f005f7c20ce990 Mon Sep 17 00:00:00 2001
    From: Ammar Faizi <[email protected]>
    Date: Mon, 17 Jan 2022 00:25:09 +0700
    Subject: [PATCH v1 0/3] Cleanup and fix potential undefined behavior
    
    Hi Steven,
    
    There are 3 patches in this series.
    
      - PATCH 1/3 is just a trivial cleanup.
      - PATCH 2/3 adds *.patch file to .gitignore.
      - PATCH 3/3 fixes potential undefined behavior of ctype functions.
    
    Please review...
    
    ---
    Ammar Faizi (3):
      ccli: Remove unused semicolon
      .gitignore: Add `*.patch` file to .gitignore
      ccli: Cast argument of ctype functions to unsigned char
    
     .gitignore |  1 +
     src/ccli.c | 12 ++++++------
     2 files changed, 7 insertions(+), 6 deletions(-)
    
    
    base-commit: 37bfea9cfb117bcb2a408e23b0ab2fab1c043509
    -- 
    2.32.0
    
Related tags
C++ lib and CLI for playing media files on a Chromecast

castr - a CLI and C++ library to cast media files to Chromecast devices using the built in Default Media Receiver

Aug 29, 2022
The KISS file manager: CLI-based, ultra-lightweight, lightning fast, and written in C
 The KISS file manager: CLI-based, ultra-lightweight, lightning fast, and written in C

CliFM is a CLI-based, shell-like (non-curses) and KISS terminal file manager written in C: simple, fast, and lightweight as hell

Oct 1, 2022
Creating CLI's just got a whole lot better
 Creating CLI's just got a whole lot better

Staq Creating CLI's just got a whole lot better. Don't worry about CLI colouring, networking, Size of Executables, Speed ever again Have any doubts? R

Jun 1, 2021
CLI Application that provides the Freedesktop Secret Service using Pass as its backend!

pass-secrets CLI Application that provides the Freedesktop Secret Service using Pass as its backend! Status Currently working to store secrets with pr

Sep 13, 2022
Fegeya Freud, CLI FPaper renderer, based on Totem (`less`-like tool without `--help`)
Fegeya Freud, CLI FPaper renderer, based on Totem (`less`-like tool without `--help`)

Fegeya Freud, CLI FPaper renderer, based on Totem (`less`-like tool without `--help`)

Jun 11, 2021
Um CLI para encontrar os seus alias
Um CLI para encontrar os seus alias

Manager-Alias Que tal gerenciar todos os seus alias de um único local? Pesquisar e encontrar o que você precisa sem ter que ficar lendo diversos arqui

Oct 26, 2021
Port of ani-cli with more features 😉

Port of ani-cli with more features ??

Jun 25, 2022
A CLI for extracting libraries from Apple's dyld shared cache file

dyld-shared-cache-extractor As of macOS Big Sur, instead of shipping the system libraries with macOS, Apple ships a generated cache of all built in dy

Sep 19, 2022
The Efficient Study Planner (ESP) is a CLI app that gives an optimized plan to study for an upcoming exam.

Welcome to Efficient Study Planner ?? Optimize your study plan with ESP! Table of Contents About The Project Tech Stack Prerequisites How To Use? Lice

Aug 3, 2022
Windows Package Manager CLI (aka winget)
Windows Package Manager CLI (aka winget)

Welcome to the Windows Package Manager Client (aka winget.exe) repository This repository contains the source code for the Windows Package Manager Cli

Oct 1, 2022
CLI to play a word-guessing game like Wordle
CLI to play a word-guessing game like Wordle

Lexeme What is this? Python program to play a word-guessing game like Wordle, but… More addictive because you can play it over and over and over, not

Feb 7, 2022
A CLI program that helps you find classes and plan pre-requisites. Written in C++ and Python.

CourseHelper A CLI program created to help you prepare for course registration. Note: At the moment, this project is built specifically for other UCLA

Jan 25, 2022
File's sizes as a markdown table (CLI)

File's sizes as a markdown table (CLI)

Feb 6, 2022
A CLI based solver for the popular word guessing game WORDLE
A CLI based solver for the popular word guessing game WORDLE

Project WAR WAR stands for Wordle Answer and Resolver About Wordle is a web-based word game developed by Welsh-born software engineer Josh Wardle, for

Feb 19, 2022
CLI for single-cell analyses

CLI for single-cell analyses This repository provides a no-frills command-line interface for single-cell RNA-seq data analysis from a Matrix Market fi

Jan 28, 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 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

Sep 26, 2022
:computer: C++ Functional Terminal User Interface. :heart:
:computer: C++ Functional Terminal User Interface. :heart:

FTXUI Functional Terminal (X) User interface A simple C++ library for terminal based user interface. Demo: Feature Functional style. Inspired by [1] a

Sep 29, 2022
ImTui: Immediate Mode Text-based User Interface
ImTui: Immediate Mode Text-based User Interface

imtui ImTui is an immediate mode text-based user interface library. Supports 256 ANSI colors and mouse/keyboard input. Live demo in the browser Eventh

Sep 23, 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

Sep 18, 2021