Browse Source

kaction: Add 'permanent' and 'syc' attrs

Serj Kalichev 2 years ago
parent
commit
707cc3756d
7 changed files with 121 additions and 0 deletions
  1. 19 0
      klish.xsd
  2. 2 0
      klish/iaction.h
  3. 22 0
      klish/ischeme/iaction.c
  4. 1 0
      klish/ischeme/ientry.c
  5. 15 0
      klish/kaction.h
  6. 58 0
      klish/kscheme/kaction.c
  7. 4 0
      klish/xml-helper/load.c

+ 19 - 0
klish.xsd

@@ -137,6 +137,11 @@
 *
 * [access]  - access rights
 *
+* [filter="true/false"] - Developer can define 'filter' command to filter stdout
+*	of piped ("|") commands. Filter can't contain 'sync' ACTIONs. It will be
+*	always fork()-ed. Only filters can be on the right hand to pipe "|".
+*	Consider filters as a special type of commands.
+*
 ********************************************************
 -->
 	<xs:simpleType name="entry_mode_t">
@@ -170,6 +175,7 @@
 		<xs:attribute name="value" type="xs:string" use="optional"/>
 		<xs:attribute name="restore" type="xs:boolean" use="optional" default="false"/>
 		<xs:attribute name="order" type="xs:boolean" use="optional" default="false"/>
+		<xs:attribute name="filter" type="xs:boolean" use="optional" default="false"/>
 	</xs:complexType>
 
 
@@ -348,6 +354,17 @@
 *	by current ACTION's return code or ACTION's return code can be ignored.
 *	Default is "true".
 *
+* [permanent="true/false"] - The klish can be invoked with --dry-run option. In
+*	this case all ACTIONs will be not actually executed but will always
+*	return success. But some actions like navigation is necessary to be
+*	executed in any case. Permanent flag will inform engine to always
+*	execute ACTION.
+*
+* [sync="true/false"] - Common behaviour is to fork() process before ACTION
+*	execution. But ACTION may be executed in-place (without fork()) if sync
+*	flag is set to true. It's not recommended to use sync ACTIONs widely.
+*	It's usefull for small fast functions only.
+*
 ********************************************************
 -->
 	<xs:simpleType name="action_cond_t">
@@ -367,6 +384,8 @@
 				<xs:attribute name="interactive" type="xs:boolean" use="optional" default="false"/>
 				<xs:attribute name="exec_on" type="action_cond_t" use="optional" default="success"/>
 				<xs:attribute name="update_retcode" type="xs:boolean" use="optional" default="true"/>
+				<xs:attribute name="permanent" type="xs:boolean" use="optional" default="false"/>
+				<xs:attribute name="sync" type="xs:boolean" use="optional" default="false"/>
 			</xs:extension>
 		</xs:simpleContent>
 	</xs:complexType>

+ 2 - 0
klish/iaction.h

@@ -16,6 +16,8 @@ typedef struct iaction_s {
 	char *interactive;
 	char *exec_on;
 	char *update_retcode;
+	char *permanent;
+	char *sync;
 	char *script;
 } iaction_t;
 

+ 22 - 0
klish/ischeme/iaction.c

@@ -84,6 +84,26 @@ bool_t iaction_parse(const iaction_t *info, kaction_t *action, faux_error_t *err
 		}
 	}
 
+	// Permanent
+	if (!faux_str_is_empty(info->permanent)) {
+		tri_t b = TRI_UNDEFINED;
+		if (!faux_conv_str2tri(info->permanent, &b) ||
+			!kaction_set_permanent(action, b)) {
+			faux_error_add(error, TAG": Illegal 'permanent' attribute");
+			retcode = BOOL_FALSE;
+		}
+	}
+
+	// Sync
+	if (!faux_str_is_empty(info->sync)) {
+		tri_t b = TRI_UNDEFINED;
+		if (!faux_conv_str2tri(info->sync, &b) ||
+			!kaction_set_sync(action, b)) {
+			faux_error_add(error, TAG": Illegal 'sync' attribute");
+			retcode = BOOL_FALSE;
+		}
+	}
+
 	// Script
 	if (!faux_str_is_empty(info->script)) {
 		if (!kaction_set_script(action, info->script)) {
@@ -147,6 +167,8 @@ char *iaction_deploy(const kaction_t *kaction, int level)
 	}
 	attr2ctext(&str, "exec_on", exec_on, level + 1);
 	attr2ctext(&str, "update_retcode", faux_conv_bool2str(kaction_update_retcode(kaction)), level + 1);
+	attr2ctext(&str, "permanent", faux_conv_tri2str(kaction_permanent(kaction)), level + 1);
+	attr2ctext(&str, "sync", faux_conv_tri2str(kaction_sync(kaction)), level + 1);
 	attr2ctext(&str, "script", kaction_script(kaction), level + 1);
 
 	tmp = faux_str_sprintf("%*c},\n\n", level, ' ');

+ 1 - 0
klish/ischeme/ientry.c

@@ -312,6 +312,7 @@ char *ientry_deploy(const kentry_t *kentry, int level)
 		attr2ctext(&str, "value", kentry_value(kentry), level + 1);
 		attr2ctext(&str, "restore", faux_conv_bool2str(kentry_restore(kentry)), level + 1);
 		attr2ctext(&str, "order", faux_conv_bool2str(kentry_order(kentry)), level + 1);
+		attr2ctext(&str, "filter", faux_conv_bool2str(kentry_filter(kentry)), level + 1);
 
 		// ENTRY list
 		entrys_iter = kentry_entrys_iter(kentry);

+ 15 - 0
klish/kaction.h

@@ -27,21 +27,36 @@ void kaction_free(kaction_t *action);
 
 const char *kaction_sym_ref(const kaction_t *action);
 bool_t kaction_set_sym_ref(kaction_t *action, const char *sym_ref);
+
 const char *kaction_lock(const kaction_t *action);
 bool_t kaction_set_lock(kaction_t *action, const char *lock);
+
 bool_t kaction_interrupt(const kaction_t *action);
 bool_t kaction_set_interrupt(kaction_t *action, bool_t interrupt);
+
 bool_t kaction_interactive(const kaction_t *action);
 bool_t kaction_set_interactive(kaction_t *action, bool_t interactive);
+
 kaction_cond_e kaction_exec_on(const kaction_t *action);
 bool_t kaction_set_exec_on(kaction_t *action, kaction_cond_e exec_on);
+
 bool_t kaction_update_retcode(const kaction_t *action);
 bool_t kaction_set_update_retcode(kaction_t *action, bool_t update_retcode);
+
 const char *kaction_script(const kaction_t *action);
 bool_t kaction_set_script(kaction_t *action, const char *script);
+
 ksym_t *kaction_sym(const kaction_t *action);
 bool_t kaction_set_sym(kaction_t *action, ksym_t *sym);
 
+tri_t kaction_permanent(const kaction_t *action);
+bool_t kaction_set_permanent(kaction_t *action, tri_t permanent);
+bool_t kaction_is_permanent(const kaction_t *action);
+
+tri_t kaction_sync(const kaction_t *action);
+bool_t kaction_set_sync(kaction_t *action, tri_t sync);
+bool_t kaction_is_sync(const kaction_t *action);
+
 C_DECL_END
 
 #endif // _klish_kaction_h

+ 58 - 0
klish/kscheme/kaction.c

@@ -21,6 +21,8 @@ struct kaction_s {
 //	bool_t async;
 	kaction_cond_e exec_on;
 	bool_t update_retcode;
+	tri_t permanent;
+	tri_t sync;
 	char *script;
 };
 
@@ -51,6 +53,14 @@ KSET(action, kaction_cond_e, exec_on);
 KGET_BOOL(action, update_retcode);
 KSET_BOOL(action, update_retcode);
 
+// Permanent
+KGET(action, tri_t, permanent);
+KSET(action, tri_t, permanent);
+
+// Sync
+KGET(action, tri_t, sync);
+KSET(action, tri_t, sync);
+
 // Script
 KGET_STR(action, script);
 KSET_STR(action, script);
@@ -94,3 +104,51 @@ void kaction_free(kaction_t *action)
 
 	faux_free(action);
 }
+
+
+bool_t kaction_is_permanent(const kaction_t *action)
+{
+	ksym_t *sym = NULL;
+	tri_t val = TRI_UNDEFINED;
+
+	assert(action);
+	if (!action)
+		return BOOL_FALSE;
+
+	sym = kaction_sym(action);
+	if (!sym)
+		return BOOL_FALSE;
+
+	val = ksym_permanent(sym);
+	if (TRI_UNDEFINED == val)
+		val = kaction_permanent(action);
+
+	if (TRI_TRUE == val)
+		return BOOL_TRUE;
+
+	return BOOL_FALSE; // Default if not set
+}
+
+
+bool_t kaction_is_sync(const kaction_t *action)
+{
+	ksym_t *sym = NULL;
+	tri_t val = TRI_UNDEFINED;
+
+	assert(action);
+	if (!action)
+		return BOOL_FALSE;
+
+	sym = kaction_sym(action);
+	if (!sym)
+		return BOOL_FALSE;
+
+	val = ksym_sync(sym);
+	if (TRI_UNDEFINED == val)
+		val = kaction_sync(action);
+
+	if (TRI_TRUE == val)
+		return BOOL_TRUE;
+
+	return BOOL_FALSE; // Default if not set
+}

+ 4 - 0
klish/xml-helper/load.c

@@ -656,6 +656,8 @@ static bool_t process_action(const kxml_node_t *element, void *parent,
 	iaction.interactive = kxml_node_attr(element, "interactive");
 	iaction.exec_on = kxml_node_attr(element, "exec_on");
 	iaction.update_retcode = kxml_node_attr(element, "update_retcode");
+	iaction.permanent = kxml_node_attr(element, "permanent");
+	iaction.sync = kxml_node_attr(element, "sync");
 	iaction.script = kxml_node_content(element);
 
 	action = iaction_load(&iaction, error);
@@ -692,6 +694,8 @@ err:
 	kxml_node_attr_free(iaction.interactive);
 	kxml_node_attr_free(iaction.exec_on);
 	kxml_node_attr_free(iaction.update_retcode);
+	kxml_node_attr_free(iaction.permanent);
+	kxml_node_attr_free(iaction.sync);
 	kxml_node_content_free(iaction.script);
 
 	return res;