mandoc(1): Update to 1.9.11.
authorSascha Wildner <saw@online.de>
Thu, 29 Oct 2009 10:35:49 +0000 (11:35 +0100)
committerSascha Wildner <saw@online.de>
Thu, 29 Oct 2009 10:36:08 +0000 (11:36 +0100)
Taken-from: OpenBSD

27 files changed:
usr.bin/mandoc/Makefile
usr.bin/mandoc/html.c
usr.bin/mandoc/html.h
usr.bin/mandoc/libman.h
usr.bin/mandoc/main.c
usr.bin/mandoc/man.7
usr.bin/mandoc/man.c
usr.bin/mandoc/man.h
usr.bin/mandoc/man_action.c
usr.bin/mandoc/man_html.c
usr.bin/mandoc/man_macro.c
usr.bin/mandoc/man_term.c
usr.bin/mandoc/man_validate.c
usr.bin/mandoc/mandoc.1
usr.bin/mandoc/mdoc.7
usr.bin/mandoc/mdoc.c
usr.bin/mandoc/mdoc.h
usr.bin/mandoc/mdoc_action.c
usr.bin/mandoc/mdoc_argv.c
usr.bin/mandoc/mdoc_html.c
usr.bin/mandoc/mdoc_macro.c
usr.bin/mandoc/mdoc_strings.c
usr.bin/mandoc/mdoc_term.c
usr.bin/mandoc/mdoc_validate.c
usr.bin/mandoc/out.c
usr.bin/mandoc/out.h
usr.bin/mandoc/term.c

index 46882b3..31a7ccb 100644 (file)
@@ -1,6 +1,6 @@
-#      $OpenBSD: Makefile,v 1.19 2009/10/19 09:16:58 schwarze Exp $
+#      $OpenBSD: Makefile,v 1.21 2009/10/27 21:40:07 schwarze Exp $
 
-VERSION=1.9.9
+VERSION=1.9.11
 CFLAGS+=-DVERSION=\"${VERSION}\"
 WARNS?=        3
 
index 6703cd0..2b13e37 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: html.c,v 1.1 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: html.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -15,7 +15,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include <sys/types.h>
-#include <sys/queue.h>
 
 #include <assert.h>
 #include <err.h>
@@ -98,8 +97,8 @@ html_alloc(char *outopts)
        if (NULL == (h = calloc(1, sizeof(struct html))))
                return(NULL);
 
-       SLIST_INIT(&h->tags);
-       SLIST_INIT(&h->ords);
+       h->tags.head = NULL;
+       h->ords.head = NULL;
 
        if (NULL == (h->symtab = chars_init(CHARS_HTML))) {
                free(h);
@@ -134,15 +133,13 @@ html_free(void *p)
 
        h = (struct html *)p;
 
-       while ( ! SLIST_EMPTY(&h->ords)) {
-               ord = SLIST_FIRST(&h->ords);
-               SLIST_REMOVE_HEAD(&h->ords, entry);
+       while ((ord = h->ords.head) != NULL) {
+               h->ords.head = ord->next;
                free(ord);
        }
 
-       while ( ! SLIST_EMPTY(&h->tags)) {
-               tag = SLIST_FIRST(&h->tags);
-               SLIST_REMOVE_HEAD(&h->tags, entry);
+       while ((tag = h->tags.head) != NULL) {
+               h->tags.head = tag->next;
                free(tag);
        }
 
@@ -354,7 +351,8 @@ print_otag(struct html *h, enum htmltag tag,
                if (NULL == (t = malloc(sizeof(struct tag))))
                        err(EXIT_FAILURE, "malloc");
                t->tag = tag;
-               SLIST_INSERT_HEAD(&h->tags, t, entry);
+               t->next = h->tags.head;
+               h->tags.head = t;
        } else
                t = NULL;
 
@@ -464,10 +462,9 @@ print_tagq(struct html *h, const struct tag *until)
 {
        struct tag      *tag;
 
-       while ( ! SLIST_EMPTY(&h->tags)) {
-               tag = SLIST_FIRST(&h->tags);
+       while ((tag = h->tags.head) != NULL) {
                print_ctag(h, tag->tag);
-               SLIST_REMOVE_HEAD(&h->tags, entry);
+               h->tags.head = tag->next;
                free(tag);
                if (until && tag == until)
                        return;
@@ -480,12 +477,11 @@ print_stagq(struct html *h, const struct tag *suntil)
 {
        struct tag      *tag;
 
-       while ( ! SLIST_EMPTY(&h->tags)) {
-               tag = SLIST_FIRST(&h->tags);
+       while ((tag = h->tags.head) != NULL) {
                if (suntil && tag == suntil)
                        return;
                print_ctag(h, tag->tag);
-               SLIST_REMOVE_HEAD(&h->tags, entry);
+               h->tags.head = tag->next;
                free(tag);
        }
 }
index 758b0be..1221607 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: html.h,v 1.1 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: html.h,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -62,18 +62,22 @@ enum        htmlattr {
 };
 
 struct tag {
+       struct tag       *next;
        enum htmltag      tag;
-       SLIST_ENTRY(tag)  entry;
 };
 
 struct ord {
-       int               pos;
+       struct ord       *next;
        const void       *cookie;
-       SLIST_ENTRY(ord)  entry;
+       int               pos;
 };
 
-SLIST_HEAD(tagq, tag);
-SLIST_HEAD(ordq, ord);
+struct tagq {
+       struct tag       *head;
+};
+struct ordq {
+       struct ord       *head;
+};
 
 struct htmlpair {
        enum htmlattr     key;
index f0a5de1..7529587 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: libman.h,v 1.9 2009/09/21 21:11:36 schwarze Exp $ */
+/*     $Id: libman.h,v 1.10 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -54,7 +54,6 @@ enum  merr {
        WHEADARGS,
        WBODYARGS,
        WNHEADARGS,
-       WMACRO,
        WMACROFORM,
        WEXITSCOPE,
        WNOSCOPE,
index 03b8f2c..dc009b6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: main.c,v 1.17 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: main.c,v 1.18 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -75,7 +75,7 @@ struct        curparse {
        out_man           outman;
        out_free          outfree;
        void             *outdata;
-       char             *outopts;
+       char              outopts[BUFSIZ];
 };
 
 static int               foptions(int *, char *);
@@ -111,7 +111,7 @@ main(int argc, char *argv[])
        curp.outtype = OUTT_ASCII;
 
        /* LINTED */
-       while (-1 != (c = getopt(argc, argv, "f:m:o:T:VW:")))
+       while (-1 != (c = getopt(argc, argv, "f:m:O:T:VW:")))
                switch (c) {
                case ('f'):
                        if ( ! foptions(&curp.fflags, optarg))
@@ -121,8 +121,9 @@ main(int argc, char *argv[])
                        if ( ! moptions(&curp.inttype, optarg))
                                return(EXIT_FAILURE);
                        break;
-               case ('o'):
-                       curp.outopts = optarg;
+               case ('O'):
+                       (void)strlcat(curp.outopts, optarg, BUFSIZ);
+                       (void)strlcat(curp.outopts, ",", BUFSIZ);
                        break;
                case ('T'):
                        if ( ! toptions(&curp.outtype, optarg))
@@ -208,8 +209,8 @@ usage(void)
 {
 
        (void)fprintf(stderr, "usage: %s [-V] [-foption...] "
-                       "[-mformat] [-Toutput] [-Werr...]\n",
-                       __progname);
+                       "[-mformat] [-Ooption] [-Toutput] "
+                       "[-Werr...]\n", __progname);
        exit(EXIT_FAILURE);
 }
 
index 974eda2..9c969f1 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $Id: man.7,v 1.12 2009/10/21 19:13:50 schwarze Exp $
+.\"    $Id: man.7,v 1.13 2009/10/27 21:40:07 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: September 18 2009 $
+.Dd October 29, 2009
 .Dt MAN 7
 .Os
 .
@@ -237,6 +237,63 @@ The \efBfoo\efR utility processes files...
 \&.\e\*q .SH BUGS
 \&.\e\*q .SH SECURITY CONSIDERATIONS
 .Ed
+.Pp
+The sections in a
+.Nm
+document are conventionally ordered as they appear above.  Sections
+should be composed as follows:
+.Bl -tag -width Ds -offset Ds
+.It NAME
+The name(s) and a short description of the documented material.  The
+syntax for this is generally as follows:
+.Pp
+.D1 \efBname\efR \e(en description
+.It LIBRARY
+The name of the library containing the documented material, which is
+assumed to be a function in a section 2 or 3 manual.  For functions in
+the C library, this may be as follows:
+.Pp
+.D1 Standard C Library (libc, -lc)
+.It SYNOPSIS
+Documents the utility invocation syntax, function call syntax, or device
+configuration.
+.Pp
+For the first, utilities (sections 1, 6, and 8), this is
+generally structured as follows:
+.Pp
+.D1 \efBname\efR [-\efBab\efR] [-\efBc\efR\efIarg\efR] \efBpath\efR...
+.Pp
+For the second, function calls (sections 2, 3, 9):
+.Pp
+.D1 \. Ns Sx \&B No char *name(char *\efIarg\efR);
+.Pp
+And for the third, configurations (section 4):
+.Pp
+.D1 \. Ns Sx \&B No name* at cardbus ? function ?
+.Pp
+Manuals not in these sections generally don't need a SYNOPSIS.
+.It DESCRIPTION
+This expands upon the brief, one-line description in NAME.  It usually
+contains a break-down of the options (if documenting a command).
+.It IMPLEMENTATION NOTES
+Implementation-specific notes should be kept here.  This is useful when
+implementing standard functions that may have side effects or notable
+algorithmic implications.
+.It EXIT STATUS
+.It RETURN VALUES
+.It ENVIRONMENT
+.It FILES
+.It EXAMPLES
+.It DIAGNOSTICS
+.It ERRORS
+.It SEE ALSO
+.It STANDARDS
+.It HISTORY
+.It AUTHORS
+.It CAVEATS
+.It BUGS
+.It SECURITY CONSIDERATIONS
+.El
 .
 .
 .Sh MACRO SYNTAX
@@ -290,6 +347,7 @@ If a next-line macro is proceded by a block macro, it is ignored.
 .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
@@ -308,6 +366,7 @@ If a next-line macro is proceded by a block macro, it is ignored.
 .
 .Pp
 The
+.Sx \&PD ,
 .Sx \&RS ,
 .Sx \&RE ,
 .Sx \&UC ,
@@ -370,6 +429,7 @@ No closure refers to an explicit block closing macro.
 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 ,
@@ -525,6 +585,8 @@ If
 .Va width
 is specified, it's saved for later paragraph left-margins; if
 unspecified, the saved or default width is used.
+.Ss \&PD
+Has no effect.  Included for compatibility.
 .Ss \&UC
 Has no effect.  Included for compatibility.
 .Ss \&br
index 5356635..84fb724 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man.c,v 1.14 2009/10/19 10:20:24 schwarze Exp $ */
+/*     $Id: man.c,v 1.15 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -40,7 +40,6 @@ const char *const __man_merrnames[WERRMAX] = {
        "expected block head arguments", /* WHEADARGS */
        "expected block body arguments", /* WBODYARGS */
        "expected empty block head", /* WNHEADARGS */
-       "unknown macro", /* WMACRO */
        "ill-formed macro", /* WMACROFORM */
        "scope open on exit", /* WEXITSCOPE */
        "no scope context", /* WNOSCOPE */
@@ -56,7 +55,7 @@ const char *const __man_macronames[MAN_MAX] = {
        "R",            "B",            "I",            "IR",
        "RI",           "na",           "i",            "sp",
        "nf",           "fi",           "r",            "RE",
-       "RS",           "DT",           "UC"
+       "RS",           "DT",           "UC",           "PD"
        };
 
 const  char * const *man_macronames = __man_macronames;
@@ -71,6 +70,7 @@ static        void             man_free1(struct man *);
 static int              man_alloc1(struct man *);
 static int              pstring(struct man *, int, int,
                                const char *, size_t);
+static int              macrowarn(struct man *, int, const char *);
 
 
 const struct man_node *
@@ -452,6 +452,18 @@ descope:
 }
 
 
+static int
+macrowarn(struct man *m, int ln, const char *buf)
+{
+       if ( ! (MAN_IGN_MACRO & m->pflags))
+               return(man_verr(m, ln, 0,
+                               "unknown macro: %s%s",
+                               buf, strlen(buf) > 3 ? "..." : ""));
+       return(man_vwarn(m, ln, 0, "unknown macro: %s%s",
+                               buf, strlen(buf) > 3 ? "..." : ""));
+}
+
+
 int
 man_pmacro(struct man *m, int ln, char *buf)
 {
@@ -506,11 +518,7 @@ man_pmacro(struct man *m, int ln, char *buf)
        }
 
        if (MAN_MAX == (c = man_hash_find(mac))) {
-               if ( ! (MAN_IGN_MACRO & m->pflags)) {
-                       (void)man_perr(m, ln, ppos, WMACRO);
-                       goto err;
-               }
-               if ( ! man_pwarn(m, ln, ppos, WMACRO))
+               if ( ! macrowarn(m, ln, mac))
                        goto err;
                return(1);
        }
index deb7b89..31841e5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man.h,v 1.10 2009/10/19 21:08:58 schwarze Exp $ */
+/*     $Id: man.h,v 1.11 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -50,7 +50,8 @@
 #define        MAN_RS           28
 #define        MAN_DT           29
 #define        MAN_UC           30
-#define        MAN_MAX          31
+#define        MAN_PD           31
+#define        MAN_MAX          32
 
 enum   man_type {
        MAN_TEXT,
index a7870ad..aab4650 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_action.c,v 1.8 2009/09/18 22:46:14 schwarze Exp $ */
+/*     $Id: man_action.c,v 1.9 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -63,6 +63,7 @@ const struct actions man_actions[MAN_MAX] = {
        { NULL }, /* RS */
        { NULL }, /* DT */
        { NULL }, /* UC */
+       { NULL }, /* PD */
 };
 
 static time_t    man_atotime(const char *);
index 63152bc..c8cad04 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_html.c,v 1.1 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: man_html.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -15,7 +15,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include <sys/types.h>
-#include <sys/queue.h>
 
 #include <assert.h>
 #include <ctype.h>
@@ -30,6 +29,7 @@
 #include "main.h"
 
 /* TODO: preserve ident widths. */
+/* FIXME: have PD set the default vspace width. */
 
 #define        INDENT            5
 #define        HALFINDENT        3
@@ -99,6 +99,7 @@ static        const struct htmlman mans[MAN_MAX] = {
        { man_RS_pre, NULL }, /* RS */
        { man_ign_pre, NULL }, /* DT */
        { man_ign_pre, NULL }, /* UC */
+       { man_ign_pre, NULL }, /* PD */
 };
 
 
@@ -173,7 +174,7 @@ print_man_node(MAN_ARGS)
        struct tag      *t;
 
        child = 1;
-       t = SLIST_FIRST(&h->tags);
+       t = h->tags.head;
 
        bufinit(h);
 
@@ -276,15 +277,11 @@ man_root_pre(MAN_ARGS)
 static void
 man_root_post(MAN_ARGS)
 {
-       struct tm        tm;
        struct htmlpair  tag[2];
        struct tag      *t, *tt;
-       char             b[BUFSIZ];
+       char             b[DATESIZ];
 
-       (void)localtime_r(&m->date, &tm);
-
-       if (0 == strftime(b, BUFSIZ - 1, "%B %e, %Y", &tm))
-               err(EXIT_FAILURE, "strftime");
+       time2a(m->date, b, DATESIZ);
 
        PAIR_CLASS_INIT(&tag[0], "footer");
        bufcat_style(h, "width", "100%");
index 6a62e78..bf9ac24 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_macro.c,v 1.8 2009/09/18 22:46:14 schwarze Exp $ */
+/*     $Id: man_macro.c,v 1.9 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -67,6 +67,7 @@ const struct man_macro __man_macros[MAN_MAX] = {
        { blk_imp, MAN_EXPLICIT }, /* RS */
        { in_line_eoln, 0 }, /* DT */
        { in_line_eoln, 0 }, /* UC */
+       { in_line_eoln, 0 }, /* PD */
 };
 
 const  struct man_macro * const man_macros = __man_macros;
index f6d59cd..7c9f05f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_term.c,v 1.18 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: man_term.c,v 1.19 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -32,6 +32,8 @@
 #define        INDENT            7
 #define        HALFINDENT        3
 
+/* FIXME: have PD set the default vspace width. */
+
 struct mtermp {
        int               fl;
 #define        MANT_LITERAL     (1 << 0)
@@ -62,14 +64,14 @@ struct      termact {
        void            (*post)(DECL_ARGS);
 };
 
-static int               arg2width(const struct man_node *);
-static int               arg2height(const struct man_node *);
+static int               a2width(const struct man_node *);
+static int               a2height(const struct man_node *);
 
-static void              print_head(struct termp *,
+static void              print_man_head(struct termp *,
                                const struct man_meta *);
-static void              print_body(DECL_ARGS);
-static void              print_node(DECL_ARGS);
-static void              print_foot(struct termp *,
+static void              print_man_body(DECL_ARGS);
+static void              print_man_node(DECL_ARGS);
+static void              print_man_foot(struct termp *,
                                const struct man_meta *);
 static void              print_bvspace(struct termp *,
                                const struct man_node *);
@@ -136,6 +138,7 @@ static      const struct termact termacts[MAN_MAX] = {
        { pre_RS, post_RS }, /* RS */
        { pre_ign, NULL }, /* DT */
        { pre_ign, NULL }, /* UC */
+       { pre_ign, NULL }, /* PD */
 };
 
 
@@ -163,7 +166,7 @@ terminal_man(void *arg, const struct man *man)
        n = man_node(man);
        m = man_meta(man);
 
-       print_head(p, m);
+       print_man_head(p, m);
        p->flags |= TERMP_NOSPACE;
 
        mt.fl = 0;
@@ -171,13 +174,13 @@ terminal_man(void *arg, const struct man *man)
        mt.offset = INDENT;
 
        if (n->child)
-               print_body(p, &mt, n->child, m);
-       print_foot(p, m);
+               print_man_body(p, &mt, n->child, m);
+       print_man_foot(p, m);
 }
 
 
 static int
-arg2height(const struct man_node *n)
+a2height(const struct man_node *n)
 {
        struct roffsu    su;
 
@@ -191,7 +194,7 @@ arg2height(const struct man_node *n)
 
 
 static int
-arg2width(const struct man_node *n)
+a2width(const struct man_node *n)
 {
        struct roffsu    su;
 
@@ -302,7 +305,7 @@ pre_IR(DECL_ARGS)
                        p->under++;
                if (i > 0)
                        p->flags |= TERMP_NOSPACE;
-               print_node(p, mt, nn, m);
+               print_man_node(p, mt, nn, m);
                if ( ! (i % 2))
                        p->under--;
        }
@@ -326,7 +329,7 @@ pre_RB(DECL_ARGS)
                if (i > 0)
                        p->flags |= TERMP_NOSPACE;
 
-               print_node(p, mt, nn, m);
+               print_man_node(p, mt, nn, m);
 
                if (i % 2 && MAN_RB == n->tok)
                        p->bold--;
@@ -349,7 +352,7 @@ pre_RI(DECL_ARGS)
                        p->under++;
                if (i > 0)
                        p->flags |= TERMP_NOSPACE;
-               print_node(p, mt, nn, m);
+               print_man_node(p, mt, nn, m);
                if ( ! (i % 2))
                        p->under--;
        }
@@ -376,7 +379,7 @@ pre_BI(DECL_ARGS)
 
                if (i)
                        p->flags |= TERMP_NOSPACE;
-               print_node(p, mt, nn, m);
+               print_man_node(p, mt, nn, m);
 
                if (i % 2 && MAN_BI == n->tok)
                        p->under--;
@@ -416,7 +419,7 @@ pre_sp(DECL_ARGS)
 {
        int              i, len;
 
-       len = n->child ? arg2height(n->child) : 1;
+       len = n->child ? a2height(n->child) : 1;
 
        if (0 == len)
                term_newln(p);
@@ -463,7 +466,7 @@ pre_HP(DECL_ARGS)
        /* Calculate offset. */
 
        if (NULL != (nn = n->parent->head->child))
-               if ((ival = arg2width(nn)) >= 0)
+               if ((ival = a2width(nn)) >= 0)
                        len = (size_t)ival;
 
        if (0 == len)
@@ -553,7 +556,7 @@ pre_IP(DECL_ARGS)
                if (NULL != (nn = nn->next)) {
                        for ( ; nn->next; nn = nn->next)
                                /* Do nothing. */ ;
-                       if ((ival = arg2width(nn)) >= 0)
+                       if ((ival = a2width(nn)) >= 0)
                                len = (size_t)ival;
                }
 
@@ -573,7 +576,7 @@ pre_IP(DECL_ARGS)
 
                /* Don't print the length value. */
                for (nn = n->child; nn->next; nn = nn->next)
-                       print_node(p, mt, nn, m);
+                       print_man_node(p, mt, nn, m);
                return(0);
        case (MAN_BODY):
                p->offset = mt->offset + len;
@@ -640,7 +643,7 @@ pre_TP(DECL_ARGS)
 
        if (NULL != (nn = n->parent->head->child))
                if (NULL != nn->next)
-                       if ((ival = arg2width(nn)) >= 0)
+                       if ((ival = a2width(nn)) >= 0)
                                len = (size_t)ival;
 
        switch (n->type) {
@@ -655,7 +658,7 @@ pre_TP(DECL_ARGS)
                /* Don't print same-line elements. */
                for (nn = n->child; nn; nn = nn->next)
                        if (nn->line > n->line)
-                               print_node(p, mt, nn, m);
+                               print_man_node(p, mt, nn, m);
 
                if (ival >= 0)
                        mt->lmargin = (size_t)ival;
@@ -818,7 +821,7 @@ pre_RS(DECL_ARGS)
                return(1);
        }
 
-       if ((ival = arg2width(nn)) < 0)
+       if ((ival = a2width(nn)) < 0)
                return(1);
 
        mt->offset = INDENT + (size_t)ival;
@@ -846,7 +849,7 @@ post_RS(DECL_ARGS)
 
 
 static void
-print_node(DECL_ARGS)
+print_man_node(DECL_ARGS)
 {
        int              c, sz;
 
@@ -882,7 +885,7 @@ print_node(DECL_ARGS)
        }
 
        if (c && n->child)
-               print_body(p, mt, n->child, m);
+               print_man_body(p, mt, n->child, m);
 
        if (MAN_TEXT != n->type)
                if (termacts[n->tok].post)
@@ -891,26 +894,22 @@ print_node(DECL_ARGS)
 
 
 static void
-print_body(DECL_ARGS)
+print_man_body(DECL_ARGS)
 {
 
-       print_node(p, mt, n, m);
+       print_man_node(p, mt, n, m);
        if ( ! n->next)
                return;
-       print_body(p, mt, n->next, m);
+       print_man_body(p, mt, n->next, m);
 }
 
 
 static void
-print_foot(struct termp *p, const struct man_meta *meta)
+print_man_foot(struct termp *p, const struct man_meta *meta)
 {
-       struct tm       *tm;
-       char             buf[BUFSIZ];
-
-       tm = localtime(&meta->date);
+       char            buf[DATESIZ];
 
-       if (0 == strftime(buf, p->rmargin, "%B %d, %Y", tm))
-               (void)strlcpy(buf, "(invalid date)", BUFSIZ);
+       time2a(meta->date, buf, DATESIZ);
 
        term_vspace(p);
 
@@ -935,7 +934,7 @@ print_foot(struct termp *p, const struct man_meta *meta)
 
 
 static void
-print_head(struct termp *p, const struct man_meta *meta)
+print_man_head(struct termp *p, const struct man_meta *meta)
 {
        char            *buf, *title;
 
index 38a7283..9b0cb6b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_validate.c,v 1.10 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: man_validate.c,v 1.11 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -86,6 +86,7 @@ static        const struct man_valid man_valids[MAN_MAX] = {
        { NULL, posts_part }, /* RS */
        { NULL, NULL }, /* DT */
        { NULL, NULL }, /* UC */
+       { NULL, NULL }, /* PD */
 };
 
 
index ea744ea..98a439a 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $Id: mandoc.1,v 1.17 2009/10/21 19:13:50 schwarze Exp $
+.\"    $Id: mandoc.1,v 1.18 2009/10/27 21:40:07 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 October 27, 2009
+.Dd October 29, 2009
 .Dt MANDOC 1
 .Os
 .
@@ -28,7 +28,7 @@
 .Nm mandoc
 .Op Fl f Ns Ar option...
 .Op Fl m Ns Ar format
-.Op Fl o Ns Ar option...
+.Op Fl O Ns Ar option...
 .Op Fl T Ns Ar output
 .Op Fl V
 .Op Fl W Ns Ar err...
@@ -54,7 +54,7 @@ Input format.  See
 for available formats.  Defaults to
 .Fl m Ns Ar andoc .
 .
-.It Fl o Ns Ar option...
+.It Fl O Ns Ar option...
 Comma-separated output options.  See
 .Sx Output Options
 for details.
@@ -255,12 +255,12 @@ For the time being, only
 .Fl T Ns Ar html
 is the only mode with output options:
 .Bl -tag -width Ds
-.It Fl o Ns Ar style=style.css
+.It Fl O Ns Ar style=style.css
 The file
 .Ar style.css
 is used for an external style-sheet.  This must be a valid absolute or
 relative URI.
-.It Fl o Ns Ar includes=fmt
+.It Fl O Ns Ar includes=fmt
 The string
 .Ar fmt ,
 for example,
@@ -271,7 +271,7 @@ macro).  Instances of
 .Sq \&%I
 are replaced with the include filename.  The default is not to present a
 hyperlink.
-.It Fl o Ns Ar man=fmt
+.It Fl O Ns Ar man=fmt
 The string
 .Ar fmt ,
 for example,
@@ -413,4 +413,4 @@ the maximum size of an element attribute is determined by
 .Dv BUFSIZ ,
 which is usually 1024 bytes.  Be aware of this when setting long link
 formats with
-.Fl o Ns Ar man=fmt .
+.Fl O Ns Ar man=fmt .
index 47ff812..80441bd 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $Id: mdoc.7,v 1.17 2009/10/21 19:13:50 schwarze Exp $
+.\"    $Id: mdoc.7,v 1.18 2009/10/27 21:40:07 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: October 19 2009 $
+.Dd October 29, 2009
 .Dt MDOC 7
 .Os
 .
@@ -611,8 +611,10 @@ then the macro accepts an arbitrary number of arguments.
 .It Sx \&%N  Ta    \&No     Ta    \&No     Ta    >0
 .It Sx \&%O  Ta    \&No     Ta    \&No     Ta    >0
 .It Sx \&%P  Ta    \&No     Ta    \&No     Ta    >0
+.It Sx \&%Q  Ta    \&No     Ta    \&No     Ta    >0
 .It Sx \&%R  Ta    \&No     Ta    \&No     Ta    >0
 .It Sx \&%T  Ta    \&No     Ta    \&No     Ta    >0
+.It Sx \&%U  Ta    \&No     Ta    \&No     Ta    >0
 .It Sx \&%V  Ta    \&No     Ta    \&No     Ta    >0
 .It Sx \&Ad  Ta    Yes      Ta    Yes      Ta    n
 .It Sx \&An  Ta    Yes      Ta    Yes      Ta    n
@@ -756,6 +758,9 @@ Article title of an
 block.  This macro may also be used in a non-bibliographical context
 when referring to article titles.
 .
+.Ss \&%U
+URI of reference document.
+.
 .Ss \&%V
 Volume number of an
 .Sx \&Rs
@@ -943,7 +948,7 @@ which aligns around an imagined centre axis.
 .It
 As a precalculated width for a named macro.  The most popular is the
 imaginary macro
-.Ar Ds ,
+.Ar \&Ds ,
 which resolves to
 .Ar 6n .
 .It
@@ -1446,6 +1451,19 @@ and
 .Ss \&Lb
 .Ss \&Li
 .Ss \&Lk
+Format a hyperlink.  The calling syntax is as follows:
+.Pp
+.D1 \. Ns Sx \&Lk Cm uri Op Cm name
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.Lk http://bsd.lv "The BSD.lv Project"
+\&.Lk http://bsd.lv
+.Ed
+.Pp
+See also
+.Sx \&Mt .
+.
 .Ss \&Lp
 .Ss \&Ms
 .Ss \&Mt
@@ -1547,7 +1565,7 @@ block.  Does not have any tail arguments.
 .Ss \&Rs
 Begins a bibliographic
 .Pq Dq reference
-block.  Does not have any head arguments.  The block macro and may only
+block.  Does not have any head arguments.  The block macro may only
 contain
 .Sx \&%A ,
 .Sx \&%B ,
index d793843..a0e4bd9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc.c,v 1.30 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: mdoc.c,v 1.31 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -116,7 +116,9 @@ const       char *const __mdoc_macronames[MDOC_MAX] = {
        /* LINTED */
        "Brc",          "\%C",          "Es",           "En",
        /* LINTED */
-       "Dx",           "\%Q",          "br",           "sp"
+       "Dx",           "\%Q",          "br",           "sp",
+       /* LINTED */
+       "\%U"
        };
 
 const  char *const __mdoc_argnames[MDOC_ARG_MAX] = {
@@ -659,7 +661,6 @@ parsetext(struct mdoc *m, int line, char *buf)
 
 
 
-
 static int
 macrowarn(struct mdoc *m, int ln, const char *buf)
 {
index f92cfd7..1126bf7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc.h,v 1.14 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: mdoc.h,v 1.15 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -17,8 +17,6 @@
 #ifndef MDOC_H
 #define MDOC_H
 
-#include <time.h>
-
 /*
  * This library implements a validating scanner/parser for ``mdoc'' roff
  * macro documents, a.k.a. BSD manual page documents.  The mdoc.c file
 #define        MDOC__Q          117
 #define MDOC_br                 118
 #define MDOC_sp                 119
-#define        MDOC_MAX         120
+#define MDOC__U                 120
+#define        MDOC_MAX         121
 
 /* What follows is a list of ALL possible macro arguments. */
 
index 715c2b6..1521dda 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_action.c,v 1.23 2009/10/19 16:27:52 schwarze Exp $ */
+/*     $Id: mdoc_action.c,v 1.24 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#ifndef        OSNAME
 #include <sys/utsname.h>
+#endif
 
 #include <assert.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
 #include "libmdoc.h"
 
@@ -170,7 +173,7 @@ static      const struct actions mdoc_actions[MDOC_MAX] = {
        { NULL, NULL }, /* Ud */
        { NULL, post_lb }, /* Lb */
        { NULL, NULL }, /* Lp */
-       { NULL, post_tilde }, /* Lk */
+       { NULL, NULL }, /* Lk */
        { NULL, NULL }, /* Mt */
        { NULL, NULL }, /* Brq */
        { NULL, NULL }, /* Bro */
@@ -182,9 +185,10 @@ static     const struct actions mdoc_actions[MDOC_MAX] = {
        { NULL, NULL }, /* %Q */
        { NULL, NULL }, /* br */
        { NULL, NULL }, /* sp */
+       { NULL, NULL }, /* %U */
 };
 
-#define        RSORD_MAX 13
+#define        RSORD_MAX 14
 
 static const int rsord[RSORD_MAX] = {
        MDOC__A,
@@ -199,7 +203,8 @@ static      const int rsord[RSORD_MAX] = {
        MDOC__Q,
        MDOC__D,
        MDOC__O,
-       MDOC__C
+       MDOC__C,
+       MDOC__U
 };
 
 
@@ -516,7 +521,15 @@ static int
 post_os(POST_ARGS)
 {
        char              buf[64];
+#ifndef        OSNAME
        struct utsname    utsname;
+#endif
+
+       /*
+        * Setting OSNAME to be the name of the target operating system,
+        * e.g., "OpenBSD 4.4", will result in the compile-time constant
+        * by supplied instead of the value in uname().
+        */
 
        if (m->meta.os)
                free(m->meta.os);
@@ -526,6 +539,10 @@ post_os(POST_ARGS)
                return(0);
 
        if (0 == buf[0]) {
+#ifdef OSNAME
+               if (strlcat(buf, OSNAME, 64) >= 64)
+                       return(mdoc_nerr(m, n, EUTSNAME));
+#else
                if (-1 == uname(&utsname))
                        return(mdoc_nerr(m, n, EUTSNAME));
                if (strlcat(buf, utsname.sysname, 64) >= 64)
@@ -534,6 +551,7 @@ post_os(POST_ARGS)
                        return(mdoc_nerr(m, n, ETOOLONG));
                if (strlcat(buf, utsname.release, 64) >= 64)
                        return(mdoc_nerr(m, n, ETOOLONG));
+#endif
        }
 
        if (NULL == (m->meta.os = strdup(buf)))
@@ -753,7 +771,6 @@ post_tilde(POST_ARGS)
        np = n;
        m->next = MDOC_NEXT_CHILD;
 
-       /* XXX: not documented for `Lk'. */
        if ( ! mdoc_word_alloc(m, n->line, n->pos, "~"))
                return(0);
        m->last = np;
index 18085a8..fd30208 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_argv.c,v 1.17 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: mdoc_argv.c,v 1.18 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -203,6 +203,7 @@ static      int mdoc_argflags[MDOC_MAX] = {
        0, /* %Q */
        0, /* br */
        0, /* sp */
+       0, /* %U */
 };
 
 
index e258afd..0ad0315 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_html.c,v 1.1 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: mdoc_html.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -16,7 +16,6 @@
  */
 #include <sys/types.h>
 #include <sys/param.h>
-#include <sys/queue.h>
 
 #include <assert.h>
 #include <ctype.h>
@@ -249,6 +248,7 @@ static      const struct htmlmdoc mdocs[MDOC_MAX] = {
        {mdoc__x_pre, mdoc__x_post}, /* %Q */
        {mdoc_sp_pre, NULL}, /* br */
        {mdoc_sp_pre, NULL}, /* sp */
+       {mdoc__x_pre, mdoc__x_post}, /* %U */
 };
 
 
@@ -411,7 +411,7 @@ print_mdoc_node(MDOC_ARGS)
        struct tag      *t;
 
        child = 1;
-       t = SLIST_FIRST(&h->tags);
+       t = h->tags.head;
 
        bufinit(h);
        switch (n->type) {
@@ -451,10 +451,11 @@ print_mdoc_node(MDOC_ARGS)
 static void
 mdoc_root_post(MDOC_ARGS)
 {
-       struct tm        tm;
        struct htmlpair  tag[2];
        struct tag      *t, *tt;
-       char             b[BUFSIZ];
+       char             b[DATESIZ];
+
+       time2a(m->date, b, DATESIZ);
 
        /*
         * XXX: this should use divs, but in Firefox, divs with nested
@@ -462,11 +463,6 @@ mdoc_root_post(MDOC_ARGS)
         * below.  So I use tables, instead.
         */
 
-       (void)localtime_r(&m->date, &tm);
-
-       if (0 == strftime(b, BUFSIZ - 1, "%B %e, %Y", &tm))
-               err(EXIT_FAILURE, "strftime");
-
        PAIR_CLASS_INIT(&tag[0], "footer");
        bufcat_style(h, "width", "100%");
        PAIR_STYLE_INIT(&tag[1], h);
@@ -979,7 +975,7 @@ mdoc_it_head_pre(MDOC_ARGS, int type, struct roffsu *width)
                print_otag(h, TAG_SPAN, 1, &tag);
                break;
        case (MDOC_Enum):
-               ord = SLIST_FIRST(&h->ords);
+               ord = h->ords.head;
                assert(ord);
                nbuf[BUFSIZ - 1] = 0;
                (void)snprintf(nbuf, BUFSIZ - 1, "%d.", ord->pos++);
@@ -1114,7 +1110,8 @@ mdoc_bl_pre(MDOC_ARGS)
                err(EXIT_FAILURE, "malloc");
        ord->cookie = n;
        ord->pos = 1;
-       SLIST_INSERT_HEAD(&h->ords, ord, entry);
+       ord->next = h->ords.head;
+       h->ords.head = ord;
        return(1);
 }
 
@@ -1130,9 +1127,9 @@ mdoc_bl_post(MDOC_ARGS)
        if (MDOC_Enum != a2list(n))
                return;
 
-       ord = SLIST_FIRST(&h->ords);
+       ord = h->ords.head;
        assert(ord);
-       SLIST_REMOVE_HEAD(&h->ords, entry);
+       h->ords.head = ord->next;
        free(ord);
 }
 
@@ -1755,6 +1752,9 @@ mdoc_lk_pre(MDOC_ARGS)
        tag[1].val = nn->string;
        print_otag(h, TAG_A, 2, tag);
 
+       if (NULL == nn->next)
+               return(1);
+
        for (nn = nn->next; nn; nn = nn->next)
                print_text(h, nn->string);
 
@@ -2145,56 +2145,65 @@ mdoc_lb_pre(MDOC_ARGS)
 static int
 mdoc__x_pre(MDOC_ARGS)
 {
-       struct htmlpair tag;
+       struct htmlpair tag[2];
 
        switch (n->tok) {
        case(MDOC__A):
-               PAIR_CLASS_INIT(&tag, "ref-auth");
+               PAIR_CLASS_INIT(&tag[0], "ref-auth");
                break;
        case(MDOC__B):
-               PAIR_CLASS_INIT(&tag, "ref-book");
+               PAIR_CLASS_INIT(&tag[0], "ref-book");
                break;
        case(MDOC__C):
-               PAIR_CLASS_INIT(&tag, "ref-city");
+               PAIR_CLASS_INIT(&tag[0], "ref-city");
                break;
        case(MDOC__D):
-               PAIR_CLASS_INIT(&tag, "ref-date");
+               PAIR_CLASS_INIT(&tag[0], "ref-date");
                break;
        case(MDOC__I):
-               PAIR_CLASS_INIT(&tag, "ref-issue");
+               PAIR_CLASS_INIT(&tag[0], "ref-issue");
                break;
        case(MDOC__J):
-               PAIR_CLASS_INIT(&tag, "ref-jrnl");
+               PAIR_CLASS_INIT(&tag[0], "ref-jrnl");
                break;
        case(MDOC__N):
-               PAIR_CLASS_INIT(&tag, "ref-num");
+               PAIR_CLASS_INIT(&tag[0], "ref-num");
                break;
        case(MDOC__O):
-               PAIR_CLASS_INIT(&tag, "ref-opt");
+               PAIR_CLASS_INIT(&tag[0], "ref-opt");
                break;
        case(MDOC__P):
-               PAIR_CLASS_INIT(&tag, "ref-page");
+               PAIR_CLASS_INIT(&tag[0], "ref-page");
                break;
        case(MDOC__Q):
-               PAIR_CLASS_INIT(&tag, "ref-corp");
+               PAIR_CLASS_INIT(&tag[0], "ref-corp");
                break;
        case(MDOC__R):
-               PAIR_CLASS_INIT(&tag, "ref-rep");
+               PAIR_CLASS_INIT(&tag[0], "ref-rep");
                break;
        case(MDOC__T):
-               PAIR_CLASS_INIT(&tag, "ref-title");
+               PAIR_CLASS_INIT(&tag[0], "ref-title");
                print_text(h, "\\(lq");
                h->flags |= HTML_NOSPACE;
                break;
+       case(MDOC__U):
+               PAIR_CLASS_INIT(&tag[0], "link-ref");
+               break;
        case(MDOC__V):
-               PAIR_CLASS_INIT(&tag, "ref-vol");
+               PAIR_CLASS_INIT(&tag[0], "ref-vol");
                break;
        default:
                abort();
                /* NOTREACHED */
        }
 
-       print_otag(h, TAG_SPAN, 1, &tag);
+       if (MDOC__U != n->tok) {
+               print_otag(h, TAG_SPAN, 1, tag);
+               return(1);
+       }
+
+       PAIR_HREF_INIT(&tag[1], n->child->string);
+       print_otag(h, TAG_A, 2, tag);
        return(1);
 }
 
index 26332ca..9b73f9b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_macro.c,v 1.24 2009/09/21 21:11:37 schwarze Exp $ */
+/*     $Id: mdoc_macro.c,v 1.25 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -174,6 +174,7 @@ const       struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
        { in_line_eoln, 0 }, /* %Q */
        { in_line_eoln, 0 }, /* br */
        { in_line_eoln, 0 }, /* sp */
+       { in_line_eoln, 0 }, /* %U */
 };
 
 const  struct mdoc_macro * const mdoc_macros = __mdoc_macros;
index 05502c4..ab3f56f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_strings.c,v 1.9 2009/08/22 22:11:24 schwarze Exp $ */
+/*     $Id: mdoc_strings.c,v 1.10 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 
 #include "libmdoc.h"
 
index 7c2b91d..5844ddb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_term.c,v 1.61 2009/10/21 19:13:50 schwarze Exp $ */
+/*     $Id: mdoc_term.c,v 1.62 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -48,6 +48,23 @@ struct       termact {
        void    (*post)(DECL_ARGS);
 };
 
+static size_t    a2width(const struct mdoc_argv *, int);
+static size_t    a2height(const struct mdoc_node *);
+static size_t    a2offs(const struct mdoc_argv *);
+
+static int       arg_hasattr(int, const struct mdoc_node *);
+static int       arg_getattrs(const int *, int *, size_t,
+                       const struct mdoc_node *);
+static int       arg_getattr(int, const struct mdoc_node *);
+static int       arg_listtype(const struct mdoc_node *);
+static void      print_bvspace(struct termp *,
+                       const struct mdoc_node *,
+                       const struct mdoc_node *);
+static void      print_node(DECL_ARGS);
+static void      print_head(DECL_ARGS);
+static void      print_body(DECL_ARGS);
+static void      print_foot(DECL_ARGS);
+
 static void      termp____post(DECL_ARGS);
 static void      termp_an_post(DECL_ARGS);
 static void      termp_aq_post(DECL_ARGS);
@@ -236,25 +253,9 @@ static     const struct termact termacts[MDOC_MAX] = {
        { NULL, termp____post }, /* %Q */
        { termp_sp_pre, NULL }, /* br */
        { termp_sp_pre, NULL }, /* sp */
+       { termp_under_pre, termp____post }, /* %U */
 };
 
-static size_t    arg2width(const struct mdoc_argv *, int);
-static size_t    arg2height(const struct mdoc_node *);
-static size_t    arg2offs(const struct mdoc_argv *);
-
-static int       arg_hasattr(int, const struct mdoc_node *);
-static int       arg_getattrs(const int *, int *, size_t,
-                       const struct mdoc_node *);
-static int       arg_getattr(int, const struct mdoc_node *);
-static int       arg_listtype(const struct mdoc_node *);
-static void      print_bvspace(struct termp *,
-                       const struct mdoc_node *,
-                       const struct mdoc_node *);
-static void      print_node(DECL_ARGS);
-static void      print_head(DECL_ARGS);
-static void      print_body(DECL_ARGS);
-static void      print_foot(DECL_ARGS);
-
 
 void
 terminal_mdoc(void *arg, const struct mdoc *mdoc)
@@ -342,8 +343,8 @@ print_node(DECL_ARGS)
 static void
 print_foot(DECL_ARGS)
 {
-       struct tm       *tm;
-       char            *buf, *os;
+       char             buf[DATESIZ];
+       char            *os;
 
        /*
         * Output the footer in new-groff style, that is, three columns
@@ -353,15 +354,10 @@ print_foot(DECL_ARGS)
         * SYSTEM                  DATE                    SYSTEM
         */
 
-       if (NULL == (buf = malloc(p->rmargin)))
-               err(EXIT_FAILURE, "malloc");
        if (NULL == (os = malloc(p->rmargin)))
                err(EXIT_FAILURE, "malloc");
 
-       tm = localtime(&m->date);
-
-       if (0 == strftime(buf, p->rmargin, "%B %e, %Y", tm))
-               err(EXIT_FAILURE, "strftime");
+       time2a(m->date, buf, DATESIZ);
 
        (void)strlcpy(os, m->os, p->rmargin);
 
@@ -393,7 +389,6 @@ print_foot(DECL_ARGS)
        p->rmargin = p->maxrmargin;
        p->flags = 0;
 
-       free(buf);
        free(os);
 }
 
@@ -469,7 +464,7 @@ print_head(DECL_ARGS)
 
 
 static size_t
-arg2height(const struct mdoc_node *n)
+a2height(const struct mdoc_node *n)
 {
        struct roffsu    su;
 
@@ -483,7 +478,7 @@ arg2height(const struct mdoc_node *n)
 
 
 static size_t
-arg2width(const struct mdoc_argv *arg, int pos)
+a2width(const struct mdoc_argv *arg, int pos)
 {
        struct roffsu    su;
 
@@ -538,7 +533,7 @@ arg_listtype(const struct mdoc_node *n)
 
 
 static size_t
-arg2offs(const struct mdoc_argv *arg)
+a2offs(const struct mdoc_argv *arg)
 {
        struct roffsu    su;
 
@@ -717,23 +712,23 @@ termp_it_pre(DECL_ARGS)
                for (i = 0, nn = n->prev; nn &&
                                i < (int)bl->args->argv[vals[2]].sz;
                                nn = nn->prev, i++)
-                       offset += arg2width
+                       offset += a2width
                                (&bl->args->argv[vals[2]], i);
 
                /* Whether exceeds maximum column. */
                if (i < (int)bl->args->argv[vals[2]].sz)
-                       width = arg2width(&bl->args->argv[vals[2]], i);
+                       width = a2width(&bl->args->argv[vals[2]], i);
                else
                        width = 0;
 
                if (vals[1] >= 0)
-                       offset += arg2offs(&bl->args->argv[vals[1]]);
+                       offset += a2offs(&bl->args->argv[vals[1]]);
                break;
        default:
                if (vals[0] >= 0)
-                       width = arg2width(&bl->args->argv[vals[0]], 0);
+                       width = a2width(&bl->args->argv[vals[0]], 0);
                if (vals[1] >= 0)
-                       offset += arg2offs(&bl->args->argv[vals[1]]);
+                       offset += a2offs(&bl->args->argv[vals[1]]);
                break;
        }
 
@@ -1556,7 +1551,7 @@ termp_bd_pre(DECL_ARGS)
                        type = nn->args->argv[i].arg;
                        break;
                case (MDOC_Offset):
-                       p->offset += arg2offs(&nn->args->argv[i]);
+                       p->offset += a2offs(&nn->args->argv[i]);
                        break;
                default:
                        break;
@@ -1811,7 +1806,7 @@ termp_sp_pre(DECL_ARGS)
 
        switch (n->tok) {
        case (MDOC_sp):
-               len = n->child ? arg2height(n->child) : 1;
+               len = n->child ? a2height(n->child) : 1;
                break;
        case (MDOC_br):
                len = 0;
@@ -2007,6 +2002,8 @@ static void
 termp____post(DECL_ARGS)
 {
 
+       /* TODO: %U. */
+
        p->flags |= TERMP_NOSPACE;
        switch (n->tok) {
        case (MDOC__T):
@@ -2026,16 +2023,17 @@ termp_lk_pre(DECL_ARGS)
 {
        const struct mdoc_node *nn;
 
-       if (NULL == (nn = n->child->next)) {
-               p->under++;
+       p->under++;
+       nn = n->child;
+
+       if (NULL == nn->next)
                return(1);
-       }
 
-       p->under++;
        term_word(p, nn->string);
+       p->under--;
+
        p->flags |= TERMP_NOSPACE;
        term_word(p, ":");
-       p->under--;
 
        p->bold++;
        for (nn = nn->next; nn; nn = nn->next)
index ab96455..2011fa8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_validate.c,v 1.37 2009/10/21 19:13:51 schwarze Exp $ */
+/*     $Id: mdoc_validate.c,v 1.38 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -115,19 +115,18 @@ static    v_post   posts_bf[] = { hwarn_le1, post_bf, NULL };
 static v_post   posts_bl[] = { bwarn_ge1, post_bl, NULL };
 static v_post   posts_bool[] = { eerr_eq1, ebool, NULL };
 static v_post   posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL };
-static v_post   posts_in[] = { eerr_eq1, NULL };
 static v_post   posts_it[] = { post_it, NULL };
 static v_post   posts_lb[] = { eerr_eq1, post_lb, NULL };
 static v_post   posts_nd[] = { berr_ge1, NULL };
 static v_post   posts_nm[] = { post_nm, NULL };
 static v_post   posts_notext[] = { eerr_eq0, NULL };
-static v_post   posts_pf[] = { eerr_eq1, NULL };
 static v_post   posts_rs[] = { berr_ge1, herr_eq0, post_rs, NULL };
 static v_post   posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL };
 static v_post   posts_sp[] = { eerr_le1, NULL };
 static v_post   posts_ss[] = { herr_ge1, NULL };
 static v_post   posts_st[] = { eerr_eq1, post_st, NULL };
 static v_post   posts_text[] = { eerr_ge1, NULL };
+static v_post   posts_text1[] = { eerr_eq1, NULL };
 static v_post   posts_wline[] = { bwarn_ge1, herr_eq0, NULL };
 static v_post   posts_wtext[] = { ewarn_ge1, NULL };
 static v_post   posts_xr[] = { eerr_ge1, eerr_le2, NULL };
@@ -178,7 +177,7 @@ const       struct valids mdoc_valids[MDOC_MAX] = {
        { NULL, posts_text },                   /* Fn */
        { NULL, posts_wtext },                  /* Ft */
        { NULL, posts_text },                   /* Ic */
-       { NULL, posts_in },                     /* In */
+       { NULL, posts_text1 },                  /* In */
        { NULL, NULL },                         /* Li */
        { NULL, posts_nd },                     /* Nd */
        { NULL, posts_nm },                     /* Nm */
@@ -226,7 +225,7 @@ const       struct valids mdoc_valids[MDOC_MAX] = {
        { NULL, NULL },                         /* Nx */
        { NULL, NULL },                         /* Ox */
        { NULL, NULL },                         /* Pc */
-       { NULL, posts_pf },                     /* Pf */
+       { NULL, posts_text1 },                  /* Pf */
        { NULL, NULL },                         /* Po */
        { NULL, posts_wline },                  /* Pq */
        { NULL, NULL },                         /* Qc */
@@ -257,7 +256,7 @@ const       struct valids mdoc_valids[MDOC_MAX] = {
        { NULL, posts_notext },                 /* Ud */
        { pres_lb, posts_lb },                  /* Lb */
        { NULL, posts_notext },                 /* Lp */
-       { NULL, NULL },                         /* Lk */
+       { NULL, posts_text },                   /* Lk */
        { NULL, posts_text },                   /* Mt */
        { NULL, posts_wline },                  /* Brq */
        { NULL, NULL },                         /* Bro */
@@ -269,6 +268,7 @@ const       struct valids mdoc_valids[MDOC_MAX] = {
        { NULL, posts_text },                   /* %Q */
        { NULL, posts_notext },                 /* br */
        { NULL, posts_sp },                     /* sp */
+       { NULL, posts_text1 },                  /* %U */
 };
 
 
@@ -692,6 +692,8 @@ pre_bd(PRE_ARGS)
        for (i = 0, err = type = 0; ! err &&
                        i < (int)n->args->argc; i++)
                switch (n->args->argv[i].arg) {
+               case (MDOC_Centred):
+                       /* FALLTHROUGH */
                case (MDOC_Ragged):
                        /* FALLTHROUGH */
                case (MDOC_Unfilled):
@@ -1149,6 +1151,8 @@ post_rs(POST_ARGS)
 
        for (nn = mdoc->last->child; nn; nn = nn->next)
                switch (nn->tok) {
+               case(MDOC__U):
+                       /* FALLTHROUGH */
                case(MDOC__Q):
                        /* FALLTHROUGH */
                case(MDOC__C):
index 228dd9c..bfd4337 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: out.c,v 1.1 2009/10/21 19:13:51 schwarze Exp $ */
+/*     $Id: out.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
  */
 #include <sys/types.h>
 
+#include <assert.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <time.h>
 
 #include "out.h"
 
-
 /*
  * Convert a `scaling unit' to a consistent form, or fail.  Scaling
  * units are documented in groff.7, mdoc.7, man.7.
@@ -117,3 +119,45 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
 
        return(1);
 }
+
+
+/*
+ * Correctly writes the time in nroff form, which differs from standard
+ * form in that a space isn't printed in lieu of the extra %e field for
+ * single-digit dates.
+ */
+void
+time2a(time_t t, char *dst, size_t sz)
+{
+       struct tm        tm;
+       char             buf[5];
+       char            *p;
+       size_t           nsz;
+
+       assert(sz > 1);
+       localtime_r(&t, &tm);
+
+       p = dst;
+       nsz = 0;
+
+       dst[0] = '\0';
+
+       if (0 == (nsz = strftime(p, sz, "%B ", &tm)))
+               return;
+
+       p += (int)nsz;
+       sz -= nsz;
+
+       if (0 == strftime(buf, sizeof(buf), "%e, ", &tm))
+               return;
+
+       nsz = strlcat(p, buf + (' ' == buf[0] ? 1 : 0), sz);
+
+       if (nsz >= sz)
+               return;
+
+       p += (int)nsz;
+       sz -= nsz;
+
+       (void)strftime(p, sz, "%Y", &tm);
+}
index 9ce9ecf..88d6131 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: out.h,v 1.1 2009/10/21 19:13:51 schwarze Exp $ */
+/*     $Id: out.h,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -17,6 +17,8 @@
 #ifndef OUT_H
 #define OUT_H
 
+#define        DATESIZ         24
+
 __BEGIN_DECLS
 
 enum   roffscale {
@@ -52,6 +54,7 @@ struct        roffsu {
 
 int              a2roffsu(const char *,
                        struct roffsu *, enum roffscale);
+void             time2a(time_t, char *, size_t);
 
 __END_DECLS
 
index 8d5f71f..74f3c6c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: term.c,v 1.17 2009/10/24 13:13:20 schwarze Exp $ */
+/*     $Id: term.c,v 1.18 2009/10/27 21:40:07 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -204,7 +204,8 @@ term_flushln(struct termp *p)
                                vis = 0;
                        }
                        /* Remove the overstep width. */
-                       bp += overstep;
+                       bp += (int)/* LINTED */
+                               overstep;
                        overstep = 0;
                } else {
                        for (j = 0; j < (int)vbl; j++)
@@ -222,14 +223,15 @@ term_flushln(struct termp *p)
                }
                vis += vsz;
        }
+
        p->col = 0;
+       overstep = 0;
 
        if ( ! (TERMP_NOBREAK & p->flags)) {
                putchar('\n');
                return;
        }
 
-       overstep = 0;
        if (TERMP_HANG & p->flags) {
                /* We need one blank after the tag. */
                overstep = /* LINTED */
@@ -545,14 +547,14 @@ encode(struct termp *p, char c)
 {
 
        if (' ' != c) {
-               if (p->bold) {
-                       buffer(p, c);
-                       buffer(p, 8);
-               }
                if (p->under) {
                        buffer(p, '_');
                        buffer(p, 8);
                }
+               if (p->bold) {
+                       buffer(p, c);
+                       buffer(p, 8);
+               }
        }
        buffer(p, c);
 }