From 04736aac15e84c2dacbbb0788d3e89d2daf75cd4 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Mon, 7 Jul 2014 11:35:06 +0000 Subject: implement .dei and .ami --- mandoc.h | 1 - read.c | 1 - roff.7 | 25 ++++++++++--------- roff.c | 86 ++++++++++++++++++++++++++++++++++++++++------------------------ 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); -- cgit