File:  [ELWIX - Embedded LightWeight unIX -] / libaitcli / src / aitcli.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Apr 16 13:20:29 2010 UTC (14 years, 3 months ago) by misho
Branches: start
CVS tags: misho, cli1_0
libaitcli AIT CLI API

    1: /*************************************************************************
    2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
    3: *  by Michael Pounov <misho@openbsd-bg.org>
    4: *
    5: * $Author: misho $
    6: * $Id: aitcli.c,v 1.1.1.1 2010/04/16 13:20:29 misho Exp $
    7: *
    8: *************************************************************************/
    9: #include "global.h"
   10: 
   11: 
   12: #pragma GCC visibility push(hidden)
   13: 
   14: cliCommands_t cli_stdCmds[] = {
   15: 	{ "test", cli_Cmd_Unsupported, "Test - Don`t use default command structure!", "test <cr>", cli_Comp_Filename }, 
   16: 	{ "-------", NULL, "---------------------", NULL, NULL }, 
   17: 	{ "help", cli_Cmd_Help, "Help screen", "help [command] <cr>", NULL }, 
   18: 	{ "exit", cli_Cmd_Exit, "Exit from console", "exit <cr>", NULL }, 
   19: 	{ NULL, NULL, NULL, NULL }
   20: };
   21: 
   22: // ------------------------------------------------
   23: 
   24: int cli_Errno;
   25: char cli_Error[STRSIZ];
   26: 
   27: #pragma GCC visibility pop
   28: 
   29: 
   30: // cli_GetErrno() Get error code of last operation
   31: inline int cli_GetErrno()
   32: {
   33: 	return cli_Errno;
   34: }
   35: 
   36: // io_GetError() Get error text of last operation
   37: inline const char *cli_GetError()
   38: {
   39: 	return cli_Error;
   40: }
   41: 
   42: // cli_SetErr() Set error to variables for internal use!!!
   43: inline void cli_SetErr(int eno, char *estr, ...)
   44: {
   45: 	va_list lst;
   46: 
   47: 	cli_Errno = eno;
   48: 	memset(cli_Error, 0, STRSIZ);
   49: 	va_start(lst, estr);
   50: 	vsnprintf(cli_Error, STRSIZ, estr, lst);
   51: 	va_end(lst);
   52: }
   53: 
   54: // ------------------------------------------------------------
   55: 
   56: /*
   57:  * cli_Printf() Printf CLI features
   58:  * @out = Output stream
   59:  * @csFormat = Printf format string
   60:  * return: none
   61: */
   62: inline int cli_Printf(FILE *out, const char *csFormat, ...)
   63: {
   64: 	va_list lst;
   65: 	int ret;
   66: 
   67: 	va_start(lst, csFormat);
   68: 
   69: 	ret = vfprintf(out, csFormat, lst);
   70: 	if (-1 == ret)
   71: 		LOGERR;
   72: 
   73: 	va_end(lst);
   74: 	return ret;
   75: }
   76: 
   77: 
   78: /*
   79:  * cliComp() Initialize completion CLI features
   80:  * @cmdComplete = Completion function
   81:  * @cmdEntry = Compentry function
   82:  * return: none
   83: */
   84: inline void cliComp(cli_Completion_t *cmdComplete, cli_CompEntry_t *cmdEntry)
   85: {
   86: 	// command completon
   87: 	rl_attempted_completion_function = cmdComplete;
   88: 	rl_completion_entry_function = cmdEntry;
   89: }
   90: 
   91: /*
   92:  * cliExec() Execute CLI main loop
   93:  * @cmdList = Commands list
   94:  * @out = Output handle
   95:  * @csPrompt = Prompt text
   96:  * return: -1 error, 0 = exit w/^+D, 1 done.
   97: */
   98: int cliExec(cliCommands_t *cmdList, FILE *out, const char *csPrompt)
   99: {
  100: 	char *line, *s, *t, **app, *items[MAX_PROMPT_ITEMS];
  101: 	int ret = 0;
  102: 	register int i;
  103: 	cliCommands_t *cmd = NULL;
  104: 
  105: 	inline int inline_help()
  106: 	{
  107: 		cli_Cmd_Help(cmdList ? cmdList : cli_stdCmds, -1, out, NULL);
  108: 		rl_on_new_line();
  109: 		return 0;
  110: 	}
  111: 
  112: 	char **cli_stdCompletion(const char *text, int start, int end)
  113: 	{
  114: 		register int i;
  115: 		char **matches = NULL;
  116: 
  117: 		char *cmdCompGet(const char *text, int state)
  118: 		{
  119: 			int len = strlen(text);
  120: 
  121: 			for (i = state; cmdList[i].cmd_name; i++) {
  122: 				if (strncmp(cmdList[i].cmd_name, "---", 3) && 
  123: 						!strncmp(cmdList[i].cmd_name, text, len))
  124: 					return strdup(cmdList[i].cmd_name);
  125: 			}
  126: 
  127: 			return NULL;
  128: 		}
  129: 
  130: 		if (!start)
  131: 			matches = rl_completion_matches(text, cmdCompGet);
  132: 		else
  133: 			for (i = 0; cmdList[i].cmd_name; i++) {
  134: 				if (!cmdList[i].cmd_comp)
  135: 					continue;
  136: 				if (!strncmp(rl_line_buffer, cmdList[i].cmd_name, strlen(cmdList[i].cmd_name)))
  137: 					matches = rl_completion_matches(text, cmdList[i].cmd_comp);
  138: 			}
  139: 
  140: 		return matches;
  141: 	}
  142: 	char *cli_stdCompEntry(const char *ignore, int invoking_key)
  143: 	{
  144: 		return NULL;
  145: 	}
  146: 
  147: 	/* --- main body of CLI --- */
  148: 
  149: 	rl_bind_key('?', inline_help);
  150: 	if (!rl_attempted_completion_function) 
  151: 		cliComp(cli_stdCompletion, cli_stdCompEntry);
  152: 
  153: 	do {
  154: 		line = readline(csPrompt);
  155: 		if (!line) {	// ^+d
  156: 			cli_Printf(out, "\n");
  157: 			break;
  158: 		}
  159: 		// clear whitespaces
  160: 		for (s = line; isspace(*s); s++);
  161: 		if (*s) {
  162: 			for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);
  163: 			*++t = 0;
  164: 		}
  165: 
  166: 		if (*s) {
  167: 			add_history(s);
  168: 
  169: 			memset(items, 0, sizeof(char*) * MAX_PROMPT_ITEMS);
  170: 			for (app = items; app < items + MAX_PROMPT_ITEMS - 1 && (*app = strsep(&s, " \t")); 
  171: 					*app ? app++ : app);
  172: 
  173: 			/*
  174: 			for (i = 0; i < MAX_PROMPT_ITEMS; i++)
  175: 				cli_Printf(out, "i=%d %s\n", i, items[i]);
  176: 				*/
  177: 
  178: 			// exec_cmd ...
  179: 			for (cmd = NULL, i = 0; cmdList[i].cmd_name; i++)
  180: 				if (*items[0] && !strncmp(cmdList[i].cmd_name, items[0], strlen(items[0]))) {
  181: 					cmd = &cmdList[i];
  182: 					break;
  183: 				}
  184: 			if (!cmd) {
  185: 				cli_Printf(out, "Command '%s' not found!\n", items[0]);
  186: 				ret = -1;
  187: 			} else
  188: 				ret = cmd->cmd_func(cmdList, i, out, items);
  189: 		}
  190: 
  191: 		free(line);
  192: 	} while (ret < 1);
  193: 
  194: 	return ret;
  195: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>