aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-07-27 07:09:41 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-07-27 07:09:41 +0000
commit5a69146534b5566f6abd37c3808daff6754a4c79 (patch)
treeb2c876ce9e39f1569c42a5315bce4ddf44708b07
parent9b45ea9374c6a536a053d5e474e212ae1bf3b1e1 (diff)
downloadmandoc-5a69146534b5566f6abd37c3808daff6754a4c79.tar.gz
mandoc-5a69146534b5566f6abd37c3808daff6754a4c79.tar.zst
mandoc-5a69146534b5566f6abd37c3808daff6754a4c79.zip
First, roff_res() has no need to invoke ROFF_RERUN: since it's executed
before any other roff processing occurs, it's Ok to just let it do its thing and pass through. Also, make sure this function is ALWAYS called, not just when first_string is defined. Second, add a new function, roff_parsetext(), that post-processes non-macro lines. This, for the time being, amounts to detecting soft hyphens. This fixes a long-standing bug in that -man now has proper hyphen breaking!
-rw-r--r--mdoc.c7
-rw-r--r--roff.c63
2 files changed, 48 insertions, 22 deletions
diff --git a/mdoc.c b/mdoc.c
index 786ef67e..4d3c5fb6 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.191 2011/07/25 15:37:00 kristaps Exp $ */
+/* $Id: mdoc.c,v 1.192 2011/07/27 07:09:41 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
@@ -755,11 +755,6 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
ws = NULL;
for (c = end = buf + offs; *c; c++) {
switch (*c) {
- case '-':
- if (mandoc_hyph(buf + offs, c))
- *c = ASCII_HYPH;
- ws = NULL;
- break;
case ' ':
if (NULL == ws)
ws = c;
diff --git a/roff.c b/roff.c
index 498e85be..e287a80b 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.153 2011/07/26 14:24:06 kristaps Exp $ */
+/* $Id: roff.c,v 1.154 2011/07/27 07:09:41 kristaps Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -159,7 +159,7 @@ static const char *roff_getstrn(const struct roff *,
const char *, size_t);
static enum rofferr roff_line_ignore(ROFF_ARGS);
static enum rofferr roff_nr(ROFF_ARGS);
-static int roff_res(struct roff *,
+static void roff_res(struct roff *,
char **, size_t *, int, int);
static enum rofferr roff_rm(ROFF_ARGS);
static void roff_setstr(struct roff *,
@@ -400,8 +400,8 @@ roff_alloc(struct mparse *parse)
* `\*', e.g., `\*(ab'). These must be handled before the actual line
* is processed.
* This also checks the syntax of regular escapes.
-*/
-static int
+ */
+static void
roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
{
enum mandoc_esc esc;
@@ -413,8 +413,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
size_t nsz;
char *n;
- /* Search for a leading backslash and save a pointer to it. */
-
+again:
cp = *bufp + pos;
while (NULL != (cp = strchr(cp, '\\'))) {
stesc = cp++;
@@ -426,7 +425,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
*/
if ('\0' == *cp)
- return(1);
+ return;
if ('*' != *cp) {
res = cp;
@@ -437,7 +436,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
mandoc_msg
(MANDOCERR_BADESCAPE, r->parse,
ln, (int)(stesc - *bufp), NULL);
- continue;
+ return;
}
cp++;
@@ -450,7 +449,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
switch (*cp) {
case ('\0'):
- return(1);
+ return;
case ('('):
cp++;
maxl = 2;
@@ -473,7 +472,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
(MANDOCERR_BADESCAPE,
r->parse, ln,
(int)(stesc - *bufp), NULL);
- return(1);
+ return;
}
if (0 == maxl && ']' == *cp)
break;
@@ -495,6 +494,8 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
/* Replace the escape sequence by the string. */
+ pos += (stesc - *bufp);
+
nsz = *szp + strlen(res) + 1;
n = mandoc_malloc(nsz);
@@ -506,10 +507,41 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
*bufp = n;
*szp = nsz;
- return(0);
+ goto again;
+ }
+}
+
+/*
+ * Process text streams: convert all breakable hyphens into ASCII_HYPH.
+ */
+static enum rofferr
+roff_parsetext(char *p)
+{
+ size_t sz;
+ const char *start;
+ enum mandoc_esc esc;
+
+ start = p;
+
+ while ('\0' != *p) {
+ sz = strcspn(p, "-\\");
+ p += sz;
+
+ if ('\\' == *p) {
+ /* Skip over escapes. */
+ p++;
+ esc = mandoc_escape
+ ((const char **)&p, NULL, NULL);
+ if (ESCAPE_ERROR == esc)
+ break;
+ } else if ('-' == *p) {
+ if (mandoc_hyph(start, p))
+ *p = ASCII_HYPH;
+ p++;
+ }
}
- return(1);
+ return(ROFF_CONT);
}
enum rofferr
@@ -525,8 +557,7 @@ roff_parseln(struct roff *r, int ln, char **bufp,
* words to fill in.
*/
- if ( ! roff_res(r, bufp, szp, ln, pos))
- return(ROFF_REPARSE);
+ roff_res(r, bufp, szp, ln, pos);
ppos = pos;
ctl = mandoc_getcontrol(*bufp, &pos);
@@ -551,13 +582,13 @@ roff_parseln(struct roff *r, int ln, char **bufp,
return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
if (r->tbl)
return(tbl_read(r->tbl, ln, *bufp, pos));
- return(ROFF_CONT);
+ return(roff_parsetext(*bufp + pos));
} else if ( ! ctl) {
if (r->eqn)
return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
if (r->tbl)
return(tbl_read(r->tbl, ln, *bufp, pos));
- return(ROFF_CONT);
+ return(roff_parsetext(*bufp + pos));
} else if (r->eqn)
return(eqn_read(&r->eqn, ln, *bufp, ppos, offs));