From: Takashi Iwai Date: Thu, 18 Aug 2005 14:53:39 +0000 (+0000) Subject: Clean up string parser X-Git-Tag: v1.0.10rc1~2 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=e120114bde308ff361b55599be1432af9fefdc01;p=alsa-lib.git Clean up string parser Clean up string parser routines. --- diff --git a/src/conf.c b/src/conf.c index 930815fa..73556cf7 100644 --- a/src/conf.c +++ b/src/conf.c @@ -671,29 +671,75 @@ static int get_quotedchar(input_t *input) } } +#define LOCAL_STR_BUFSIZE 64 +struct local_string { + char *buf; + size_t alloc; + size_t idx; + char tmpbuf[LOCAL_STR_BUFSIZE]; +}; + +static void init_local_string(struct local_string *s) +{ + memset(s, 0, sizeof(*s)); + s->buf = s->tmpbuf; + s->alloc = LOCAL_STR_BUFSIZE; +} + +static void free_local_string(struct local_string *s) +{ + if (s->buf != s->tmpbuf) + free(s->buf); +} + +static int add_char_local_string(struct local_string *s, int c) +{ + if (s->idx >= s->alloc) { + size_t nalloc = s->alloc * 2; + if (s->buf == s->tmpbuf) { + s->buf = malloc(nalloc); + if (s->buf == NULL) + return -ENOMEM; + memcpy(s->buf, s->tmpbuf, s->alloc); + } else { + char *ptr = realloc(s->buf, nalloc); + if (ptr == NULL) + return -ENOMEM; + s->buf = ptr; + } + s->alloc = nalloc; + } + s->buf[s->idx++] = c; + return 0; +} + +static char *copy_local_string(struct local_string *s) +{ + char *dst = malloc(s->idx + 1); + if (dst) { + memcpy(dst, s->buf, s->idx); + dst[s->idx] = '\0'; + } + return dst; +} + static int get_freestring(char **string, int id, input_t *input) { - const size_t bufsize = 64; - char _buf[bufsize]; - char *buf = _buf; - size_t alloc = bufsize; - size_t idx = 0; + struct local_string str; int c; + + init_local_string(&str); while (1) { c = get_char(input); if (c < 0) { if (c == LOCAL_UNEXPECTED_EOF) { - char *s = malloc(idx + 1); - if (!s) - return -ENOMEM; - memcpy(s, buf, idx); - s[idx] = '\0'; - *string = s; - c = 0; + *string = copy_local_string(&str); + if (! *string) + c = -ENOMEM; + else + c = 0; } - if (alloc > bufsize) - free(buf); - return c; + break; } switch (c) { case '.': @@ -715,95 +761,58 @@ static int get_freestring(char **string, int id, input_t *input) case '"': case '\\': case '#': - { - char *s = malloc(idx + 1); - if (!s) - return -ENOMEM; - unget_char(c, input); - memcpy(s, buf, idx); - s[idx] = '\0'; - *string = s; - if (alloc > bufsize) - free(buf); - return 0; - } + *string = copy_local_string(&str); + if (! *string) + c = -ENOMEM; + else { + unget_char(c, input); + c = 0; + } + goto _out; default: break; } - if (idx >= alloc) { - size_t old_alloc = alloc; - alloc *= 2; - if (old_alloc == bufsize) { - buf = malloc(alloc); - if (buf == NULL) - return -ENOMEM; - memcpy(buf, _buf, old_alloc); - } else { - char *ptr = realloc(buf, alloc); - if (ptr == NULL) { - free(buf); - return -ENOMEM; - } - buf = ptr; - } + if (add_char_local_string(&str, c) < 0) { + c = -ENOMEM; + break; } - buf[idx++] = c; } - return 0; + _out: + free_local_string(&str); + return c; } static int get_delimstring(char **string, int delim, input_t *input) { - const size_t bufsize = 64; - char _buf[bufsize]; - char *buf = _buf; - size_t alloc = bufsize; - size_t idx = 0; + struct local_string str; int c; + + init_local_string(&str); while (1) { c = get_char(input); if (c < 0) - return c; - switch (c) { - case '\\': + break; + if (c == '\\') { c = get_quotedchar(input); if (c < 0) - return c; + break; if (c == '\n') continue; + } else if (c == delim) { + *string = copy_local_string(&str); + if (! *string) + c = -ENOMEM; + else + c = 0; break; - default: - if (c == delim) { - char *s = malloc(idx + 1); - if (!s) - return -ENOMEM; - memcpy(s, buf, idx); - s[idx] = '\0'; - *string = s; - if (alloc > bufsize) - free(buf); - return 0; - } } - if (idx >= alloc) { - size_t old_alloc = alloc; - alloc *= 2; - if (old_alloc == bufsize) { - buf = malloc(alloc); - if (buf == NULL) - return -ENOMEM; - memcpy(buf, _buf, old_alloc); - } else { - char *ptr = realloc(buf, alloc); - if (ptr == NULL) { - free(buf); - return -ENOMEM; - } - buf = ptr; - } + if (add_char_local_string(&str, c) < 0) { + c = -ENOMEM; + break; } - buf[idx++] = c; } + free_local_string(&str); + return c; } /* Return 0 for free string, 1 for delimited string */ @@ -978,14 +987,14 @@ static int parse_array_defs(snd_config_t *farther, input_t *input, int skip, int static int parse_array_def(snd_config_t *father, input_t *input, int idx, int skip, int override) { - char static_id[12], *id = NULL; + char *id = NULL; int c; int err; snd_config_t *n = NULL; if (!skip) { + char static_id[12]; snprintf(static_id, sizeof(static_id), "%i", idx); - static_id[sizeof(static_id)-1] = '\0'; id = strdup(static_id); if (id == NULL) return -ENOMEM;