print the reason for parse errors in error messages
authorFelix Fietkau <nbd@openwrt.org>
Sun, 20 Jan 2008 18:39:47 +0000 (19:39 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 20 Jan 2008 18:39:47 +0000 (19:39 +0100)
libuci.c
parse.c
uci.h

index 262ca69..cb0bc36 100644 (file)
--- a/libuci.c
+++ b/libuci.c
@@ -116,7 +116,7 @@ void uci_perror(struct uci_context *ctx, const char *str)
        switch (err) {
        case UCI_ERR_PARSE:
                if (ctx->pctx) {
        switch (err) {
        case UCI_ERR_PARSE:
                if (ctx->pctx) {
-                       fprintf(stderr, "%s: %s at line %d, byte %d\n", str, uci_errstr[err], ctx->pctx->line, ctx->pctx->byte);
+                       fprintf(stderr, "%s: %s (%s) at line %d, byte %d\n", str, uci_errstr[err], (ctx->pctx->reason ? ctx->pctx->reason : "unknown"), ctx->pctx->line, ctx->pctx->byte);
                        break;
                }
                /* fall through */
                        break;
                }
                /* fall through */
diff --git a/parse.c b/parse.c
index 4c51715..31756d9 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -56,6 +56,7 @@ static void uci_getln(struct uci_context *ctx)
                }
 
                if (pctx->bufsz > LINEBUF_MAX/2) {
                }
 
                if (pctx->bufsz > LINEBUF_MAX/2) {
+                       pctx->reason = "line too long";
                        pctx->byte = LINEBUF_MAX;
                        UCI_THROW(ctx, UCI_ERR_PARSE);
                }
                        pctx->byte = LINEBUF_MAX;
                        UCI_THROW(ctx, UCI_ERR_PARSE);
                }
@@ -137,6 +138,7 @@ static void parse_double_quote(struct uci_context *ctx, char **str, char **targe
                        break;
                }
        }
                        break;
                }
        }
+       ctx->pctx->reason = "unterminated \"";
        ctx->pctx->byte = *str - ctx->pctx->buf;
        UCI_THROW(ctx, UCI_ERR_PARSE);
 }
        ctx->pctx->byte = *str - ctx->pctx->buf;
        UCI_THROW(ctx, UCI_ERR_PARSE);
 }
@@ -160,6 +162,7 @@ static void parse_single_quote(struct uci_context *ctx, char **str, char **targe
                        addc(target, str);
                }
        }
                        addc(target, str);
                }
        }
+       ctx->pctx->reason = "unterminated '";
        ctx->pctx->byte = *str - ctx->pctx->buf;
        UCI_THROW(ctx, UCI_ERR_PARSE);
 }
        ctx->pctx->byte = *str - ctx->pctx->buf;
        UCI_THROW(ctx, UCI_ERR_PARSE);
 }
@@ -213,6 +216,7 @@ static char *next_arg(struct uci_context *ctx, char **str, bool required)
        skip_whitespace(str);
        parse_str(ctx, str, &ptr);
        if (required && !*val) {
        skip_whitespace(str);
        parse_str(ctx, str, &ptr);
        if (required && !*val) {
+               ctx->pctx->reason = "insufficient arguments";
                ctx->pctx->byte = *str - ctx->pctx->buf;
                UCI_THROW(ctx, UCI_ERR_PARSE);
        }
                ctx->pctx->byte = *str - ctx->pctx->buf;
                UCI_THROW(ctx, UCI_ERR_PARSE);
        }
@@ -230,6 +234,7 @@ static void assert_eol(struct uci_context *ctx, char **str)
 
        tmp = next_arg(ctx, str, false);
        if (tmp && *tmp) {
 
        tmp = next_arg(ctx, str, false);
        if (tmp && *tmp) {
+               ctx->pctx->reason = "too many arguments";
                ctx->pctx->byte = tmp - ctx->pctx->buf;
                UCI_THROW(ctx, UCI_ERR_PARSE);
        }
                ctx->pctx->byte = tmp - ctx->pctx->buf;
                UCI_THROW(ctx, UCI_ERR_PARSE);
        }
@@ -242,16 +247,14 @@ static void uci_parse_config(struct uci_context *ctx, char **str)
 {
        char *type, *name;
 
 {
        char *type, *name;
 
+       /* command string null-terminated by strtok */
        *str += strlen(*str) + 1;
 
        *str += strlen(*str) + 1;
 
-       if (!*str) {
-               ctx->pctx->byte = *str - ctx->pctx->buf;
-               UCI_THROW(ctx, UCI_ERR_PARSE);
-       }
-
        type = next_arg(ctx, str, true);
        name = next_arg(ctx, str, false);
        assert_eol(ctx, str);
        type = next_arg(ctx, str, true);
        name = next_arg(ctx, str, false);
        assert_eol(ctx, str);
+
+       DPRINTF("Section<%s>: %s\n", type, name);
 }
 
 /*
 }
 
 /*
@@ -261,6 +264,7 @@ static void uci_parse_option(struct uci_context *ctx, char **str)
 {
        char *name, *value;
 
 {
        char *name, *value;
 
+       /* command string null-terminated by strtok */
        *str += strlen(*str) + 1;
 
        name = next_arg(ctx, str, true);
        *str += strlen(*str) + 1;
 
        name = next_arg(ctx, str, true);
@@ -295,6 +299,7 @@ static void uci_parse_line(struct uci_context *ctx)
                                        uci_parse_option(ctx, &word);
                                break;
                        default:
                                        uci_parse_option(ctx, &word);
                                break;
                        default:
+                               pctx->reason = "unterminated command";
                                pctx->byte = word - pctx->buf;
                                UCI_THROW(ctx, UCI_ERR_PARSE);
                                break;
                                pctx->byte = word - pctx->buf;
                                UCI_THROW(ctx, UCI_ERR_PARSE);
                                break;
diff --git a/uci.h b/uci.h
index 4706255..c558696 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -97,6 +97,7 @@ struct uci_parse_context
        struct uci_config *cfg;
        FILE *file;
        char *buf;
        struct uci_config *cfg;
        FILE *file;
        char *buf;
+       char *reason;
        int bufsz;
 };
 
        int bufsz;
 };