Browse Source

Get LOG tag from XML

Serj Kalichev 5 months ago
parent
commit
48cd7428fb
5 changed files with 48 additions and 6 deletions
  1. 5 0
      klish.xsd
  2. 5 0
      klish/ischeme/ientry.c
  3. 1 0
      klish/kentry.h
  4. 27 5
      klish/kscheme/kscheme.c
  5. 10 1
      klish/xml-helper/load.c

+ 5 - 0
klish.xsd

@@ -33,6 +33,7 @@
 	<xs:element name="COMPL" type="command_t"/> <!-- Wrapper -->
 	<xs:element name="HELP" type="command_t"/> <!-- Wrapper -->
 	<xs:element name="PROMPT" type="command_t"/> <!-- Wrapper -->
+	<xs:element name="LOG" type="command_t"/> <!-- Wrapper -->
 	<xs:element name="PTYPE" type="ptype_t"/> <!-- Wrapper -->
 	<xs:element name="PARAM" type="param_t"/> <!-- Wrapper -->
 	<xs:element name="SWITCH" type="param_t"/> <!-- Wrapper -->
@@ -57,6 +58,7 @@
 			<xs:element ref="COMPL" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="HELP" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="PROMPT" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element ref="LOG" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="PARAM" minOccurs="0" maxOccurs="unbounded"/>
 		</xs:choice>
 	</xs:group>
@@ -311,6 +313,7 @@
 			<xs:element ref="COMPL" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="HELP" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="PROMPT" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element ref="LOG" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="SWITCH" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="SEQ" minOccurs="0" maxOccurs="unbounded"/>
 		</xs:choice>
@@ -388,6 +391,7 @@
 			<xs:element ref="COMPL" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="HELP" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="PROMPT" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element ref="LOG" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="SWITCH" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="SEQ" minOccurs="0" maxOccurs="unbounded"/>
 		</xs:choice>
@@ -423,6 +427,7 @@
 			<xs:element ref="COND" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="COMPL" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="HELP" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element ref="LOG" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="SWITCH" minOccurs="0" maxOccurs="unbounded"/>
 			<xs:element ref="SEQ" minOccurs="0" maxOccurs="unbounded"/>
 		</xs:choice>

+ 5 - 0
klish/ischeme/ientry.c

@@ -70,6 +70,8 @@ bool_t ientry_parse(const ientry_t *info, kentry_t *entry, faux_error_t *error)
 			purpose = KENTRY_PURPOSE_COMPLETION;
 		else if (!faux_str_casecmp(info->purpose, "help"))
 			purpose = KENTRY_PURPOSE_HELP;
+		else if (!faux_str_casecmp(info->purpose, "log"))
+			purpose = KENTRY_PURPOSE_LOG;
 		if ((KENTRY_PURPOSE_NONE == purpose) || !kentry_set_purpose(entry, purpose)) {
 			faux_error_add(error, TAG": Illegal 'purpose' attribute");
 			retcode = BOOL_FALSE;
@@ -360,6 +362,9 @@ char *ientry_deploy(const kentry_t *kentry, int level)
 		case KENTRY_PURPOSE_HELP:
 			purpose = "help";
 			break;
+		case KENTRY_PURPOSE_LOG:
+			purpose = "log";
+			break;
 		default:
 			purpose = NULL;
 		}

+ 1 - 0
klish/kentry.h

@@ -33,6 +33,7 @@ typedef enum {
 	KENTRY_PURPOSE_COND, // Conditional expression
 	KENTRY_PURPOSE_COMPLETION, // Engine to generate completions
 	KENTRY_PURPOSE_HELP,
+	KENTRY_PURPOSE_LOG, // Log klish commands
 	KENTRY_PURPOSE_MAX,
 } kentry_purpose_e;
 

+ 27 - 5
klish/kscheme/kscheme.c

@@ -358,16 +358,38 @@ bool_t kscheme_prepare_entry(kscheme_t *scheme, kentry_t *entry,
 	if (!kscheme_prepare_action_list(scheme, entry, error))
 		retcode = BOOL_FALSE;
 
-	// Process nested ENTRYs
+	// Create fast links to nested entries with special purposes. Do it
+	// before preparing child elements because some fields can be inhereted
+	// by child from its parent
 	iter = kentry_entrys_iter(entry);
-	while ((nested_entry = kentry_entrys_each(&iter))) {
-		if (!kscheme_prepare_entry(scheme, nested_entry, error))
-			retcode = BOOL_FALSE;
-		// Create fast links to nested entries with special purposes
+	while ((nested_entry = kentry_entrys_each(&iter)))
 		kentry_set_nested_by_purpose(entry,
 			kentry_purpose(nested_entry), nested_entry);
+	// Inherit LOG from parent if it's not specified explicitly
+	if (!kentry_nested_by_purpose(entry, KENTRY_PURPOSE_LOG)) {
+		kentry_t *parent = kentry_parent(entry);
+		if (parent) { // Get LOG from parent entry
+			kentry_set_nested_by_purpose(entry, KENTRY_PURPOSE_LOG,
+				kentry_nested_by_purpose(parent,
+				KENTRY_PURPOSE_LOG));
+		} else { // High level entries has no parents
+			iter = kscheme_entrys_iter(scheme);
+			while ((nested_entry = kscheme_entrys_each(&iter))) {
+				if (kentry_purpose(nested_entry) !=
+					KENTRY_PURPOSE_LOG)
+					continue;
+				kentry_set_nested_by_purpose(entry,
+					KENTRY_PURPOSE_LOG, nested_entry);
+			}
+		}
 	}
 
+	// Process nested ENTRYs
+	iter = kentry_entrys_iter(entry);
+	while ((nested_entry = kentry_entrys_each(&iter)))
+		if (!kscheme_prepare_entry(scheme, nested_entry, error))
+			retcode = BOOL_FALSE;
+
 	return retcode;
 }
 

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

@@ -54,6 +54,7 @@ typedef enum {
 	KTAG_COMPL,
 	KTAG_HELP,
 	KTAG_PROMPT,
+	KTAG_LOG,
 	KTAG_HOTKEY,
 	KTAG_MAX,
 } ktags_e;
@@ -75,6 +76,7 @@ static const char * const kxml_tags[] = {
 	"COMPL",
 	"HELP",
 	"PROMPT",
+	"LOG",
 	"HOTKEY",
 };
 
@@ -95,6 +97,7 @@ static kxml_process_fn *kxml_handlers[] = {
 	process_command,
 	process_command,
 	process_command,
+	process_command,
 	process_hotkey,
 };
 
@@ -791,7 +794,7 @@ err:
 }
 
 
-// COMMAND, FILTER, COND, COMPL, HELP, PROMPT
+// COMMAND, FILTER, COND, COMPL, HELP, PROMPT, LOG
 static bool_t process_command(const kxml_node_t *element, void *parent,
 	faux_error_t *error)
 {
@@ -827,6 +830,9 @@ static bool_t process_command(const kxml_node_t *element, void *parent,
 		case KTAG_PROMPT:
 			ientry.name = "__prompt";
 			break;
+		case KTAG_LOG:
+			ientry.name = "__log";
+			break;
 		default:
 			faux_error_sprintf(error, TAG": Unknown tag");
 			return BOOL_FALSE;
@@ -849,6 +855,9 @@ static bool_t process_command(const kxml_node_t *element, void *parent,
 	case KTAG_PROMPT:
 		ientry.purpose = "prompt";
 		break;
+	case KTAG_LOG:
+		ientry.purpose = "log";
+		break;
 	default:
 		ientry.purpose = "common";
 		break;