*/
/*
- * functions for debug and error handling
+ * functions for debug and error handling, for internal use only
*/
#ifdef DEBUG
} \
} while (0)
-
static void *uci_malloc(struct uci_context *ctx, size_t size)
{
void *ptr;
-
+
ptr = malloc(size);
if (!ptr)
UCI_THROW(ctx, UCI_ERR_MEM);
return ptr;
}
+/*
+ * UCI wrapper for strdup, which uses exception handling
+ */
+static char *uci_strdup(struct uci_context *ctx, const char *str)
+{
+ char *ptr;
+
+ ptr = strdup(str);
+ if (!ptr)
+ UCI_THROW(ctx, UCI_ERR_MEM);
+
+ return ptr;
+}
+
#include "list.c"
#include "parse.c"
struct uci_context *uci_alloc(void)
{
struct uci_context *ctx;
-
+
ctx = (struct uci_context *) malloc(sizeof(struct uci_context));
memset(ctx, 0, sizeof(struct uci_context));
-
+ uci_list_init(&ctx->root);
+
return ctx;
}
err = UCI_ERR_INVAL;
else
err = ctx->errno;
-
+
if ((err < 0) || (err >= UCI_ERR_LAST))
err = UCI_ERR_UNKNOWN;
* uci_perror: Print the last uci error that occured
* @ctx: uci context
* @str: string to print before the error message
- */
+ */
extern void uci_perror(struct uci_context *ctx, const char *str);
/**
struct uci_context
{
struct uci_list root;
-
+
/* for error handling only */
struct uci_parse_context *pctx;
#define uci_list_entry(type, ptr) \
((struct uci_#type *) ((char *)(ptr) - offsetof(struct uci_#type,list)))
-
#define uci_foreach_entry(type, list, ptr) \
for(ptr = uci_list_entry(type, (list)->next); \
&ptr->list != list; \
* GNU General Public License for more details.
*/
+/* initialize a list head/item */
+static inline void uci_list_init(struct uci_list *ptr)
+{
+ ptr->prev = ptr;
+ ptr->next = ptr;
+}
+
+/* inserts a new list entry between two consecutive entries */
+static inline void __uci_list_add(struct uci_list *prev, struct uci_list *next, struct uci_list *ptr)
+{
+ prev->next = ptr;
+ next->prev = ptr;
+ ptr->prev = prev;
+ ptr->next = next;
+}
+
+/* inserts a new list entry at the tail of the list */
+static inline void uci_list_add(struct uci_list *head, struct uci_list *ptr)
+{
+ /* NB: head->prev points at the tail */
+ __uci_list_add(head->prev, head, ptr);
+}
+
+
+static struct uci_config *uci_add_file(struct uci_context *ctx, const char *name)
+{
+ struct uci_config *cfg;
+
+ cfg = (struct uci_config *) uci_malloc(ctx, sizeof(struct uci_config));
+ uci_list_init(&cfg->list);
+ uci_list_init(&cfg->sections);
+ cfg->name = uci_strdup(ctx, name);
+ uci_list_add(&ctx->root, &cfg->list);
+
+ return cfg;
+}