=================================================================== RCS file: /cvs/mandoc/mdoc_argv.c,v retrieving revision 1.106 retrieving revision 1.110 diff -u -p -r1.106 -r1.110 --- mandoc/mdoc_argv.c 2015/10/15 22:45:43 1.106 +++ mandoc/mdoc_argv.c 2017/03/03 15:05:48 1.110 @@ -1,7 +1,7 @@ -/* $Id: mdoc_argv.c,v 1.106 2015/10/15 22:45:43 schwarze Exp $ */ +/* $Id: mdoc_argv.c,v 1.110 2017/03/03 15:05:48 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2012, 2014, 2015 Ingo Schwarze + * Copyright (c) 2012, 2014-2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,6 +29,7 @@ #include "roff.h" #include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" #include "libmdoc.h" #define MULTI_STEP 5 /* pre-allocate argument values */ @@ -423,8 +424,6 @@ mdoc_args(struct roff_man *mdoc, int line, int *pos, if (v == NULL) v = &v_local; fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok].flags; - if (tok != MDOC_It) - return args(mdoc, line, pos, buf, fl, v); /* * We know that we're in an `It', so it's reasonable to expect @@ -433,12 +432,15 @@ mdoc_args(struct roff_man *mdoc, int line, int *pos, * safe fall-back into the default behaviour. */ - for (n = mdoc->last; n; n = n->parent) - if (MDOC_Bl == n->tok) - if (LIST_column == n->norm->Bl.type) { + if (tok == MDOC_It) { + for (n = mdoc->last; n != NULL; n = n->parent) { + if (n->tok != MDOC_Bl) + continue; + if (n->norm->Bl.type == LIST_column) fl = ARGSFL_TABSEP; - break; - } + break; + } + } return args(mdoc, line, pos, buf, fl, v); } @@ -449,11 +451,10 @@ args(struct roff_man *mdoc, int line, int *pos, { char *p; int pairs; - enum margserr rc; if (buf[*pos] == '\0') { if (mdoc->flags & MDOC_PHRASELIT && - ! (mdoc->flags & MDOC_PPHRASE)) { + ! (mdoc->flags & MDOC_PHRASE)) { mandoc_msg(MANDOCERR_ARG_QUOTE, mdoc->parse, line, *pos, NULL); mdoc->flags &= ~MDOC_PHRASELIT; @@ -473,18 +474,41 @@ args(struct roff_man *mdoc, int line, int *pos, if (fl == ARGSFL_TABSEP) { if ((p = strchr(*v, '\t')) != NULL) { - /* Skip any blank characters after the tab. */ + + /* + * Words right before and right after + * tab characters are not parsed, + * unless there is a blank in between. + */ + + if (p > buf && p[-1] != ' ') + mdoc->flags |= MDOC_PHRASEQL; + if (p[1] != ' ') + mdoc->flags |= MDOC_PHRASEQN; + + /* + * One or more blanks after a tab cause + * one leading blank in the next column. + * So skip all but one of them. + */ + *pos += (int)(p - *v) + 1; - while (buf[*pos] == ' ') + while (buf[*pos] == ' ' && buf[*pos + 1] == ' ') (*pos)++; - rc = ARGS_PPHRASE; + + /* + * A tab at the end of an input line + * switches to the next column. + */ + + if (buf[*pos] == '\0' || buf[*pos + 1] == '\0') + mdoc->flags |= MDOC_PHRASEQN; } else { p = strchr(*v, '\0'); if (p[-1] == ' ') mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse, line, *pos, NULL); *pos += (int)(p - *v); - rc = ARGS_PEND; } /* Skip any trailing blank characters. */ @@ -493,7 +517,7 @@ args(struct roff_man *mdoc, int line, int *pos, p--; *p = '\0'; - return rc; + return ARGS_PHRASE; } /* @@ -504,11 +528,11 @@ args(struct roff_man *mdoc, int line, int *pos, * Whitespace is NOT involved in literal termination. */ - if (MDOC_PHRASELIT & mdoc->flags || '\"' == buf[*pos]) { - if ( ! (MDOC_PHRASELIT & mdoc->flags)) + if (mdoc->flags & MDOC_PHRASELIT || buf[*pos] == '\"') { + if ( ! (mdoc->flags & MDOC_PHRASELIT)) *v = &buf[++(*pos)]; - if (MDOC_PPHRASE & mdoc->flags) + if (mdoc->flags & MDOC_PHRASE) mdoc->flags |= MDOC_PHRASELIT; pairs = 0; @@ -528,11 +552,10 @@ args(struct roff_man *mdoc, int line, int *pos, if (pairs) buf[*pos - pairs] = '\0'; - if ('\0' == buf[*pos]) { - if (MDOC_PPHRASE & mdoc->flags) - return ARGS_QWORD; - mandoc_msg(MANDOCERR_ARG_QUOTE, - mdoc->parse, line, *pos, NULL); + if (buf[*pos] == '\0') { + if ( ! (mdoc->flags & MDOC_PHRASE)) + mandoc_msg(MANDOCERR_ARG_QUOTE, + mdoc->parse, line, *pos, NULL); return ARGS_QWORD; } @@ -555,6 +578,15 @@ args(struct roff_man *mdoc, int line, int *pos, p = &buf[*pos]; *v = mandoc_getarg(mdoc->parse, &p, line, pos); + /* + * After parsing the last word in this phrase, + * tell lookup() whether or not to interpret it. + */ + + if (*p == '\0' && mdoc->flags & MDOC_PHRASEQL) { + mdoc->flags &= ~MDOC_PHRASEQL; + mdoc->flags |= MDOC_PHRASEQF; + } return ARGS_WORD; }