Last active
August 29, 2015 13:57
-
-
Save carlmartus/9411426 to your computer and use it in GitHub Desktop.
Simple C commands program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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