summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--regress/usr.bin/mandoc/roff/esc/c_man.in19
-rw-r--r--regress/usr.bin/mandoc/roff/esc/c_man.out_ascii13
-rw-r--r--usr.bin/mandoc/man.c49
3 files changed, 60 insertions, 21 deletions
diff --git a/regress/usr.bin/mandoc/roff/esc/c_man.in b/regress/usr.bin/mandoc/roff/esc/c_man.in
index c530a4728fc..f6a5b0e5bb0 100644
--- a/regress/usr.bin/mandoc/roff/esc/c_man.in
+++ b/regress/usr.bin/mandoc/roff/esc/c_man.in
@@ -1,15 +1,18 @@
-.\" $OpenBSD: c_man.in,v 1.3 2017/07/04 14:53:27 schwarze Exp $
-.TH ESC-C_MAN 1 "December 2, 2014"
+.\" $OpenBSD: c_man.in,v 1.4 2018/08/25 12:28:52 schwarze Exp $
+.TH ESC-C_MAN 1 "August 25, 2018"
.SH NAME
esc-c_man \- the roff escape c sequence: remove trailing space
.SH DESCRIPTION
No space between "one" and "word":
one\c
word
+.PP
+The same in no-fill mode:
.nf
one\c
word
.fi
+.PP
Blank line after \ec:
one\c
@@ -19,4 +22,16 @@ one\c
word
.fi
+.PP
+In next-line element scope:
+.B
+one\c
+word
+.PP
+In next-line block scope:
+.TP
+one\c
+word
+list body
+.PP
final text
diff --git a/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii b/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii
index 9062c335ae2..a3a50889c45 100644
--- a/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii
+++ b/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii
@@ -7,12 +7,23 @@ NNAAMMEE
DDEESSCCRRIIPPTTIIOONN
No space between "one" and "word": oneword
+
+ The same in no-fill mode:
oneword
+
Blank line after \c: one word
one
word
+
+ In next-line element scope: oonneewwoorrdd
+
+ In next-line block scope:
+
+ oneword
+ list body
+
final text
-OpenBSD December 2, 2014 ESC-C_MAN(1)
+OpenBSD August 25, 2018 ESC-C_MAN(1)
diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c
index 770024800a5..7eb8458497d 100644
--- a/usr.bin/mandoc/man.c
+++ b/usr.bin/mandoc/man.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: man.c,v 1.126 2018/08/23 19:32:03 schwarze Exp $ */
+/* $OpenBSD: man.c,v 1.127 2018/08/25 12:28:52 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -33,7 +33,8 @@
#include "roff_int.h"
#include "libman.h"
-static void man_descope(struct roff_man *, int, int);
+static void man_descope(struct roff_man *, int, int, char *);
+static char *man_hasc(char *);
static int man_ptext(struct roff_man *, int, char *, int);
static int man_pmacro(struct roff_man *, int, char *, int);
@@ -50,9 +51,32 @@ man_parseln(struct roff_man *man, int ln, char *buf, int offs)
man_ptext(man, ln, buf, offs);
}
+/*
+ * If the string ends with \c, return a pointer to the backslash.
+ * Otherwise, return NULL.
+ */
+static char *
+man_hasc(char *start)
+{
+ char *cp, *ep;
+
+ ep = strchr(start, '\0') - 2;
+ if (ep < start || ep[0] != '\\' || ep[1] != 'c')
+ return NULL;
+ for (cp = ep; cp > start; cp--)
+ if (cp[-1] != '\\')
+ break;
+ return (ep - cp) % 2 ? NULL : ep;
+}
+
static void
-man_descope(struct roff_man *man, int line, int offs)
+man_descope(struct roff_man *man, int line, int offs, char *start)
{
+ /* Trailing \c keeps next-line scope open. */
+
+ if (man_hasc(start) != NULL)
+ return;
+
/*
* Co-ordinate what happens with having a next-line scope open:
* first close out the element scope (if applicable), then close
@@ -74,14 +98,13 @@ static int
man_ptext(struct roff_man *man, int line, char *buf, int offs)
{
int i;
- const char *cp, *sp;
char *ep;
/* Literal free-form text whitespace is preserved. */
if (man->flags & MAN_LITERAL) {
roff_word_alloc(man, line, offs, buf + offs);
- man_descope(man, line, offs);
+ man_descope(man, line, offs, buf + offs);
return 1;
}
@@ -102,20 +125,10 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
}
if (man->last->tok == MAN_SH || man->last->tok == MAN_SS)
return 1;
- switch (man->last->type) {
- case ROFFT_TEXT:
- sp = man->last->string;
- cp = ep = strchr(sp, '\0') - 2;
- if (cp < sp || cp[0] != '\\' || cp[1] != 'c')
- break;
- while (cp > sp && cp[-1] == '\\')
- cp--;
- if ((ep - cp) % 2)
- break;
+ if (man->last->type == ROFFT_TEXT &&
+ ((ep = man_hasc(man->last->string)) != NULL)) {
*ep = '\0';
return 1;
- default:
- break;
}
roff_elem_alloc(man, line, offs, ROFF_sp);
man->next = ROFF_NEXT_SIBLING;
@@ -155,7 +168,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
if (mandoc_eos(buf, (size_t)i))
man->last->flags |= NODE_EOS;
- man_descope(man, line, offs);
+ man_descope(man, line, offs, buf + offs);
return 1;
}