Browse Source

The 'test' field for PARAM

git-svn-id: https://klish.googlecode.com/svn/trunk@248 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 13 years ago
parent
commit
fa109feae3
7 changed files with 64 additions and 19 deletions
  1. 4 0
      clish.xsd
  2. 5 0
      clish/param.h
  3. 23 2
      clish/param/param.c
  4. 1 0
      clish/param/private.h
  5. 22 5
      clish/pargv/pargv.c
  6. 4 0
      clish/shell/shell_tinyxml_read.cpp
  7. 5 12
      lub/system/test.c

+ 4 - 0
clish.xsd

@@ -265,6 +265,9 @@
 * [hidden]  - define the visibility of the parameter while ${__line}
 *           and ${__params} auto variables expanding. The allowed values
 *           is "true" and "false".
+*
+* [test]    - define the condition (see the description of 'test'
+*           utility) to process this parameter.
 ********************************************************
     -->
 
@@ -288,6 +291,7 @@
         <xs:attribute name="optional" type="bool_t" use="optional" default="false"/>
         <xs:attribute name="value" type="xs:string" use="optional"/>
         <xs:attribute name="hidden" type="bool_t" use="optional" default="false"/>
+        <xs:attribute name="test" type="xs:string" use="optional"/>
     </xs:complexType>
     <!--
 ********************************************************

+ 5 - 0
clish/param.h

@@ -19,6 +19,7 @@ typedef struct clish_paramv_s clish_paramv_t;
 typedef struct clish_param_s clish_param_t;
 
 #include "clish/ptype.h"
+#include "clish/pargv.h"
 
 /**
  * The means by which the param is interpreted.
@@ -79,6 +80,10 @@ void clish_param__set_value(clish_param_t * instance, const char * value);
 char *clish_param__get_value(const clish_param_t * instance);
 void clish_param__set_hidden(clish_param_t * instance, bool_t hidden);
 bool_t clish_param__get_hidden(const clish_param_t * instance);
+void clish_param__set_test(clish_param_t * instance, const char *test);
+char *clish_param__get_test(const clish_param_t * instance,
+	const char * viewid, const clish_command_t * cmd,
+	clish_pargv_t * pargv);
 
 /* paramv methods */
 clish_paramv_t *clish_paramv_new(void);

+ 23 - 2
clish/param/param.c

@@ -5,6 +5,7 @@
  */
 #include "private.h"
 #include "lub/string.h"
+#include "clish/variable.h"
 
 #include <assert.h>
 #include <stdlib.h>
@@ -16,9 +17,8 @@
  *--------------------------------------------------------- */
 static void
 clish_param_init(clish_param_t * this,
-		 const char *name, const char *text, clish_ptype_t * ptype)
+	const char *name, const char *text, clish_ptype_t * ptype)
 {
-
 	/* initialise the help part */
 	this->name = lub_string_dup(name);
 	this->text = lub_string_dup(text);
@@ -30,6 +30,7 @@ clish_param_init(clish_param_t * this,
 	this->optional = BOOL_FALSE;
 	this->value = NULL;
 	this->hidden = BOOL_FALSE;
+	this->test = NULL;
 
 	this->paramv = clish_paramv_new();
 }
@@ -48,6 +49,8 @@ static void clish_param_fini(clish_param_t * this)
 	this->text = NULL;
 	lub_string_free(this->value);
 	this->value = NULL;
+	lub_string_free(this->test);
+	this->test = NULL;
 
 	clish_paramv_delete(this->paramv);
 }
@@ -317,3 +320,21 @@ bool_t clish_param__get_hidden(const clish_param_t * this)
 {
 	return this->hidden;
 }
+
+/*--------------------------------------------------------- */
+void clish_param__set_test(clish_param_t * this, const char *test)
+{
+	assert(NULL == this->test);
+	this->test = lub_string_dup(test);
+}
+
+/*--------------------------------------------------------- */
+char *clish_param__get_test(const clish_param_t * this,
+	const char * viewid, const clish_command_t * cmd,
+	clish_pargv_t * pargv)
+{
+	if (!this->test)
+		return NULL;
+	return clish_variable_expand(this->test, viewid, cmd, pargv);
+}
+

+ 1 - 0
clish/param/private.h

@@ -22,4 +22,5 @@ struct clish_param_s {
 	clish_param_mode_e mode;
 	bool_t optional;
 	bool_t hidden;
+	char *test; /* the condition */
 };

+ 22 - 5
clish/pargv/pargv.c

@@ -4,6 +4,7 @@
 #include "private.h"
 #include "lub/string.h"
 #include "lub/argv.h"
+#include "lub/system.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -95,10 +96,10 @@ static void set_defaults(clish_pargv_t * this, const clish_command_t * cmd)
 /*--------------------------------------------------------- */
 clish_pargv_status_t
 clish_pargv_parse(clish_pargv_t * this,
-		const clish_command_t * cmd,
-		clish_paramv_t * paramv,
-		const lub_argv_t * argv,
-		unsigned *idx, clish_pargv_t * last, unsigned need_index)
+	const clish_command_t * cmd,
+	clish_paramv_t * paramv,
+	const lub_argv_t * argv,
+	unsigned *idx, clish_pargv_t * last, unsigned need_index)
 {
 	unsigned start = *idx;
 	unsigned argc = lub_argv__get_count(argv);
@@ -116,6 +117,7 @@ clish_pargv_parse(clish_pargv_t * this,
 		clish_param_t *param = clish_paramv__get_param(paramv,index);
 		clish_param_t *cparam = NULL;
 		int is_switch = 0;
+		int is_tested = 0;
 
 		/* Use real arg or PARAM's default value as argument */
 		if (*idx >= argc)
@@ -127,8 +129,23 @@ clish_pargv_parse(clish_pargv_t * this,
 		if (CLISH_PARAM_SWITCH == clish_param__get_mode(param))
 			is_switch = 1;
 
+		/* Check the 'test' condition */
+		if (param) {
+			char *str = clish_param__get_test(param,
+				NULL, cmd, this);
+			if (!str)
+				is_tested = 1;
+			else {
+				if (lub_system_line_test(str))
+					is_tested = 1;
+				else
+					is_tested = 0;
+				lub_string_free(str);
+			}
+		}
+
 		/* Add param for help and completion */
-		if (last && (*idx == need_index) &&
+		if (last && (*idx == need_index) && is_tested &&
 			(NULL == clish_pargv_find_arg(this, clish_param__get_name(param)))) {
 			if (is_switch) {
 				clish_paramv_t *rec_paramv = clish_param__get_paramv(param);

+ 4 - 0
clish/shell/shell_tinyxml_read.cpp

@@ -326,6 +326,7 @@ process_param(clish_shell_t * shell, TiXmlElement * element, void *parent)
 		const char *optional = element->Attribute("optional");
 		const char *value = element->Attribute("value");
 		const char *hidden = element->Attribute("hidden");
+		const char *test = element->Attribute("test");
 		clish_param_t *param;
 		clish_ptype_t *tmp = NULL;
 
@@ -413,6 +414,9 @@ process_param(clish_shell_t * shell, TiXmlElement * element, void *parent)
 				CLISH_PARAM_SUBCOMMAND);
 		}
 
+		if (NULL != test)
+			clish_param__set_test(param, test);
+
 		if (cmd)
 			// add the parameter to the command
 			clish_command_insert_param(cmd, param);

+ 5 - 12
lub/system/test.c

@@ -156,7 +156,8 @@ static int getn(const char *s);
 static int newerf(const char *, const char *);
 static int olderf(const char *, const char *);
 static int equalf(const char *, const char *);
-static void syntax(const char *op, char *msg);
+
+#define syntax(op,msg) {return 2;}
 
 int
 main(int argc, char *argv[])
@@ -165,7 +166,7 @@ main(int argc, char *argv[])
 
 	if (strcmp(argv[0], "[") == 0) {
 		if (strcmp(argv[--argc], "]"))
-			errx(2, "missing ]");
+			syntax(NULL, "missing ]");
 		argv[argc] = NULL;
 	}
 
@@ -209,14 +210,6 @@ main(int argc, char *argv[])
 	return res;
 }
 
-static __dead void
-syntax(const char *op, char *msg)
-{
-	if (op && *op)
-		errx(2, "%s: %s", op, msg);
-	else
-		errx(2, "%s", msg);
-}
 
 static int
 oexpr(enum token n)
@@ -464,13 +457,13 @@ getn(const char *s)
 	r = strtol(s, &p, 10);
 
 	if (errno != 0)
-		errx(2, "%s: out of range", s);
+		syntax(NULL, "out of range");
 
 	while (isspace(*p))
 		p++;
 
 	if (*p)
-		errx(2, "%s: bad number", s);
+		syntax(NULL, "bad number");
 
 	return (int) r;
 }