Browse Source

Add optional parameters with "order" field.

git-svn-id: https://klish.googlecode.com/svn/trunk@522 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 12 years ago
parent
commit
a5d0ea7d34
6 changed files with 40 additions and 9 deletions
  1. 7 1
      clish.xsd
  2. 2 0
      clish/param.h
  3. 13 0
      clish/param/param.c
  4. 1 0
      clish/param/private.h
  5. 11 8
      clish/shell/shell_parse.c
  6. 6 0
      clish/shell/shell_tinyxml.cpp

+ 7 - 1
clish.xsd

@@ -273,7 +273,12 @@
 *           value of this parameter.
 *
 * [optional]- Specify whether parameter is optional. The allowed values
-*           is "true" or "false". It false by default.
+*           is "true" or "false". It's false by default.
+*
+* [order]   - Used only together with "optional=true" field.
+*           If order="true" then user can't enter previously declared
+*           optional parameters after current validated parameter.
+*           The allowed values is "true" or "false". It's false by default.
 *
 * [default] - defines a default value for a parameter. Any parameters
 *           at the end of command line which have default values need 
@@ -313,6 +318,7 @@
         <xs:attribute name="prefix" type="xs:string" use="optional"/>
         <xs:attribute name="mode" type="param_mode_t" use="optional" default="common"/>
         <xs:attribute name="optional" type="bool_t" use="optional" default="false"/>
+        <xs:attribute name="order" 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"/>

+ 2 - 0
clish/param.h

@@ -78,6 +78,8 @@ unsigned int clish_param__get_param_count(const clish_param_t * instance);
 clish_paramv_t *clish_param__get_paramv(clish_param_t * instance);
 void clish_param__set_optional(clish_param_t * instance, bool_t optional);
 bool_t clish_param__get_optional(const clish_param_t * instance);
+void clish_param__set_order(clish_param_t * instance, bool_t order);
+bool_t clish_param__get_order(const clish_param_t * instance);
 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);

+ 13 - 0
clish/param/param.c

@@ -27,6 +27,7 @@ static void clish_param_init(clish_param_t *this, const char *name,
 	this->defval = NULL;
 	this->mode = CLISH_PARAM_COMMON;
 	this->optional = BOOL_FALSE;
+	this->order = BOOL_FALSE;
 	this->value = NULL;
 	this->hidden = BOOL_FALSE;
 	this->test = NULL;
@@ -217,6 +218,18 @@ bool_t clish_param__get_optional(const clish_param_t * this)
 	return this->optional;
 }
 
+/*--------------------------------------------------------- */
+void clish_param__set_order(clish_param_t * this, bool_t order)
+{
+	this->order = order;
+}
+
+/*--------------------------------------------------------- */
+bool_t clish_param__get_order(const clish_param_t * this)
+{
+	return this->order;
+}
+
 /*--------------------------------------------------------- */
 
 /* paramv methods */

+ 1 - 0
clish/param/private.h

@@ -21,6 +21,7 @@ struct clish_param_s {
 	clish_paramv_t *paramv;
 	clish_param_mode_e mode;
 	bool_t optional;
+	bool_t order;
 	bool_t hidden;
 	char *test; /* The condition to enable param */
 	char *completion; /* Possible completions */

+ 11 - 8
clish/shell/shell_parse.c

@@ -174,13 +174,13 @@ clish_pargv_status_t clish_shell_parse_pargv(clish_pargv_t *pargv,
 			 * to restore index if the optional parameters
 			 * will be used.
 			 */
-			if (BOOL_TRUE != clish_param__get_optional(param)) {
+			if (!clish_param__get_optional(param)) {
 				nopt_param = param;
 				nopt_index = index;
 			}
 
 			/* Validate the current parameter. */
-			if (NULL != clish_pargv_find_arg(pargv, clish_param__get_name(param))) {
+			if (clish_pargv_find_arg(pargv, clish_param__get_name(param))) {
 				/* Duplicated parameter */
 				validated = NULL;
 			} else if (is_switch) {
@@ -198,9 +198,8 @@ clish_pargv_status_t clish_shell_parse_pargv(clish_pargv_t *pargv,
 					}
 				}
 			} else {
-				validated =
-				    arg ? clish_param_validate(param,
-							       arg) : NULL;
+				validated = arg ?
+					clish_param_validate(param, arg) : NULL;
 			}
 
 			if (validated) {
@@ -235,12 +234,17 @@ clish_pargv_status_t clish_shell_parse_pargv(clish_pargv_t *pargv,
 				}
 
 				/* Choose the next parameter */
-				if (BOOL_TRUE == clish_param__get_optional(param)) {
+				if (clish_param__get_optional(param) &&
+					!clish_param__get_order(param)) {
 					if (nopt_param)
 						index = nopt_index + 1;
 					else
 						index = 0;
 				} else {
+					/* Save non-option position in
+					   case of ordered optional param */
+					nopt_param = param;
+					nopt_index = index;
 					index++;
 				}
 
@@ -248,8 +252,7 @@ clish_pargv_status_t clish_shell_parse_pargv(clish_pargv_t *pargv,
 				/* Choose the next parameter if current
 				 * is not validated.
 				 */
-				if (BOOL_TRUE ==
-					clish_param__get_optional(param))
+				if (clish_param__get_optional(param))
 					index++;
 				else {
 					if (!arg)

+ 6 - 0
clish/shell/shell_tinyxml.cpp

@@ -372,6 +372,7 @@ process_param(clish_shell_t * shell, TiXmlElement * element, void *parent)
 		const char *defval = element->Attribute("default");
 		const char *mode = element->Attribute("mode");
 		const char *optional = element->Attribute("optional");
+		const char *order = element->Attribute("order");
 		const char *value = element->Attribute("value");
 		const char *hidden = element->Attribute("hidden");
 		const char *test = element->Attribute("test");
@@ -458,6 +459,11 @@ process_param(clish_shell_t * shell, TiXmlElement * element, void *parent)
 		else
 			clish_param__set_optional(param, BOOL_FALSE);
 
+		if (order && (lub_string_nocasecmp(order, "true") == 0))
+			clish_param__set_order(param, BOOL_TRUE);
+		else
+			clish_param__set_order(param, BOOL_FALSE);
+
 		if (value) {
 			clish_param__set_value(param, value);
 			/* Force mode to subcommand */