Browse Source

scheme: Change error handling

Serj Kalichev 3 years ago
parent
commit
8815f900ad

+ 4 - 16
klish/kplugin.h

@@ -33,27 +33,13 @@
 
 typedef struct kplugin_s kplugin_t;
 
-typedef enum {
-	KPLUGIN_ERROR_OK,
-	KPLUGIN_ERROR_INTERNAL,
-	KPLUGIN_ERROR_ALLOC,
-	KPLUGIN_ERROR_ATTR_NAME,
-	KPLUGIN_ERROR_ATTR_ID,
-	KPLUGIN_ERROR_ATTR_FILE,
-	KPLUGIN_ERROR_ATTR_GLOBAL,
-	KPLUGIN_ERROR_ATTR_CONF,
-} kplugin_error_e;
-
 
 C_DECL_BEGIN
 
+kplugin_t *kplugin_new(const char *name);
 void kplugin_free(kplugin_t *plugin);
-bool_t kplugin_parse(kplugin_t *plugin, const iplugin_t *info, kplugin_error_e *error);
-kplugin_t *kplugin_new(const iplugin_t *info, kplugin_error_e *error);
-const char *kplugin_strerror(kplugin_error_e error);
 
 const char *kplugin_name(const kplugin_t *plugin);
-bool_t kplugin_set_name(kplugin_t *plugin, const char *name);
 const char *kplugin_id(const kplugin_t *plugin);
 bool_t kplugin_set_id(kplugin_t *plugin, const char *id);
 const char *kplugin_file(const kplugin_t *plugin);
@@ -71,8 +57,10 @@ bool_t kplugin_set_udata(kplugin_t *plugin, void *udata);
 
 bool_t kplugin_add_sym(kplugin_t *plugin, ksym_t *sym);
 ksym_t *kplugin_find_sym(const kplugin_t *plugin, const char *name);
+ssize_t kplugin_syms_len(const kplugin_t *plugin);
 
-kplugin_t *kplugin_from_iplugin(iplugin_t *iplugin, faux_error_t *error_stack);
+bool_t kplugin_parse(kplugin_t *plugin, const iplugin_t *info, faux_error_t *error);
+kplugin_t *kplugin_from_iplugin(iplugin_t *iplugin, faux_error_t *error);
 
 C_DECL_END
 

+ 4 - 10
klish/kscheme.h

@@ -13,20 +13,14 @@
 #include <klish/kptype.h>
 #include <klish/kview.h>
 
-typedef struct kscheme_s kscheme_t;
 
-typedef enum {
-	KSCHEME_ERROR_OK,
-	KSCHEME_ERROR_INTERNAL,
-	KSCHEME_ERROR_ALLOC,
-} kscheme_error_e;
+typedef struct kscheme_s kscheme_t;
 
 
 C_DECL_BEGIN
 
-kscheme_t *kscheme_new(kscheme_error_e *error);
+kscheme_t *kscheme_new(void);
 void kscheme_free(kscheme_t *scheme);
-const char *kscheme_strerror(kscheme_error_e error);
 
 bool_t kscheme_add_view(kscheme_t *scheme, kview_t *view);
 kview_t *kscheme_find_view(const kscheme_t *scheme, const char *name);
@@ -36,8 +30,8 @@ bool_t kscheme_add_plugin(kscheme_t *scheme, kplugin_t *plugin);
 kplugin_t *kscheme_find_plugin(const kscheme_t *scheme, const char *name);
 
 bool_t kscheme_nested_from_ischeme(kscheme_t *kscheme, ischeme_t *ischeme,
-	faux_error_t *error_stack);
-kscheme_t *kscheme_from_ischeme(ischeme_t *ischeme, faux_error_t *error_stack);
+	faux_error_t *error);
+kscheme_t *kscheme_from_ischeme(ischeme_t *ischeme, faux_error_t *error);
 
 C_DECL_END
 

+ 4 - 1
klish/kscheme/Makefile.am

@@ -2,6 +2,7 @@ libklish_la_SOURCES += \
 	klish/kscheme/khelper.c \
 	klish/kscheme/ksym.c \
 	klish/kscheme/kplugin.c \
+	klish/kscheme/kplugin_parse.c \
 	klish/kscheme/kptype.c \
 	klish/kscheme/kaction.c \
 	klish/kscheme/kaction_parse.c \
@@ -10,4 +11,6 @@ libklish_la_SOURCES += \
 	klish/kscheme/kcommand.c \
 	klish/kscheme/kcommand_parse.c \
 	klish/kscheme/kview.c \
-	klish/kscheme/kscheme.c
+	klish/kscheme/kview_parse.c \
+	klish/kscheme/kscheme.c \
+	klish/kscheme/kscheme_parse.c

+ 6 - 139
klish/kscheme/kplugin.c

@@ -34,7 +34,6 @@ struct kplugin_s {
 
 // Name
 KGET_STR(plugin, name);
-KSET_STR_ONCE(plugin, name);
 
 // ID
 KGET_STR(plugin, id);
@@ -69,19 +68,23 @@ static KCMP_NESTED(plugin, sym, name);
 static KCMP_NESTED_BY_KEY(plugin, sym, name);
 KADD_NESTED(plugin, sym);
 KFIND_NESTED(plugin, sym);
+KNESTED_LEN(plugin, sym);
 
 
-static kplugin_t *kplugin_new_empty(void)
+kplugin_t *kplugin_new(const char *name)
 {
 	kplugin_t *plugin = NULL;
 
+	if (faux_str_is_empty(name))
+		return NULL;
+
 	plugin = faux_zmalloc(sizeof(*plugin));
 	assert(plugin);
 	if (!plugin)
 		return NULL;
 
 	// Initialize
-	plugin->name = NULL;
+	plugin->name = faux_str_dup(name);
 	plugin->id = NULL;
 	plugin->file = NULL;
 	plugin->global = BOOL_FALSE;
@@ -103,30 +106,6 @@ static kplugin_t *kplugin_new_empty(void)
 }
 
 
-kplugin_t *kplugin_new(const iplugin_t *info, kplugin_error_e *error)
-{
-	kplugin_t *plugin = NULL;
-
-	plugin = kplugin_new_empty();
-	assert(plugin);
-	if (!plugin) {
-		if (error)
-			*error = KPLUGIN_ERROR_ALLOC;
-		return NULL;
-	}
-
-	if (!info)
-		return plugin;
-
-	if (!kplugin_parse(plugin, info, error)) {
-		kplugin_free(plugin);
-		return NULL;
-	}
-
-	return plugin;
-}
-
-
 void kplugin_free(kplugin_t *plugin)
 {
 	if (!plugin)
@@ -145,118 +124,6 @@ void kplugin_free(kplugin_t *plugin)
 }
 
 
-const char *kplugin_strerror(kplugin_error_e error)
-{
-	const char *str = NULL;
-
-	switch (error) {
-	case KPLUGIN_ERROR_OK:
-		str = "Ok";
-		break;
-	case KPLUGIN_ERROR_INTERNAL:
-		str = "Internal error";
-		break;
-	case KPLUGIN_ERROR_ALLOC:
-		str = "Memory allocation error";
-		break;
-	case KPLUGIN_ERROR_ATTR_NAME:
-		str = "Illegal 'name' attribute";
-		break;
-	case KPLUGIN_ERROR_ATTR_ID:
-		str = "Illegal 'id' attribute";
-		break;
-	case KPLUGIN_ERROR_ATTR_FILE:
-		str = "Illegal 'file' attribute";
-		break;
-	case KPLUGIN_ERROR_ATTR_GLOBAL:
-		str = "Illegal 'global' attribute";
-		break;
-	case KPLUGIN_ERROR_ATTR_CONF:
-		str = "Illegal conf";
-		break;
-	default:
-		str = "Unknown error";
-		break;
-	}
-
-	return str;
-}
-
-
-bool_t kplugin_parse(kplugin_t *plugin, const iplugin_t *info, kplugin_error_e *error)
-{
-	// Name [mandatory]
-	if (faux_str_is_empty(info->name)) {
-		if (error)
-			*error = KPLUGIN_ERROR_ATTR_NAME;
-		return BOOL_FALSE;
-	} else {
-		if (!kplugin_set_name(plugin, info->name)) {
-			if (error)
-				*error = KPLUGIN_ERROR_ATTR_NAME;
-			return BOOL_FALSE;
-		}
-	}
-
-	// ID
-	if (!faux_str_is_empty(info->id)) {
-		if (!kplugin_set_id(plugin, info->id)) {
-			if (error)
-				*error = KPLUGIN_ERROR_ATTR_ID;
-			return BOOL_FALSE;
-		}
-	}
-
-	// File
-	if (!faux_str_is_empty(info->file)) {
-		if (!kplugin_set_file(plugin, info->file)) {
-			if (error)
-				*error = KPLUGIN_ERROR_ATTR_FILE;
-			return BOOL_FALSE;
-		}
-	}
-
-	// Global
-	if (!faux_str_is_empty(info->global)) {
-		bool_t b = BOOL_FALSE;
-		if (!faux_conv_str2bool(info->global, &b) ||
-			!kplugin_set_global(plugin, b)) {
-			if (error)
-				*error = KPLUGIN_ERROR_ATTR_GLOBAL;
-			return BOOL_FALSE;
-		}
-	}
-
-	// Conf
-	if (!faux_str_is_empty(info->conf)) {
-		if (!kplugin_set_conf(plugin, info->conf)) {
-			if (error)
-				*error = KPLUGIN_ERROR_ATTR_CONF;
-			return BOOL_FALSE;
-		}
-	}
-
-	return BOOL_TRUE;
-}
-
-
-kplugin_t *kplugin_from_iplugin(iplugin_t *iplugin, faux_error_t *error_stack)
-{
-	kplugin_t *kplugin = NULL;
-	kplugin_error_e kplugin_error = KPLUGIN_ERROR_OK;
-
-	kplugin = kplugin_new(iplugin, &kplugin_error);
-	if (!kplugin) {
-		faux_error_sprintf(error_stack, "PLUGIN \"%s\": %s",
-			iplugin->name ? iplugin->name : "(null)",
-			kplugin_strerror(kplugin_error));
-		return NULL;
-	}
-
-	return kplugin;
-}
-
-
 bool_t kplugin_load(kplugin_t *plugin)
 {
 	char *file_name = NULL;

+ 83 - 0
klish/kscheme/kplugin_parse.c

@@ -0,0 +1,83 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <dlfcn.h>
+
+#include <faux/str.h>
+#include <faux/list.h>
+#include <faux/conv.h>
+#include <faux/error.h>
+#include <klish/khelper.h>
+#include <klish/iplugin.h>
+#include <klish/kplugin.h>
+#include <klish/ksym.h>
+
+#define TAG "PLUGIN"
+
+
+bool_t kplugin_parse(kplugin_t *plugin, const iplugin_t *info, faux_error_t *error)
+{
+	bool_t retcode = BOOL_TRUE;
+
+	// ID
+	if (!faux_str_is_empty(info->id)) {
+		if (!kplugin_set_id(plugin, info->id)) {
+			faux_error_add(error, TAG": Illegal 'id' attribute");
+			retcode = BOOL_FALSE;
+		}
+	}
+
+	// File
+	if (!faux_str_is_empty(info->file)) {
+		if (!kplugin_set_file(plugin, info->file)) {
+			faux_error_add(error, TAG": Illegal 'file' attribute");
+			retcode = BOOL_FALSE;
+		}
+	}
+
+	// Global
+	if (!faux_str_is_empty(info->global)) {
+		bool_t b = BOOL_FALSE;
+		if (!faux_conv_str2bool(info->global, &b) ||
+			!kplugin_set_global(plugin, b)) {
+			faux_error_add(error, TAG": Illegal 'global' attribute");
+			retcode = BOOL_FALSE;
+		}
+	}
+
+	// Conf
+	if (!faux_str_is_empty(info->conf)) {
+		if (!kplugin_set_conf(plugin, info->conf)) {
+			faux_error_add(error, TAG": Illegal 'conf' attribute");
+			retcode = BOOL_FALSE;
+		}
+	}
+
+	return retcode;
+}
+
+
+kplugin_t *kplugin_from_iplugin(iplugin_t *iplugin, faux_error_t *error)
+{
+	kplugin_t *kplugin = NULL;
+
+	// Name [mandatory]
+	if (faux_str_is_empty(iplugin->name))
+		return NULL;
+
+	kplugin = kplugin_new(iplugin->name);
+	if (!kplugin) {
+		faux_error_sprintf(error, TAG" \"%s\": Can't create object",
+			iplugin->name);
+		return NULL;
+	}
+
+	if (!kplugin_parse(kplugin, iplugin, error)) {
+		kplugin_free(kplugin);
+		return NULL;
+	}
+
+	return kplugin;
+}

+ 2 - 187
klish/kscheme/kscheme.c

@@ -39,17 +39,14 @@ KADD_NESTED(scheme, view);
 KFIND_NESTED(scheme, view);
 
 
-kscheme_t *kscheme_new(kscheme_error_e *error)
+kscheme_t *kscheme_new(void)
 {
 	kscheme_t *scheme = NULL;
 
 	scheme = faux_zmalloc(sizeof(*scheme));
 	assert(scheme);
-	if (!scheme) {
-		if (error)
-			*error = KSCHEME_ERROR_ALLOC;
+	if (!scheme)
 		return NULL;
-	}
 
 	// PLUGIN list
 	scheme->plugins = faux_list_new(FAUX_LIST_SORTED, FAUX_LIST_UNIQUE,
@@ -83,185 +80,3 @@ void kscheme_free(kscheme_t *scheme)
 	faux_list_free(scheme->views);
 	faux_free(scheme);
 }
-
-
-const char *kscheme_strerror(kscheme_error_e error)
-{
-	const char *str = NULL;
-
-	switch (error) {
-	case KSCHEME_ERROR_OK:
-		str = "Ok";
-		break;
-	case KSCHEME_ERROR_INTERNAL:
-		str = "Internal error";
-		break;
-	case KVIEW_ERROR_ALLOC:
-		str = "Memory allocation error";
-		break;
-	default:
-		str = "Unknown error";
-		break;
-	}
-
-	return str;
-}
-
-
-bool_t kscheme_nested_from_ischeme(kscheme_t *kscheme, ischeme_t *ischeme,
-	faux_error_t *error_stack)
-{
-	bool_t retval = BOOL_TRUE;
-
-	if (!kscheme || !ischeme) {
-		faux_error_add(error_stack,
-			kscheme_strerror(KSCHEME_ERROR_INTERNAL));
-		return BOOL_FALSE;
-	}
-
-	// PLUGIN list
-	if (ischeme->plugins) {
-		iplugin_t **p_iplugin = NULL;
-		for (p_iplugin = *ischeme->plugins; *p_iplugin; p_iplugin++) {
-			kplugin_t *kplugin = NULL;
-			iplugin_t *iplugin = *p_iplugin;
-
-			kplugin = kplugin_from_iplugin(iplugin, error_stack);
-			if (!kplugin) {
-				retval = BOOL_FALSE; // Don't stop
-				continue;
-			}
-			if (!kscheme_add_plugin(kscheme, kplugin)) {
-				// Search for PLUGIN duplicates
-				if (kscheme_find_plugin(kscheme,
-					kplugin_name(kplugin))) {
-					faux_error_sprintf(error_stack,
-						"SCHEME: "
-						"Can't add duplicate PLUGIN "
-						"\"%s\"",
-						kplugin_name(kplugin));
-				} else {
-					faux_error_sprintf(error_stack,
-						"SCHEME: "
-						"Can't add PLUGIN \"%s\"",
-						kplugin_name(kplugin));
-				}
-				kplugin_free(kplugin);
-				retval = BOOL_FALSE;
-			}
-		}
-	}
-
-	// PTYPE list
-	if (ischeme->ptypes) {
-		iptype_t **p_iptype = NULL;
-		for (p_iptype = *ischeme->ptypes; *p_iptype; p_iptype++) {
-			kptype_t *kptype = NULL;
-			iptype_t *iptype = *p_iptype;
-
-			kptype = kptype_from_iptype(iptype, error_stack);
-			if (!kptype) {
-				retval = BOOL_FALSE; // Don't stop
-				continue;
-			}
-			if (!kscheme_add_ptype(kscheme, kptype)) {
-				// Search for PTYPE duplicates
-				if (kscheme_find_ptype(kscheme,
-					kptype_name(kptype))) {
-					faux_error_sprintf(error_stack,
-						"SCHEME: "
-						"Can't add duplicate PTYPE "
-						"\"%s\"",
-						kptype_name(kptype));
-				} else {
-					faux_error_sprintf(error_stack,
-						"SCHEME: "
-						"Can't add PTYPE \"%s\"",
-						kptype_name(kptype));
-				}
-				kptype_free(kptype);
-				retval = BOOL_FALSE;
-			}
-		}
-	}
-
-	// VIEW list
-	// VIEW entries can be duplicate. Duplicated entries will add nested
-	// elements to existent VIEW. Also it can overwrite VIEW attributes.
-	// So there is no special rule which attribute value will be "on top".
-	// It's a random. Technically later VIEW entries will rewrite previous
-	// values.
-	if (ischeme->views) {
-		iview_t **p_iview = NULL;
-		for (p_iview = *ischeme->views; *p_iview; p_iview++) {
-			kview_t *kview = NULL;
-			iview_t *iview = *p_iview;
-			const char *view_name = iview->name;
-
-			if (view_name)
-				kview = kscheme_find_view(kscheme, view_name);
-
-			// VIEW already exists
-			if (kview) {
-				kview_error_e kview_error = KVIEW_ERROR_OK;
-				if (!kview_parse(kview, iview, &kview_error)) {
-					faux_error_sprintf(error_stack,
-						"VIEW \"%s\": %s",
-						iview->name ? iview->name : "(null)",
-						kview_strerror(kview_error));
-					retval = BOOL_FALSE;
-					continue;
-				}
-				if (!kview_nested_from_iview(kview, iview,
-					error_stack)) {
-					retval = BOOL_FALSE;
-					continue;
-				}
-				continue;
-			}
-
-			// New VIEW
-			kview = kview_from_iview(iview, error_stack);
-			if (!kview) {
-				retval = BOOL_FALSE;
-				continue;
-			}
-			if (!kscheme_add_view(kscheme, kview)) {
-				faux_error_sprintf(error_stack,
-					"SCHEME: "
-					"Can't add VIEW \"%s\"",
-					kview_name(kview));
-				kview_free(kview);
-				retval = BOOL_FALSE;
-				continue;
-			}
-		}
-	}
-
-	if (!retval)
-		faux_error_sprintf(error_stack, "SCHEME: Illegal nested elements");
-
-	return retval;
-}
-
-
-kscheme_t *kscheme_from_ischeme(ischeme_t *ischeme, faux_error_t *error_stack)
-{
-	kscheme_t *kscheme = NULL;
-	kscheme_error_e kscheme_error = KSCHEME_ERROR_OK;
-
-	kscheme = kscheme_new(&kscheme_error);
-	if (!kscheme) {
-		faux_error_sprintf(error_stack, "SCHEME: %s",
-			kscheme_strerror(kscheme_error));
-		return NULL;
-	}
-
-	// Parse nested elements
-	if (!kscheme_nested_from_ischeme(kscheme, ischeme, error_stack)) {
-		kscheme_free(kscheme);
-		return NULL;
-	}
-
-	return kscheme;
-}

+ 159 - 0
klish/kscheme/kscheme_parse.c

@@ -0,0 +1,159 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <faux/str.h>
+#include <faux/list.h>
+#include <klish/khelper.h>
+#include <klish/ischeme.h>
+#include <klish/kplugin.h>
+#include <klish/kptype.h>
+#include <klish/kview.h>
+#include <klish/kscheme.h>
+
+#define TAG "SCHEME"
+
+
+bool_t kscheme_nested_from_ischeme(kscheme_t *kscheme, ischeme_t *ischeme,
+	faux_error_t *error)
+{
+	bool_t retval = BOOL_TRUE;
+
+	if (!kscheme || !ischeme) {
+		faux_error_add(error, TAG": Internal error");
+		return BOOL_FALSE;
+	}
+
+	// PLUGIN list
+	if (ischeme->plugins) {
+		iplugin_t **p_iplugin = NULL;
+		for (p_iplugin = *ischeme->plugins; *p_iplugin; p_iplugin++) {
+			kplugin_t *kplugin = NULL;
+			iplugin_t *iplugin = *p_iplugin;
+
+			kplugin = kplugin_from_iplugin(iplugin, error);
+			if (!kplugin) {
+				retval = BOOL_FALSE; // Don't stop
+				continue;
+			}
+			if (!kscheme_add_plugin(kscheme, kplugin)) {
+				// Search for PLUGIN duplicates
+				if (kscheme_find_plugin(kscheme,
+					kplugin_name(kplugin))) {
+					faux_error_sprintf(error,
+						TAG": Can't add duplicate PLUGIN "
+						"\"%s\"", kplugin_name(kplugin));
+				} else {
+					faux_error_sprintf(error,
+						TAG": Can't add PLUGIN \"%s\"",
+						kplugin_name(kplugin));
+				}
+				kplugin_free(kplugin);
+				retval = BOOL_FALSE;
+			}
+		}
+	}
+
+	// PTYPE list
+	if (ischeme->ptypes) {
+		iptype_t **p_iptype = NULL;
+		for (p_iptype = *ischeme->ptypes; *p_iptype; p_iptype++) {
+			kptype_t *kptype = NULL;
+			iptype_t *iptype = *p_iptype;
+
+			kptype = kptype_from_iptype(iptype, error);
+			if (!kptype) {
+				retval = BOOL_FALSE; // Don't stop
+				continue;
+			}
+			if (!kscheme_add_ptype(kscheme, kptype)) {
+				// Search for PTYPE duplicates
+				if (kscheme_find_ptype(kscheme,
+					kptype_name(kptype))) {
+					faux_error_sprintf(error,
+						TAG": Can't add duplicate PTYPE "
+						"\"%s\"", kptype_name(kptype));
+				} else {
+					faux_error_sprintf(error,
+						TAG": Can't add PTYPE \"%s\"",
+						kptype_name(kptype));
+				}
+				kptype_free(kptype);
+				retval = BOOL_FALSE;
+			}
+		}
+	}
+
+	// VIEW list
+	// VIEW entries can be duplicate. Duplicated entries will add nested
+	// elements to existent VIEW. Also it can overwrite VIEW attributes.
+	// So there is no special rule which attribute value will be "on top".
+	// It's a random. Technically later VIEW entries will rewrite previous
+	// values.
+	if (ischeme->views) {
+		iview_t **p_iview = NULL;
+		for (p_iview = *ischeme->views; *p_iview; p_iview++) {
+			kview_t *kview = NULL;
+			iview_t *iview = *p_iview;
+			const char *view_name = iview->name;
+
+			if (view_name)
+				kview = kscheme_find_view(kscheme, view_name);
+
+			// VIEW already exists
+			if (kview) {
+				if (!kview_parse(kview, iview, error)) {
+					retval = BOOL_FALSE;
+					continue;
+				}
+				if (!kview_nested_from_iview(kview, iview,
+					error)) {
+					retval = BOOL_FALSE;
+					continue;
+				}
+				continue;
+			}
+
+			// New VIEW
+			kview = kview_from_iview(iview, error);
+			if (!kview) {
+				retval = BOOL_FALSE;
+				continue;
+			}
+			if (!kscheme_add_view(kscheme, kview)) {
+				faux_error_sprintf(error,
+					TAG": Can't add VIEW \"%s\"",
+					kview_name(kview));
+				kview_free(kview);
+				retval = BOOL_FALSE;
+				continue;
+			}
+		}
+	}
+
+	if (!retval)
+		faux_error_sprintf(error, TAG": Illegal nested elements");
+
+	return retval;
+}
+
+
+kscheme_t *kscheme_from_ischeme(ischeme_t *ischeme, faux_error_t *error)
+{
+	kscheme_t *kscheme = NULL;
+
+	kscheme = kscheme_new();
+	if (!kscheme) {
+		faux_error_sprintf(error, TAG": Can't create object");
+		return NULL;
+	}
+
+	// Parse nested elements
+	if (!kscheme_nested_from_ischeme(kscheme, ischeme, error)) {
+		kscheme_free(kscheme);
+		return NULL;
+	}
+
+	return kscheme;
+}

+ 5 - 41
klish/kscheme/ksym.c

@@ -28,39 +28,26 @@ KGET(sym, const void *, fn);
 KSET(sym, const void *, fn);
 
 
-static ksym_t *ksym_new_empty(void)
+ksym_t *ksym_new(const char *name)
 {
 	ksym_t *sym = NULL;
 
+	if (faux_str_is_empty(name))
+		return NULL;
+
 	sym = faux_zmalloc(sizeof(*sym));
 	assert(sym);
 	if (!sym)
 		return NULL;
 
 	// Initialize
-	sym->name = NULL;
+	sym->name = faux_str_dup(name);
 	sym->fn = NULL;
 
 	return sym;
 }
 
 
-ksym_t *ksym_new(ksym_error_e *error)
-{
-	ksym_t *sym = NULL;
-
-	sym = ksym_new_empty();
-	assert(sym);
-	if (!sym) {
-		if (error)
-			*error = KSYM_ERROR_ALLOC;
-		return NULL;
-	}
-
-	return sym;
-}
-
-
 void ksym_free(ksym_t *sym)
 {
 	if (!sym)
@@ -70,26 +57,3 @@ void ksym_free(ksym_t *sym)
 
 	faux_free(sym);
 }
-
-
-const char *ksym_strerror(ksym_error_e error)
-{
-	const char *str = NULL;
-
-	switch (error) {
-	case KSYM_ERROR_OK:
-		str = "Ok";
-		break;
-	case KSYM_ERROR_INTERNAL:
-		str = "Internal error";
-		break;
-	case KSYM_ERROR_ALLOC:
-		str = "Memory allocation error";
-		break;
-	default:
-		str = "Unknown error";
-		break;
-	}
-
-	return str;
-}

+ 5 - 148
klish/kscheme/kview.c

@@ -20,7 +20,6 @@ struct kview_s {
 
 // Name
 KGET_STR(view, name);
-KSET_STR_ONCE(view, name);
 
 // COMMAND list
 KCMP_NESTED(view, command, name);
@@ -29,17 +28,20 @@ KADD_NESTED(view, command);
 KFIND_NESTED(view, command);
 
 
-static kview_t *kview_new_empty(void)
+kview_t *kview_new(const char *name)
 {
 	kview_t *view = NULL;
 
+	if (faux_str_is_empty(name))
+		return NULL;
+
 	view = faux_zmalloc(sizeof(*view));
 	assert(view);
 	if (!view)
 		return NULL;
 
 	// Initialize
-	view->name = NULL;
+	view->name = faux_str_dup(name);
 
 	view->commands = faux_list_new(FAUX_LIST_SORTED, FAUX_LIST_UNIQUE,
 		kview_command_compare, kview_command_kcompare,
@@ -50,30 +52,6 @@ static kview_t *kview_new_empty(void)
 }
 
 
-kview_t *kview_new(const iview_t *info, kview_error_e *error)
-{
-	kview_t *view = NULL;
-
-	view = kview_new_empty();
-	assert(view);
-	if (!view) {
-		if (error)
-			*error = KVIEW_ERROR_ALLOC;
-		return NULL;
-	}
-
-	if (!info)
-		return view;
-
-	if (!kview_parse(view, info, error)) {
-		kview_free(view);
-		return NULL;
-	}
-
-	return view;
-}
-
-
 void kview_free(kview_t *view)
 {
 	if (!view)
@@ -84,124 +62,3 @@ void kview_free(kview_t *view)
 
 	faux_free(view);
 }
-
-
-const char *kview_strerror(kview_error_e error)
-{
-	const char *str = NULL;
-
-	switch (error) {
-	case KVIEW_ERROR_OK:
-		str = "Ok";
-		break;
-	case KVIEW_ERROR_INTERNAL:
-		str = "Internal error";
-		break;
-	case KVIEW_ERROR_ALLOC:
-		str = "Memory allocation error";
-		break;
-	case KVIEW_ERROR_ATTR_NAME:
-		str = "Illegal 'name' attribute";
-		break;
-	default:
-		str = "Unknown error";
-		break;
-	}
-
-	return str;
-}
-
-
-bool_t kview_parse(kview_t *view, const iview_t *info, kview_error_e *error)
-{
-	// Name [mandatory]
-	if (faux_str_is_empty(info->name)) {
-		if (error)
-			*error = KVIEW_ERROR_ATTR_NAME;
-		return BOOL_FALSE;
-	} else {
-		if (!kview_set_name(view, info->name)) {
-			if (error)
-				*error = KVIEW_ERROR_ATTR_NAME;
-			return BOOL_FALSE;
-		}
-	}
-
-	return BOOL_TRUE;
-}
-
-
-bool_t kview_nested_from_iview(kview_t *kview, iview_t *iview,
-	faux_error_t *error_stack)
-{
-	bool_t retval = BOOL_TRUE;
-
-	if (!kview || !iview) {
-		faux_error_add(error_stack,
-			kview_strerror(KVIEW_ERROR_INTERNAL));
-		return BOOL_FALSE;
-	}
-
-	// COMMAND list
-	if (iview->commands) {
-		icommand_t **p_icommand = NULL;
-		for (p_icommand = *iview->commands; *p_icommand; p_icommand++) {
-			kcommand_t *kcommand = NULL;
-			icommand_t *icommand = *p_icommand;
-			kcommand = kcommand_from_icommand(icommand, error_stack);
-			if (!kcommand) {
-				retval = BOOL_FALSE;
-				continue;
-			}
-			if (!kview_add_command(kview, kcommand)) {
-				// Search for COMMAND duplicates
-				if (kview_find_command(kview,
-					kcommand_name(kcommand))) {
-					faux_error_sprintf(error_stack,
-						"VIEW: "
-						"Can't add duplicate COMMAND "
-						"\"%s\"",
-						kcommand_name(kcommand));
-				} else {
-					faux_error_sprintf(error_stack,
-						"VIEW: "
-						"Can't add COMMAND \"%s\"",
-						kcommand_name(kcommand));
-				}
-				kcommand_free(kcommand);
-				retval = BOOL_FALSE;
-				continue;
-			}
-		}
-	}
-
-	if (!retval)
-		faux_error_sprintf(error_stack,
-			"VIEW \"%s\": Illegal nested elements",
-			kview_name(kview));
-
-	return retval;
-}
-
-
-kview_t *kview_from_iview(iview_t *iview, faux_error_t *error_stack)
-{
-	kview_t *kview = NULL;
-	kview_error_e kview_error = KVIEW_ERROR_OK;
-
-	kview = kview_new(iview, &kview_error);
-	if (!kview) {
-		faux_error_sprintf(error_stack, "VIEW \"%s\": %s",
-			iview->name ? iview->name : "(null)",
-			kview_strerror(kview_error));
-		return NULL;
-	}
-
-	// Parse nested elements
-	if (!kview_nested_from_iview(kview, iview, error_stack)) {
-		kview_free(kview);
-		return NULL;
-	}
-
-	return kview;
-}

+ 105 - 0
klish/kscheme/kview_parse.c

@@ -0,0 +1,105 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <faux/str.h>
+#include <faux/list.h>
+#include <faux/error.h>
+#include <klish/khelper.h>
+#include <klish/kcommand.h>
+#include <klish/kview.h>
+
+#define TAG "VIEW"
+
+
+bool_t kview_parse(kview_t *view, const iview_t *info, faux_error_t *error)
+{
+	bool_t retcode = BOOL_TRUE;
+
+	view = view;
+	info = info;
+	error = error;
+
+	return retcode;
+}
+
+
+bool_t kview_nested_from_iview(kview_t *kview, iview_t *iview,
+	faux_error_t *error)
+{
+	bool_t retval = BOOL_TRUE;
+
+	if (!kview || !iview) {
+		faux_error_add(error, TAG": Internal error");
+		return BOOL_FALSE;
+	}
+
+	// COMMAND list
+	if (iview->commands) {
+		icommand_t **p_icommand = NULL;
+		for (p_icommand = *iview->commands; *p_icommand; p_icommand++) {
+			kcommand_t *kcommand = NULL;
+			icommand_t *icommand = *p_icommand;
+			kcommand = kcommand_from_icommand(icommand, error);
+			if (!kcommand) {
+				retval = BOOL_FALSE;
+				continue;
+			}
+			if (!kview_add_command(kview, kcommand)) {
+				// Search for COMMAND duplicates
+				if (kview_find_command(kview,
+					kcommand_name(kcommand))) {
+					faux_error_sprintf(error,
+						TAG": Can't add duplicate COMMAND "
+						"\"%s\"", kcommand_name(kcommand));
+				} else {
+					faux_error_sprintf(error,
+						TAG": Can't add COMMAND \"%s\"",
+						kcommand_name(kcommand));
+				}
+				kcommand_free(kcommand);
+				retval = BOOL_FALSE;
+				continue;
+			}
+		}
+	}
+
+	if (!retval)
+		faux_error_sprintf(error, TAG" \"%s\": Illegal nested elements",
+			kview_name(kview));
+
+	return retval;
+}
+
+
+kview_t *kview_from_iview(iview_t *iview, faux_error_t *error)
+{
+	kview_t *kview = NULL;
+
+	// Name [mandatory]
+	if (faux_str_is_empty(iview->name)) {
+		faux_error_add(error, TAG": Empty 'name' attribute");
+		return NULL;
+	}
+
+	kview = kview_new(iview->name);
+	if (!kview) {
+		faux_error_sprintf(error, TAG": \"%s\": Can't create object",
+			iview->name);
+		return NULL;
+	}
+
+	if (!kview_parse(kview, iview, error)) {
+		kview_free(kview);
+		return NULL;
+	}
+
+	// Parse nested elements
+	if (!kview_nested_from_iview(kview, iview, error)) {
+		kview_free(kview);
+		return NULL;
+	}
+
+	return kview;
+}

+ 1 - 10
klish/ksym.h

@@ -6,26 +6,17 @@
 #ifndef _klish_ksym_h
 #define _klish_ksym_h
 
-#include <faux/error.h>
 
 typedef struct ksym_s ksym_t;
 
-typedef enum {
-	KSYM_ERROR_OK,
-	KSYM_ERROR_INTERNAL,
-	KSYM_ERROR_ALLOC,
-} ksym_error_e;
-
 
 C_DECL_BEGIN
 
 // ksym_t
-ksym_t *ksym_new(ksym_error_e *error);
+ksym_t *ksym_new(const char *name);
 void ksym_free(ksym_t *sym);
-const char *ksym_strerror(ksym_error_e error);
 
 const char *ksym_name(const ksym_t *sym);
-bool_t ksym_set_name(ksym_t *sym, const char *name);
 const void *ksym_fn(const ksym_t *sym);
 bool_t ksym_set_fn(ksym_t *sym, const void *fn);
 

+ 6 - 14
klish/kview.h

@@ -11,32 +11,24 @@
 #include <klish/iview.h>
 #include <klish/kcommand.h>
 
-typedef struct kview_s kview_t;
 
-typedef enum {
-	KVIEW_ERROR_OK,
-	KVIEW_ERROR_INTERNAL,
-	KVIEW_ERROR_ALLOC,
-	KVIEW_ERROR_ATTR_NAME,
-} kview_error_e;
+typedef struct kview_s kview_t;
 
 
 C_DECL_BEGIN
 
-// kview_t
-kview_t *kview_new(const iview_t *info, kview_error_e *error);
+kview_t *kview_new(const char *name);
 void kview_free(kview_t *view);
-bool_t kview_parse(kview_t *view, const iview_t *info, kview_error_e *error);
-const char *kview_strerror(kview_error_e error);
 
 const char *kview_name(const kview_t *view);
-bool_t kview_set_name(kview_t *view, const char *name);
 
 bool_t kview_add_command(kview_t *view, kcommand_t *command);
+kcommand_t *kview_find_command(const kview_t *view, const char *name);
 
+bool_t kview_parse(kview_t *view, const iview_t *info, faux_error_t *error);
 bool_t kview_nested_from_iview(kview_t *kview, iview_t *iview,
-	faux_error_t *error_stack);
-kview_t *kview_from_iview(iview_t *iview, faux_error_t *error_stack);
+	faux_error_t *error);
+kview_t *kview_from_iview(iview_t *iview, faux_error_t *error);
 
 C_DECL_END