summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mandoc.h1
-rw-r--r--read.c1
-rw-r--r--roff.725
-rw-r--r--roff.c86
4 files changed, 67 insertions, 46 deletions
diff --git a/mandoc.h b/mandoc.h
index 794cfec4..54b41e2a 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -141,7 +141,6 @@ enum mandocerr {
MANDOCERR_NONAME, /* manual name not yet set */
MANDOCERR_NOTEXT, /* skipping text before first section header */
MANDOCERR_MACRO, /* skipping unknown macro */
- MANDOCERR_REQUEST, /* NOT IMPLEMENTED: skipping request */
MANDOCERR_ARGCOUNT, /* argument count wrong */
MANDOCERR_RS_SKIP, /* skipping invalid content in .Rs block: macro */
MANDOCERR_ST_BAD, /* unknown standard specifier: standard */
diff --git a/read.c b/read.c
index 8672f917..0896fc0a 100644
--- a/read.c
+++ b/read.c
@@ -185,7 +185,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"manual name not yet set",
"skipping text before first section header",
"skipping unknown macro",
- "NOT IMPLEMENTED, please use groff: skipping request",
"argument count wrong",
"skipping invalid content in .Rs block",
"unknown standard specifier",
diff --git a/roff.7 b/roff.7
index c6bb631e..4ca48a98 100644
--- a/roff.7
+++ b/roff.7
@@ -409,24 +409,21 @@ and the number of arguments is not checked.
Append to a macro definition.
The syntax of this request is the same as that of
.Sx \&de .
-It is currently ignored by
-.Xr mandoc 1 ,
-as are its children.
.Ss \&ami
Append to a macro definition, specifying the macro name indirectly.
The syntax of this request is the same as that of
.Sx \&dei .
-It is currently ignored by
-.Xr mandoc 1 ,
-as are its children.
.Ss \&am1
Append to a macro definition, switching roff compatibility mode off
during macro execution.
The syntax of this request is the same as that of
.Sx \&de1 .
-It is currently ignored by
-.Xr mandoc 1 ,
-as are its children.
+Since
+.Xr mandoc 1
+does not implement
+.Nm
+compatibility mode at all, it handles this request as an alias for
+.Sx \&am .
.Ss \&as
Append to a user-defined string.
The syntax of this request is the same as that of
@@ -554,9 +551,13 @@ Define a
macro, specifying the macro name indirectly.
The syntax of this request is the same as that of
.Sx \&de .
-It is currently ignored by
-.Xr mandoc 1 ,
-as are its children.
+The request
+.Pp
+.D1 Pf . Cm \&dei Ar name Op Ar end
+.Pp
+has the same effect as:
+.Pp
+.D1 Pf . Cm \&de No \e* Ns Bo Ar name Bc Op \e* Ns Bq Ar end
.Ss \&de1
Define a
.Nm
diff --git a/roff.c b/roff.c
index d8d59fa5..8153b69e 100644
--- a/roff.c
+++ b/roff.c
@@ -847,11 +847,10 @@ roff_cblock(ROFF_ARGS)
switch (r->last->tok) {
case ROFF_am:
+ /* ROFF_am1 is remapped to ROFF_am in roff_block(). */
/* FALLTHROUGH */
case ROFF_ami:
/* FALLTHROUGH */
- case ROFF_am1:
- /* FALLTHROUGH */
case ROFF_de:
/* ROFF_de1 is remapped to ROFF_de in roff_block(). */
/* FALLTHROUGH */
@@ -919,34 +918,47 @@ roff_ccond(struct roff *r, int ln, int ppos)
static enum rofferr
roff_block(ROFF_ARGS)
{
- char *name, *cp;
+ const char *name;
+ char *iname, *cp;
size_t namesz;
- name = cp = *bufp + pos;
- namesz = 0;
-
- if (ROFF_ig != tok) {
- if ('\0' == *cp) {
- mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse,
- ln, ppos, roffs[tok].name);
- return(ROFF_IGN);
- }
+ /* Ignore groff compatibility mode for now. */
- /*
- * Re-write `de1', since we don't really care about
- * groff's strange compatibility mode, into `de'.
- */
+ if (ROFF_de1 == tok)
+ tok = ROFF_de;
+ else if (ROFF_am1 == tok)
+ tok = ROFF_am;
- if (ROFF_de1 == tok)
- tok = ROFF_de;
- else if (ROFF_de != tok)
- mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos,
- roffs[tok].name);
+ /* Parse the macro name argument. */
+ cp = *bufp + pos;
+ if (ROFF_ig == tok) {
+ iname = NULL;
+ namesz = 0;
+ } else {
+ iname = cp;
namesz = roff_getname(r, &cp, ln, ppos);
- name[namesz] = '\0';
+ iname[namesz] = '\0';
+ }
+
+ /* Resolve the macro name argument if it is indirect. */
+
+ if (namesz && (ROFF_dei == tok || ROFF_ami == tok)) {
+ if (NULL == (name = roff_getstrn(r, iname, namesz))) {
+ mandoc_vmsg(MANDOCERR_STR_UNDEF,
+ r->parse, ln, (int)(iname - *bufp),
+ "%.*s", (int)namesz, iname);
+ namesz = 0;
+ } else
+ namesz = strlen(name);
} else
- name = NULL;
+ name = iname;
+
+ if (0 == namesz && ROFF_ig != tok) {
+ mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse,
+ ln, ppos, roffs[tok].name);
+ return(ROFF_IGN);
+ }
roffnode_push(r, tok, name, ln, ppos);
@@ -956,16 +968,30 @@ roff_block(ROFF_ARGS)
* appended from roff_block_text() in multiline mode.
*/
- if (namesz && ROFF_de == tok)
+ if (ROFF_de == tok || ROFF_dei == tok)
roff_setstrn(&r->strtab, name, namesz, "", 0, 0);
if ('\0' == *cp)
return(ROFF_IGN);
- /* If present, process the custom end-of-line marker. */
+ /* Get the custom end marker. */
- name = cp;
+ iname = cp;
namesz = roff_getname(r, &cp, ln, ppos);
+
+ /* Resolve the end marker if it is indirect. */
+
+ if (namesz && (ROFF_dei == tok || ROFF_ami == tok)) {
+ if (NULL == (name = roff_getstrn(r, iname, namesz))) {
+ mandoc_vmsg(MANDOCERR_STR_UNDEF,
+ r->parse, ln, (int)(iname - *bufp),
+ "%.*s", (int)namesz, iname);
+ namesz = 0;
+ } else
+ namesz = strlen(name);
+ } else
+ name = iname;
+
if (namesz)
r->last->end = mandoc_strndup(name, namesz);
@@ -1020,12 +1046,8 @@ roff_block_sub(ROFF_ARGS)
t = roff_parse(r, *bufp, &pos, ln, ppos);
- /*
- * Macros other than block-end are only significant
- * in `de' blocks; elsewhere, simply throw them away.
- */
if (ROFF_cblock != t) {
- if (ROFF_de == tok)
+ if (ROFF_ig != tok)
roff_setstr(r, r->last->name, *bufp + ppos, 2);
return(ROFF_IGN);
}
@@ -1038,7 +1060,7 @@ static enum rofferr
roff_block_text(ROFF_ARGS)
{
- if (ROFF_de == tok)
+ if (ROFF_ig != tok)
roff_setstr(r, r->last->name, *bufp + pos, 2);
return(ROFF_IGN);