Skip to content

Instantly share code, notes, and snippets.

@carlmartus
Last active August 29, 2015 13:57
Show Gist options
  • Save carlmartus/9411426 to your computer and use it in GitHub Desktop.
Save carlmartus/9411426 to your computer and use it in GitHub Desktop.
Simple C commands program
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
static void
cmd_skeleton(int argc, const char **argv)
{
printf("Skeleton! With %d parameters\n", argc);
}
// Command handler {{{
static bool run;
static void cmd_help();
static void
cmd_exit()
{
run = false;
}
static const struct command {
const char *name;
void (*func) (int argc, const char **argv);
const char *description;
} cmds[] = {
{ "help", cmd_help, "List commands" },
{ "exit", cmd_exit, "Exit program" },
{ "skeleton", cmd_skeleton, "Skeleton command!" },
// INSERT YOUR OWN COMMANDS HERE
{ NULL, NULL },
};
static int
is_whitespace(char ch)
{
switch (ch) {
case ' ' :
case '\t' :
case '\n' :
case '\r' : return 1;
default : return 0;
}
}
static void
cmd_help()
{
printf("Available commands:\n");
const struct command *itr;
itr = cmds;
while (itr->name) {
printf(" %s - %s\n", itr->name, itr->description);
itr++;
}
}
static int
proc_cmd(const char **argv, int argc)
{
if (argc <= 0) return 1;
const struct command *itr;
itr = cmds;
while (itr->name) {
if (strncmp(argv[0], itr->name, 300) == 0) {
itr->func(argc, argv);
return 0;
}
itr++;
}
return 1;
}
static int
proces_buf_magic(const char *line, size_t len)
{
char *argv[len];
int argc = 0;
char tot[len+1];
bool skiplast = true;
char *dst = tot;
const char *src = line;
while (*src != '\0') {
if (is_whitespace(*src)) {
*dst = '\0';
skiplast = true;
} else {
*dst = *src;
if (skiplast) {
argv[argc++] = dst;
}
skiplast = false;
}
dst++;
src++;
}
*dst = '\0';
return proc_cmd((const char**) argv, argc);
}
static void
process_input(const char *line)
{
if (line[0] == '\0') return;
if (proces_buf_magic(line, strlen(line))) {
printf("No available command \"%s\"\n", line);
printf("Type 'help' to se commands\n");
}
}
int
main(int argc, char **argv)
{
if (argc > 1) {
return proc_cmd((const char **) (argv+1), argc-1);
} else {
run = true;
char line[400];
while (run) {
printf(" > ");
fflush(stdout);
fgets(line, sizeof(line)-1, stdin);
size_t len = strlen(line);
if (len <= 1) break;
line[len-1] = '\0';
process_input(line);
}
}
return 0;
}
// }}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment