diff options
author | 2010-03-26 01:22:05 +0000 | |
---|---|---|
committer | 2010-03-26 01:22:05 +0000 | |
commit | ac531cf149bb0c92daec85dbe45c2ebf82fae36f (patch) | |
tree | ce0a8314675b2eb8304dccef3896bb6be3b8204c | |
parent | Reformat default value of PreferredAuthentications entry (current formatting (diff) | |
download | wireguard-openbsd-ac531cf149bb0c92daec85dbe45c2ebf82fae36f.tar.xz wireguard-openbsd-ac531cf149bb0c92daec85dbe45c2ebf82fae36f.zip |
merge 1.9.17, keeping local patches
* much improved pod2man support and low-level roff robustness
* have -Tlint imply -Wall and -fstrict
* use fewer macros and more enum in libman
* and various bug fixes
-rw-r--r-- | usr.bin/mandoc/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/mandoc/chars.c | 4 | ||||
-rw-r--r-- | usr.bin/mandoc/chars.in | 31 | ||||
-rw-r--r-- | usr.bin/mandoc/libman.h | 20 | ||||
-rw-r--r-- | usr.bin/mandoc/main.c | 70 | ||||
-rw-r--r-- | usr.bin/mandoc/man.7 | 189 | ||||
-rw-r--r-- | usr.bin/mandoc/man.c | 107 | ||||
-rw-r--r-- | usr.bin/mandoc/man.h | 84 | ||||
-rw-r--r-- | usr.bin/mandoc/man_action.c | 33 | ||||
-rw-r--r-- | usr.bin/mandoc/man_hash.c | 57 | ||||
-rw-r--r-- | usr.bin/mandoc/man_html.c | 26 | ||||
-rw-r--r-- | usr.bin/mandoc/man_macro.c | 157 | ||||
-rw-r--r-- | usr.bin/mandoc/man_term.c | 26 | ||||
-rw-r--r-- | usr.bin/mandoc/man_validate.c | 30 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.1 | 21 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_term.c | 5 | ||||
-rw-r--r-- | usr.bin/mandoc/term.c | 30 | ||||
-rw-r--r-- | usr.bin/mandoc/term.h | 3 |
18 files changed, 591 insertions, 306 deletions
diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile index fa3c9fe1736..cbbf8c7e74f 100644 --- a/usr.bin/mandoc/Makefile +++ b/usr.bin/mandoc/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.28 2010/03/25 23:23:01 schwarze Exp $ +# $OpenBSD: Makefile,v 1.29 2010/03/26 01:22:05 schwarze Exp $ .include <bsd.own.mk> -VERSION=1.9.16 +VERSION=1.9.17 CFLAGS+=-DVERSION=\"${VERSION}\" CFLAGS+=-W -Wall -Wstrict-prototypes .if ${USE_GCC3:L} != "no" diff --git a/usr.bin/mandoc/chars.c b/usr.bin/mandoc/chars.c index edeec1abb30..0e8348bc13a 100644 --- a/usr.bin/mandoc/chars.c +++ b/usr.bin/mandoc/chars.c @@ -1,4 +1,4 @@ -/* $Id: chars.c,v 1.5 2010/02/18 02:11:25 schwarze Exp $ */ +/* $Id: chars.c,v 1.6 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -38,7 +38,7 @@ struct ln { #define CHARS_BOTH (CHARS_CHAR | CHARS_STRING) }; -#define LINES_MAX 350 +#define LINES_MAX 369 #define CHAR(w, x, y, z, a, b) \ { NULL, (w), (y), (a), (x), (z), (b), CHARS_CHAR }, diff --git a/usr.bin/mandoc/chars.in b/usr.bin/mandoc/chars.in index 75b6601ee09..429d12ee9d9 100644 --- a/usr.bin/mandoc/chars.in +++ b/usr.bin/mandoc/chars.in @@ -1,4 +1,4 @@ -/* $Id: chars.in,v 1.5 2010/03/02 00:38:59 schwarze Exp $ */ +/* $Id: chars.in,v 1.6 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -50,10 +50,10 @@ CHAR("a\"", 2, "\"", 1, "̋", 6) CHAR("a-", 2, "-", 1, "¯", 6) CHAR("a.", 2, ".", 1, "˙", 6) CHAR("a^", 2, "^", 1, "̂", 6) -CHAR("\'", 1, "\'", 1, "́", 6) +BOTH("\'", 1, "\'", 1, "́", 6) BOTH("aa", 2, "\'", 1, "́", 6) BOTH("ga", 2, "`", 1, "̀", 6) -CHAR("`", 1, "`", 1, "̀", 6) +BOTH("`", 1, "`", 1, "̀", 6) CHAR("ab", 2, "`", 1, "̆", 6) CHAR("ac", 2, ",", 1, "̧", 6) CHAR("ad", 2, "\"", 1, "̈", 6) @@ -321,8 +321,8 @@ CHAR("fi", 2, "fi", 2, "fi", 8) CHAR("fl", 2, "fl", 2, "fl", 8) CHAR("Fi", 2, "ffi", 3, "ffi", 8) CHAR("Fl", 2, "ffl", 3, "ffl", 8) -CHAR("AE", 2, "AE", 2, "Æ", 6) -CHAR("ae", 2, "ae", 2, "æ", 6) +BOTH("AE", 2, "AE", 2, "Æ", 6) +BOTH("ae", 2, "ae", 2, "æ", 6) CHAR("OE", 2, "OE", 2, "Œ", 6) CHAR("oe", 2, "oe", 2, "œ", 6) CHAR("ss", 2, "ss", 2, "ß", 6) @@ -347,6 +347,27 @@ CHAR("Po", 2, "L", 1, "£", 6) CHAR("Cs", 2, "x", 1, "¤", 6) CHAR("Fn", 2, "f", 1, "ƒ", 6) +/* pod2man holdovers. */ +STRING("--", 2, "--", 2, "—", 7) +STRING("PI", 2, "pi", 2, "π", 6) +STRING("L\"", 2, "``", 2, "“", 7) +STRING("R\"", 2, "\'\'", 2, "”", 7) +STRING("C+", 2, "C++", 3, "C++", 3) +STRING("C`", 2, "`", 1, "‘", 7) +STRING("C\'", 2, "\'", 1, "’", 7) +STRING("Aq", 2, "\'", 1, "\'", 1) +STRING("^", 1, "^", 1, "^", 1) +STRING(",", 1, ",", 1, ",", 1) +STRING("~", 1, "~", 1, "~", 1) +STRING("/", 1, "/", 1, "/", 1) +STRING(":", 1, "\"", 1, "̈", 6) +STRING("8", 1, "B", 1, "β", 6) +STRING("o", 1, "o", 1, "°", 6) +STRING("D-", 2, "D", 1, "Ð", 6) +STRING("d-", 2, "o", 1, "ð", 6) +STRING("TH", 2, "b", 1, "Þ", 6) +STRING("th", 2, "b", 1, "þ", 6) + /* Old style. */ STRING("Am", 2, "&", 1, "&", 5) STRING("Ba", 2, "|", 1, "|", 1) diff --git a/usr.bin/mandoc/libman.h b/usr.bin/mandoc/libman.h index cc225c088ec..1bb92ebf14d 100644 --- a/usr.bin/mandoc/libman.h +++ b/usr.bin/mandoc/libman.h @@ -1,4 +1,4 @@ -/* $Id: libman.h,v 1.12 2010/03/25 23:23:01 schwarze Exp $ */ +/* $Id: libman.h,v 1.13 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -60,10 +60,11 @@ enum merr { WNOSCOPE, WOLITERAL, WNLITERAL, + WROFFNEST, WERRMAX }; -#define MACRO_PROT_ARGS struct man *m, int tok, int line, \ +#define MACRO_PROT_ARGS struct man *m, enum mant tok, int line, \ int ppos, int *pos, char *buf struct man_macro { @@ -73,6 +74,7 @@ struct man_macro { #define MAN_EXPLICIT (1 << 1) /* See blk_imp(). */ #define MAN_FSCOPED (1 << 2) /* See blk_imp(). */ #define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */ +#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */ }; extern const struct man_macro *const man_macros; @@ -89,15 +91,13 @@ __BEGIN_DECLS man_err((m), (n)->line, (n)->pos, 0, (t)) int man_word_alloc(struct man *, int, int, const char *); -int man_block_alloc(struct man *, int, int, int); -int man_head_alloc(struct man *, int, int, int); -int man_body_alloc(struct man *, int, int, int); -int man_elem_alloc(struct man *, int, int, int); -void man_node_free(struct man_node *); -void man_node_freelist(struct man_node *); -void man_node_unlink(struct man *, struct man_node *); +int man_block_alloc(struct man *, int, int, enum mant); +int man_head_alloc(struct man *, int, int, enum mant); +int man_body_alloc(struct man *, int, int, enum mant); +int man_elem_alloc(struct man *, int, int, enum mant); +void man_node_delete(struct man *, struct man_node *); void man_hash_init(void); -int man_hash_find(const char *); +enum mant man_hash_find(const char *); int man_macroend(struct man *); int man_args(struct man *, int, int *, char *, char **); #define ARGS_ERROR (-1) diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c index 5688ec04728..0f2ab0b03b0 100644 --- a/usr.bin/mandoc/main.c +++ b/usr.bin/mandoc/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.21 2010/02/18 02:11:26 schwarze Exp $ */ +/* $Id: main.c,v 1.22 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -60,11 +60,11 @@ struct curparse { #define WARN_WALL (1 << 0) /* All-warnings mask. */ #define WARN_WERR (1 << 2) /* Warnings->errors. */ int fflags; -#define IGN_SCOPE (1 << 0) /* Ignore scope errors. */ -#define NO_IGN_ESCAPE (1 << 1) /* Don't ignore bad escapes. */ -#define NO_IGN_MACRO (1 << 2) /* Don't ignore bad macros. */ -#define NO_IGN_CHARS (1 << 3) /* Don't ignore bad chars. */ -#define IGN_ERRORS (1 << 4) /* Ignore failed parse. */ +#define FL_IGN_SCOPE (1 << 0) /* Ignore scope errors. */ +#define FL_NIGN_ESCAPE (1 << 1) /* Don't ignore bad escapes. */ +#define FL_NIGN_MACRO (1 << 2) /* Don't ignore bad macros. */ +#define FL_NIGN_CHARS (1 << 3) /* Don't ignore bad chars. */ +#define FL_IGN_ERRORS (1 << 4) /* Ignore failed parse. */ enum intt inttype; /* Input parsers... */ struct man *man; struct man *lastman; @@ -78,8 +78,12 @@ struct curparse { char outopts[BUFSIZ]; }; +#define FL_STRICT FL_NIGN_ESCAPE | \ + FL_NIGN_MACRO | \ + FL_NIGN_CHARS + static int foptions(int *, char *); -static int toptions(enum outt *, char *); +static int toptions(struct curparse *, char *); static int moptions(enum intt *, char *); static int woptions(int *, char *); static int merr(void *, int, int, const char *); @@ -132,7 +136,7 @@ main(int argc, char *argv[]) (void)strlcat(curp.outopts, ",", BUFSIZ); break; case ('T'): - if ( ! toptions(&curp.outtype, optarg)) + if ( ! toptions(&curp, optarg)) return(EXIT_FAILURE); break; case ('W'): @@ -160,7 +164,7 @@ main(int argc, char *argv[]) curp.fd = STDIN_FILENO; c = fdesc(&blk, &ln, &curp); - if ( ! (IGN_ERRORS & curp.fflags)) + if ( ! (FL_IGN_ERRORS & curp.fflags)) rc = 1 == c ? 1 : 0; else rc = -1 == c ? 0 : 1; @@ -168,7 +172,7 @@ main(int argc, char *argv[]) while (rc && *argv) { c = ffile(&blk, &ln, *argv, &curp); - if ( ! (IGN_ERRORS & curp.fflags)) + if ( ! (FL_IGN_ERRORS & curp.fflags)) rc = 1 == c ? 1 : 0; else rc = -1 == c ? 0 : 1; @@ -232,11 +236,11 @@ man_init(struct curparse *curp) pflags = MAN_IGN_MACRO | MAN_IGN_ESCAPE | MAN_IGN_CHARS; - if (curp->fflags & NO_IGN_MACRO) + if (curp->fflags & FL_NIGN_MACRO) pflags &= ~MAN_IGN_MACRO; - if (curp->fflags & NO_IGN_CHARS) + if (curp->fflags & FL_NIGN_CHARS) pflags &= ~MAN_IGN_CHARS; - if (curp->fflags & NO_IGN_ESCAPE) + if (curp->fflags & FL_NIGN_ESCAPE) pflags &= ~MAN_IGN_ESCAPE; return(man_alloc(curp, pflags, &mancb)); @@ -256,13 +260,13 @@ mdoc_init(struct curparse *curp) pflags = MDOC_IGN_MACRO | MDOC_IGN_ESCAPE | MDOC_IGN_CHARS; - if (curp->fflags & IGN_SCOPE) + if (curp->fflags & FL_IGN_SCOPE) pflags |= MDOC_IGN_SCOPE; - if (curp->fflags & NO_IGN_ESCAPE) + if (curp->fflags & FL_NIGN_ESCAPE) pflags &= ~MDOC_IGN_ESCAPE; - if (curp->fflags & NO_IGN_MACRO) + if (curp->fflags & FL_NIGN_MACRO) pflags &= ~MDOC_IGN_MACRO; - if (curp->fflags & NO_IGN_CHARS) + if (curp->fflags & FL_NIGN_CHARS) pflags &= ~MDOC_IGN_CHARS; return(mdoc_alloc(curp, pflags, &mdoccb)); @@ -534,19 +538,22 @@ moptions(enum intt *tflags, char *arg) static int -toptions(enum outt *tflags, char *arg) +toptions(struct curparse *curp, char *arg) { if (0 == strcmp(arg, "ascii")) - *tflags = OUTT_ASCII; - else if (0 == strcmp(arg, "lint")) - *tflags = OUTT_LINT; + curp->outtype = OUTT_ASCII; + else if (0 == strcmp(arg, "lint")) { + curp->outtype = OUTT_LINT; + curp->wflags |= WARN_WALL; + curp->fflags |= FL_STRICT; + } else if (0 == strcmp(arg, "tree")) - *tflags = OUTT_TREE; + curp->outtype = OUTT_TREE; else if (0 == strcmp(arg, "html")) - *tflags = OUTT_HTML; + curp->outtype = OUTT_HTML; else if (0 == strcmp(arg, "xhtml")) - *tflags = OUTT_XHTML; + curp->outtype = OUTT_XHTML; else { fprintf(stderr, "%s: Bad argument\n", arg); return(0); @@ -575,26 +582,25 @@ foptions(int *fflags, char *arg) o = arg; switch (getsubopt(&arg, UNCONST(toks), &v)) { case (0): - *fflags |= IGN_SCOPE; + *fflags |= FL_IGN_SCOPE; break; case (1): - *fflags |= NO_IGN_ESCAPE; + *fflags |= FL_NIGN_ESCAPE; break; case (2): - *fflags |= NO_IGN_MACRO; + *fflags |= FL_NIGN_MACRO; break; case (3): - *fflags |= NO_IGN_CHARS; + *fflags |= FL_NIGN_CHARS; break; case (4): - *fflags |= IGN_ERRORS; + *fflags |= FL_IGN_ERRORS; break; case (5): - *fflags |= NO_IGN_ESCAPE | - NO_IGN_MACRO | NO_IGN_CHARS; + *fflags |= FL_STRICT; break; case (6): - *fflags &= ~NO_IGN_ESCAPE; + *fflags &= ~FL_NIGN_ESCAPE; break; default: fprintf(stderr, "%s: Bad argument\n", o); diff --git a/usr.bin/mandoc/man.7 b/usr.bin/mandoc/man.7 index b2d04bb2567..860013dc77a 100644 --- a/usr.bin/mandoc/man.7 +++ b/usr.bin/mandoc/man.7 @@ -1,4 +1,4 @@ -.\" $Id: man.7,v 1.17 2010/03/25 23:23:01 schwarze Exp $ +.\" $Id: man.7,v 1.18 2010/03/26 01:22:05 schwarze Exp $ .\" .\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 25 2010 $ +.Dd $Mdocdate: March 26 2010 $ .Dt MAN 7 .Os . @@ -438,6 +438,7 @@ If a next-line macro is followed by a non-next-line macro, an error is raised (unless in the case of .Sx \&br , .Sx \&sp , +.Sx \&Sp , or .Sx \&na ) . .Pp @@ -448,54 +449,51 @@ The syntax is as follows: .Ed . .Pp -.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "ScopeXXXXX" -.It Em Macro Ta Em Arguments Ta Em Scope -.It Sx \&B Ta n Ta next-line -.It Sx \&BI Ta n Ta current -.It Sx \&BR Ta n Ta current -.It Sx \&DT Ta 0 Ta current -.It Sx \&I Ta n Ta next-line -.It Sx \&IB Ta n Ta current -.It Sx \&IR Ta n Ta current -.It Sx \&PD Ta n Ta current -.It Sx \&R Ta n Ta next-line -.It Sx \&RB Ta n Ta current -.It Sx \&RI Ta n Ta current -.It Sx \&SB Ta n Ta next-line -.It Sx \&SM Ta n Ta next-line -.It Sx \&TH Ta >1, <6 Ta current -.It Sx \&UC Ta n Ta current -.It Sx \&br Ta 0 Ta current -.It Sx \&fi Ta 0 Ta current -.It Sx \&i Ta n Ta current -.It Sx \&na Ta 0 Ta current -.It Sx \&nf Ta 0 Ta current -.It Sx \&r Ta 0 Ta current -.It Sx \&sp Ta 1 Ta current +.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "ScopeXXXXX" "CompatX" +.It Em Macro Ta Em Arguments Ta Em Scope Ta Em Notes +.It Sx \&B Ta n Ta next-line Ta \& +.It Sx \&BI Ta n Ta current Ta \& +.It Sx \&BR Ta n Ta current Ta \& +.It Sx \&DT Ta 0 Ta current Ta \& +.It Sx \&I Ta n Ta next-line Ta \& +.It Sx \&IB Ta n Ta current Ta \& +.It Sx \&IR Ta n Ta current Ta \& +.\" .It Sx \&PD Ta n Ta current Ta compat +.It Sx \&R Ta n Ta next-line Ta \& +.It Sx \&RB Ta n Ta current Ta \& +.It Sx \&RI Ta n Ta current Ta \& +.It Sx \&SB Ta n Ta next-line Ta \& +.It Sx \&SM Ta n Ta next-line Ta \& +.It Sx \&TH Ta >1, <6 Ta current Ta \& +.\" .It Sx \&UC Ta n Ta current Ta compat +.It Sx \&br Ta 0 Ta current Ta compat +.It Sx \&fi Ta 0 Ta current Ta compat +.It Sx \&i Ta n Ta current Ta compat +.It Sx \&na Ta 0 Ta current Ta compat +.It Sx \&nf Ta 0 Ta current Ta compat +.It Sx \&r Ta 0 Ta current Ta compat +.It Sx \&sp Ta 1 Ta current Ta compat +.\" .It Sx \&Sp Ta 0 Ta current Ta compat +.\" .It Sx \&Vb Ta <1 Ta current Ta compat +.\" .It Sx \&Ve Ta 0 Ta current Ta compat .El . .Pp -The -.Sx \&PD , -.Sx \&RS , -.Sx \&RE , -.Sx \&UC , -.Sx \&br , -.Sx \&fi , -.Sx \&i , -.Sx \&na , -.Sx \&nf , -.Sx \&r , -and -.Sx \&sp -macros should not be used. They're included for compatibility. +Macros marked as +.Qq compat +are included for compatibility with the significant corpus of existing +manuals that mix dialects of roff. These macros should not be used for +portable +.Nm +manuals. . . .Ss Block Macros Block macros are comprised of a head and body. Like for in-line macros, the head is scoped to the current line and, in one circumstance, the -next line (the next-line stipulations for line macros apply here as -well). +next line (the next-line stipulations as in +.Sx Line Macros +apply here as well). .Pp The syntax is as follows: .Bd -literal -offset indent @@ -523,33 +521,34 @@ or No closure refers to an explicit block closing macro. . .Pp -.Bl -column "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" -compact -offset indent -.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope -.It Sx \&HP Ta <2 Ta current Ta paragraph -.It Sx \&IP Ta <3 Ta current Ta paragraph -.It Sx \&LP Ta 0 Ta current Ta paragraph -.It Sx \&P Ta 0 Ta current Ta paragraph -.It Sx \&PP Ta 0 Ta current Ta paragraph -.It Sx \&RE Ta 0 Ta current Ta none -.It Sx \&RS Ta 1 Ta current Ta part -.It Sx \&SH Ta >0 Ta next-line Ta section -.It Sx \&SS Ta >0 Ta next-line Ta sub-section -.It Sx \&TP Ta n Ta next-line Ta paragraph +As a rule, block macros may not be nested; thus, calling a block macro +while another block macro scope is open, and the open scope is not +implicitly closed, is syntactically incorrect. +. +.Pp +.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" "compatX" +.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes +.It Sx \&HP Ta <2 Ta current Ta paragraph Ta \& +.It Sx \&IP Ta <3 Ta current Ta paragraph Ta \& +.It Sx \&LP Ta 0 Ta current Ta paragraph Ta \& +.It Sx \&P Ta 0 Ta current Ta paragraph Ta \& +.It Sx \&PP Ta 0 Ta current Ta paragraph Ta \& +.It Sx \&RE Ta 0 Ta current Ta none Ta compat +.It Sx \&RS Ta 1 Ta current Ta part Ta compat +.It Sx \&SH Ta >0 Ta next-line Ta section Ta \& +.It Sx \&SS Ta >0 Ta next-line Ta sub-section Ta \& +.It Sx \&TP Ta n Ta next-line Ta paragraph Ta \& .El +.Pp +. +Macros marked +.Qq compat +are as mentioned in +.Sx Line Macros . . .Pp If a block macro is next-line scoped, it may only be followed by in-line -macros (excluding -.Sx \&DT , -.Sx \&PD , -.Sx \&TH , -.Sx \&UC , -.Sx \&br , -.Sx \&na , -.Sx \&sp , -.Sx \&nf , -and -.Sx \&fi ) . +macros for decorating text. . . .Sh REFERENCE @@ -904,14 +903,14 @@ See also .Sx \&P , and .Sx \&PP . -. -. -.Ss \&PD -Has no effect. Included for compatibility. -. -. -.Ss \&UC -Has no effect. Included for compatibility. +.\" . +.\" . +.\" .Ss \&PD +.\" Has no effect. Included for compatibility. +.\" . +.\" . +.\" .Ss \&UC +.\" Has no effect. Included for compatibility. . . .Ss \&br @@ -979,31 +978,43 @@ macro. Defaults to 1, if unspecified. See also .Sx \&br . . +.\" .Ss \&Sp +.\" A synonym for +.\" .Sx \&sp +.\" .Cm 0.5v . +.\" . +.\" .Ss \&Vb +.\" A synonym for +.\" .Sx \&nf . +.\" Accepts an argument (the height of the formatted space) which is +.\" disregarded. +.\" . +.\" .Ss \&Ve +.\" A synonym for +.\" .Sx \&fi . +.\" . . .Sh COMPATIBILITY -This section documents compatibility with other roff implementations, at -this time limited to -.Xr groff 1 . +This section documents areas of questionable portability between +implementations of the +.Nm +language. .Pp .Bl -dash -compact .It -The -.Xr groff 1 -.Sx \&i -macro will italicise all subsequent text if a line argument is not -provided. This behaviour is not implemented. +In quoted literals, GNU troff allowed pair-wise double-quotes to produce +a standalone double-quote in formatted output. It is not known whether +this behaviour is exhibited by other formatters. .It -In quoted literals, groff allowed pair-wise double-quotes to produce a -standalone double-quote in formatted output. This idiosyncratic -behaviour is no longer applicable. +Blocks of whitespace are stripped from macro and free-form text lines +(except when in literal mode) in mandoc. This is not the case for GNU +troff: for maximum portability, whitespace sensitive blocks should be +enclosed in literal contexts. .It The .Sx \&sp -macro does not accept negative numbers. -.It -Blocks of whitespace are stripped from both macro and free-form text -lines (except when in literal mode), while groff would retain whitespace -in free-form text lines. +macro does not accept negative values in mandoc. In GNU troff, this +would result in strange behaviour. .El . . diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c index 5d94334ea9b..ec14a091747 100644 --- a/usr.bin/mandoc/man.c +++ b/usr.bin/mandoc/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.21 2010/03/25 23:23:01 schwarze Exp $ */ +/* $Id: man.c,v 1.22 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -45,7 +45,8 @@ const char *const __man_merrnames[WERRMAX] = { "scope open on exit", /* WEXITSCOPE */ "no scope context", /* WNOSCOPE */ "literal context already open", /* WOLITERAL */ - "no literal context open" /* WNLITERAL */ + "no literal context open", /* WNLITERAL */ + "invalid nesting of roff declarations", /* WROFFNEST */ }; const char *const __man_macronames[MAN_MAX] = { @@ -57,15 +58,20 @@ const char *const __man_macronames[MAN_MAX] = { "RI", "na", "i", "sp", "nf", "fi", "r", "RE", "RS", "DT", "UC", "PD", - "Sp", "Vb", "Ve", + "Sp", "Vb", "Ve", "de", + "dei", "am", "ami", "ig", + ".", }; const char * const *man_macronames = __man_macronames; static struct man_node *man_node_alloc(int, int, - enum man_type, int); + enum man_type, enum mant); static int man_node_append(struct man *, struct man_node *); +static void man_node_free(struct man_node *); +static void man_node_unlink(struct man *, + struct man_node *); static int man_ptext(struct man *, int, char *); static int man_pmacro(struct man *, int, char *); static void man_free1(struct man *); @@ -156,7 +162,7 @@ man_free1(struct man *man) { if (man->first) - man_node_freelist(man->first); + man_node_delete(man, man->first); if (man->meta.title) free(man->meta.title); if (man->meta.source) @@ -175,6 +181,7 @@ man_alloc1(struct man *m) m->last = mandoc_calloc(1, sizeof(struct man_node)); m->first = m->last; m->last->type = MAN_ROOT; + m->last->tok = MAN_MAX; m->next = MAN_NEXT_CHILD; } @@ -202,6 +209,7 @@ man_node_append(struct man *man, struct man_node *p) /* NOTREACHED */ } + assert(p->parent); p->parent->nchild++; if ( ! man_valid_pre(man, p)) @@ -238,7 +246,7 @@ man_node_append(struct man *man, struct man_node *p) static struct man_node * -man_node_alloc(int line, int pos, enum man_type type, int tok) +man_node_alloc(int line, int pos, enum man_type type, enum mant tok) { struct man_node *p; @@ -252,7 +260,7 @@ man_node_alloc(int line, int pos, enum man_type type, int tok) int -man_elem_alloc(struct man *m, int line, int pos, int tok) +man_elem_alloc(struct man *m, int line, int pos, enum mant tok) { struct man_node *p; @@ -265,7 +273,7 @@ man_elem_alloc(struct man *m, int line, int pos, int tok) int -man_head_alloc(struct man *m, int line, int pos, int tok) +man_head_alloc(struct man *m, int line, int pos, enum mant tok) { struct man_node *p; @@ -278,7 +286,7 @@ man_head_alloc(struct man *m, int line, int pos, int tok) int -man_body_alloc(struct man *m, int line, int pos, int tok) +man_body_alloc(struct man *m, int line, int pos, enum mant tok) { struct man_node *p; @@ -291,7 +299,7 @@ man_body_alloc(struct man *m, int line, int pos, int tok) int -man_block_alloc(struct man *m, int line, int pos, int tok) +man_block_alloc(struct man *m, int line, int pos, enum mant tok) { struct man_node *p; @@ -310,7 +318,7 @@ pstring(struct man *m, int line, int pos, struct man_node *n; size_t sv; - n = man_node_alloc(line, pos, MAN_TEXT, -1); + n = man_node_alloc(line, pos, MAN_TEXT, MAN_MAX); n->string = mandoc_malloc(len + 1); sv = strlcpy(n->string, p, len + 1); @@ -332,30 +340,29 @@ man_word_alloc(struct man *m, int line, int pos, const char *word) } -void +/* + * Free all of the resources held by a node. This does NOT unlink a + * node from its context; for that, see man_node_unlink(). + */ +static void man_node_free(struct man_node *p) { if (p->string) free(p->string); - if (p->parent) - p->parent->nchild--; free(p); } void -man_node_freelist(struct man_node *p) +man_node_delete(struct man *m, struct man_node *p) { - struct man_node *n; - if (p->child) - man_node_freelist(p->child); - assert(0 == p->nchild); - n = p->next; + while (p->child) + man_node_delete(m, p->child); + + man_node_unlink(m, p); man_node_free(p); - if (n) - man_node_freelist(n); } @@ -465,7 +472,8 @@ macrowarn(struct man *m, int ln, const char *buf) int man_pmacro(struct man *m, int ln, char *buf) { - int i, j, c, ppos, fl; + int i, j, ppos, fl; + enum mant tok; char mac[5]; struct man_node *n; @@ -515,7 +523,7 @@ man_pmacro(struct man *m, int ln, char *buf) return(1); } - if (MAN_MAX == (c = man_hash_find(mac))) { + if (MAN_MAX == (tok = man_hash_find(mac))) { if ( ! macrowarn(m, ln, mac)) goto err; return(1); @@ -538,7 +546,7 @@ man_pmacro(struct man *m, int ln, char *buf) * macros---they don't print text---so we let those slip by. */ - if ( ! (MAN_NSCOPED & man_macros[c].flags) && + if ( ! (MAN_NSCOPED & man_macros[tok].flags) && m->flags & MAN_ELINE) { assert(MAN_TEXT != m->last->type); @@ -563,22 +571,24 @@ man_pmacro(struct man *m, int ln, char *buf) if ( ! man_nwarn(m, n, WLNSCOPE)) return(0); - man_node_unlink(m, n); - man_node_free(n); + man_node_delete(m, n); m->flags &= ~MAN_ELINE; } /* Begin recursive parse sequence. */ - assert(man_macros[c].fp); + assert(man_macros[tok].fp); - if ( ! (*man_macros[c].fp)(m, c, ln, ppos, &i, buf)) + if ( ! (*man_macros[tok].fp)(m, tok, ln, ppos, &i, buf)) goto err; out: /* * We weren't in a block-line scope when entering the * above-parsed macro, so return. + * + * FIXME: this prohibits the nesting of blocks (e.g., `de' and + * family) within BLINE or ELINE systems. This is annoying. */ if ( ! (MAN_BLINE & fl)) { @@ -667,26 +677,43 @@ man_err(struct man *m, int line, int pos, int iserr, enum merr type) } -void +/* + * Unlink a node from its context. If "m" is provided, the last parse + * point will also be adjusted accordingly. + */ +static void man_node_unlink(struct man *m, struct man_node *n) { - if (n->prev) { + /* Adjust siblings. */ + + if (n->prev) n->prev->next = n->next; - if (m->last == n) { - assert(NULL == n->next); + if (n->next) + n->next->prev = n->prev; + + /* Adjust parent. */ + + if (n->parent) { + n->parent->nchild--; + if (n->parent->child == n) + n->parent->child = n->prev ? n->prev : n->next; + } + + /* Adjust parse point, if applicable. */ + + if (m && m->last == n) { + /*XXX: this can occur when bailing from validation. */ + /*assert(NULL == n->next);*/ + if (n->prev) { m->last = n->prev; m->next = MAN_NEXT_SIBLING; - } - } else { - n->parent->child = n->next; - if (m->last == n) { - assert(NULL == n->next); + } else { m->last = n->parent; m->next = MAN_NEXT_CHILD; } } - if (n->next) - n->next->prev = n->prev; + if (m && m->first == n) + m->first = NULL; } diff --git a/usr.bin/mandoc/man.h b/usr.bin/mandoc/man.h index b99ffda6026..5fb1befdbcb 100644 --- a/usr.bin/mandoc/man.h +++ b/usr.bin/mandoc/man.h @@ -1,4 +1,4 @@ -/* $Id: man.h,v 1.13 2010/03/02 01:00:39 schwarze Exp $ */ +/* $Id: man.h,v 1.14 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -19,42 +19,50 @@ #include <time.h> -#define MAN_br 0 -#define MAN_TH 1 -#define MAN_SH 2 -#define MAN_SS 3 -#define MAN_TP 4 -#define MAN_LP 5 -#define MAN_PP 6 -#define MAN_P 7 -#define MAN_IP 8 -#define MAN_HP 9 -#define MAN_SM 10 -#define MAN_SB 11 -#define MAN_BI 12 -#define MAN_IB 13 -#define MAN_BR 14 -#define MAN_RB 15 -#define MAN_R 16 -#define MAN_B 17 -#define MAN_I 18 -#define MAN_IR 19 -#define MAN_RI 20 -#define MAN_na 21 -#define MAN_i 22 -#define MAN_sp 23 -#define MAN_nf 24 -#define MAN_fi 25 -#define MAN_r 26 -#define MAN_RE 27 -#define MAN_RS 28 -#define MAN_DT 29 -#define MAN_UC 30 -#define MAN_PD 31 -#define MAN_Sp 32 -#define MAN_Vb 33 -#define MAN_Ve 34 -#define MAN_MAX 35 +enum mant { + MAN_br = 0, + MAN_TH, + MAN_SH, + MAN_SS, + MAN_TP, + MAN_LP, + MAN_PP, + MAN_P, + MAN_IP, + MAN_HP, + MAN_SM, + MAN_SB, + MAN_BI, + MAN_IB, + MAN_BR, + MAN_RB, + MAN_R, + MAN_B, + MAN_I, + MAN_IR, + MAN_RI, + MAN_na, + MAN_i, + MAN_sp, + MAN_nf, + MAN_fi, + MAN_r, + MAN_RE, + MAN_RS, + MAN_DT, + MAN_UC, + MAN_PD, + MAN_Sp, + MAN_Vb, + MAN_Ve, + MAN_de, + MAN_dei, + MAN_am, + MAN_ami, + MAN_ig, + MAN_dot, + MAN_MAX, +}; enum man_type { MAN_TEXT, @@ -81,7 +89,7 @@ struct man_node { int nchild; int line; int pos; - int tok; + enum mant tok; int flags; #define MAN_VALID (1 << 0) #define MAN_ACTED (1 << 1) diff --git a/usr.bin/mandoc/man_action.c b/usr.bin/mandoc/man_action.c index ee9c20014a3..b9850dcbbf7 100644 --- a/usr.bin/mandoc/man_action.c +++ b/usr.bin/mandoc/man_action.c @@ -1,4 +1,4 @@ -/* $Id: man_action.c,v 1.13 2010/03/25 23:23:01 schwarze Exp $ */ +/* $Id: man_action.c,v 1.14 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -14,7 +14,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/utsname.h> #include <assert.h> #include <stdlib.h> @@ -28,6 +27,7 @@ struct actions { }; static int post_TH(struct man *); +static int post_de(struct man *); static int post_fi(struct man *); static int post_nf(struct man *); @@ -67,6 +67,12 @@ const struct actions man_actions[MAN_MAX] = { { NULL }, /* Sp */ { post_nf }, /* Vb */ { post_fi }, /* Ve */ + { post_de }, /* de */ + { post_de }, /* dei */ + { post_de }, /* am */ + { post_de }, /* ami */ + { post_de }, /* ig */ + { NULL }, /* . */ }; @@ -106,6 +112,21 @@ post_fi(struct man *m) static int +post_de(struct man *m) +{ + + /* + * XXX: for the time being, we indiscriminately remove roff + * instructions from the parse stream. + */ + if (MAN_BLOCK == m->last->type) + man_node_delete(m, m->last); + + return(1); +} + + +static int post_nf(struct man *m) { @@ -177,8 +198,10 @@ post_TH(struct man *m) if (n && (n = n->next)) m->meta.vol = mandoc_strdup(n->string); - n = m->last; - man_node_unlink(m, n); - man_node_freelist(n); + /* + * Remove the `TH' node after we've processed it for our + * meta-data. + */ + man_node_delete(m, m->last); return(1); } diff --git a/usr.bin/mandoc/man_hash.c b/usr.bin/mandoc/man_hash.c index 506f997b909..4d0a6a05d9a 100644 --- a/usr.bin/mandoc/man_hash.c +++ b/usr.bin/mandoc/man_hash.c @@ -1,4 +1,4 @@ -/* $Id: man_hash.c,v 1.7 2009/10/19 10:20:24 schwarze Exp $ */ +/* $Id: man_hash.c,v 1.8 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -17,13 +17,33 @@ #include <sys/types.h> #include <assert.h> +#include <ctype.h> #include <limits.h> #include <stdlib.h> #include <string.h> #include "libman.h" -static u_char table[26 * 6]; +#define HASH_DEPTH 6 + +#define HASH_ROW(x) do { \ + if ('.' == (x)) \ + (x) = 26; \ + else if (isupper((u_char)(x))) \ + (x) -= 65; \ + else \ + (x) -= 97; \ + (x) *= HASH_DEPTH; \ + } while (/* CONSTCOND */ 0) + +/* + * Lookup table is indexed first by lower-case first letter (plus one + * for the period, which is stored in the last row), then by lower or + * uppercase second letter. Buckets correspond to the index of the + * macro (the integer value of the enum stored as a char to save a bit + * of space). + */ +static u_char table[27 * HASH_DEPTH]; /* * XXX - this hash has global scope, so if intended for use as a library @@ -36,39 +56,44 @@ man_hash_init(void) memset(table, UCHAR_MAX, sizeof(table)); + assert(/* CONSTCOND */ MAN_MAX < UCHAR_MAX); + for (i = 0; i < MAN_MAX; i++) { x = man_macronames[i][0]; - assert((x >= 65 && x <= 90) || - (x >= 97 && x <= 122)); - x -= (x <= 90) ? 65 : 97; - x *= 6; + assert(isalpha((u_char)x) || '.' == x); - for (j = 0; j < 6; j++) + HASH_ROW(x); + + for (j = 0; j < HASH_DEPTH; j++) if (UCHAR_MAX == table[x + j]) { table[x + j] = (u_char)i; break; } - assert(j < 6); + + assert(j < HASH_DEPTH); } } -int + +enum mant man_hash_find(const char *tmp) { - int x, i, tok; + int x, y, i; + enum mant tok; - if (0 == (x = tmp[0])) + if ('\0' == (x = tmp[0])) return(MAN_MAX); - if ( ! ((x >= 65 && x <= 90) || (x >= 97 && x <= 122))) + if ( ! (isalpha((u_char)x) || '.' == x)) return(MAN_MAX); - x -= (x <= 90) ? 65 : 97; - x *= 6; + HASH_ROW(x); - for (i = 0; i < 6; i++) { - if (UCHAR_MAX == (tok = table[x + i])) + for (i = 0; i < HASH_DEPTH; i++) { + if (UCHAR_MAX == (y = table[x + i])) return(MAN_MAX); + + tok = (enum mant)y; if (0 == strcmp(tmp, man_macronames[tok])) return(tok); } diff --git a/usr.bin/mandoc/man_html.c b/usr.bin/mandoc/man_html.c index 1d984a8833f..339bbf967e4 100644 --- a/usr.bin/mandoc/man_html.c +++ b/usr.bin/mandoc/man_html.c @@ -1,4 +1,4 @@ -/* $Id: man_html.c,v 1.7 2010/03/25 23:23:01 schwarze Exp $ */ +/* $Id: man_html.c,v 1.8 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -100,8 +100,14 @@ static const struct htmlman mans[MAN_MAX] = { { man_ign_pre, NULL }, /* UC */ { man_ign_pre, NULL }, /* PD */ { man_br_pre, NULL }, /* Sp */ - { NULL, NULL }, /* Vb */ - { NULL, NULL }, /* Vi */ + { man_ign_pre, NULL }, /* Vb */ + { NULL, NULL }, /* Ve */ + { man_ign_pre, NULL }, /* de */ + { man_ign_pre, NULL }, /* dei */ + { man_ign_pre, NULL }, /* am */ + { man_ign_pre, NULL }, /* ami */ + { man_ign_pre, NULL }, /* ig */ + { NULL, NULL }, /* . */ }; @@ -340,10 +346,18 @@ man_br_pre(MAN_ARGS) SCALE_VS_INIT(&su, 1); - if ((MAN_sp == n->tok || MAN_Sp == n->tok) && n->child) - a2roffsu(n->child->string, &su, SCALE_VS); - else if (MAN_br == n->tok) + switch (n->tok) { + case (MAN_Sp): + SCALE_VS_INIT(&su, 0.5); + break; + case (MAN_sp): + if (n->child) + a2roffsu(n->child->string, &su, SCALE_VS); + break; + default: su.scale = 0; + break; + } bufcat_su(h, "height", &su); PAIR_STYLE_INIT(&tag, h); diff --git a/usr.bin/mandoc/man_macro.c b/usr.bin/mandoc/man_macro.c index c282ea3db7a..8e62c005f22 100644 --- a/usr.bin/mandoc/man_macro.c +++ b/usr.bin/mandoc/man_macro.c @@ -1,4 +1,4 @@ -/* $Id: man_macro.c,v 1.11 2010/03/25 23:23:01 schwarze Exp $ */ +/* $Id: man_macro.c,v 1.12 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -21,18 +21,23 @@ #include "libman.h" -#define REW_REWIND (0) /* See rew_scope(). */ -#define REW_NOHALT (1) /* See rew_scope(). */ -#define REW_HALT (2) /* See rew_scope(). */ +enum rew { + REW_REWIND, + REW_NOHALT, + REW_HALT, +}; -static int in_line_eoln(MACRO_PROT_ARGS); -static int blk_imp(MACRO_PROT_ARGS); static int blk_close(MACRO_PROT_ARGS); +static int blk_dotted(MACRO_PROT_ARGS); +static int blk_exp(MACRO_PROT_ARGS); +static int blk_imp(MACRO_PROT_ARGS); +static int in_line_eoln(MACRO_PROT_ARGS); -static int rew_scope(enum man_type, struct man *, int); -static int rew_dohalt(int, enum man_type, +static int rew_scope(enum man_type, + struct man *, enum mant); +static enum rew rew_dohalt(enum mant, enum man_type, const struct man_node *); -static int rew_block(int, enum man_type, +static enum rew rew_block(enum mant, enum man_type, const struct man_node *); const struct man_macro __man_macros[MAN_MAX] = { @@ -64,13 +69,19 @@ const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, 0 }, /* fi */ { in_line_eoln, 0 }, /* r */ { blk_close, 0 }, /* RE */ - { blk_imp, MAN_EXPLICIT }, /* RS */ + { blk_exp, MAN_EXPLICIT }, /* RS */ { in_line_eoln, 0 }, /* DT */ { in_line_eoln, 0 }, /* UC */ { in_line_eoln, 0 }, /* PD */ - { in_line_eoln, 0 }, /* Sp */ + { in_line_eoln, MAN_NSCOPED }, /* Sp */ { in_line_eoln, 0 }, /* Vb */ { in_line_eoln, 0 }, /* Ve */ + { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* de */ + { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* dei */ + { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* am */ + { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ami */ + { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ig */ + { blk_dotted, 0 }, /* . */ }; const struct man_macro * const man_macros = __man_macros; @@ -81,7 +92,6 @@ man_unscope(struct man *m, const struct man_node *n) { assert(n); - m->next = MAN_NEXT_SIBLING; /* LINTED */ while (m->last != n) { @@ -95,12 +105,18 @@ man_unscope(struct man *m, const struct man_node *n) if ( ! man_valid_post(m)) return(0); - return(man_action_post(m)); + if ( ! man_action_post(m)) + return(0); + + m->next = MAN_ROOT == m->last->type ? + MAN_NEXT_CHILD : MAN_NEXT_SIBLING; + + return(1); } -static int -rew_block(int ntok, enum man_type type, const struct man_node *n) +static enum rew +rew_block(enum mant ntok, enum man_type type, const struct man_node *n) { if (MAN_BLOCK == type && ntok == n->parent->tok && @@ -115,10 +131,10 @@ rew_block(int ntok, enum man_type type, const struct man_node *n) * section (all less sections), and scoped to subsections (all less * sections and subsections). */ -static int -rew_dohalt(int tok, enum man_type type, const struct man_node *n) +static enum rew +rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n) { - int c; + enum rew c; if (MAN_ROOT == n->type) return(REW_HALT); @@ -171,10 +187,10 @@ rew_dohalt(int tok, enum man_type type, const struct man_node *n) * scopes. When a scope is closed, it must be validated and actioned. */ static int -rew_scope(enum man_type type, struct man *m, int tok) +rew_scope(enum man_type type, struct man *m, enum mant tok) { struct man_node *n; - int c; + enum rew c; /* LINTED */ for (n = m->last; n; n = n->parent) { @@ -197,11 +213,50 @@ rew_scope(enum man_type type, struct man *m, int tok) } +/* + * Closure for dotted macros (de, dei, am, ami, ign). This must handle + * any of these as the parent node, so it needs special handling. + * Beyond this, it's the same as blk_close(). + */ +/* ARGSUSED */ +int +blk_dotted(MACRO_PROT_ARGS) +{ + enum mant ntok; + struct man_node *nn; + + for (nn = m->last->parent; nn; nn = nn->parent) + if (nn->tok == MAN_de || nn->tok == MAN_dei || + nn->tok == MAN_am || + nn->tok == MAN_ami || + nn->tok == MAN_ig) { + ntok = nn->tok; + break; + } + + if (NULL == nn) { + if ( ! man_pwarn(m, line, ppos, WNOSCOPE)) + return(0); + return(1); + } + + if ( ! rew_scope(MAN_BODY, m, ntok)) + return(0); + if ( ! rew_scope(MAN_BLOCK, m, ntok)) + return(0); + + return(1); +} + + +/* + * Close out a generic explicit macro. + */ /* ARGSUSED */ int blk_close(MACRO_PROT_ARGS) { - int ntok; + enum mant ntok; const struct man_node *nn; switch (tok) { @@ -225,11 +280,58 @@ blk_close(MACRO_PROT_ARGS) return(0); if ( ! rew_scope(MAN_BLOCK, m, ntok)) return(0); - m->next = MAN_NEXT_SIBLING; + return(1); } +int +blk_exp(MACRO_PROT_ARGS) +{ + int w, la; + char *p; + + /* + * Close out prior scopes. "Regular" explicit macros cannot be + * nested, but we allow roff macros to be placed just about + * anywhere. + */ + + if ( ! (MAN_NOCLOSE & man_macros[tok].flags)) { + if ( ! rew_scope(MAN_BODY, m, tok)) + return(0); + if ( ! rew_scope(MAN_BLOCK, m, tok)) + return(0); + } + + if ( ! man_block_alloc(m, line, ppos, tok)) + return(0); + if ( ! man_head_alloc(m, line, ppos, tok)) + return(0); + + for (;;) { + la = *pos; + w = man_args(m, line, pos, buf, &p); + + if (-1 == w) + return(0); + if (0 == w) + break; + + if ( ! man_word_alloc(m, line, la, p)) + return(0); + } + + assert(m); + assert(tok != MAN_MAX); + + if ( ! rew_scope(MAN_HEAD, m, tok)) + return(0); + return(man_body_alloc(m, line, ppos, tok)); +} + + + /* * Parse an implicit-block macro. These contain a MAN_HEAD and a * MAN_BODY contained within a MAN_BLOCK. Rules for closing out other @@ -289,7 +391,6 @@ blk_imp(MACRO_PROT_ARGS) if ( ! rew_scope(MAN_HEAD, m, tok)) return(0); - return(man_body_alloc(m, line, ppos, tok)); } @@ -314,11 +415,6 @@ in_line_eoln(MACRO_PROT_ARGS) return(0); if (0 == w) break; - - /* XXX ignore Vb arguments for now */ - if (MAN_Vb == tok) - continue; - if ( ! man_word_alloc(m, line, la, p)) return(0); } @@ -369,8 +465,9 @@ in_line_eoln(MACRO_PROT_ARGS) return(0); if (m->last->type != MAN_ROOT && ! man_action_post(m)) return(0); - if (m->last->type != MAN_ROOT) - m->next = MAN_NEXT_SIBLING; + + m->next = MAN_ROOT == m->last->type ? + MAN_NEXT_CHILD : MAN_NEXT_SIBLING; return(1); } diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c index dcb24a50516..44dc484f2bb 100644 --- a/usr.bin/mandoc/man_term.c +++ b/usr.bin/mandoc/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.26 2010/03/25 23:23:01 schwarze Exp $ */ +/* $Id: man_term.c,v 1.27 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -135,9 +135,15 @@ static const struct termact termacts[MAN_MAX] = { { pre_ign, NULL, 0 }, /* DT */ { pre_ign, NULL, 0 }, /* UC */ { pre_ign, NULL, 0 }, /* PD */ - { pre_sp, NULL, MAN_NOTEXT }, /* Sp */ - { pre_nf, NULL, 0 }, /* Vb */ - { pre_fi, NULL, 0 }, /* Ve */ + { pre_sp, NULL, MAN_NOTEXT }, /* Sp */ + { pre_nf, NULL, 0 }, /* Vb */ + { pre_fi, NULL, 0 }, /* Ve */ + { pre_ign, NULL, MAN_NOTEXT }, /* de */ + { pre_ign, NULL, MAN_NOTEXT }, /* dei */ + { pre_ign, NULL, MAN_NOTEXT }, /* am */ + { pre_ign, NULL, MAN_NOTEXT }, /* ami */ + { pre_ign, NULL, MAN_NOTEXT }, /* ig */ + { NULL, NULL, 0 }, /* . */ }; @@ -152,10 +158,12 @@ terminal_man(void *arg, const struct man *man) p = (struct termp *)arg; + p->overstep = 0; + p->maxrmargin = 65; + if (NULL == p->symtab) switch (p->enc) { case (TERMENC_ASCII): - p->maxrmargin = 65; p->symtab = chars_init(CHARS_ASCII); break; default: @@ -259,10 +267,11 @@ static int pre_nf(DECL_ARGS) { - p->rmargin = p->maxrmargin = 160; + p->rmargin = p->maxrmargin = 78; term_newln(p); mt->fl |= MANT_LITERAL; - return(1); + + return(MAN_Vb != n->tok); } @@ -778,6 +787,8 @@ post_RS(DECL_ARGS) case (MAN_BLOCK): mt->offset = mt->lmargin = INDENT; break; + case (MAN_HEAD): + break; default: term_newln(p); p->offset = INDENT; @@ -878,6 +889,7 @@ print_man_head(struct termp *p, const struct man_meta *m) size_t buflen, titlen; p->rmargin = p->maxrmargin; + p->offset = 0; buf[0] = title[0] = '\0'; diff --git a/usr.bin/mandoc/man_validate.c b/usr.bin/mandoc/man_validate.c index 68d87fa3ef0..4630457a58a 100644 --- a/usr.bin/mandoc/man_validate.c +++ b/usr.bin/mandoc/man_validate.c @@ -1,4 +1,4 @@ -/* $Id: man_validate.c,v 1.13 2010/03/02 01:00:39 schwarze Exp $ */ +/* $Id: man_validate.c,v 1.14 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -42,6 +42,7 @@ static int check_ge2(CHKARGS); static int check_le5(CHKARGS); static int check_par(CHKARGS); static int check_part(CHKARGS); +static int check_roff(CHKARGS); static int check_root(CHKARGS); static int check_sec(CHKARGS); static int check_text(CHKARGS); @@ -53,10 +54,11 @@ static v_check posts_part[] = { check_part, NULL }; static v_check posts_sec[] = { check_sec, NULL }; static v_check posts_le1[] = { check_le1, NULL }; static v_check pres_bline[] = { check_bline, NULL }; +static v_check pres_roff[] = { check_bline, check_roff, NULL }; static const struct man_valid man_valids[MAN_MAX] = { { NULL, posts_eq0 }, /* br */ - { pres_bline, posts_ge2_le5 }, /* TH */ + { pres_bline, posts_ge2_le5 }, /* TH */ /* FIXME: make sure capitalised. */ { pres_bline, posts_sec }, /* SH */ { pres_bline, posts_sec }, /* SS */ { pres_bline, posts_par }, /* TP */ @@ -90,6 +92,12 @@ static const struct man_valid man_valids[MAN_MAX] = { { NULL, posts_le1 }, /* Sp */ { pres_bline, posts_le1 }, /* Vb */ { pres_bline, posts_eq0 }, /* Ve */ + { pres_roff, NULL }, /* de */ + { pres_roff, NULL }, /* dei */ + { pres_roff, NULL }, /* am */ + { pres_roff, NULL }, /* ami */ + { pres_roff, NULL }, /* ig */ + { NULL, NULL }, /* . */ }; @@ -280,6 +288,24 @@ check_bline(CHKARGS) assert( ! (MAN_ELINE & m->flags)); if (MAN_BLINE & m->flags) return(man_nerr(m, n, WLNSCOPE)); + return(1); } + +static int +check_roff(CHKARGS) +{ + + if (MAN_BLOCK != n->type) + return(1); + + for (n = n->parent; n; n = n->parent) + if (MAN_de == n->tok || MAN_dei == n->tok || + MAN_am == n->tok || + MAN_ami == n->tok || + MAN_ig == n->tok) + return(man_nerr(m, n, WROFFNEST)); + + return(1); +} diff --git a/usr.bin/mandoc/mandoc.1 b/usr.bin/mandoc/mandoc.1 index d34f39e56d3..4285e14d7c8 100644 --- a/usr.bin/mandoc/mandoc.1 +++ b/usr.bin/mandoc/mandoc.1 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.1,v 1.22 2010/03/25 23:23:01 schwarze Exp $ +.\" $Id: mandoc.1,v 1.23 2010/03/26 01:22:05 schwarze Exp $ .\" .\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 25 2010 $ +.Dd $Mdocdate: March 26 2010 $ .Dt MANDOC 1 .Os . @@ -176,6 +176,10 @@ Produce an indented parse tree. . .It Fl T Ns Ar lint Parse only: produce no output. +Implies +.Fl W Ns Ar all +and +.Fl f Ns Ar strict . .El . .Pp @@ -225,6 +229,8 @@ over a large set of manuals passed on the command line. .Ss Output Options For the time being, only .Fl T Ns Ar html +and +.Fl T Ns Ar xhtml accepts output options: .Bl -tag -width Ds .It Fl O Ns Ar style=style.css @@ -527,7 +533,7 @@ and .Xr man 7 . .Pp Nesting elements within next-line element scopes of -.Fl m Ar Ns an , +.Fl m Ns Ar an , such as .Sq br within an empty @@ -536,4 +542,11 @@ will confuse .Fl T Ns Ar html and .Fl T Ns Ar xhtml -and cause it to forget the formatting. +and cause them to forget the formatting of the prior next-line scope. +.Pp +The +.Sq i +macro in +.Fl m Ns Ar an +should italicise all subsequent text if a line argument is not provided. +This behaviour is not implemented. diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c index dba0d2db54f..438853ecae4 100644 --- a/usr.bin/mandoc/mdoc_term.c +++ b/usr.bin/mandoc/mdoc_term.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.70 2010/03/02 00:38:59 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.71 2010/03/26 01:22:05 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -268,6 +268,9 @@ terminal_mdoc(void *arg, const struct mdoc *mdoc) p = (struct termp *)arg; + p->overstep = 0; + p->maxrmargin = 78; + if (NULL == p->symtab) switch (p->enc) { case (TERMENC_ASCII): diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c index ea72b39410f..06d9efab18d 100644 --- a/usr.bin/mandoc/term.c +++ b/usr.bin/mandoc/term.c @@ -1,4 +1,4 @@ -/* $Id: term.c,v 1.25 2010/03/22 23:16:21 schwarze Exp $ */ +/* $Id: term.c,v 1.26 2010/03/26 01:22:07 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -79,7 +79,6 @@ term_alloc(enum termenc enc) perror(NULL); exit(EXIT_FAILURE); } - p->maxrmargin = 78; p->enc = enc; return(p); } @@ -134,7 +133,6 @@ term_flushln(struct termp *p) int jhy; /* last hyphen before line overflow */ size_t maxvis, mmax; static int line_started = 0; - static int overstep = 0; /* * First, establish the maximum columns of "visible" content. @@ -145,12 +143,12 @@ term_flushln(struct termp *p) assert(p->offset < p->rmargin); - maxvis = (int)(p->rmargin - p->offset) - overstep < 0 ? + maxvis = (int)(p->rmargin - p->offset) - p->overstep < 0 ? /* LINTED */ - 0 : p->rmargin - p->offset - overstep; - mmax = (int)(p->maxrmargin - p->offset) - overstep < 0 ? + 0 : p->rmargin - p->offset - p->overstep; + mmax = (int)(p->maxrmargin - p->offset) - p->overstep < 0 ? /* LINTED */ - 0 : p->maxrmargin - p->offset - overstep; + 0 : p->maxrmargin - p->offset - p->overstep; bp = TERMP_NOBREAK & p->flags ? mmax : maxvis; @@ -224,10 +222,10 @@ term_flushln(struct termp *p) for (j = 0; j < (int)p->offset; j++) putchar(' '); } - /* Remove the overstep width. */ + /* Remove the p->overstep width. */ bp += (int)/* LINTED */ - overstep; - overstep = 0; + p->overstep; + p->overstep = 0; } else { for (j = 0; j < (int)vbl; j++) putchar(' '); @@ -252,7 +250,7 @@ term_flushln(struct termp *p) } p->col = 0; - overstep = 0; + p->overstep = 0; if ( ! (TERMP_NOBREAK & p->flags)) { if (line_started) { @@ -264,7 +262,7 @@ term_flushln(struct termp *p) if (TERMP_HANG & p->flags) { /* We need one blank after the tag. */ - overstep = /* LINTED */ + p->overstep = /* LINTED */ vis - maxvis + 1; /* @@ -277,12 +275,12 @@ term_flushln(struct termp *p) * move it one step LEFT and flag the rest of the line * to be longer. */ - if (overstep >= -1) { - assert((int)maxvis + overstep >= 0); + if (p->overstep >= -1) { + assert((int)maxvis + p->overstep >= 0); /* LINTED */ - maxvis += overstep; + maxvis += p->overstep; } else - overstep = 0; + p->overstep = 0; } else if (TERMP_DANGLE & p->flags) return; diff --git a/usr.bin/mandoc/term.h b/usr.bin/mandoc/term.h index ad29d165d77..83c9f017a2d 100644 --- a/usr.bin/mandoc/term.h +++ b/usr.bin/mandoc/term.h @@ -1,4 +1,4 @@ -/* $Id: term.h,v 1.13 2009/12/24 02:08:14 schwarze Exp $ */ +/* $Id: term.h,v 1.14 2010/03/26 01:22:07 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -35,6 +35,7 @@ struct termp { size_t maxcols; /* Max size of buf. */ size_t offset; /* Margin offest. */ size_t col; /* Bytes in buf. */ + int overstep; /* See termp_flushln(). */ int flags; #define TERMP_NOSPACE (1 << 2) /* No space before words. */ #define TERMP_NOLPAD (1 << 3) /* See term_flushln(). */ |