mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
Clean up string parser
Clean up string parser routines.
This commit is contained in:
parent
f1acd7726c
commit
e120114bde
1 changed files with 94 additions and 85 deletions
179
src/conf.c
179
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)
|
static int get_freestring(char **string, int id, input_t *input)
|
||||||
{
|
{
|
||||||
const size_t bufsize = 64;
|
struct local_string str;
|
||||||
char _buf[bufsize];
|
|
||||||
char *buf = _buf;
|
|
||||||
size_t alloc = bufsize;
|
|
||||||
size_t idx = 0;
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
init_local_string(&str);
|
||||||
while (1) {
|
while (1) {
|
||||||
c = get_char(input);
|
c = get_char(input);
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
if (c == LOCAL_UNEXPECTED_EOF) {
|
if (c == LOCAL_UNEXPECTED_EOF) {
|
||||||
char *s = malloc(idx + 1);
|
*string = copy_local_string(&str);
|
||||||
if (!s)
|
if (! *string)
|
||||||
return -ENOMEM;
|
c = -ENOMEM;
|
||||||
memcpy(s, buf, idx);
|
else
|
||||||
s[idx] = '\0';
|
c = 0;
|
||||||
*string = s;
|
|
||||||
c = 0;
|
|
||||||
}
|
}
|
||||||
if (alloc > bufsize)
|
break;
|
||||||
free(buf);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '.':
|
case '.':
|
||||||
|
|
@ -715,95 +761,58 @@ static int get_freestring(char **string, int id, input_t *input)
|
||||||
case '"':
|
case '"':
|
||||||
case '\\':
|
case '\\':
|
||||||
case '#':
|
case '#':
|
||||||
{
|
*string = copy_local_string(&str);
|
||||||
char *s = malloc(idx + 1);
|
if (! *string)
|
||||||
if (!s)
|
c = -ENOMEM;
|
||||||
return -ENOMEM;
|
else {
|
||||||
unget_char(c, input);
|
unget_char(c, input);
|
||||||
memcpy(s, buf, idx);
|
c = 0;
|
||||||
s[idx] = '\0';
|
}
|
||||||
*string = s;
|
goto _out;
|
||||||
if (alloc > bufsize)
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idx >= alloc) {
|
if (add_char_local_string(&str, c) < 0) {
|
||||||
size_t old_alloc = alloc;
|
c = -ENOMEM;
|
||||||
alloc *= 2;
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
buf[idx++] = c;
|
|
||||||
}
|
}
|
||||||
return 0;
|
_out:
|
||||||
|
free_local_string(&str);
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_delimstring(char **string, int delim, input_t *input)
|
static int get_delimstring(char **string, int delim, input_t *input)
|
||||||
{
|
{
|
||||||
const size_t bufsize = 64;
|
struct local_string str;
|
||||||
char _buf[bufsize];
|
|
||||||
char *buf = _buf;
|
|
||||||
size_t alloc = bufsize;
|
|
||||||
size_t idx = 0;
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
init_local_string(&str);
|
||||||
while (1) {
|
while (1) {
|
||||||
c = get_char(input);
|
c = get_char(input);
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
return c;
|
break;
|
||||||
switch (c) {
|
if (c == '\\') {
|
||||||
case '\\':
|
|
||||||
c = get_quotedchar(input);
|
c = get_quotedchar(input);
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
return c;
|
break;
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
continue;
|
continue;
|
||||||
|
} else if (c == delim) {
|
||||||
|
*string = copy_local_string(&str);
|
||||||
|
if (! *string)
|
||||||
|
c = -ENOMEM;
|
||||||
|
else
|
||||||
|
c = 0;
|
||||||
break;
|
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) {
|
if (add_char_local_string(&str, c) < 0) {
|
||||||
size_t old_alloc = alloc;
|
c = -ENOMEM;
|
||||||
alloc *= 2;
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
buf[idx++] = c;
|
|
||||||
}
|
}
|
||||||
|
free_local_string(&str);
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 0 for free string, 1 for delimited string */
|
/* 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)
|
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 c;
|
||||||
int err;
|
int err;
|
||||||
snd_config_t *n = NULL;
|
snd_config_t *n = NULL;
|
||||||
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
|
char static_id[12];
|
||||||
snprintf(static_id, sizeof(static_id), "%i", idx);
|
snprintf(static_id, sizeof(static_id), "%i", idx);
|
||||||
static_id[sizeof(static_id)-1] = '\0';
|
|
||||||
id = strdup(static_id);
|
id = strdup(static_id);
|
||||||
if (id == NULL)
|
if (id == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue