+static char *next_arg(struct uci_context *ctx, bool required, bool name)
+{
+ struct uci_parse_context *pctx = ctx->pctx;
+ int val, ptr;
+
+ skip_whitespace(ctx);
+ val = ptr = pctx_pos(pctx);
+ if(pctx_cur_char(pctx) == ';') {
+ pctx_cur_char(pctx) = 0;
+ pctx->pos += 1;
+ } else {
+ parse_str(ctx, &ptr);
+ }
+ if (!pctx_char(pctx, val)) {
+ if (required)
+ uci_parse_error(ctx, "insufficient arguments");
+ goto done;
+ }
+
+ if (name && !uci_validate_name(pctx_str(pctx, val)))
+ uci_parse_error(ctx, "invalid character in name field");
+
+done:
+ return pctx_str(pctx, 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;
+ } else {
+ UCI_ASSERT(ctx, ctx->pctx->pos == *str - ctx->pctx->buf);
+ }
+
+ *result = next_arg(ctx, false, false);
+
+ return 0;
+}
+
+static int
+uci_fill_ptr(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_element *e)