Browse Source

scheme: Add SWITCH, SUBCOMMAND, MULTI tags. PARAM aliases with different modes

Serj Kalichev 2 years ago
parent
commit
917f14cca5
5 changed files with 95 additions and 5 deletions
  1. 1 0
      klish/iparam.h
  2. 19 4
      klish/ischeme/iaction.c
  3. 37 0
      klish/ischeme/iparam.c
  4. 1 0
      klish/kparam.h
  5. 37 1
      klish/xml-helper/load.c

+ 1 - 0
klish/iparam.h

@@ -15,6 +15,7 @@ struct iparam_s {
 	char *name;
 	char *help;
 	char *ptype;
+	char *mode;
 	iparam_t * (*params)[]; // Nested PARAMs
 };
 

+ 19 - 4
klish/ischeme/iaction.c

@@ -62,11 +62,11 @@ bool_t iaction_parse(const iaction_t *info, kaction_t *action, faux_error_t *err
 	// Exec_on
 	if (!faux_str_is_empty(info->exec_on)) {
 		kaction_cond_e c = KACTION_COND_NONE;
-		if (faux_str_casecmp(info->exec_on, "fail"))
+		if (!faux_str_casecmp(info->exec_on, "fail"))
 			c = KACTION_COND_FAIL;
-		else if (faux_str_casecmp(info->exec_on, "success"))
+		else if (!faux_str_casecmp(info->exec_on, "success"))
 			c = KACTION_COND_SUCCESS;
-		else if (faux_str_casecmp(info->exec_on, "always"))
+		else if (!faux_str_casecmp(info->exec_on, "always"))
 			c = KACTION_COND_ALWAYS;
 		if ((KACTION_COND_NONE == c) || !kaction_set_exec_on(action, c)) {
 			faux_error_add(error, TAG": Illegal 'exec_on' attribute");
@@ -118,6 +118,7 @@ char *iaction_deploy(const kaction_t *kaction, int level)
 {
 	char *str = NULL;
 	char *tmp = NULL;
+	char *exec_on = NULL;
 
 	if (!kaction)
 		return NULL;
@@ -130,7 +131,21 @@ char *iaction_deploy(const kaction_t *kaction, int level)
 	attr2ctext(&str, "lock", kaction_lock(kaction), level + 1);
 	attr2ctext(&str, "interrupt", faux_conv_bool2str(kaction_interrupt(kaction)), level + 1);
 	attr2ctext(&str, "interactive", faux_conv_bool2str(kaction_interactive(kaction)), level + 1);
-	attr2ctext(&str, "exec_on", faux_conv_bool2str(kaction_exec_on(kaction)), level + 1);
+	// Exec_on
+	switch (kaction_exec_on(kaction)) {
+	case KACTION_COND_FAIL:
+		exec_on = "fail";
+		break;
+	case KACTION_COND_SUCCESS:
+		exec_on = "success";
+		break;
+	case KACTION_COND_ALWAYS:
+		exec_on = "always";
+		break;
+	default:
+		exec_on = NULL;
+	}
+	attr2ctext(&str, "exec_on", exec_on, level + 1);
 	attr2ctext(&str, "update_retcode", faux_conv_bool2str(kaction_update_retcode(kaction)), level + 1);
 	attr2ctext(&str, "script", kaction_script(kaction), level + 1);
 

+ 37 - 0
klish/ischeme/iparam.c

@@ -37,6 +37,23 @@ bool_t iparam_parse(const iparam_t *info, kparam_t *param, faux_error_t *error)
 		}
 	}
 
+	// Mode
+	if (!faux_str_is_empty(info->mode)) {
+		kparam_mode_e mode = KPARAM_NONE;
+		if (!faux_str_casecmp(info->mode, "common"))
+			mode = KPARAM_COMMON;
+		else if (!faux_str_casecmp(info->mode, "switch"))
+			mode = KPARAM_SWITCH;
+		else if (!faux_str_casecmp(info->mode, "subcommand"))
+			mode = KPARAM_SUBCOMMAND;
+		else if (!faux_str_casecmp(info->mode, "multi"))
+			mode = KPARAM_MULTI;
+		if ((KPARAM_NONE == mode) || !kparam_set_mode(param, mode)) {
+			faux_error_add(error, TAG": Illegal 'mode' attribute");
+			retcode = BOOL_FALSE;
+		}
+	}
+
 	return retcode;
 }
 
@@ -129,6 +146,7 @@ char *iparam_deploy(const kparam_t *kparam, int level)
 {
 	char *str = NULL;
 	char *tmp = NULL;
+	char *mode = NULL;
 	kparam_params_node_t *params_iter = NULL;
 
 	tmp = faux_str_sprintf("%*cPARAM {\n", level, ' ');
@@ -139,6 +157,25 @@ char *iparam_deploy(const kparam_t *kparam, int level)
 	attr2ctext(&str, "help", kparam_help(kparam), level + 1);
 	attr2ctext(&str, "ptype", kparam_ptype_ref(kparam), level + 1);
 
+	// Mode
+	switch (kparam_mode(kparam)) {
+	case KPARAM_COMMON:
+		mode = "common";
+		break;
+	case KPARAM_SWITCH:
+		mode = "switch";
+		break;
+	case KPARAM_SUBCOMMAND:
+		mode = "subcommand";
+		break;
+	case KPARAM_MULTI:
+		mode = "multi";
+		break;
+	default:
+		mode = NULL;
+	}
+	attr2ctext(&str, "mode", mode, level + 1);
+
 	// PARAM list
 	params_iter = kparam_params_iter(kparam);
 	if (params_iter) {

+ 1 - 0
klish/kparam.h

@@ -14,6 +14,7 @@ typedef struct kparam_s kparam_t;
 typedef faux_list_node_t kparam_params_node_t;
 
 typedef enum {
+	KPARAM_NONE, // Illegal
 	KPARAM_COMMON, // Common parameter
 	KPARAM_SUBCOMMAND, // The value of this parameter is its name
 	KPARAM_SWITCH, // User can choose one of nested parameters

+ 37 - 1
klish/xml-helper/load.c

@@ -44,6 +44,9 @@ typedef enum {
 	KTAG_NONE,
 	KTAG_ACTION,
 	KTAG_PARAM,
+	KTAG_SWITCH, // PARAM alias
+	KTAG_SUBCOMMAND, // PARAM alias
+	KTAG_MULTI, // PARAM alias
 	KTAG_COMMAND,
 	KTAG_VIEW,
 	KTAG_PTYPE,
@@ -57,6 +60,9 @@ static const char * const kxml_tags[] = {
 	NULL,
 	"ACTION",
 	"PARAM",
+	"SWITCH",
+	"SUBCOMMAND",
+	"MULTI",
 	"COMMAND",
 	"VIEW",
 	"PTYPE",
@@ -69,6 +75,9 @@ static kxml_process_fn *kxml_handlers[] = {
 	NULL,
 	process_action,
 	process_param,
+	process_param,
+	process_param,
+	process_param,
 	process_command,
 	process_view,
 	process_ptype,
@@ -451,10 +460,31 @@ static bool_t process_param(const kxml_node_t *element, void *parent,
 	kparam_t *param = NULL;
 	bool_t res = BOOL_FALSE;
 	ktags_e parent_tag = kxml_node_tag(kxml_node_parent(element));
+	ktags_e tag = kxml_node_tag(element);
+	char *mode = NULL;
 
 	iparam.name = kxml_node_attr(element, "name");
 	iparam.help = kxml_node_attr(element, "help");
 	iparam.ptype = kxml_node_attr(element, "ptype");
+	// Special case for mode
+	mode = kxml_node_attr(element, "mode");
+	if (!faux_str_is_empty(mode)) {
+		iparam.mode = mode;
+	} else {
+		switch (tag) {
+		case KTAG_SWITCH:
+			iparam.mode = "switch";
+			break;
+		case KTAG_SUBCOMMAND:
+			iparam.mode = "subcommand";
+			break;
+		case KTAG_MULTI:
+			iparam.mode = "multi";
+			break;
+		default:
+			break;
+		}
+	}
 
 	param = iparam_load(&iparam, error);
 	if (!param)
@@ -470,7 +500,12 @@ static bool_t process_param(const kxml_node_t *element, void *parent,
 			kparam_free(param);
 			goto err;
 		}
-	} else if (KTAG_PARAM == parent_tag) {
+	} else if (
+		(KTAG_PARAM == parent_tag) ||
+		(KTAG_SWITCH == parent_tag) ||
+		(KTAG_SUBCOMMAND == parent_tag) ||
+		(KTAG_MULTI == parent_tag)
+		) {
 		kparam_t *parent_param = (kparam_t *)parent;
 		if (!kparam_add_param(parent_param, param)) {
 			faux_error_sprintf(error,
@@ -496,6 +531,7 @@ err:
 	kxml_node_attr_free(iparam.name);
 	kxml_node_attr_free(iparam.help);
 	kxml_node_attr_free(iparam.ptype);
+	kxml_node_attr_free(mode);
 
 	return res;
 }