File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / Attic / cli.c
Revision 1.1.2.3: download - view: text, annotated - select for diffs - revision graph
Thu Mar 11 00:17:52 2010 UTC (14 years, 6 months ago) by misho
Branches: io1_1
added new helper function

    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: cli.c,v 1.1.2.3 2010/03/11 00:17:52 misho Exp $
    7: *
    8: *************************************************************************/
    9: #include "global.h"
   10: 
   11: 
   12: /*
   13:  * io_Cmd_Exit() Builtin helper function for Exit from Cli
   14:  * @cmds = Commands list
   15:  * @out = Output handle
   16:  * @args = Parsed arguments array
   17:  * return: 1 exit from Cli!
   18: */
   19: int io_Cmd_Exit(void *cmds, FILE *out, char ** __restrict args)
   20: {
   21: 	return 1;
   22: }
   23: 
   24: /*
   25:  * io_Cmd_Help() Builtin helper function for Help screen
   26:  * @cmds = Commands list
   27:  * @out = Output handle
   28:  * @args = Parsed arguments array
   29:  * return: -1 error, 0 = ok
   30: */
   31: int io_Cmd_Help(void *cmds, FILE *out, char ** __restrict args)
   32: {
   33: 	register int i;
   34: 	ioCommands_t *commands = cmds;
   35: 
   36: 	if (!cmds)
   37: 		return -1;
   38: 
   39: 	if (!args) {
   40: 		fprintf(out, "\n");
   41: 		for (i = 0; commands[i].cmd_name; i++)
   42: 			fprintf(out, "%s\t\t%s\n", commands[i].cmd_name, commands[i].cmd_doc);
   43: 	} else {
   44: 		if (!args[1])
   45: 			fprintf(out, "Help screen::\n");
   46: 		else
   47: 			if (!strncmp(args[1], "---", 3))
   48: 				return 0;
   49: 
   50: 		for (i = 0; commands[i].cmd_name; i++) {
   51: 			if (args[1] && strcmp(args[1], commands[i].cmd_name))
   52: 				continue;
   53: 
   54: 			fprintf(out, "%s%s\t\t%s\n", args[1] ? "Syntax::\n\t" : "", commands[i].cmd_name, 
   55: 					args[1] ? commands[i].cmd_help : commands[i].cmd_doc);
   56: 		}
   57: 	}
   58: 
   59: 	return 0;
   60: }
   61: 
   62: /*
   63:  * io_Cmd_Unsupported() Builtin helper function for unsupported commands
   64:  * @cmds = Commands list
   65:  * @out = Output handle
   66:  * @args = Parsed arguments array
   67:  * return: -1 error, 0 = ok, 1 exit from Cli!
   68: */
   69: int io_Cmd_Unsupported(void *cmds, FILE *out, char ** __restrict args)
   70: {
   71: 	fprintf(out, "Command %s not supported in this version ...\n", args[0]);
   72: 	return 0;
   73: }
   74: 
   75: // ------------------------------------------------------------
   76: 
   77: /*
   78:  * io_Comp_Filename() Builtin helper function for filename completion arguments
   79:  * @text = Text line
   80:  * @state = Position state
   81:  * return: NULL not found filename, != NULL filename
   82: */
   83: char *io_Comp_Filename(const char *text, int state)
   84: {
   85: 	return rl_filename_completion_function(text, state);
   86: }
   87: 
   88: // ------------------------------------------------------------
   89: 
   90: #pragma GCC visibility push(hidden)
   91: 
   92: ioCommands_t io_stdCmds[] = {
   93: 	{ "test", io_Cmd_Unsupported, "Test - Don`t use default command structure!", "test <cr>", NULL }, 
   94: 	{ "-------", NULL, "---------------------", NULL, NULL }, 
   95: 	{ "help", io_Cmd_Help, "Help screen", "help [command] <cr>", NULL }, 
   96: 	{ "exit", io_Cmd_Exit, "Exit from console", "exit <cr>", NULL }, 
   97: 	{ NULL, NULL, NULL, NULL }
   98: };
   99: 
  100: #pragma GCC visibility pop
  101: 
  102: // ------------------------------------------------------------
  103: 
  104: /*
  105:  * ioCLIComp() Initialize completion CLI features
  106:  * @cmdComplete = Completion function
  107:  * @cmdEntry = Compentry function
  108:  * return: none
  109: */
  110: inline void ioCLIComp(io_Completion_t *cmdComplete, io_CompEntry_t *cmdEntry)
  111: {
  112: 	// command completon
  113: 	rl_attempted_completion_function = cmdComplete;
  114: 	rl_completion_entry_function = cmdEntry;
  115: }
  116: 
  117: /*
  118:  * ioCLIExec() Execute CLI main loop
  119:  * @cmdList = Commands list
  120:  * @out = Output handle
  121:  * @csPrompt = Prompt text
  122:  * return: -1 error, 0 = exit w/^+D, 1 done.
  123: */
  124: int ioCLIExec(ioCommands_t *cmdList, FILE *out, const char *csPrompt)
  125: {
  126: 	char *line, *s, *t, **app, *items[20];
  127: 	int ret = 0;
  128: 	register int i;
  129: 	ioCommands_t *cmd = NULL;
  130: 
  131: 	inline int inline_help()
  132: 	{
  133: 		io_Cmd_Help(cmdList ? cmdList : io_stdCmds, out, NULL);
  134: 		rl_on_new_line();
  135: 		return 0;
  136: 	}
  137: 
  138: 	char **io_stdCompletion(const char *text, int start, int end)
  139: 	{
  140: 		register int i;
  141: 		char **matches = NULL;
  142: 
  143: 		char *cmdCompGet(const char *text, int state)
  144: 		{
  145: 			int len = strlen(text);
  146: 
  147: 			for (i = state; cmdList[i].cmd_name; i++)
  148: 				if (strncmp(cmdList[i].cmd_name, "---", 3) && 
  149: 						!strncmp(cmdList[i].cmd_name, text, len))
  150: 					return strdup(cmdList[i].cmd_name);
  151: 
  152: 			return NULL;
  153: 		}
  154: 
  155: 		if (!start)
  156: 			matches = rl_completion_matches(text, cmdCompGet);
  157: 		else
  158: 			for (i = 0; cmdList[i].cmd_name; i++)
  159: 				if (cmdList[i].cmd_comp && !strncmp(rl_line_buffer, 
  160: 							cmdList[i].cmd_name, strlen(cmdList[i].cmd_name)))
  161: 					matches = rl_completion_matches(text, cmdList[i].cmd_comp);
  162: 
  163: 		return matches;
  164: 	}
  165: 	char *io_stdCompEntry(const char *ignore, int invoking_key)
  166: 	{
  167: 		return NULL;
  168: 	}
  169: 
  170: 	rl_bind_key('?', inline_help);
  171: 	if (!rl_attempted_completion_function) 
  172: 		ioCLIComp(io_stdCompletion, io_stdCompEntry);
  173: 
  174: 	do {
  175: 		line = readline(csPrompt);
  176: 		if (!line) {	// ^+d
  177: 			fprintf(out, "\n");
  178: 			fflush(out);
  179: 			break;
  180: 		}
  181: 		// clear whitespaces
  182: 		for (s = line; isspace(*s); s++);
  183: 		if (*s) {
  184: 			for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);
  185: 			*++t = 0;
  186: 		}
  187: 
  188: 		if (*s) {
  189: 			add_history(s);
  190: 
  191: 			memset(items, 0, sizeof(char*) * 20);
  192: 			for (app = items; app < items + 19 && (*app = strsep(&s, " \t")); *app ? app++ : app);
  193: 
  194: 			/*
  195: 			for (i = 0; i < 20; i++)
  196: 				printf("i=%d %s\n", i, items[i]);
  197: 				*/
  198: 
  199: 			// exec_cmd ...
  200: 			for (cmd = NULL, i = 0; cmdList[i].cmd_name; i++)
  201: 				if (*items[0] && !strncmp(cmdList[i].cmd_name, items[0], strlen(items[0]))) {
  202: 					cmd = &cmdList[i];
  203: 					break;
  204: 				}
  205: 			if (!cmd) {
  206: 				fprintf(out, "Command '%s' not found!\n", items[0]);
  207: 				ret = -1;
  208: 			} else
  209: 				ret = cmd->cmd_func(cmdList, out, items);
  210: 		}
  211: 
  212: 		free(line);
  213: 	} while (ret < 1);
  214: 
  215: 	return ret;
  216: }

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