diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | lr.c | 22 |
2 files changed, 20 insertions, 4 deletions
diff --git a/README.md b/README.md index 9d0ae0b..2fc52c3 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Default: `n`. | =~ -- POSIX Extended Regular Expressions | =~~ -- case insensitive POSIX Extended Regular Expressions - <str> ::= " [^"]+ " + <str> ::= " ([^"] | "")+ " -- use "" for a single " inside " <typetest> ::= type == ( b | c | d | p | f | l ) diff --git a/lr.c b/lr.c index 82832de..16d7661 100644 --- a/lr.c +++ b/lr.c @@ -322,12 +322,28 @@ parse_type() static int parse_string(char **s) { + char *buf = 0; + size_t bufsiz = 0; + size_t len = 0; + if (*pos == '"') { pos++; - char *e = strchr(pos, '"'); - *s = strndup(pos, e - pos); - pos += e - pos + 1; + while (*pos != '"' || (*pos == '"' && *(pos+1) == '"')) { + if (len >= bufsiz) { + bufsiz = 2*bufsiz + 16; + buf = realloc(buf, bufsiz); + if (!buf) + parse_error("string too long"); + } + if (*pos == '"') + pos++; + buf[len++] = *pos++; + } + if (buf) + buf[len] = 0; + pos++; ws(); + *s = buf ? buf : (char *) ""; return 1; } |