X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=util.c;h=ac7b8cb4c0e6f234f21e5d032c18c5d75289da04;hp=bc137c31788af588c0772b41a5a5a928ebe46764;hb=8dd3eb50025224bd2aa286c0e5c27d230efb7bde;hpb=cba72526bbd55932caf58bcb673b8fa8b1b98c89 diff --git a/util.c b/util.c index bc137c3..ac7b8cb 100644 --- a/util.c +++ b/util.c @@ -13,8 +13,8 @@ */ /* - * This file contains wrappers to standard functions, which - * throw exceptions upon failure. + * This file contains misc utility functions and wrappers to standard + * functions, which throw exceptions upon failure. */ #include #include @@ -27,7 +27,7 @@ #define LINEBUF 32 #define LINEBUF_MAX 4096 -static void *uci_malloc(struct uci_context *ctx, size_t size) +__plugin void *uci_malloc(struct uci_context *ctx, size_t size) { void *ptr; @@ -39,7 +39,7 @@ static void *uci_malloc(struct uci_context *ctx, size_t size) return ptr; } -static void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size) +__plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size) { ptr = realloc(ptr, size); if (!ptr) @@ -48,7 +48,7 @@ static void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size) return ptr; } -static char *uci_strdup(struct uci_context *ctx, const char *str) +__plugin char *uci_strdup(struct uci_context *ctx, const char *str) { char *ptr; @@ -59,6 +59,22 @@ static char *uci_strdup(struct uci_context *ctx, const char *str) return ptr; } +/* Based on an efficient hash function published by D. J. Bernstein */ +static unsigned int djbhash(unsigned int hash, char *str) +{ + int len = strlen(str); + int i; + + /* initial value */ + if (hash == ~0) + hash = 5381; + + for(i = 0; i < len; i++) { + hash = ((hash << 5) + hash) + str[i]; + } + return (hash & 0x7FFFFFFF); +} + /* * validate strings for names and types, reject special characters * for names, only alphanum and _ is allowed (shell compatibility) @@ -97,36 +113,35 @@ int uci_parse_tuple(struct uci_context *ctx, char *str, char **package, char **s UCI_HANDLE_ERR(ctx); UCI_ASSERT(ctx, str && package && section && option); - *package = strtok(str, "."); + last = strchr(str, '='); + if (last) { + *last = 0; + last++; + } + + *package = strsep(&str, "."); if (!*package || !uci_validate_name(*package)) goto error; - last = *package; - *section = strtok(NULL, "."); + *section = strsep(&str, "."); if (!*section) goto lastval; - last = *section; - *option = strtok(NULL, "."); + *option = strsep(&str, "."); if (!*option) goto lastval; - last = *option; - lastval: - last = strchr(last, '='); if (last) { if (!value) goto error; - *last = 0; - last++; if (!*last) goto error; *value = last; } - if (*section && !uci_validate_name(*section)) + if (*section && *section[0] && !uci_validate_name(*section)) goto error; if (*option && !uci_validate_name(*option)) goto error; @@ -356,7 +371,6 @@ int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char * if (ctx->pctx) { if (ctx->pctx->file != stream) { - ctx->internal = true; uci_cleanup(ctx); } } else {