Browse Source

split off and compile file.c separately

Felix Fietkau 13 years ago
parent
commit
6ce771b109
7 changed files with 362 additions and 341 deletions
  1. 3 3
      Makefile
  2. 280 4
      file.c
  3. 1 1
      history.c
  4. 1 3
      libuci.c
  5. 4 78
      list.c
  6. 69 0
      uci_internal.h
  7. 4 252
      util.c

+ 3 - 3
Makefile

@@ -22,7 +22,7 @@ endef
 
 all: uci libuci.$(SHLIB_EXT) uci-static ucimap-example
 
-$(eval $(call add_dep,libuci,file.c history.c list.c util.c uci.h uci_config.h uci_internal.h))
+$(eval $(call add_dep,libuci,history.c list.c util.c uci.h uci_config.h uci_internal.h))
 $(eval $(call add_dep,ucimap,uci.h uci_config.h ucimap.h))
 
 cli.o: cli.c uci.h uci_config.h
@@ -56,12 +56,12 @@ uci-static: cli.o libuci.a
 
 ucimap.c: ucimap.h uci.h
 
-libuci.a: libuci.static.o ucimap.static.o
+libuci.a: libuci.static.o ucimap.static.o file.static.o
 	rm -f $@
 	$(AR) rc $@ $^
 	$(RANLIB) $@
 
-libuci.$(SHLIB_EXT): libuci.shared.o ucimap.shared.o
+libuci.$(SHLIB_EXT): libuci.shared.o file.shared.o ucimap.shared.o
 	$(LINK) $(SHLIB_FLAGS) -o $(SHLIB_FILE) $^ $(LIBS)
 	ln -sf $(SHLIB_FILE) $@
 

+ 280 - 4
file.c

@@ -25,8 +25,284 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <glob.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "uci.h"
+#include "uci_internal.h"
+
+#define LINEBUF	32
+#define LINEBUF_MAX	4096
+
+/*
+ * Fetch a new line from the input stream and resize buffer if necessary
+ */
+__private void uci_getln(struct uci_context *ctx, int offset)
+{
+	struct uci_parse_context *pctx = ctx->pctx;
+	char *p;
+	int ofs;
+
+	if (pctx->buf == NULL) {
+		pctx->buf = uci_malloc(ctx, LINEBUF);
+		pctx->bufsz = LINEBUF;
+	}
+
+	ofs = offset;
+	do {
+		p = &pctx->buf[ofs];
+		p[ofs] = 0;
+
+		p = fgets(p, pctx->bufsz - ofs, pctx->file);
+		if (!p || !*p)
+			return;
+
+		ofs += strlen(p);
+		if (pctx->buf[ofs - 1] == '\n') {
+			pctx->line++;
+			pctx->buf[ofs - 1] = 0;
+			return;
+		}
+
+		if (pctx->bufsz > LINEBUF_MAX/2)
+			uci_parse_error(ctx, p, "line too long");
+
+		pctx->bufsz *= 2;
+		pctx->buf = uci_realloc(ctx, pctx->buf, pctx->bufsz);
+	} while (1);
+}
+
+
+/*
+ * parse a character escaped by '\'
+ * returns true if the escaped character is to be parsed
+ * returns false if the escaped character is to be ignored
+ */
+static inline bool parse_backslash(struct uci_context *ctx, char **str)
+{
+	/* skip backslash */
+	*str += 1;
+
+	/* undecoded backslash at the end of line, fetch the next line */
+	if (!**str) {
+		*str += 1;
+		uci_getln(ctx, *str - ctx->pctx->buf);
+		return false;
+	}
+
+	/* FIXME: decode escaped char, necessary? */
+	return true;
+}
+
+/*
+ * move the string pointer forward until a non-whitespace character or
+ * EOL is reached
+ */
+static void skip_whitespace(struct uci_context *ctx, char **str)
+{
+restart:
+	while (**str && isspace(**str))
+		*str += 1;
+
+	if (**str == '\\') {
+		if (!parse_backslash(ctx, str))
+			goto restart;
+	}
+}
+
+static inline void addc(char **dest, char **src)
+{
+	**dest = **src;
+	*dest += 1;
+	*src += 1;
+}
+
+/*
+ * parse a double quoted string argument from the command line
+ */
+static void parse_double_quote(struct uci_context *ctx, char **str, char **target)
+{
+	char c;
+
+	/* skip quote character */
+	*str += 1;
+
+	while ((c = **str)) {
+		switch(c) {
+		case '"':
+			**target = 0;
+			*str += 1;
+			return;
+		case '\\':
+			if (!parse_backslash(ctx, str))
+				continue;
+			/* fall through */
+		default:
+			addc(target, str);
+			break;
+		}
+	}
+	uci_parse_error(ctx, *str, "unterminated \"");
+}
+
+/*
+ * parse a single quoted string argument from the command line
+ */
+static void parse_single_quote(struct uci_context *ctx, char **str, char **target)
+{
+	char c;
+	/* skip quote character */
+	*str += 1;
+
+	while ((c = **str)) {
+		switch(c) {
+		case '\'':
+			**target = 0;
+			*str += 1;
+			return;
+		default:
+			addc(target, str);
+		}
+	}
+	uci_parse_error(ctx, *str, "unterminated '");
+}
+
+/*
+ * parse a string from the command line and detect the quoting style
+ */
+static void parse_str(struct uci_context *ctx, char **str, char **target)
+{
+	bool next = true;
+	do {
+		switch(**str) {
+		case '\'':
+			parse_single_quote(ctx, str, target);
+			break;
+		case '"':
+			parse_double_quote(ctx, str, target);
+			break;
+		case '#':
+			**str = 0;
+			/* fall through */
+		case 0:
+			goto done;
+		case ';':
+			next = false;
+			goto done;
+		case '\\':
+			if (!parse_backslash(ctx, str))
+				continue;
+			/* fall through */
+		default:
+			addc(target, str);
+			break;
+		}
+	} while (**str && !isspace(**str));
+done:
+
+	/* 
+	 * if the string was unquoted and we've stopped at a whitespace
+	 * character, skip to the next one, because the whitespace will
+	 * be overwritten by a null byte here
+	 */
+	if (**str && next)
+		*str += 1;
+
+	/* terminate the parsed string */
+	**target = 0;
+}
+
+/*
+ * extract the next argument from the command line
+ */
+static char *next_arg(struct uci_context *ctx, char **str, bool required, bool name)
+{
+	char *val;
+	char *ptr;
+
+	val = ptr = *str;
+	skip_whitespace(ctx, str);
+	if(*str[0] == ';') {
+		*str[0] = 0;
+		*str += 1;
+	} else {
+		parse_str(ctx, str, &ptr);
+	}
+	if (!*val) {
+		if (required)
+			uci_parse_error(ctx, *str, "insufficient arguments");
+		goto done;
+	}
+
+	if (name && !uci_validate_name(val))
+		uci_parse_error(ctx, val, "invalid character in field");
+
+done:
+	return val;
+}
+
+int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char **result)
+{
+	UCI_HANDLE_ERR(ctx);
+	UCI_ASSERT(ctx, str != NULL);
+	UCI_ASSERT(ctx, result != NULL);
+
+	if (ctx->pctx && (ctx->pctx->file != stream))
+		uci_cleanup(ctx);
+
+	if (!ctx->pctx)
+		uci_alloc_parse_context(ctx);
+
+	ctx->pctx->file = stream;
+
+	if (!*str) {
+		uci_getln(ctx, 0);
+		*str = ctx->pctx->buf;
+	}
+
+	*result = next_arg(ctx, str, false, false);
+
+	return 0;
+}
+
+static int
+uci_fill_ptr(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_element *e, bool complete)
+{
+	UCI_ASSERT(ctx, ptr != NULL);
+	UCI_ASSERT(ctx, e != NULL);
+
+	memset(ptr, 0, sizeof(struct uci_ptr));
+	switch(e->type) {
+	case UCI_TYPE_OPTION:
+		ptr->o = uci_to_option(e);
+		goto fill_option;
+	case UCI_TYPE_SECTION:
+		ptr->s = uci_to_section(e);
+		goto fill_section;
+	case UCI_TYPE_PACKAGE:
+		ptr->p = uci_to_package(e);
+		goto fill_package;
+	default:
+		UCI_THROW(ctx, UCI_ERR_INVAL);
+	}
+
+fill_option:
+	ptr->option = ptr->o->e.name;
+	ptr->s = ptr->o->section;
+fill_section:
+	ptr->section = ptr->s->e.name;
+	ptr->p = ptr->s->package;
+fill_package:
+	ptr->package = ptr->p->e.name;
+
+	ptr->flags |= UCI_LOOKUP_DONE;
+	if (complete)
+		ptr->flags |= UCI_LOOKUP_COMPLETE;
+
+	return 0;
+}
+
 
-static struct uci_backend uci_file_backend;
 
 /*
  * verify that the end of the line or command is reached.
@@ -128,7 +404,7 @@ static void uci_parse_config(struct uci_context *ctx, char **str)
 		ctx->internal = !pctx->merge;
 		UCI_NESTED(uci_add_section, ctx, pctx->package, type, &pctx->section);
 	} else {
-		UCI_NESTED(uci_fill_ptr, ctx, &ptr, &pctx->package->e, false);
+		uci_fill_ptr(ctx, &ptr, &pctx->package->e, false);
 		e = uci_lookup_list(&pctx->package->sections, name);
 		if (e)
 			ptr.s = uci_to_section(e);
@@ -162,7 +438,7 @@ static void uci_parse_option(struct uci_context *ctx, char **str, bool list)
 	value = next_arg(ctx, str, false, false);
 	assert_eol(ctx, str);
 
-	UCI_NESTED(uci_fill_ptr, ctx, &ptr, &pctx->section->e, false);
+	uci_fill_ptr(ctx, &ptr, &pctx->section->e, false);
 	e = uci_lookup_list(&pctx->section->options, name);
 	if (e)
 		ptr.o = uci_to_option(e);
@@ -576,7 +852,7 @@ done:
 	return package;
 }
 
-static UCI_BACKEND(uci_file_backend, "file",
+__private UCI_BACKEND(uci_file_backend, "file",
 	.load = uci_file_load,
 	.commit = uci_file_commit,
 	.list_configs = uci_list_config_files,

+ 1 - 1
history.c

@@ -239,7 +239,7 @@ done:
 }
 
 /* returns the number of changes that were successfully parsed */
-static int uci_load_history(struct uci_context *ctx, struct uci_package *p, bool flush)
+__private int uci_load_history(struct uci_context *ctx, struct uci_package *p, bool flush)
 {
 	struct uci_element *e;
 	char *filename = NULL;

+ 1 - 3
libuci.c

@@ -40,14 +40,12 @@ static const char *uci_errstr[] = {
 	[UCI_ERR_UNKNOWN] =   "Unknown error",
 };
 
-static void uci_cleanup(struct uci_context *ctx);
 static void uci_unload_plugin(struct uci_context *ctx, struct uci_plugin *p);
 
 #include "uci_internal.h"
 #include "util.c"
 #include "list.c"
 #include "history.c"
-#include "file.c"
 
 /* exported functions */
 struct uci_context *uci_alloc_context(void)
@@ -117,7 +115,7 @@ int uci_set_confdir(struct uci_context *ctx, const char *dir)
 	return 0;
 }
 
-static void uci_cleanup(struct uci_context *ctx)
+__private void uci_cleanup(struct uci_context *ctx)
 {
 	struct uci_parse_context *pctx;
 

+ 4 - 78
list.c

@@ -12,43 +12,7 @@
  * 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 after a given entry */
-static inline void uci_list_insert(struct uci_list *list, struct uci_list *ptr)
-{
-	list->next->prev = ptr;
-	ptr->prev = list;
-	ptr->next = list->next;
-	list->next = ptr;
-}
-
-/* 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_insert(head->prev, ptr);
-}
-
-static inline void uci_list_del(struct uci_list *ptr)
-{
-	struct uci_list *next, *prev;
-
-	next = ptr->next;
-	prev = ptr->prev;
-
-	prev->next = next;
-	next->prev = prev;
-
-	uci_list_init(ptr);
-}
-
-static inline void uci_list_set_pos(struct uci_list *head, struct uci_list *ptr, int pos)
+static void uci_list_set_pos(struct uci_list *head, struct uci_list *ptr, int pos)
 {
 	struct uci_list *new_head = head;
 	struct uci_element *p = NULL;
@@ -164,7 +128,7 @@ uci_alloc_list(struct uci_section *s, const char *name)
 }
 
 /* fix up an unnamed section, e.g. after adding options to it */
-static void uci_fixup_section(struct uci_context *ctx, struct uci_section *s)
+__private void uci_fixup_section(struct uci_context *ctx, struct uci_section *s)
 {
 	unsigned int hash = ~0;
 	struct uci_element *e;
@@ -249,7 +213,7 @@ uci_alloc_package(struct uci_context *ctx, const char *name)
 	return p;
 }
 
-static void
+__private void
 uci_free_package(struct uci_package **package)
 {
 	struct uci_element *e, *tmp;
@@ -289,7 +253,7 @@ uci_free_any(struct uci_element **e)
 	*e = NULL;
 }
 
-static inline struct uci_element *
+__private struct uci_element *
 uci_lookup_list(struct uci_list *list, const char *name)
 {
 	struct uci_element *e;
@@ -437,44 +401,6 @@ notfound:
 	return 0;
 }
 
-int
-uci_fill_ptr(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_element *e, bool complete)
-{
-	UCI_HANDLE_ERR(ctx);
-	UCI_ASSERT(ctx, ptr != NULL);
-	UCI_ASSERT(ctx, e != NULL);
-
-	memset(ptr, 0, sizeof(struct uci_ptr));
-	switch(e->type) {
-	case UCI_TYPE_OPTION:
-		ptr->o = uci_to_option(e);
-		goto fill_option;
-	case UCI_TYPE_SECTION:
-		ptr->s = uci_to_section(e);
-		goto fill_section;
-	case UCI_TYPE_PACKAGE:
-		ptr->p = uci_to_package(e);
-		goto fill_package;
-	default:
-		UCI_THROW(ctx, UCI_ERR_INVAL);
-	}
-
-fill_option:
-	ptr->option = ptr->o->e.name;
-	ptr->s = ptr->o->section;
-fill_section:
-	ptr->section = ptr->s->e.name;
-	ptr->p = ptr->s->package;
-fill_package:
-	ptr->package = ptr->p->e.name;
-
-	ptr->flags |= UCI_LOOKUP_DONE;
-	if (complete)
-		ptr->flags |= UCI_LOOKUP_COMPLETE;
-
-	return 0;
-}
-
 static struct uci_element *
 expand_ptr(struct uci_context *ctx, struct uci_ptr *ptr, bool complete)
 {

+ 69 - 0
uci_internal.h

@@ -15,6 +15,7 @@
 #ifndef __UCI_INTERNAL_H
 #define __UCI_INTERNAL_H
 
+#define __private __attribute__((visibility("hidden")))
 #define __public
 #ifdef UCI_PLUGIN_SUPPORT
 #define __plugin extern
@@ -47,6 +48,74 @@ __plugin void uci_add_history(struct uci_context *ctx, struct uci_list *list, in
 __plugin void uci_free_history(struct uci_history *h);
 __plugin struct uci_package *uci_alloc_package(struct uci_context *ctx, const char *name);
 
+__private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, int pos, bool write, bool create);
+__private void uci_close_stream(FILE *stream);
+__private void uci_getln(struct uci_context *ctx, int offset);
+
+__private void uci_parse_error(struct uci_context *ctx, char *pos, char *reason);
+__private void uci_alloc_parse_context(struct uci_context *ctx);
+
+__private void uci_cleanup(struct uci_context *ctx);
+__private struct uci_element *uci_lookup_list(struct uci_list *list, const char *name);
+__private void uci_fixup_section(struct uci_context *ctx, struct uci_section *s);
+__private void uci_free_package(struct uci_package **package);
+
+__private int uci_load_history(struct uci_context *ctx, struct uci_package *p, bool flush);
+
+static inline bool uci_validate_package(const char *str)
+{
+	return uci_validate_str(str, false);
+}
+
+static inline bool uci_validate_type(const char *str)
+{
+	return uci_validate_str(str, false);
+}
+
+static inline bool uci_validate_name(const char *str)
+{
+	return uci_validate_str(str, true);
+}
+
+/* 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 after a given entry */
+static inline void uci_list_insert(struct uci_list *list, struct uci_list *ptr)
+{
+	list->next->prev = ptr;
+	ptr->prev = list;
+	ptr->next = list->next;
+	list->next = ptr;
+}
+
+/* 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_insert(head->prev, ptr);
+}
+
+static inline void uci_list_del(struct uci_list *ptr)
+{
+	struct uci_list *next, *prev;
+
+	next = ptr->next;
+	prev = ptr->prev;
+
+	prev->next = next;
+	next->prev = prev;
+
+	uci_list_init(ptr);
+}
+
+
+extern struct uci_backend uci_file_backend;
+
 #ifdef UCI_PLUGIN_SUPPORT
 /**
  * uci_add_backend: add an extra backend

+ 4 - 252
util.c

@@ -25,9 +25,6 @@
 #include <fcntl.h>
 #include <errno.h>
 
-#define LINEBUF	32
-#define LINEBUF_MAX	4096
-
 __plugin void *uci_malloc(struct uci_context *ctx, size_t size)
 {
 	void *ptr;
@@ -97,21 +94,6 @@ __plugin bool uci_validate_str(const char *str, bool name)
 	return true;
 }
 
-static inline bool uci_validate_package(const char *str)
-{
-	return uci_validate_str(str, false);
-}
-
-static inline bool uci_validate_type(const char *str)
-{
-	return uci_validate_str(str, false);
-}
-
-static inline bool uci_validate_name(const char *str)
-{
-	return uci_validate_str(str, true);
-}
-
 bool uci_validate_text(const char *str)
 {
 	while (*str) {
@@ -124,7 +106,7 @@ bool uci_validate_text(const char *str)
 	return true;
 }
 
-static void uci_alloc_parse_context(struct uci_context *ctx)
+__private void uci_alloc_parse_context(struct uci_context *ctx)
 {
 	ctx->pctx = (struct uci_parse_context *) uci_malloc(ctx, sizeof(struct uci_parse_context));
 }
@@ -188,7 +170,7 @@ error:
 }
 
 
-static void uci_parse_error(struct uci_context *ctx, char *pos, char *reason)
+__private void uci_parse_error(struct uci_context *ctx, char *pos, char *reason)
 {
 	struct uci_parse_context *pctx = ctx->pctx;
 
@@ -198,236 +180,6 @@ static void uci_parse_error(struct uci_context *ctx, char *pos, char *reason)
 }
 
 
-/*
- * Fetch a new line from the input stream and resize buffer if necessary
- */
-static void uci_getln(struct uci_context *ctx, int offset)
-{
-	struct uci_parse_context *pctx = ctx->pctx;
-	char *p;
-	int ofs;
-
-	if (pctx->buf == NULL) {
-		pctx->buf = uci_malloc(ctx, LINEBUF);
-		pctx->bufsz = LINEBUF;
-	}
-
-	ofs = offset;
-	do {
-		p = &pctx->buf[ofs];
-		p[ofs] = 0;
-
-		p = fgets(p, pctx->bufsz - ofs, pctx->file);
-		if (!p || !*p)
-			return;
-
-		ofs += strlen(p);
-		if (pctx->buf[ofs - 1] == '\n') {
-			pctx->line++;
-			pctx->buf[ofs - 1] = 0;
-			return;
-		}
-
-		if (pctx->bufsz > LINEBUF_MAX/2)
-			uci_parse_error(ctx, p, "line too long");
-
-		pctx->bufsz *= 2;
-		pctx->buf = uci_realloc(ctx, pctx->buf, pctx->bufsz);
-	} while (1);
-}
-
-/* 
- * parse a character escaped by '\'
- * returns true if the escaped character is to be parsed
- * returns false if the escaped character is to be ignored
- */
-static inline bool parse_backslash(struct uci_context *ctx, char **str)
-{
-	/* skip backslash */
-	*str += 1;
-
-	/* undecoded backslash at the end of line, fetch the next line */
-	if (!**str) {
-		*str += 1;
-		uci_getln(ctx, *str - ctx->pctx->buf);
-		return false;
-	}
-
-	/* FIXME: decode escaped char, necessary? */
-	return true;
-}
-
-/*
- * move the string pointer forward until a non-whitespace character or
- * EOL is reached
- */
-static void skip_whitespace(struct uci_context *ctx, char **str)
-{
-restart:
-	while (**str && isspace(**str))
-		*str += 1;
-
-	if (**str == '\\') {
-		if (!parse_backslash(ctx, str))
-			goto restart;
-	}
-}
-
-static inline void addc(char **dest, char **src)
-{
-	**dest = **src;
-	*dest += 1;
-	*src += 1;
-}
-
-/*
- * parse a double quoted string argument from the command line
- */
-static void parse_double_quote(struct uci_context *ctx, char **str, char **target)
-{
-	char c;
-
-	/* skip quote character */
-	*str += 1;
-
-	while ((c = **str)) {
-		switch(c) {
-		case '"':
-			**target = 0;
-			*str += 1;
-			return;
-		case '\\':
-			if (!parse_backslash(ctx, str))
-				continue;
-			/* fall through */
-		default:
-			addc(target, str);
-			break;
-		}
-	}
-	uci_parse_error(ctx, *str, "unterminated \"");
-}
-
-/*
- * parse a single quoted string argument from the command line
- */
-static void parse_single_quote(struct uci_context *ctx, char **str, char **target)
-{
-	char c;
-	/* skip quote character */
-	*str += 1;
-
-	while ((c = **str)) {
-		switch(c) {
-		case '\'':
-			**target = 0;
-			*str += 1;
-			return;
-		default:
-			addc(target, str);
-		}
-	}
-	uci_parse_error(ctx, *str, "unterminated '");
-}
-
-/*
- * parse a string from the command line and detect the quoting style
- */
-static void parse_str(struct uci_context *ctx, char **str, char **target)
-{
-	bool next = true;
-	do {
-		switch(**str) {
-		case '\'':
-			parse_single_quote(ctx, str, target);
-			break;
-		case '"':
-			parse_double_quote(ctx, str, target);
-			break;
-		case '#':
-			**str = 0;
-			/* fall through */
-		case 0:
-			goto done;
-		case ';':
-			next = false;
-			goto done;
-		case '\\':
-			if (!parse_backslash(ctx, str))
-				continue;
-			/* fall through */
-		default:
-			addc(target, str);
-			break;
-		}
-	} while (**str && !isspace(**str));
-done:
-
-	/* 
-	 * if the string was unquoted and we've stopped at a whitespace
-	 * character, skip to the next one, because the whitespace will
-	 * be overwritten by a null byte here
-	 */
-	if (**str && next)
-		*str += 1;
-
-	/* terminate the parsed string */
-	**target = 0;
-}
-
-/*
- * extract the next argument from the command line
- */
-static char *next_arg(struct uci_context *ctx, char **str, bool required, bool name)
-{
-	char *val;
-	char *ptr;
-
-	val = ptr = *str;
-	skip_whitespace(ctx, str);
-	if(*str[0] == ';') {
-		*str[0] = 0;
-		*str += 1;
-	} else {
-		parse_str(ctx, str, &ptr);
-	}
-	if (!*val) {
-		if (required)
-			uci_parse_error(ctx, *str, "insufficient arguments");
-		goto done;
-	}
-
-	if (name && !uci_validate_name(val))
-		uci_parse_error(ctx, val, "invalid character in field");
-
-done:
-	return val;
-}
-
-int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char **result)
-{
-	UCI_HANDLE_ERR(ctx);
-	UCI_ASSERT(ctx, str != NULL);
-	UCI_ASSERT(ctx, result != NULL);
-
-	if (ctx->pctx && (ctx->pctx->file != stream))
-		uci_cleanup(ctx);
-
-	if (!ctx->pctx)
-		uci_alloc_parse_context(ctx);
-
-	ctx->pctx->file = stream;
-
-	if (!*str) {
-		uci_getln(ctx, 0);
-		*str = ctx->pctx->buf;
-	}
-
-	*result = next_arg(ctx, str, false, false);
-
-	return 0;
-}
-
 
 /*
  * open a stream and go to the right position
@@ -435,7 +187,7 @@ int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char *
  * note: when opening for write and seeking to the beginning of
  * the stream, truncate the file
  */
-static FILE *uci_open_stream(struct uci_context *ctx, const char *filename, int pos, bool write, bool create)
+__private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, int pos, bool write, bool create)
 {
 	struct stat statbuf;
 	FILE *file = NULL;
@@ -473,7 +225,7 @@ done:
 	return file;
 }
 
-static void uci_close_stream(FILE *stream)
+__private void uci_close_stream(FILE *stream)
 {
 	int fd;