File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / Attic / cli.c
Revision 1.1.2.5: download - view: text, annotated - select for diffs - revision graph
Thu Mar 18 23:40:56 2010 UTC (14 years, 4 months ago) by misho
Branches: io1_1
added flush stream

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

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