summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc/mdoc.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2010-05-20 00:58:03 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2010-05-20 00:58:03 +0000
commit0c83ccafaea1f0c8603a8aea73b075667939517e (patch)
tree7202cb2dbb730c8e3aa83595497aad753dc2d2ef /usr.bin/mandoc/mdoc.c
parentc713a7721e58dd0a453fae998afd21f12fd821e8 (diff)
Support nested roff instructions:
* allow roff_parseln() to be re-run * allow roff_parseln() to manipulate the line buffer offset * support the offset in the man and mdoc libraries * adapt .if, .ie, .el, .ig, .am* and .de* support * interpret some instructions even in conditional-negative context Coded by kristaps during the last day of the mandoc hackathon. To avoid regressions in the OpenBSD tree, commit this together with some small local additions: * detect roff block end "\}" even on macro lines * actually implement the ".if n" conditional * ignore .ds, .rm and .tr in libroff Also back my old .if/.ie/.el-handling out of libman, reverting: man.h 1.15 man.c 1.25 man_macro.c 1.15 man_validate.c 1.19 man_action.c 1.15 man_term.c 1.28 man_html.c 1.9.
Diffstat (limited to 'usr.bin/mandoc/mdoc.c')
-rw-r--r--usr.bin/mandoc/mdoc.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c
index e5c8121963b..261edfc35a6 100644
--- a/usr.bin/mandoc/mdoc.c
+++ b/usr.bin/mandoc/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.52 2010/05/16 20:46:15 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.53 2010/05/20 00:58:02 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -146,9 +146,10 @@ static struct mdoc_node *node_alloc(struct mdoc *, int, int,
enum mdoct, enum mdoc_type);
static int node_append(struct mdoc *,
struct mdoc_node *);
-static int mdoc_ptext(struct mdoc *, int, char *);
-static int mdoc_pmacro(struct mdoc *, int, char *);
-static int macrowarn(struct mdoc *, int, const char *);
+static int mdoc_ptext(struct mdoc *, int, char *, int);
+static int mdoc_pmacro(struct mdoc *, int, char *, int);
+static int macrowarn(struct mdoc *, int,
+ const char *, int);
const struct mdoc_node *
@@ -280,16 +281,16 @@ mdoc_endparse(struct mdoc *m)
* the macro (mdoc_pmacro()) or text parser (mdoc_ptext()).
*/
int
-mdoc_parseln(struct mdoc *m, int ln, char *buf)
+mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs)
{
if (MDOC_HALT & m->flags)
return(0);
m->flags |= MDOC_NEWLINE;
- return(('.' == *buf || '\'' == *buf) ?
- mdoc_pmacro(m, ln, buf) :
- mdoc_ptext(m, ln, buf));
+ return(('.' == buf[offs] || '\'' == buf[offs]) ?
+ mdoc_pmacro(m, ln, buf, offs) :
+ mdoc_ptext(m, ln, buf, offs));
}
@@ -626,26 +627,28 @@ mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
* control character.
*/
static int
-mdoc_ptext(struct mdoc *m, int line, char *buf)
+mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
{
char *c, *ws, *end;
/* Ignore bogus comments. */
- if ('\\' == buf[0] && '.' == buf[1] && '\"' == buf[2])
- return(mdoc_pwarn(m, line, 0, EBADCOMMENT));
+ if ('\\' == buf[offs] &&
+ '.' == buf[offs + 1] &&
+ '"' == buf[offs + 2])
+ return(mdoc_pwarn(m, line, offs, EBADCOMMENT));
/* No text before an initial macro. */
if (SEC_NONE == m->lastnamed)
- return(mdoc_perr(m, line, 0, ETEXTPROL));
+ return(mdoc_perr(m, line, offs, ETEXTPROL));
/*
* Search for the beginning of unescaped trailing whitespace (ws)
* and for the first character not to be output (end).
*/
ws = NULL;
- for (c = end = buf; *c; c++) {
+ for (c = end = buf + offs; *c; c++) {
switch (*c) {
case ' ':
if (NULL == ws)
@@ -683,7 +686,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf)
if ( ! mdoc_pwarn(m, line, (int)(ws-buf), ETAILWS))
return(0);
- if ('\0' == *buf && ! (MDOC_LITERAL & m->flags)) {
+ if ('\0' == buf[offs] && ! (MDOC_LITERAL & m->flags)) {
if ( ! mdoc_pwarn(m, line, (int)(c-buf), ENOBLANK))
return(0);
@@ -692,14 +695,14 @@ mdoc_ptext(struct mdoc *m, int line, char *buf)
* blank lines aren't allowed, but enough manuals assume this
* behaviour that we want to work around it.
*/
- if ( ! mdoc_elem_alloc(m, line, 0, MDOC_Pp, NULL))
+ if ( ! mdoc_elem_alloc(m, line, offs, MDOC_Pp, NULL))
return(0);
m->next = MDOC_NEXT_SIBLING;
return(1);
}
- if ( ! mdoc_word_alloc(m, line, 0, buf))
+ if ( ! mdoc_word_alloc(m, line, offs, buf+offs))
return(0);
if (MDOC_LITERAL & m->flags)
@@ -713,7 +716,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf)
assert(buf < end);
- if (mandoc_eos(buf, (size_t)(end-buf)))
+ if (mandoc_eos(buf+offs, (size_t)(end-buf-offs)))
m->last->flags |= MDOC_EOS;
return(1);
@@ -721,12 +724,12 @@ mdoc_ptext(struct mdoc *m, int line, char *buf)
static int
-macrowarn(struct mdoc *m, int ln, const char *buf)
+macrowarn(struct mdoc *m, int ln, const char *buf, int offs)
{
if ( ! (MDOC_IGN_MACRO & m->pflags))
- return(mdoc_verr(m, ln, 0, "unknown macro: %s%s",
+ return(mdoc_verr(m, ln, offs, "unknown macro: %s%s",
buf, strlen(buf) > 3 ? "..." : ""));
- return(mdoc_vwarn(m, ln, 0, "unknown macro: %s%s",
+ return(mdoc_vwarn(m, ln, offs, "unknown macro: %s%s",
buf, strlen(buf) > 3 ? "..." : ""));
}
@@ -736,7 +739,7 @@ macrowarn(struct mdoc *m, int ln, const char *buf)
* character.
*/
int
-mdoc_pmacro(struct mdoc *m, int ln, char *buf)
+mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
{
enum mdoct tok;
int i, j, sv;
@@ -744,10 +747,12 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf)
/* Empty lines are ignored. */
- if ('\0' == buf[1])
+ offs++;
+
+ if ('\0' == buf[offs])
return(1);
- i = 1;
+ i = offs;
/* Accept whitespace after the initial control char. */
@@ -776,16 +781,16 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf)
return(mdoc_perr(m, ln, i, EPRINT));
}
- mac[j] = 0;
+ mac[j] = '\0';
if (j == 4 || j < 2) {
- if ( ! macrowarn(m, ln, mac))
+ if ( ! macrowarn(m, ln, mac, sv))
goto err;
return(1);
}
if (MDOC_MAX == (tok = mdoc_hash_find(mac))) {
- if ( ! macrowarn(m, ln, mac))
+ if ( ! macrowarn(m, ln, mac, sv))
goto err;
return(1);
}