diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2015-10-26 15:57:59 +0100 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2015-10-26 15:57:59 +0100 |
commit | fbaac08df997df37f4ef4e13240ba5e9eabe74af (patch) | |
tree | bbe72e05c5cceec54a1c1363f4bb8918246dbe46 | |
parent | 2033efcc95c9bdb73a7db1fb6932f691bf6098ed (diff) | |
download | lr-fbaac08df997df37f4ef4e13240ba5e9eabe74af.tar.gz lr-fbaac08df997df37f4ef4e13240ba5e9eabe74af.tar.xz lr-fbaac08df997df37f4ef4e13240ba5e9eabe74af.zip |
parse "" as " inside strings
-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; } |