Clean up string parser

Clean up string parser routines.
This commit is contained in:
Takashi Iwai 2005-08-18 14:53:39 +00:00
parent f1acd7726c
commit e120114bde

View file

@ -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;