summaryrefslogtreecommitdiffstats
path: root/mdoc_argv.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2010-05-14 12:55:22 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2010-05-14 12:55:22 +0000
commita833976284885670ea154f3f0327d83d71f658c2 (patch)
tree5c6ce0bc2300bb8ed3b801369a1876a34f74d3e7 /mdoc_argv.c
parent342d24c886a6b292ac067b3d34f489262f2fc6dc (diff)
downloadmandoc-a833976284885670ea154f3f0327d83d71f658c2.tar.gz
Proper handling of quoted tab-separated column lists.
Diffstat (limited to 'mdoc_argv.c')
-rw-r--r--mdoc_argv.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/mdoc_argv.c b/mdoc_argv.c
index ea6f8fc4..c9e2170b 100644
--- a/mdoc_argv.c
+++ b/mdoc_argv.c
@@ -398,8 +398,21 @@ args(struct mdoc *m, int line, int *pos,
assert(*pos);
assert(' ' != buf[*pos]);
- if ('\0' == buf[*pos])
+ if ('\0' == buf[*pos]) {
+ if (ARGS_PPHRASED & fl)
+ return(ARGS_EOLN);
+ /*
+ * If we're not in a partial phrase and the flag for
+ * being a phrase literal is still set, the punctuation
+ * is unterminated.
+ */
+ if (MDOC_PHRASELIT & m->flags)
+ if ( ! mdoc_pwarn(m, line, *pos, EQUOTTERM))
+ return(ARGS_ERROR);
+
+ m->flags &= ~MDOC_PHRASELIT;
return(ARGS_EOLN);
+ }
/*
* If the first character is a closing delimiter and we're to
@@ -410,7 +423,7 @@ args(struct mdoc *m, int line, int *pos,
if ((fl & ARGS_DELIM) && mdoc_iscdelim(buf[*pos]) > 1) {
for (i = *pos; buf[i]; ) {
- if ( mdoc_iscdelim(buf[i]) < 2)
+ if (mdoc_iscdelim(buf[i]) < 2)
break;
i++;
if ('\0' == buf[i] || ' ' != buf[i])
@@ -444,16 +457,18 @@ args(struct mdoc *m, int line, int *pos,
if (ARGS_TABSEP & fl) {
/* Scan ahead to tab (can't be escaped). */
p = strchr(*v, '\t');
+ pp = NULL;
/* Scan ahead to unescaped `Ta'. */
- for (pp = *v; ; pp++) {
- if (NULL == (pp = strstr(pp, "Ta")))
- break;
- if (pp > *v && ' ' != *(pp - 1))
- continue;
- if (' ' == *(pp + 2) || 0 == *(pp + 2))
- break;
- }
+ if ( ! (MDOC_PHRASELIT & m->flags))
+ for (pp = *v; ; pp++) {
+ if (NULL == (pp = strstr(pp, "Ta")))
+ break;
+ if (pp > *v && ' ' != *(pp - 1))
+ continue;
+ if (' ' == *(pp + 2) || 0 == *(pp + 2))
+ break;
+ }
/* By default, assume a phrase. */
rc = ARGS_PHRASE;
@@ -506,8 +521,12 @@ args(struct mdoc *m, int line, int *pos,
* Whitespace is NOT involved in literal termination.
*/
- if ('\"' == buf[*pos]) {
- *v = &buf[++(*pos)];
+ if (MDOC_PHRASELIT & m->flags || '\"' == buf[*pos]) {
+ if ( ! (MDOC_PHRASELIT & m->flags))
+ *v = &buf[++(*pos)];
+
+ if (ARGS_PPHRASED & fl)
+ m->flags |= MDOC_PHRASELIT;
for ( ; buf[*pos]; (*pos)++) {
if ('\"' != buf[*pos])
@@ -517,17 +536,18 @@ args(struct mdoc *m, int line, int *pos,
(*pos)++;
}
- if (0 == buf[*pos]) {
- if (ARGS_NOWARN & fl)
+ if ('\0' == buf[*pos]) {
+ if (ARGS_NOWARN & fl || ARGS_PPHRASED & fl)
return(ARGS_QWORD);
if ( ! mdoc_pwarn(m, line, *pos, EQUOTTERM))
return(ARGS_ERROR);
return(ARGS_QWORD);
}
- buf[(*pos)++] = 0;
+ m->flags &= ~MDOC_PHRASELIT;
+ buf[(*pos)++] = '\0';
- if (0 == buf[*pos])
+ if ('\0' == buf[*pos])
return(ARGS_QWORD);
while (' ' == buf[*pos])
@@ -549,15 +569,15 @@ args(struct mdoc *m, int line, int *pos,
if (' ' == buf[*pos] && '\\' != buf[*pos - 1])
break;
- if (0 == buf[*pos])
+ if ('\0' == buf[*pos])
return(ARGS_WORD);
- buf[(*pos)++] = 0;
+ buf[(*pos)++] = '\0';
while (' ' == buf[*pos])
(*pos)++;
- if (0 == buf[*pos] && ! (ARGS_NOWARN & fl))
+ if ('\0' == buf[*pos] && ! (ARGS_NOWARN & fl))
if ( ! mdoc_pwarn(m, line, *pos, ETAILWS))
return(ARGS_ERROR);