Command Line Interface (CLI): your recommendations
- From: "Roman Mashak" <mrv@xxxxxxxx>
- Date: Sun, 12 Feb 2006 01:14:51 +0700
Hello, All!
I'm implementing simple CLI (flat model, no tree-style menu etc.). Command
line looks like this: <command> <param1> <param2> ... <paramN> (where
N=1..4)
And idea is pretty simple:
1) get whole string of input line
2) preset table of strings matching <command>
3) preset table of function calls
4) scan <command> table for string, if match - call matching function (I
declare ALL callback functions as having the same format)
Here is code implementing part of this algorithm. The problem I came across
is if pressing 'Enter' continuously then sometimes output of PROMPT turnes
out clumsy, i.e. it's printed repeatedly in a line.
Before I went too far, I would like to ask your opinion about concept I'm
using and recommendations if possible:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define COUNT(a) (sizeof(a) / sizeof(a[0]))
const char *PROMPT = "CLI>";
enum errCodes { RC_SUCCESS = 0, RC_ERROR = -1 };
/* table of <commands> */
const char *commands[] = {
"show",
"version",
"help",
"port",
"exit"
};
/* callback function */
typedef int (*handler_ptr_t)(int, char**);
/* define command line: <command> <param1> <param2> ... <paramN> */
typedef struct cmdLineEntry_s {
#define MAX_NAME 20
char command[MAX_NAME];
#define MAX_ARGS 4
char params[MAX_ARGS];
unsigned int params_num;
handler_ptr_t cmd_handler;
} cmdLineEntry_t;
int cliShow(int argc, char *argv[])
{
puts("cliShow() stub");
return 0;
}
int cliVersion(int argc, char *argv[])
{
puts("cliVersion() stub");
return 0;
}
int cliHelp(int argc, char *argv[])
{
puts("cliHelp() stub");
return 0;
}
int cliPort(int argc, char *argv[])
{
puts("cliPort() stub");
return 0;
}
int cliExit(int argc, char *argv[])
{
puts("cliExit() stub");
exit(EXIT_SUCCESS);
}
/* define table functions pointers */
handler_ptr_t ftable[] = { cliShow, cliVersion, cliHelp, cliPort, cliExit };
/* parse command line and fill structure */
static int
cliParseCommandLine(char *buf, cmdLineEntry_t *cli)
{
const char delim[] = " \t\n";
unsigned int i;
char *token;
memset(cli, 0, sizeof *cli);
token = strtok(buf, delim);
for (i = 0; i < COUNT(commands); i++) {
if (!strcmp(token, commands[i])) {
strcpy(cli->command, token);
cli->cmd_handler = ftable[i];
i = 0;
for (token = strtok(NULL, delim); token != NULL; ) {
cli->params[i++] = token;
token = strtok(NULL, delim);
}
cli->params_num = i;
return 0;
}
}
return -1;
}
int main(void)
{
char buf[BUFSIZ] = {0};
cmdLineEntry_t cli = { {0}, {NULL}, 0, NULL };
while (1) {
printf("%s", PROMPT);
if ( fgets(buf, BUFSIZ, stdin) ) {
/* skip LF/CR/TAB/SP */
if (buf[0] == '\n' || buf[0] == ' ' || buf[0] == '\r' || buf[0]
== '\t')
continue;
/* parse stream */
if ( cliParseCommandLine(buf, &cli) < 0 ) {
printf("Error : invalid command!\n");
continue;
}
else {
cli.cmd_handler(cli.params_num, cli.params);
}
}
else continue; /* EOL */
} /* while */
return 0;
}
TIA!
With best regards, Roman Mashak. E-mail: mrv@xxxxxxxx
.
- Follow-Ups:
- Re: Command Line Interface (CLI): your recommendations
- From: Barry Schwarz
- Re: Command Line Interface (CLI): your recommendations
- From: RSoIsCaIrLiIoA
- Re: Command Line Interface (CLI): your recommendations
- From: Rod Pemberton
- Re: Command Line Interface (CLI): your recommendations
- From: Walter Roberson
- Re: Command Line Interface (CLI): your recommendations
- Prev by Date: Re: Segmentation fault!
- Next by Date: Re: Segmentation fault!
- Previous by thread: Compile Errors
- Next by thread: Re: Command Line Interface (CLI): your recommendations
- Index(es):
Relevant Pages
|