Procházet zdrojové kódy

Unfinished work on parsing

Serj Kalichev před 2 roky
rodič
revize
96af6c17f5
3 změnil soubory, kde provedl 35 přidání a 9 odebrání
  1. 1 0
      klish/kentry.h
  2. 2 0
      klish/kscheme/kentry.c
  3. 32 9
      klish/ksession/ksession_parse.c

+ 1 - 0
klish/kentry.h

@@ -76,6 +76,7 @@ faux_list_t *kentry_entrys(const kentry_t *entry);
 bool_t kentry_add_entry(kentry_t *entry, kentry_t *nested_entry);
 kentry_t *kentry_find_entry(const kentry_t *entry, const char *name);
 ssize_t kentry_entrys_len(const kentry_t *entry);
+bool_t kentry_entrys_is_empty(const kentry_t *entry);
 kentry_entrys_node_t *kentry_entrys_iter(const kentry_t *entry);
 kentry_t *kentry_entrys_each(kentry_entrys_node_t **iter);
 

+ 2 - 0
klish/kscheme/kentry.c

@@ -83,6 +83,8 @@ static KCMP_NESTED(entry, entry, name);
 static KCMP_NESTED_BY_KEY(entry, entry, name);
 KADD_NESTED(entry, entry);
 KFIND_NESTED(entry, entry);
+KNESTED_LEN(entry, entry);
+KNESTED_IS_EMPTY(entry, entry);
 KNESTED_ITER(entry, entry);
 KNESTED_EACH(entry, entry);
 

+ 32 - 9
klish/ksession/ksession_parse.c

@@ -26,6 +26,8 @@ typedef enum {
 
 static bool_t ksession_validate_arg(kentry_t *entry, const char *arg)
 {
+	const char *str = NULL;
+
 	assert(entry);
 	if (!entry)
 		return BOOL_FALSE;
@@ -33,6 +35,13 @@ static bool_t ksession_validate_arg(kentry_t *entry, const char *arg)
 	if (!arg)
 		return BOOL_FALSE;
 
+	// Temporary test code that implements COMMAND i.e. it compares argument
+	// to ENTRY's 'name' or 'value'. Later it will be removed by real code.
+	str = kentry_value(entry);
+	if (!str)
+		str = kentry_name(entry);
+	if (faux_str_casecmp(str, arg) == 0)
+			return BOOL_TRUE;
 
 	return BOOL_FALSE;
 }
@@ -43,7 +52,8 @@ static kparse_status_e ksession_parse_arg(kentry_t *current_entry,
 {
 	kentry_t *entry = current_entry;
 	kentry_mode_e mode = KENTRY_MODE_NONE;
-	kparse_status_e retcode = KPARSE_NONE;
+	kparse_status_e retcode = KPARSE_NOTFOUND; // For ENTRY itself
+	kparse_status_e rc = KPARSE_NOTFOUND; // For nested ENTRYs
 
 	assert(current_entry);
 	if (!current_entry)
@@ -51,13 +61,15 @@ static kparse_status_e ksession_parse_arg(kentry_t *current_entry,
 	assert(argv_iter);
 	if (!argv_iter)
 		return KPARSE_ERROR;
-	assert(*argv_iter);
-	if (!*argv_iter)
-		return KPARSE_ERROR;
 	assert(pargv);
 	if (!pargv)
 		return KPARSE_ERROR;
 
+	// If all arguments are resolved already then return INCOMPLETED
+	assert(*argv_iter);
+	if (!*argv_iter)
+		return KPARSE_INCOMPLETED;
+
 	// Is entry candidate to resolve current arg?
 	// Container can't be a candidate.
 	if (!kentry_container(entry)) {
@@ -74,6 +86,10 @@ static kparse_status_e ksession_parse_arg(kentry_t *current_entry,
 		}
 	}
 
+	// ENTRY has no nested ENTRYs so return
+	if (kentry_entrys_is_empty(entry))
+		return retcode;
+
 	// Walk through the nested entries
 	mode = kentry_mode(entry);
 	if (KENTRY_MODE_EMPTY == mode)
@@ -87,24 +103,31 @@ static kparse_status_e ksession_parse_arg(kentry_t *current_entry,
 		kentry_entrys_node_t *iter = kentry_entrys_iter(entry);
 		kentry_t *nested = NULL;
 		while ((nested = kentry_entrys_each(&iter))) {
-			if (ksession_parse_arg(nested, argv_iter, pargv)) {
-				retcode = KPARSE_INPROGRESS;
+			rc = ksession_parse_arg(nested, argv_iter, pargv);
+			// Any variant of error or INPROGRESS
+			if (rc != KPARSE_NOTFOUND)
 				break;
-			}
 		}
 
 	// SEQUENCE
 	} else if (KENTRY_MODE_SEQUENCE == mode) {
 		kentry_entrys_node_t *iter = kentry_entrys_iter(entry);
 		kentry_t *nested = NULL;
+		kparse_status_e nrc = KPARSE_NOTFOUND;
 		while ((nested = kentry_entrys_each(&iter))) {
-			if (ksession_parse_arg(nested, argv_iter, pargv))
+			if ((nrc = ksession_parse_arg(nested, argv_iter, pargv)))
 				retcode = KPARSE_INPROGRESS;
 		}
 	
 	}
 
-	return retcode;
+	// When ENTRY (not container) is found but mandatory nested ENTRY is
+	// not resolved. It's inconsistent. So NOTFOUND is not suitable in
+	// this case.
+	if ((KPARSE_NOTFOUND == rc) && (KPARSE_INPROGRESS == retcode))
+		return KPARSE_ILLEGAL;
+
+	return rc;
 }