improve the argument parser
authorFelix Fietkau <nbd@openwrt.org>
Mon, 4 Feb 2008 23:33:59 +0000 (00:33 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 4 Feb 2008 23:33:59 +0000 (00:33 +0100)
uci.h
util.c

diff --git a/uci.h b/uci.h
index 8a89b71b7a7cce2594586ba605d2b18d2a1ae443..9f03a6f811de2299b445fe84b5572e5d9d468fa8 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -263,10 +263,11 @@ extern int uci_revert(struct uci_context *ctx, struct uci_package **p, char *sec
 /**
  * uci_parse_argument: parse a shell-style argument, with an arbitrary quoting style
  * @ctx: uci context
- * @str: pointer to the input string (will be changed to the end of the parsed string)
+ * @stream: input stream
+ * @str: pointer to the current line (use NULL for parsing the next line)
  * @result: pointer for the result
  */
-extern int uci_parse_argument(struct uci_context *ctx, char **str, char **result);
+extern int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char **result);
 
 /* UCI data structures */
 enum uci_type {
diff --git a/util.c b/util.c
index 0ac33c76a15042ddcd364e0773a48aa8bc260d82..4713c74befe6eab5935c2d6be48033c95f64204a 100644 (file)
--- a/util.c
+++ b/util.c
@@ -146,10 +146,7 @@ static void uci_parse_error(struct uci_context *ctx, char *pos, char *reason)
        struct uci_parse_context *pctx = ctx->pctx;
 
        pctx->reason = reason;
-       if ((pos < pctx->buf) || (pos > pctx->buf + pctx->bufsz))
-               pctx->byte = 0;
-       else
-               pctx->byte = pos - pctx->buf;
+       pctx->byte = pos - pctx->buf;
        UCI_THROW(ctx, UCI_ERR_PARSE);
 }
 
@@ -351,13 +348,28 @@ done:
        return val;
 }
 
-int uci_parse_argument(struct uci_context *ctx, char **str, char **result)
+int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char **result)
 {
        UCI_HANDLE_ERR(ctx);
-       UCI_ASSERT(ctx, (str != NULL) && (*str != NULL));
+       UCI_ASSERT(ctx, str != NULL);
        UCI_ASSERT(ctx, result != NULL);
 
+       if (ctx->pctx) {
+               if (ctx->pctx->file != stream) {
+                       ctx->internal = true;
+                       uci_cleanup(ctx);
+               }
+       } else {
+               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;
 }