aboutsummaryrefslogtreecommitdiffstatshomepage
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
commitae7348914a6e3613b79a674a717da0186553c7e7 (patch)
tree9cd9a97ff1a8afe9a83e0353979e82e8abd30c9f /mdoc_argv.c
parent644e8f757e50094673a0aa3ee6e5c3528ffcdf47 (diff)
downloadmandoc-ae7348914a6e3613b79a674a717da0186553c7e7.tar.gz
mandoc-ae7348914a6e3613b79a674a717da0186553c7e7.tar.zst
mandoc-ae7348914a6e3613b79a674a717da0186553c7e7.zip
Proper handling of quoted tab-separated column lists.
Diffstat (limited to 'mdoc_argv.c')
-rw-r--r--mdoc_argv.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/mdoc_argv.c b/mdoc_argv.c
index 96ccef17..44b72071 100644
--- a/mdoc_argv.c
+++ b/mdoc_argv.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_argv.c,v 1.45 2010/05/09 21:06:50 kristaps Exp $ */
+/* $Id: mdoc_argv.c,v 1.46 2010/05/14 12:55:22 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -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);