Browse Source

Fix param help

git-svn-id: https://klish.googlecode.com/svn/trunk@397 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 13 years ago
parent
commit
6c2e039780

+ 1 - 0
bin/konfd.c

@@ -34,6 +34,7 @@
 #include <grp.h>
 #endif
 
+#include "clish/internal.h"
 #include "clish/private.h"
 #include "konf/tree.h"
 #include "konf/query.h"

+ 1 - 1
clish/clish_access_callback.c

@@ -12,7 +12,7 @@
 #include <sys/types.h>
 #include <grp.h>
 
-#include "private.h"
+#include "internal.h"
 /*--------------------------------------------------------- */
 bool_t clish_access_callback(const clish_shell_t * shell, const char *access)
 {

+ 1 - 1
clish/clish_config_callback.c

@@ -13,7 +13,7 @@
 #include <sys/un.h>
 #include <limits.h>
 
-#include "private.h"
+#include "internal.h"
 #include "konf/net.h"
 #include "konf/buf.h"
 #include "konf/query.h"

+ 1 - 1
clish/clish_script_callback.c

@@ -18,7 +18,7 @@
 
 #include "lub/string.h"
 #include "konf/buf.h"
-#include "private.h"
+#include "internal.h"
 
 /*--------------------------------------------------------- */
 bool_t clish_script_callback(clish_shell_t * this,

+ 3 - 2
clish/command.h

@@ -11,6 +11,7 @@ typedef struct clish_command_s clish_command_t;
 #include "clish/pargv.h"
 #include "clish/view.h"
 #include "clish/param.h"
+#include "clish/private.h"
 
 typedef enum {
 	CLISH_CONFIG_NONE,
@@ -43,8 +44,8 @@ clish_command_diff(const clish_command_t * cmd1, const clish_command_t * cmd2);
 void clish_command_delete(clish_command_t * instance);
 void
 clish_command_insert_param(clish_command_t * instance, clish_param_t * param);
-void clish_command_help(const clish_command_t * instance, const char *viewid,
-	const char *line);
+int clish_command_help(const clish_command_t * instance, help_argv_t *help,
+	const char *viewid, const char *line);
 void clish_command_dump(const clish_command_t * instance);
 
 /*-----------------

+ 9 - 12
clish/command/command.c

@@ -4,6 +4,7 @@
   * This file provides the implementation of a command definition  
   */
 #include "private.h"
+#include "clish/private.h"
 #include "clish/variable.h"
 #include "lub/bintree.h"
 #include "lub/string.h"
@@ -203,8 +204,8 @@ void clish_command_insert_param(clish_command_t * this, clish_param_t * param)
 }
 
 /*--------------------------------------------------------- */
-void clish_command_help(const clish_command_t * this, const char * viewid,
-	const char * line)
+int clish_command_help(const clish_command_t * this, help_argv_t *help,
+	const char * viewid, const char * line)
 {
 	const char *name = clish_command__get_name(this);
 	unsigned index = lub_argv_wordcount(line);
@@ -216,14 +217,10 @@ void clish_command_help(const clish_command_t * this, const char * viewid,
 	unsigned longest = 0;
 
 	if (0 == index)
-		return;
-
+		return 0;
 	/* Line has no any parameters */
-	if (strlen(line) <= strlen(name)) {
-		fprintf(stderr, "  %s  %s\n", name,
-			clish_command__get_text(this));
-		return;
-	}
+	if (strlen(line) <= strlen(name))
+		return 0;
 
 	if (line[strlen(line) - 1] != ' ')
 		index--;
@@ -253,12 +250,12 @@ void clish_command_help(const clish_command_t * this, const char * viewid,
 			clen = strlen(name);
 		if (clen > longest)
 			longest = clen;
+		clish_param_help(clish_pargv__get_param(last, i), help);
 	}
-	for (i = 0; i < cnt; i++)
-		clish_param_help(clish_pargv__get_param(last, i), longest + 1);
 	clish_pargv_delete(last);
-
 	lub_argv_delete(argv);
+
+	return longest;
 }
 
 /*--------------------------------------------------------- */

+ 5 - 0
clish/internal.h

@@ -1,6 +1,9 @@
 /*
  * internal.h
  */
+#ifndef _clish_internal_h
+#define _clish_internal_h
+
 #include "lub/c_decl.h"
 #include "clish/shell.h"
 
@@ -16,3 +19,5 @@ extern clish_shell_script_fn_t clish_dryrun_callback;
 extern clish_shell_config_fn_t clish_config_callback;
 
 _END_C_DECL
+
+#endif /* _clish_internal_h */

+ 2 - 1
clish/param.h

@@ -20,6 +20,7 @@ typedef struct clish_param_s clish_param_t;
 
 #include "clish/ptype.h"
 #include "clish/pargv.h"
+#include "clish/private.h"
 
 /**
  * The means by which the param is interpreted.
@@ -53,7 +54,7 @@ clish_param_t *clish_param_new(const char *name,
  * methods
  *----------------- */
 void clish_param_delete(clish_param_t * instance);
-void clish_param_help(const clish_param_t * instance, size_t offset);
+void clish_param_help(const clish_param_t * instance, help_argv_t *help);
 void clish_param_help_arrow(const clish_param_t * instance, size_t offset);
 char *clish_param_validate(const clish_param_t * instance, const char *text);
 void clish_param_dump(const clish_param_t * instance);

+ 15 - 9
clish/param/param.c

@@ -6,6 +6,7 @@
 #include "private.h"
 #include "lub/string.h"
 #include "clish/variable.h"
+#include "clish/private.h"
 
 #include <assert.h>
 #include <stdlib.h>
@@ -146,10 +147,11 @@ char *clish_param_validate(const clish_param_t * this, const char *text)
 }
 
 /*--------------------------------------------------------- */
-void clish_param_help(const clish_param_t * this, size_t offset)
+void clish_param_help(const clish_param_t * this, help_argv_t *help)
 {
 	const char *range = clish_ptype__get_range(this->ptype);
 	const char *name;
+	char *str = NULL;
 
 	if (CLISH_PARAM_SWITCH == clish_param__get_mode(this)) {
 		unsigned rec_paramc = clish_param__get_param_count(this);
@@ -160,23 +162,27 @@ void clish_param_help(const clish_param_t * this, size_t offset)
 			cparam = clish_param__get_param(this, i);
 			if (!cparam)
 				break;
-			clish_param_help(cparam, offset);
+			clish_param_help(cparam, help);
 		}
 		return;
 	}
 
 	if (CLISH_PARAM_SUBCOMMAND == clish_param__get_mode(this))
 		name = clish_param__get_value(this);
-	else {
+	else
 		if (!(name = clish_ptype__get_text(this->ptype)))
 			name = clish_ptype__get_name(this->ptype);
-	}
 
-	fprintf(stderr, "  %s %*c%s",
-		name, (int)(offset - strlen(name)), ' ', this->text);
-	if (NULL != range)
-		fprintf(stderr, " (%s)", range);
-	fprintf(stderr, "\n");
+	lub_string_cat(&str, this->text);
+	if (range) {
+		lub_string_cat(&str, " (");
+		lub_string_cat(&str, range);
+		lub_string_cat(&str, ")");
+	}
+	lub_argv_add(help->matches, name);
+	lub_argv_add(help->help, str);
+	lub_string_free(str);
+	lub_argv_add(help->detail, NULL);
 }
 
 /*--------------------------------------------------------- */

+ 15 - 1
clish/private.h

@@ -1,5 +1,19 @@
 /*
  * private.h
  */
+
+#ifndef _clish_private_h
+#define _clish_private_h
+
 #include "lub/c_decl.h"
-#include "clish/internal.h"
+#include "lub/argv.h"
+/*#include "clish/internal.h"*/
+
+struct help_argv_s {
+	lub_argv_t *matches;
+	lub_argv_t *help;
+	lub_argv_t *detail;
+};
+typedef struct help_argv_s help_argv_t;
+
+#endif /* _clish_private_h */

+ 2 - 4
clish/shell/private.h

@@ -104,10 +104,6 @@ const clish_command_t *clish_shell_resolve_command(const clish_shell_t *
 	instance, const char *line);
 const clish_command_t *clish_shell_resolve_prefix(const clish_shell_t *
 	instance, const char *line);
-const clish_command_t *clish_shell_getfirst_command(clish_shell_t * instance,
-	const char *line, clish_nspace_visibility_t field);
-const clish_command_t *clish_shell_getnext_command(clish_shell_t * instance,
-	const char *line);
 void clish_shell_insert_ptype(clish_shell_t * instance, clish_ptype_t * ptype);
 void clish_shell_tinyrl_history(clish_shell_t * instance, unsigned int *limit);
 tinyrl_t *clish_shell_tinyrl_new(FILE * instream,
@@ -115,3 +111,5 @@ tinyrl_t *clish_shell_tinyrl_new(FILE * instream,
 void clish_shell_tinyrl_delete(tinyrl_t * instance);
 void clish_shell_param_generator(clish_shell_t * instance, lub_argv_t *matches,
 	const clish_command_t * cmd, const char *line, unsigned offset);
+char **clish_shell_tinyrl_completion(tinyrl_t * tinyrl,
+	const char *line, unsigned start, unsigned end);

+ 0 - 17
clish/shell/shell_command_generator.c

@@ -39,23 +39,6 @@ const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
 	return result;
 }
 
-/*--------------------------------------------------------- */
-const clish_command_t *clish_shell_getfirst_command(clish_shell_t * this,
-	const char *line, clish_nspace_visibility_t field)
-{
-	clish_shell_iterator_init(&this->context.iter, field);
-
-	/* find the first command for which this is a prefix */
-	return clish_shell_getnext_command(this, line);
-}
-
-/*--------------------------------------------------------- */
-const clish_command_t *clish_shell_getnext_command(clish_shell_t * this,
-	const char *line)
-{
-	return clish_shell_find_next_completion(this, line, &this->context.iter);
-}
-
 /*--------------------------------------------------------- */
 void clish_shell_param_generator(clish_shell_t *this, lub_argv_t *matches,
 	const clish_command_t *cmd, const char *line, unsigned offset)

+ 54 - 92
clish/shell/shell_help.c

@@ -2,130 +2,92 @@
  * shell_help.c
  */
 #include "private.h"
+#include "clish/private.h"
 #include "lub/string.h"
 
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 
 /*--------------------------------------------------------- */
 /*
  * Provide a detailed list of the possible command completions
  */
-static void
-available_commands(clish_shell_t * this, const char *line, bool_t full)
+static int available_commands(clish_shell_t * this,
+	help_argv_t *help, const char *line)
 {
-	char *buf = NULL;
 	size_t max_width = 0;
 	const clish_command_t *cmd;
-	if (NULL == clish_shell_getfirst_command(this, line, CLISH_NSPACE_HELP)) {
-		/*
-		 * A totally wrong command has been inputed
-		 * Indicate the point of error and display 
-		 * a list of possible commands
-		 */
-		char *prompt = clish_view__get_prompt(this->view,
-						      this->viewid);
-		unsigned error_offset = strlen(prompt) + 1;
-		lub_string_free(prompt);
+	clish_shell_iterator_t iter;
 
-		/* find the best match... */
-		cmd = clish_shell_resolve_prefix(this, line);
-		if (cmd) {
-			error_offset +=
-			    strlen(clish_command__get_name(cmd)) + 1;
-			/* take a copy for help purposes */
-			buf = lub_string_dup(clish_command__get_name(cmd));
-		} else {
-			/* show all possible commands */
-			buf = lub_string_dup("");
-		}
-		/* indicate the point of error */
-		fprintf(stderr, "%*s\n", error_offset, "^");
-	} else {
-		/* take a copy */
-		buf = lub_string_dup(line);
-	}
-	/* iterate round to determine max_width */
-	for (cmd = clish_shell_getfirst_command(this, buf, CLISH_NSPACE_HELP);
-	     cmd; cmd = clish_shell_getnext_command(this, buf)) {
+	/* Search for COMMAND completions */
+	clish_shell_iterator_init(&iter, CLISH_NSPACE_HELP);
+	while ((cmd = clish_shell_find_next_completion(this, line, &iter))) {
 		size_t width;
-		const char *name;
-		if (full) {
-			name = clish_command__get_name(cmd);
-		} else {
-			name = clish_command__get_suffix(cmd);
-		}
+		const char *name = clish_command__get_suffix(cmd);
 		width = strlen(name);
-		if (width > max_width) {
+		if (width > max_width)
 			max_width = width;
-		}
+		lub_argv_add(help->matches, name);
+		lub_argv_add(help->help, clish_command__get_text(cmd));
+		lub_argv_add(help->detail, clish_command__get_detail(cmd));
 	}
 
-	/* now iterate round to print the help */
-	for (cmd = clish_shell_getfirst_command(this, buf, CLISH_NSPACE_HELP);
-	     cmd; cmd = clish_shell_getnext_command(this, buf)) {
-		const char *name;
-		if (full) {
-			name = clish_command__get_name(cmd);
-		} else {
-			name = clish_command__get_suffix(cmd);
-		}
-		fprintf(stderr, "  %-*s  %s\n",
-		       (int)max_width, name, clish_command__get_text(cmd));
-	}
-	/* cleanup */
-	lub_string_free(buf);
+	return max_width;
 }
 
 /*--------------------------------------------------------- */
-void clish_shell_help(clish_shell_t * this, const char *line)
+void clish_shell_help(clish_shell_t *this, const char *line)
 {
-	const clish_command_t *cmd, *next_cmd, *first_cmd;
+	help_argv_t help;
+	size_t max_width = 0;
+	const clish_command_t *cmd;
+	int i;
+
+	help.matches = lub_argv_new(NULL, 0);
+	help.help = lub_argv_new(NULL, 0);
+	help.detail = lub_argv_new(NULL, 0);
+
+	/* Get COMMAND completions */
+	max_width = available_commands(this, &help, line);
 
-	/* if there are further commands then we need to show them too */
-	cmd = clish_shell_resolve_prefix(this, line);
+	/* Resolve a command */
+	cmd = clish_shell_resolve_command(this, line);
+	/* Search for PARAM completion */
 	if (cmd) {
-		clish_shell_iterator_t iter;
+		size_t width = 0;
+		width = clish_command_help(cmd, &help, this->viewid, line);
+		if (width > max_width)
+			max_width = width;
+	}
+	if (lub_argv__get_count(help.matches) == 0)
+		goto end;
 
-		/* skip the command already known about */
-		clish_shell_iterator_init(&iter, CLISH_NSPACE_HELP);
-		first_cmd = clish_shell_find_next_completion(this, line, &iter);
-		next_cmd = clish_shell_find_next_completion(this, line, &iter);
-	} else {
-		first_cmd = next_cmd = NULL;
+	/* Print help messages */
+	for (i = 0; i < lub_argv__get_count(help.matches); i++) {
+		fprintf(stderr, "  %-*s  %s\n", (int)max_width,
+			lub_argv__get_arg(help.matches, i),
+			lub_argv__get_arg(help.help, i));
 	}
-	if (cmd && !next_cmd && (!first_cmd || (first_cmd == cmd))) {
-		/* we've resolved a particular command */
-		switch (this->state) {
-		case SHELL_STATE_HELPING:
-		{
-			const char *detail =
-				clish_command__get_detail(cmd);
-			if (NULL != detail)
-				fprintf(stderr, "%s\n", detail);
-			else
-				clish_command_help(cmd, this->viewid, line);
-			break;
-		}
-		case SHELL_STATE_OK:
-		case SHELL_STATE_SCRIPT_ERROR:
-		case SHELL_STATE_SYNTAX_ERROR:
-			/* get the command to provide help */
-			clish_command_help(cmd, this->viewid, line);
-			break;
-		default:
-			/* do nothing */
-			break;
-		}
-	} else {
-		/* dump the available commands */
-		available_commands(this, line, BOOL_FALSE);
+
+	/* Print details */
+	if ((lub_argv__get_count(help.matches) == 1) &&
+		(SHELL_STATE_HELPING == this->state)) {
+		const char *detail = lub_argv__get_arg(help.detail, 0);
+		if (detail)
+			fprintf(stderr, "%s\n", detail);
 	}
+
 	/* update the state */
 	if (this->state == SHELL_STATE_HELPING)
 		this->state = SHELL_STATE_OK;
 	else
 		this->state = SHELL_STATE_HELPING;
+
+end:
+	lub_argv_delete(help.matches);
+	lub_argv_delete(help.help);
+	lub_argv_delete(help.detail);
 }
 
 /*--------------------------------------------------------- */

+ 2 - 2
clish/shell/shell_tinyrl.c

@@ -269,8 +269,8 @@ static bool_t clish_shell_tinyrl_key_enter(tinyrl_t * this, int key)
 
 /*-------------------------------------------------------- */
 /* This is the completion function provided for CLISH */
-static tinyrl_completion_func_t clish_shell_tinyrl_completion;
-static char **clish_shell_tinyrl_completion(tinyrl_t * tinyrl,
+tinyrl_completion_func_t clish_shell_tinyrl_completion;
+char **clish_shell_tinyrl_completion(tinyrl_t * tinyrl,
 	const char *line, unsigned start, unsigned end)
 {
 	lub_argv_t *matches = lub_argv_new(NULL, 0);