# $OpenBSD: Makefile,v 1.21 2009/10/27 21:40:07 schwarze Exp $
-VERSION=1.9.11
+VERSION=1.9.13
CFLAGS+=-DVERSION=\"${VERSION}\"
WARNS?= 3
-/* $Id: arch.c,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: arch.c,v 1.5 2009/10/26 17:05:43 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
*/
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "libmdoc.h"
-/* $Id: arch.in,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: arch.in,v 1.5 2009/06/10 20:18:43 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: att.c,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: att.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
*/
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "libmdoc.h"
-/* $Id: att.in,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: att.in,v 1.5 2009/06/10 20:18:43 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: chars.c,v 1.2 2009/10/19 09:56:35 schwarze Exp $ */
+/* $Id: chars.c,v 1.12 2009/11/01 07:44:32 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
-#include <err.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int type;
#define CHARS_CHAR (1 << 0)
#define CHARS_STRING (1 << 1)
-#define CHARS_BOTH (0x03)
+#define CHARS_BOTH (CHARS_CHAR | CHARS_STRING)
};
#define LINES_MAX 351
* (they're in-line re-ordered during lookup).
*/
- if (NULL == (tab = malloc(sizeof(struct tbl))))
- err(1, "malloc");
- tab->type = type;
+ tab = malloc(sizeof(struct tbl));
+ if (NULL == tab) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
htab = calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
- if (NULL == htab)
- err(1, "malloc");
+ if (NULL == htab) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
for (i = 0; i < LINES_MAX; i++) {
hash = (int)lines[i].code[0] - PRINT_LO;
}
tab->htab = htab;
+ tab->type = type;
return(tab);
}
-/* $Id: chars.h,v 1.1 2009/10/19 09:16:58 schwarze Exp $ */
+/* $Id: chars.h,v 1.1 2009/09/17 07:41:28 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: chars.in,v 1.2 2009/10/19 09:56:35 schwarze Exp $ */
+/* $Id: chars.in,v 1.18 2009/09/24 11:55:28 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: html.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: html.c,v 1.80 2009/11/02 06:22:44 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <sys/types.h>
#include <assert.h>
-#include <err.h>
-#include <stdio.h>
+#include <ctype.h>
#include <stdarg.h>
+#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
"valign",
"target",
"id",
+ "summary",
};
+#ifdef __linux__
+extern int getsubopt(char **, char * const *, char **);
+#endif
+
void *
html_alloc(char *outopts)
{
toks[2] = "includes";
toks[3] = NULL;
- if (NULL == (h = calloc(1, sizeof(struct html))))
- return(NULL);
+ h = calloc(1, sizeof(struct html));
+ if (NULL == h) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
h->tags.head = NULL;
h->ords.head = NULL;
-
- if (NULL == (h->symtab = chars_init(CHARS_HTML))) {
- free(h);
- return(NULL);
- }
+ h->symtab = chars_init(CHARS_HTML);
while (outopts && *outopts)
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
print_spec(struct html *h, const char *p, int len)
{
const char *rhs;
- int i;
size_t sz;
rhs = chars_a2ascii(h->symtab, p, (size_t)len, &sz);
if (NULL == rhs)
return;
- for (i = 0; i < (int)sz; i++)
- putchar(rhs[i]);
+ fwrite(rhs, 1, sz, stdout);
}
print_res(struct html *h, const char *p, int len)
{
const char *rhs;
- int i;
size_t sz;
rhs = chars_a2res(h->symtab, p, (size_t)len, &sz);
if (NULL == rhs)
return;
- for (i = 0; i < (int)sz; i++)
- putchar(rhs[i]);
+ fwrite(rhs, 1, sz, stdout);
}
static void
print_encode(struct html *h, const char *p)
{
+ size_t sz;
for (; *p; p++) {
+ sz = strcspn(p, "\\<>&");
+
+ fwrite(p, 1, sz, stdout);
+ p += /* LINTED */
+ sz;
+
if ('\\' == *p) {
print_escape(h, &p);
continue;
- }
- switch (*p) {
- case ('<'):
- printf("<");
+ } else if ('\0' == *p)
break;
- case ('>'):
+
+ if ('<' == *p)
+ printf("<");
+ else if ('>' == *p)
printf(">");
- break;
- case ('&'):
+ else if ('&' == *p)
printf("&");
- break;
- default:
- putchar(*p);
- break;
- }
}
}
struct tag *t;
if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
- if (NULL == (t = malloc(sizeof(struct tag))))
- err(EXIT_FAILURE, "malloc");
+ t = malloc(sizeof(struct tag));
+ if (NULL == t) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
t->tag = tag;
t->next = h->tags.head;
h->tags.head = t;
if ( ! (HTML_NOSPACE & h->flags))
if ( ! (HTML_CLRLINE & htmltags[tag].flags))
- printf(" ");
+ putchar(' ');
printf("<%s", htmltags[tag].name);
for (i = 0; i < sz; i++) {
printf(" %s=\"", htmlattrs[p[i].key]);
assert(p->val);
print_encode(h, p[i].val);
- printf("\"");
+ putchar('\"');
}
- printf(">");
+ putchar('>');
h->flags |= HTML_NOSPACE;
if (HTML_CLRLINE & htmltags[tag].flags)
{
printf("</%s>", htmltags[tag].name);
- if (HTML_CLRLINE & htmltags[tag].flags)
+ if (HTML_CLRLINE & htmltags[tag].flags) {
h->flags |= HTML_NOSPACE;
- if (HTML_CLRLINE & htmltags[tag].flags)
h->flags |= HTML_NEWLINE;
- else
+ putchar('\n');
+ } else
h->flags &= ~HTML_NEWLINE;
}
}
if ( ! (h->flags & HTML_NOSPACE))
- printf(" ");
+ putchar(' ');
h->flags &= ~HTML_NOSPACE;
h->flags &= ~HTML_NEWLINE;
/* LINTED */
buffmt(h, "%s: %d%s;", p, (int)v, u);
}
+
+
+void
+html_idcat(char *dst, const char *src, int sz)
+{
+ int ssz;
+
+ assert(sz);
+
+ /* Cf. <http://www.w3.org/TR/html4/types.html#h-6.2>. */
+
+ for ( ; *dst != '\0' && sz; dst++, sz--)
+ /* Jump to end. */ ;
+
+ assert(sz > 2);
+
+ /* We can't start with a number (bah). */
+
+ *dst++ = 'x';
+ *dst = '\0';
+ sz--;
+
+ for ( ; *src != '\0' && sz > 1; src++) {
+ ssz = snprintf(dst, (size_t)sz, "%.2x", *src);
+ sz -= ssz;
+ dst += ssz;
+ }
+}
-/* $Id: html.h,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: html.h,v 1.17 2009/10/28 08:00:18 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
ATTR_VALIGN,
ATTR_TARGET,
ATTR_ID,
+ ATTR_SUMMARY,
ATTR_MAX
};
#define PAIR_STYLE_INIT(p, h) \
do { (p)->key = ATTR_STYLE; \
(p)->val = (h)->buf; } while (/* CONSTCOND */ 0)
+#define PAIR_SUMMARY_INIT(p, v) \
+ do { (p)->key = ATTR_SUMMARY; \
+ (p)->val = (v); } while (/* CONSTCOND */ 0)
struct html {
int flags;
void bufncat(struct html *, const char *, size_t);
void bufinit(struct html *);
+void html_idcat(char *, const char *, int);
+
__END_DECLS
#endif /*!HTML_H*/
-/* $Id: lib.c,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: lib.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
*/
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "libmdoc.h"
-/* $Id: lib.in,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: lib.in,v 1.6 2009/11/01 07:34:22 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
* Be sure to escape strings.
*/
+LINE("libarchive", "Reading and Writing Streaming Archives Library (libarchive, \\-larchive)")
LINE("libarm", "ARM Architecture Library (libarm, \\-larm)")
LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)")
+LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)")
LINE("libc", "Standard C Library (libc, \\-lc)")
LINE("libcdk", "Curses Development Kit Library (libcdk, \\-lcdk)")
LINE("libcompat", "Compatibility Library (libcompat, \\-lcompat)")
LINE("libcurses", "Curses Library (libcurses, \\-lcurses)")
LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)")
LINE("libevent", "Event Notification Library (libevent, \\-levent)")
+LINE("libfetch", "File Transfer Library for URLs (libfetch, \\-lfetch)")
LINE("libform", "Curses Form Library (libform, \\-lform)")
LINE("libi386", "i386 Architecture Library (libi386, \\-li386)")
LINE("libintl", "Internationalized Message Handling Library (libintl, \\-lintl)")
LINE("libipsec", "IPsec Policy Control Library (libipsec, \\-lipsec)")
+LINE("libiscsi", "iSCSI protocol library (libiscsi, \\-liscsi)")
LINE("libkvm", "Kernel Data Access Library (libkvm, \\-lkvm)")
LINE("libm", "Math Library (libm, \\-lm)")
LINE("libm68k", "m68k Architecture Library (libm68k, \\-lm68k)")
LINE("libmagic", "Magic Number Recognition Library (libmagic, \\-lmagic)")
LINE("libmenu", "Curses Menu Library (libmenu, \\-lmenu)")
+LINE("libnetpgp", "Netpgp signing, verification, encryption and decryption (libnetpgp, \\-lnetpgp)")
LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
LINE("libpcap", "Capture Library (libpcap, \\-lpcap)")
LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)")
LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)")
LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)")
+LINE("libprop", "Property Container Object Library (libprop, \\-lprop)")
LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
+LINE("libpuffs", "puffs Convenience Library (libpuffs, \\-lpuffs)")
+LINE("librefuse", "File System in Userspace Convenience Library (librefuse, \\-lrefuse)")
LINE("libresolv", "DNS Resolver Library (libresolv, \\-lresolv)")
LINE("librt", "POSIX Real\\-time Library (librt, -lrt)")
+LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)")
LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)")
LINE("libusbhid", "USB Human Interface Devices Library (libusbhid, \\-lusbhid)")
LINE("libutil", "System Utilities Library (libutil, \\-lutil)")
-/* $Id: libman.h,v 1.10 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: libman.h,v 1.23 2009/10/30 05:58:36 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
enum merr {
WNPRINT = 0,
- WNMEM,
WMSEC,
WDATE,
WLNSCOPE,
-/* $Id: libmandoc.h,v 1.1 2009/07/08 00:04:10 schwarze Exp $ */
+/* $Id: libmandoc.h,v 1.4 2009/11/02 06:22:45 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
__BEGIN_DECLS
int mandoc_special(const char *);
+void *mandoc_calloc(size_t, size_t);
+char *mandoc_strdup(const char *);
+void *mandoc_malloc(size_t);
+void *mandoc_realloc(void *, size_t);
+time_t mandoc_a2time(int, const char *);
+#define MTIME_CANONICAL (1 << 0)
+#define MTIME_REDUCED (1 << 1)
+#define MTIME_MDOCDATE (1 << 2)
+#define MTIME_ISO_8601 (1 << 3)
__END_DECLS
-/* $Id: libmdoc.h,v 1.23 2009/10/21 19:13:50 schwarze Exp $ */
+/* $Id: libmdoc.h,v 1.30 2009/10/30 05:58:37 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
ETAILWS = 0,
EQUOTPARM,
EQUOTTERM,
- EMALLOC,
EARGVAL,
EBODYPROL,
EPROLBODY,
-/* $Id: main.c,v 1.18 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: main.c,v 1.57 2009/11/02 08:29:25 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <sys/stat.h>
#include <assert.h>
-#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
+/* FIXME: Intel's compiler? LLVM? pcc? */
+
+#if !defined(__GNUC__) || (__GNUC__ < 2)
+# if !defined(lint)
+# define __attribute__(x)
+# endif
+#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
+
+#ifdef __linux__
+extern int getsubopt(char **, char * const *, char **);
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
typedef void (*out_mdoc)(void *, const struct mdoc *);
typedef void (*out_man)(void *, const struct man *);
typedef void (*out_free)(void *);
struct man **, struct mdoc **);
static struct man *man_init(struct curparse *);
static struct mdoc *mdoc_init(struct curparse *);
-__dead2 static void version(void);
-__dead2 static void usage(void);
+static void version(void) __attribute__((noreturn));
+static void usage(void) __attribute__((noreturn));
-extern char *__progname;
+static const char *progname;
int
struct buf ln, blk;
struct curparse curp;
- bzero(&curp, sizeof(struct curparse));
+ progname = strrchr(argv[0], '/');
+ if (progname == NULL)
+ progname = argv[0];
+ else
+ ++progname;
+
+ memset(&curp, 0, sizeof(struct curparse));
curp.inttype = INTT_AUTO;
curp.outtype = OUTT_ASCII;
argc -= optind;
argv += optind;
- bzero(&ln, sizeof(struct buf));
- bzero(&blk, sizeof(struct buf));
+ memset(&ln, 0, sizeof(struct buf));
+ memset(&blk, 0, sizeof(struct buf));
rc = 1;
argv++;
if (*argv && rc) {
if (curp.lastman)
- if ( ! man_reset(curp.lastman))
- rc = 0;
+ man_reset(curp.lastman);
if (curp.lastmdoc)
- if ( ! mdoc_reset(curp.lastmdoc))
- rc = 0;
+ mdoc_reset(curp.lastmdoc);
curp.lastman = NULL;
curp.lastmdoc = NULL;
}
}
-__dead2 static void
+static void
version(void)
{
- (void)printf("%s %s\n", __progname, VERSION);
+ (void)printf("%s %s\n", progname, VERSION);
exit(EXIT_SUCCESS);
}
-__dead2 static void
+static void
usage(void)
{
(void)fprintf(stderr, "usage: %s [-V] [-foption...] "
"[-mformat] [-Ooption] [-Toutput] "
- "[-Werr...]\n", __progname);
+ "[-Werr...]\n", progname);
exit(EXIT_FAILURE);
}
man_init(struct curparse *curp)
{
int pflags;
- struct man *man;
struct man_cb mancb;
mancb.man_err = merr;
if (curp->fflags & NO_IGN_ESCAPE)
pflags &= ~MAN_IGN_ESCAPE;
- if (NULL == (man = man_alloc(curp, pflags, &mancb)))
- warnx("memory exhausted");
-
- return(man);
+ return(man_alloc(curp, pflags, &mancb));
}
mdoc_init(struct curparse *curp)
{
int pflags;
- struct mdoc *mdoc;
struct mdoc_cb mdoccb;
mdoccb.mdoc_err = merr;
if (curp->fflags & NO_IGN_CHARS)
pflags &= ~MDOC_IGN_CHARS;
- if (NULL == (mdoc = mdoc_alloc(curp, pflags, &mdoccb)))
- warnx("memory exhausted");
-
- return(mdoc);
+ return(mdoc_alloc(curp, pflags, &mdoccb));
}
curp->file = file;
if (-1 == (curp->fd = open(curp->file, O_RDONLY, 0))) {
- warn("%s", curp->file);
+ perror(curp->file);
return(-1);
}
c = fdesc(blk, ln, curp);
if (-1 == close(curp->fd))
- warn("%s", curp->file);
+ perror(curp->file);
return(c);
}
*/
if (-1 == fstat(curp->fd, &st))
- warn("%s", curp->file);
+ perror(curp->file);
else if ((size_t)st.st_blksize > sz)
sz = st.st_blksize;
if (sz > blk->sz) {
blk->buf = realloc(blk->buf, sz);
if (NULL == blk->buf) {
- warn("realloc");
- return(-1);
+ perror(NULL);
+ exit(EXIT_FAILURE);
}
blk->sz = sz;
}
for (lnn = pos = comment = 0; ; ) {
if (-1 == (ssz = read(curp->fd, blk->buf, sz))) {
- warn("%s", curp->file);
+ perror(curp->file);
return(-1);
} else if (0 == ssz)
break;
ln->sz += 256; /* Step-size. */
ln->buf = realloc(ln->buf, ln->sz);
if (NULL == ln->buf) {
- warn("realloc");
- return(-1);
+ perror(NULL);
+ return(EXIT_FAILURE);
}
}
/* NOTE a parser may not have been assigned, yet. */
if ( ! (man || mdoc)) {
- (void)fprintf(stderr, "%s: not a manual\n",
- curp->file);
+ fprintf(stderr, "%s: Not a manual\n", curp->file);
return(0);
}
else if (0 == strcmp(arg, "an"))
*tflags = INTT_MAN;
else {
- warnx("bad argument: -m%s", arg);
+ fprintf(stderr, "%s: Bad argument\n", arg);
return(0);
}
else if (0 == strcmp(arg, "html"))
*tflags = OUTT_HTML;
else {
- warnx("bad argument: -T%s", arg);
+ fprintf(stderr, "%s: Bad argument\n", arg);
return(0);
}
foptions(int *fflags, char *arg)
{
char *v, *o;
- const char *toks[7];
+ const char *toks[8];
toks[0] = "ign-scope";
toks[1] = "no-ign-escape";
toks[3] = "no-ign-chars";
toks[4] = "ign-errors";
toks[5] = "strict";
- toks[6] = NULL;
+ toks[6] = "ign-escape";
+ toks[7] = NULL;
while (*arg) {
o = arg;
*fflags |= NO_IGN_ESCAPE |
NO_IGN_MACRO | NO_IGN_CHARS;
break;
+ case (6):
+ *fflags &= ~NO_IGN_ESCAPE;
+ break;
default:
- warnx("bad argument: -f%s", o);
+ fprintf(stderr, "%s: Bad argument\n", o);
return(0);
}
}
*wflags |= WARN_WERR;
break;
default:
- warnx("bad argument: -W%s", o);
+ fprintf(stderr, "%s: Bad argument\n", o);
return(0);
}
}
-/* $Id: main.h,v 1.1 2009/10/21 19:13:50 schwarze Exp $ */
+/* $Id: main.h,v 1.1 2009/10/13 10:57:25 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-.\" $Id: man.3,v 1.6 2009/10/20 10:15:04 schwarze Exp $
+.\" $Id: man.3,v 1.10 2009/10/03 16:36:06 kristaps Exp $
.\"
.\" Copyright (c) 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.
.\"
-.Dd $Mdocdate: August 22 2009 $
+.Dd November 6, 2009
.Dt MAN 3
.Os
.\" SECTION
-.\" $Id: man.7,v 1.13 2009/10/27 21:40:07 schwarze Exp $
+.\" $Id: man.7,v 1.46 2009/11/02 17:07:30 kristaps Exp $
.\"
.\" Copyright (c) 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.
.\"
-.Dd October 29, 2009
+.Dd November 6, 2009
.Dt MAN 7
.Os
.
whether in a macro or free-form text line, is ignored to the end of
line. A macro line with only a control character and comment escape,
.Sq \&.\e" ,
-is also ignored. Macro lines with only a control charater and
+is also ignored. Macro lines with only a control character and
optionally whitespace are stripped from input.
.
.
utility such as
.Xr mandoc 1 .
.
+.
+.Ss Dates
+The
+.Sx \&TH
+macro is the only
+.Nm
+macro that requires a date. The form for this date is the ISO-8601
+standard
+.Cm YYYY-MM-DD .
+.
+.
.Ss Scaling Widths
Many macros support scaled widths for their arguments, such as
stipulating a two-inch paragraph indentation with the following:
.Sq u ,
or
.Sq v
-is necessarily non-portable across output media. See
-.Sx COMPATIBILITY .
+is necessarily non-portable across output media.
.
.Pp
If a scaling unit is not provided, the numerical value is interpreted
at least one macro or text node must appear in the document. Documents
are generally structured as follows:
.Bd -literal -offset indent
-\&.TH FOO 1 "13 Aug 2009"
+\&.TH FOO 1 2009-10-10
\&.
\&.SH NAME
\efBfoo\efR \e(en a description goes here
\&.\e\*q The next is for sections 2, 3, & 9 only.
\&.\e\*q .SH ERRORS
\&.\e\*q .SH SEE ALSO
-\&.\e\*q \efBbar\efR(1)
+\&.\e\*q .BR foo ( 1 )
\&.\e\*q .SH STANDARDS
\&.\e\*q .SH HISTORY
\&.\e\*q .SH AUTHORS
.Nm
document are conventionally ordered as they appear above. Sections
should be composed as follows:
-.Bl -tag -width Ds -offset Ds
-.It NAME
+.Bl -ohang -offset indent
+.It Em 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
+.It Em 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
+.It Em SYNOPSIS
Documents the utility invocation syntax, function call syntax, or device
configuration.
.Pp
.Pp
For the second, function calls (sections 2, 3, 9):
.Pp
-.D1 \. Ns Sx \&B No char *name(char *\efIarg\efR);
+.D1 \&.B char *name(char *\efIarg\efR);
.Pp
And for the third, configurations (section 4):
.Pp
-.D1 \. Ns Sx \&B No name* at cardbus ? function ?
+.D1 \&.B 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
+Manuals not in these sections generally don't need a
+.Em SYNOPSIS .
+.It Em DESCRIPTION
+This expands upon the brief, one-line description in
+.Em NAME .
+It usually contains a break-down of the options (if documenting a
+command).
+.It Em 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
+.It Em EXIT STATUS
+Command exit status for section 1, 6, and 8 manuals. This section is
+the dual of
+.Em RETURN VALUES ,
+which is used for functions. Historically, this information was
+described in
+.Em DIAGNOSTICS ,
+a practise that is now discouraged.
+.
+.It Em RETURN VALUES
+This section is the dual of
+.Em EXIT STATUS ,
+which is used for commands. It documents the return values of functions
+in sections 2, 3, and 9.
+.
+.It Em ENVIRONMENT
+Documents any usages of environment variables, e.g.,
+.Xr environ 7 .
+.
+.It Em FILES
+Documents files used. It's helpful to document both the file and a
+short description of how the file is used (created, modified, etc.).
+.
+.It Em EXAMPLES
+Example usages. This often contains snippets of well-formed,
+well-tested invocations. Make doubly sure that your examples work
+properly!
+.
+.It Em DIAGNOSTICS
+Documents error conditions. This is most useful in section 4 manuals.
+Historically, this section was used in place of
+.Em EXIT STATUS
+for manuals in sections 1, 6, and 8; however, this practise is
+discouraged.
+.
+.It Em ERRORS
+Documents error handling in sections 2, 3, and 9.
+.
+.It Em SEE ALSO
+References other manuals with related topics. This section should exist
+for most manuals.
+.Pp
+.D1 \&.BR bar \&( 1 \&),
+.Pp
+Cross-references should conventionally be ordered
+first by section, then alphabetically.
+.
+.It Em STANDARDS
+References any standards implemented or used, such as
+.Pp
+.D1 IEEE Std 1003.2 (\e(lqPOSIX.2\e(rq)
+.Pp
+If not adhering to any standards, the
+.Em HISTORY
+section should be used.
+.
+.It Em HISTORY
+The history of any manual without a
+.Em STANDARDS
+section should be described in this section.
+.
+.It Em AUTHORS
+Credits to authors, if applicable, should appear in this section.
+Authors should generally be noted by both name and an e-mail address.
+.
+.It Em CAVEATS
+Explanations of common misuses and misunderstandings should be explained
+in this section.
+.
+.It Em BUGS
+Extant bugs should be described in this section.
+.
+.It Em SECURITY CONSIDERATIONS
+Documents any security precautions that operators should consider.
+.
.El
.
.
.Pp
is equivalent to
.Sq \&.I foo .
-If next-line macros are invoked consecutively, only the last is used.
-If a next-line macro is proceded by a block macro, it is ignored.
+If next-line macros are invoked consecutively, only the last is used; in
+other words, if a next-line macro is preceded by a block macro, it is
+ignored.
.Bd -literal -offset indent
\&.YO \(lBbody...\(rB
\(lBbody...\(rB
alphabetically. For the scoping of individual macros, see
.Sx MACRO SYNTAX .
.
+.
.Ss \&B
Text is rendered in bold face.
+.Pp
+See also
+.Sx \&I ,
+.Sx \&R ,
+.Sx \&b ,
+.Sx \&i ,
+and
+.Sx \&r .
+.
+.
.Ss \&BI
Text is rendered alternately in bold face and italic. Thus,
.Sq .BI this word and that
and
.Sq that
render in italics. Whitespace between arguments is omitted in output.
+.Pp
+Examples:
+.Pp
+.D1 \&.BI bold italic bold italic
+.Pp
+The output of this example will be emboldened
+.Dq bold
+and italicised
+.Dq italic ,
+with spaces stripped between arguments.
+.Pp
+See also
+.Sx \&IB ,
+.Sx \&BR ,
+.Sx \&RB ,
+.Sx \&RI ,
+and
+.Sx \&IR .
+.
+.
.Ss \&BR
Text is rendered alternately in bold face and roman (the default font).
Whitespace between arguments is omitted in output.
+.Pp
+See
+.Sx \&BI
+for an equivalent example.
+.Pp
+See also
+.Sx \&BI ,
+.Sx \&IB ,
+.Sx \&RB ,
+.Sx \&RI ,
+and
+.Sx \&IR .
+.
+.
.Ss \&DT
Has no effect. Included for compatibility.
+.
+.
.Ss \&HP
Begin a paragraph whose initial output line is left-justified, but
subsequent output lines are indented, with the following syntax:
-.Bd -literal -offset indent
-\&.HP [width]
+.Bd -filled -offset indent
+.Pf \. Sx \&HP
+.Op Cm width
.Ed
-.
.Pp
-If scaling width
-.Va width
-is specified, it's saved for later paragraph left-margins; if
-unspecified, the saved or default width is used.
+The
+.Cm width
+argument must conform to
+.Sx Scaling Widths .
+If specified, it's saved for later paragraph left-margins; if unspecified, the
+saved or default width is used.
+.Pp
+See also
+.Sx \&IP ,
+.Sx \&LP ,
+.Sx \&P ,
+.Sx \&PP ,
+and
+.Sx \&TP .
+.
+.
.Ss \&I
Text is rendered in italics.
+.Pp
+See also
+.Sx \&B ,
+.Sx \&R ,
+.Sx \&b ,
+.Sx \&i ,
+and
+.Sx \&r .
+.
+.
.Ss \&IB
Text is rendered alternately in italics and bold face. Whitespace
between arguments is omitted in output.
+.Pp
+See
+.Sx \&BI
+for an equivalent example.
+.Pp
+See also
+.Sx \&BI ,
+.Sx \&BR ,
+.Sx \&RB ,
+.Sx \&RI ,
+and
+.Sx \&IR .
+.
+.
.Ss \&IP
-Begin a paragraph with the following syntax:
-.Bd -literal -offset indent
-\&.IP [head [width]]
+Begin an indented paragraph with the following syntax:
+.Bd -filled -offset indent
+.Pf \. Sx \&IP
+.Op Cm head Op Cm width
.Ed
-.
.Pp
-This follows the behaviour of the
-.Sx \&TP
-except for the macro syntax (all arguments on the line, instead of
-having next-line scope). If
-.Va width
-is specified, it's saved for later paragraph left-margins; if
-unspecified, the saved or default width is used.
+The
+.Cm width
+argument defines the width of the left margin and is defined by
+.Sx Scaling Widths ,
+It's saved for later paragraph left-margins; if unspecified, the saved or
+default width is used.
+.Pp
+The
+.Cm head
+argument is used as a leading term, flushed to the left margin. This is
+useful for bulleted paragraphs and so on.
+.Pp
+See also
+.Sx \&HP ,
+.Sx \&LP ,
+.Sx \&P ,
+.Sx \&PP ,
+and
+.Sx \&TP .
+.
+.
.Ss \&IR
Text is rendered alternately in italics and roman (the default font).
Whitespace between arguments is omitted in output.
+.Pp
+See
+.Sx \&BI
+for an equivalent example.
+.Pp
+See also
+.Sx \&BI ,
+.Sx \&IB ,
+.Sx \&BR ,
+.Sx \&RB ,
+and
+.Sx \&RI .
+.
+.
.Ss \&LP
Begin an undecorated paragraph. The scope of a paragraph is closed by a
subsequent paragraph, sub-section, section, or end of file. The saved
paragraph left-margin width is re-set to the default.
+.Pp
+See also
+.Sx \&HP ,
+.Sx \&IP ,
+.Sx \&P ,
+.Sx \&PP ,
+and
+.Sx \&TP .
+.
+.
.Ss \&P
Synonym for
.Sx \&LP .
+.Pp
+See also
+.Sx \&HP ,
+.Sx \&IP ,
+.Sx \&LP ,
+.Sx \&PP ,
+and
+.Sx \&TP .
+.
+.
.Ss \&PP
Synonym for
.Sx \&LP .
+.Pp
+See also
+.Sx \&HP ,
+.Sx \&IP ,
+.Sx \&LP ,
+.Sx \&P ,
+and
+.Sx \&TP .
+.
+.
.Ss \&R
Text is rendered in roman (the default font).
+.Pp
+See also
+.Sx \&I ,
+.Sx \&B ,
+.Sx \&b ,
+.Sx \&i ,
+and
+.Sx \&r .
+.
+.
.Ss \&RB
Text is rendered alternately in roman (the default font) and bold face.
Whitespace between arguments is omitted in output.
+.Pp
+See
+.Sx \&BI
+for an equivalent example.
+.Pp
+See also
+.Sx \&BI ,
+.Sx \&IB ,
+.Sx \&BR ,
+.Sx \&RI ,
+and
+.Sx \&IR .
+.
+.
.Ss \&RE
Explicitly close out the scope of a prior
.Sx \&RS .
+.
+.
.Ss \&RI
Text is rendered alternately in roman (the default font) and italics.
Whitespace between arguments is omitted in output.
+.Pp
+See
+.Sx \&BI
+for an equivalent example.
+.Pp
+See also
+.Sx \&BI ,
+.Sx \&IB ,
+.Sx \&BR ,
+.Sx \&RB ,
+and
+.Sx \&IR .
+.
+.
.Ss \&RS
Begin a part setting the left margin. The left margin controls the
offset, following an initial indentation, to un-indented text such as
that of
.Sx \&PP .
-A scaling width may be specified as following:
-.Bd -literal -offset indent
-\&.RS [width]
+This has the following syntax:
+.Bd -filled -offset indent
+.Pf \. Sx \&Rs
+.Op Cm width
.Ed
-.
.Pp
-If
-.Va width
-is not specified, the saved or default width is used.
+The
+.Cm width
+argument must conform to
+.Sx Scaling Widths .
+If not specified, the saved or default width is used.
+.
+.
.Ss \&SB
Text is rendered in small size (one point smaller than the default font)
bold face.
+.
+.
.Ss \&SH
Begin a section. The scope of a section is only closed by another
section or the end of file. The paragraph left-margin width is re-set
to the default.
+.
+.
.Ss \&SM
Text is rendered in small size (one point smaller than the default
font).
+.
+.
.Ss \&SS
Begin a sub-section. The scope of a sub-section is closed by a
subsequent sub-section, section, or end of file. The paragraph
left-margin width is re-set to the default.
+.
+.
.Ss \&TH
Sets the title of the manual page with the following syntax:
-.Bd -literal -offset indent
-\&.TH title section [date [source [volume]]]
+.Bd -filled -offset indent
+.Pf \. Sx \&TH
+.Cm title section
+.Op Cm date Op Cm source Op Cm volume
.Ed
-.
.Pp
-At least the
-.Va title
-and
-.Va section
+At least the upper-case document title
+.Cm title
+and numeric manual section
+.Cm section
arguments must be provided. The
-.Va date
-argument should be formatted as
-.Qq %b [%d] %Y
-format, described in
-.Xr strptime 3 .
-The
-.Va source
+.Cm date
+argument should be formatted as described in
+.Sx Dates :
+if it does not conform, the current date is used instead. The
+.Cm source
string specifies the organisation providing the utility. The
-.Va volume
-replaces the default rendered volume as dictated by the manual section.
+.Cm volume
+string replaces the default rendered volume, which is dictated by the
+manual section.
+.Pp
+Examples:
+.Pp
+.D1 \&.TH CVS 5 "1992-02-12" GNU
+.
+.
.Ss \&TP
Begin a paragraph where the head, if exceeding the indentation width, is
followed by a newline; if not, the body follows on the same line after a
buffer to the indentation width. Subsequent output lines are indented.
-.
-.Pp
-The indentation scaling width may be set as follows:
-.Bd -literal -offset indent
-\&.TP [width]
+The syntax is as follows:
+.Bd -filled -offset indent
+.Pf \. Sx \&TP
+.Op Cm width
.Ed
-.
.Pp
-If
-.Va width
-is specified, it's saved for later paragraph left-margins; if
+The
+.Cm width
+argument must conform to
+.Sx Scaling Widths .
+If specified, it's saved for later paragraph left-margins; if
unspecified, the saved or default width is used.
+.Pp
+See also
+.Sx \&HP ,
+.Sx \&IP ,
+.Sx \&LP ,
+.Sx \&P ,
+and
+.Sx \&PP .
+.
+.
.Ss \&PD
Has no effect. Included for compatibility.
+.
+.
.Ss \&UC
Has no effect. Included for compatibility.
+.
+.
.Ss \&br
Breaks the current line. Consecutive invocations have no further effect.
+.Pp
+See also
+.Sx \&sp .
+.
+.
.Ss \&fi
End literal mode begun by
.Sx \&nf .
+.
+.
.Ss \&i
Italicise arguments. If no arguments are specified, all subsequent text
is italicised.
+.Pp
+See also
+.Sx \&B ,
+.Sx \&I ,
+.Sx \&R .
+.Sx \&b ,
+and
+.Sx \&r .
+.
+.
.Ss \&na
Don't align to the right margin.
+.
+.
.Ss \&nf
Begin literal mode: all subsequent free-form lines have their end of
line boundaries preserved. May be ended by
.Sx \&fi .
+.
+.
.Ss \&r
Fonts and styles (bold face, italics) reset to roman (default font).
+.Pp
+See also
+.Sx \&B ,
+.Sx \&I ,
+.Sx \&R ,
+.Sx \&b ,
+and
+.Sx \&i .
+.
+.
.Ss \&sp
-Insert n spaces, where n is the macro's positive numeric argument. If
-0, this is equivalent to the
+Insert vertical spaces into output with the following syntax:
+.Bd -filled -offset indent
+.Pf \. Sx \&sp
+.Op Cm height
+.Ed
+.Pp
+Insert
+.Cm height
+spaces, which must conform to
+.Sx Scaling Widths .
+If 0, this is equivalent to the
.Sx \&br
-macro.
+macro. Defaults to 1, if unspecified.
+.Pp
+See also
+.Sx \&br .
.
.
.Sh COMPATIBILITY
-/* $Id: man.c,v 1.15 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: man.c,v 1.46 2009/11/02 08:40:31 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <string.h>
#include "libman.h"
+#include "libmandoc.h"
const char *const __man_merrnames[WERRMAX] = {
"invalid character", /* WNPRINT */
- "system: malloc error", /* WNMEM */
"invalid manual section", /* WMSEC */
"invalid date format", /* WDATE */
"scope of prior line violated", /* WLNSCOPE */
static int man_ptext(struct man *, int, char *);
static int man_pmacro(struct man *, int, char *);
static void man_free1(struct man *);
-static int man_alloc1(struct man *);
+static void man_alloc1(struct man *);
static int pstring(struct man *, int, int,
const char *, size_t);
static int macrowarn(struct man *, int, const char *);
+#ifdef __linux__
+extern size_t strlcpy(char *, const char *, size_t);
+#endif
+
const struct man_node *
man_node(const struct man *m)
}
-int
+void
man_reset(struct man *man)
{
man_free1(man);
- return(man_alloc1(man));
+ man_alloc1(man);
}
{
struct man *p;
- if (NULL == (p = calloc(1, sizeof(struct man))))
- return(NULL);
+ p = mandoc_calloc(1, sizeof(struct man));
- if ( ! man_alloc1(p)) {
- free(p);
- return(NULL);
- }
+ if (cb)
+ memcpy(&p->cb, cb, sizeof(struct man_cb));
man_hash_init();
-
p->data = data;
p->pflags = pflags;
- (void)memcpy(&p->cb, cb, sizeof(struct man_cb));
+
+ man_alloc1(p);
return(p);
}
}
-static int
+static void
man_alloc1(struct man *m)
{
- bzero(&m->meta, sizeof(struct man_meta));
+ memset(&m->meta, 0, sizeof(struct man_meta));
m->flags = 0;
- m->last = calloc(1, sizeof(struct man_node));
- if (NULL == m->last)
- return(0);
+ m->last = mandoc_calloc(1, sizeof(struct man_node));
m->first = m->last;
m->last->type = MAN_ROOT;
m->next = MAN_NEXT_CHILD;
- return(1);
}
{
struct man_node *p;
- p = calloc(1, sizeof(struct man_node));
- if (NULL == p)
- return(NULL);
-
+ p = mandoc_calloc(1, sizeof(struct man_node));
p->line = line;
p->pos = pos;
p->type = type;
struct man_node *p;
p = man_node_alloc(line, pos, MAN_ELEM, tok);
- if (NULL == p)
- return(0);
if ( ! man_node_append(m, p))
return(0);
m->next = MAN_NEXT_CHILD;
struct man_node *p;
p = man_node_alloc(line, pos, MAN_HEAD, tok);
- if (NULL == p)
- return(0);
if ( ! man_node_append(m, p))
return(0);
m->next = MAN_NEXT_CHILD;
struct man_node *p;
p = man_node_alloc(line, pos, MAN_BODY, tok);
- if (NULL == p)
- return(0);
if ( ! man_node_append(m, p))
return(0);
m->next = MAN_NEXT_CHILD;
struct man_node *p;
p = man_node_alloc(line, pos, MAN_BLOCK, tok);
- if (NULL == p)
- return(0);
if ( ! man_node_append(m, p))
return(0);
m->next = MAN_NEXT_CHILD;
size_t sv;
n = man_node_alloc(line, pos, MAN_TEXT, -1);
- if (NULL == n)
- return(0);
-
- n->string = malloc(len + 1);
- if (NULL == n->string) {
- free(n);
- return(0);
- }
-
+ n->string = mandoc_malloc(len + 1);
sv = strlcpy(n->string, p, len + 1);
/* Prohibit truncation. */
fl = m->flags;
- if (0 == buf[1])
- goto out;
+ if ('\0' == buf[1])
+ return(1);
i = 1;
return(man_perr(m, ln, i, WNPRINT));
}
- mac[j] = 0;
+ mac[j] = '\0';
if (j == 4 || j < 1) {
if ( ! (MAN_IGN_MACRO & m->pflags)) {
-/* $Id: man.h,v 1.11 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: man.h,v 1.23 2009/10/30 05:58:37 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
void man_free(struct man *);
struct man *man_alloc(void *, int, const struct man_cb *);
-int man_reset(struct man *);
+void man_reset(struct man *);
int man_parseln(struct man *, int, char *buf);
int man_endparse(struct man *);
-/* $Id: man_action.c,v 1.9 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: man_action.c,v 1.24 2009/11/02 06:22:45 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <sys/utsname.h>
#include <assert.h>
-#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "libman.h"
+#include "libmandoc.h"
struct actions {
int (*post)(struct man *);
{ NULL }, /* PD */
};
-static time_t man_atotime(const char *);
-
int
man_action_post(struct man *m)
n = m->last->child;
assert(n);
-
- if (NULL == (m->meta.title = strdup(n->string)))
- return(man_nerr(m, n, WNMEM));
+ m->meta.title = mandoc_strdup(n->string);
/* TITLE ->MSEC<- DATE SOURCE VOL */
n = n->next;
assert(n);
- errno = 0;
lval = strtol(n->string, &ep, 10);
if (n->string[0] != '\0' && *ep == '\0')
m->meta.msec = (int)lval;
/* TITLE MSEC ->DATE<- SOURCE VOL */
- if (NULL == (n = n->next))
- m->meta.date = time(NULL);
- else if (0 == (m->meta.date = man_atotime(n->string))) {
- if ( ! man_nwarn(m, n, WDATE))
- return(0);
+ n = n->next;
+ if (n) {
+ m->meta.date = mandoc_a2time
+ (MTIME_ISO_8601, n->string);
+
+ if (0 == m->meta.date) {
+ if ( ! man_nwarn(m, n, WDATE))
+ return(0);
+ m->meta.date = time(NULL);
+ }
+ } else
m->meta.date = time(NULL);
- }
/* TITLE MSEC DATE ->SOURCE<- VOL */
if (n && (n = n->next))
- if (NULL == (m->meta.source = strdup(n->string)))
- return(man_nerr(m, n, WNMEM));
+ m->meta.source = mandoc_strdup(n->string);
/* TITLE MSEC DATE SOURCE ->VOL<- */
if (n && (n = n->next))
- if (NULL == (m->meta.vol = strdup(n->string)))
- return(man_nerr(m, n, WNMEM));
+ m->meta.vol = mandoc_strdup(n->string);
/*
* The end document shouldn't have the prologue macros as part
man_node_freelist(n);
return(1);
}
-
-
-static time_t
-man_atotime(const char *p)
-{
- struct tm tm;
- char *pp;
-
- bzero(&tm, sizeof(struct tm));
-
- if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%d %b %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%b %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
-
- return(0);
-}
-/* $Id: man_argv.c,v 1.1 2009/08/23 11:22:19 schwarze Exp $ */
+/* $Id: man_argv.c,v 1.1 2009/08/13 11:45:29 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: man_hash.c,v 1.7 2009/10/19 10:20:24 schwarze Exp $ */
+/* $Id: man_hash.c,v 1.15 2009/09/23 11:53:45 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: man_html.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: man_html.c,v 1.17 2009/10/30 18:53:08 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <assert.h>
#include <ctype.h>
-#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int man_SM_pre(MAN_ARGS);
static int man_SS_pre(MAN_ARGS);
+#ifdef __linux__
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
static const struct htmlman mans[MAN_MAX] = {
{ man_br_pre, NULL }, /* br */
{ NULL, NULL }, /* TH */
static int
man_root_pre(MAN_ARGS)
{
- struct htmlpair tag[2];
+ struct htmlpair tag[3];
struct tag *t, *tt;
char b[BUFSIZ], title[BUFSIZ];
PAIR_CLASS_INIT(&tag[0], "header");
bufcat_style(h, "width", "100%");
PAIR_STYLE_INIT(&tag[1], h);
- t = print_otag(h, TAG_TABLE, 2, tag);
+ PAIR_SUMMARY_INIT(&tag[2], "header");
+
+ t = print_otag(h, TAG_TABLE, 3, tag);
tt = print_otag(h, TAG_TR, 0, NULL);
bufinit(h);
static void
man_root_post(MAN_ARGS)
{
- struct htmlpair tag[2];
+ struct htmlpair tag[3];
struct tag *t, *tt;
char b[DATESIZ];
PAIR_CLASS_INIT(&tag[0], "footer");
bufcat_style(h, "width", "100%");
PAIR_STYLE_INIT(&tag[1], h);
- t = print_otag(h, TAG_TABLE, 2, tag);
+ PAIR_SUMMARY_INIT(&tag[2], "footer");
+
+ t = print_otag(h, TAG_TABLE, 3, tag);
tt = print_otag(h, TAG_TR, 0, NULL);
bufinit(h);
bufcat_su(h, "height", &su);
PAIR_STYLE_INIT(&tag, h);
print_otag(h, TAG_DIV, 1, &tag);
+ /* So the div isn't empty: */
+ print_text(h, "\\~");
+
return(0);
}
-/* $Id: man_macro.c,v 1.9 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: man_macro.c,v 1.29 2009/10/24 05:45:05 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: man_term.c,v 1.19 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: man_term.c,v 1.47 2009/10/30 18:53:08 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <assert.h>
#include <ctype.h>
-#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void (*post)(DECL_ARGS);
};
+#ifdef __linux__
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
static int a2width(const struct man_node *);
static int a2height(const struct man_node *);
static void
-print_man_head(struct termp *p, const struct man_meta *meta)
+print_man_head(struct termp *p, const struct man_meta *m)
{
- char *buf, *title;
+ char buf[BUFSIZ], title[BUFSIZ];
p->rmargin = p->maxrmargin;
p->offset = 0;
+ buf[0] = title[0] = '\0';
- if (NULL == (buf = malloc(p->rmargin)))
- err(EXIT_FAILURE, "malloc");
- if (NULL == (title = malloc(p->rmargin)))
- err(EXIT_FAILURE, "malloc");
-
- if (meta->vol)
- (void)strlcpy(buf, meta->vol, p->rmargin);
- else
- *buf = 0;
+ if (m->vol)
+ strlcpy(buf, m->vol, BUFSIZ);
- (void)snprintf(title, p->rmargin, "%s(%d)",
- meta->title, meta->msec);
+ snprintf(title, BUFSIZ, "%s(%d)", m->title, m->msec);
p->offset = 0;
p->rmargin = (p->maxrmargin - strlen(buf) + 1) / 2;
p->rmargin = p->maxrmargin;
p->offset = 0;
p->flags &= ~TERMP_NOSPACE;
-
- free(title);
- free(buf);
}
-/* $Id: man_validate.c,v 1.11 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: man_validate.c,v 1.27 2009/11/02 06:22:45 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
static const struct man_valid man_valids[MAN_MAX] = {
{ pres_bline, 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 */
-.\" $Id: mandoc.1,v 1.18 2009/10/27 21:40:07 schwarze Exp $
+.\" $Id: mandoc.1,v 1.45 2009/10/26 15:44:51 kristaps Exp $
.\"
.\" Copyright (c) 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.
.\"
-.Dd October 29, 2009
+.Dd November 11, 2009
.Dt MANDOC 1
.Os
.
scope violations. This can seriously mangle the resulting tree.
.Pq mdoc only
.
+.It Fl f Ns Ar ign-escape
+Ignore invalid escape sequences.
+This is the default, but the option can be used to override an earlier
+.Fl f Ns Ar strict .
+.
.It Fl f Ns Ar no-ign-escape
Don't ignore invalid escape sequences.
.
-/* $Id: mandoc.c,v 1.3 2009/08/22 15:18:11 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.7 2009/11/02 06:22:45 kristaps 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.
*/
+#if defined(__linux__) || defined(__MINT__)
+# define _GNU_SOURCE /* strptime() */
+#endif
+
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
#include "libmandoc.h"
+static int a2time(time_t *, const char *, const char *);
+
+
int
mandoc_special(const char *p)
{
return(*p == ']' ? c : 0);
}
+
+
+void *
+mandoc_calloc(size_t num, size_t size)
+{
+ void *ptr;
+
+ ptr = calloc(num, size);
+ if (NULL == ptr) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
+
+ return(ptr);
+}
+
+
+void *
+mandoc_malloc(size_t size)
+{
+ void *ptr;
+
+ ptr = malloc(size);
+ if (NULL == ptr) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
+
+ return(ptr);
+}
+
+
+void *
+mandoc_realloc(void *ptr, size_t size)
+{
+
+ ptr = realloc(ptr, size);
+ if (NULL == ptr) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
+
+ return(ptr);
+}
+
+
+char *
+mandoc_strdup(const char *ptr)
+{
+ char *p;
+
+ p = strdup(ptr);
+ if (NULL == p) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
+
+ return(p);
+}
+
+
+static int
+a2time(time_t *t, const char *fmt, const char *p)
+{
+ struct tm tm;
+ char *pp;
+
+ memset(&tm, 0, sizeof(struct tm));
+
+ pp = strptime(p, fmt, &tm);
+ if (NULL != pp && '\0' == *pp) {
+ *t = mktime(&tm);
+ return(1);
+ }
+
+ return(0);
+}
+
+
+/*
+ * Convert from a manual date string (see mdoc(7) and man(7)) into a
+ * date according to the stipulated date type.
+ */
+time_t
+mandoc_a2time(int flags, const char *p)
+{
+ time_t t;
+
+ if (MTIME_MDOCDATE & flags) {
+ if (0 == strcmp(p, "$" "Mdocdate$"))
+ return(time(NULL));
+ if (a2time(&t, "$" "Mdocdate: %b %d %Y $", p))
+ return(t);
+ }
+
+ if (MTIME_CANONICAL & flags || MTIME_REDUCED & flags)
+ if (a2time(&t, "%b %d, %Y", p))
+ return(t);
+
+ if (MTIME_ISO_8601 & flags)
+ if (a2time(&t, "%Y-%m-%d", p))
+ return(t);
+
+ if (MTIME_REDUCED & flags) {
+ if (a2time(&t, "%d, %Y", p))
+ return(t);
+ if (a2time(&t, "%Y", p))
+ return(t);
+ }
+
+ return(0);
+}
-.\" $Id: mandoc_char.7,v 1.7 2009/10/21 19:13:50 schwarze Exp $
+.\" $Id: mandoc_char.7,v 1.27 2009/10/17 04:37:52 kristaps Exp $
.\"
.\" Copyright (c) 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.
.\"
-.Dd $Mdocdate: October 19 2009 $
+.Dd November 11, 2009
.Dt MANDOC_CHAR 7
.Os
.
-.\" $Id: manuals.7,v 1.5 2009/08/22 16:32:22 schwarze Exp $
+.\" $Id: manuals.7,v 1.19 2009/07/27 19:43:02 kristaps Exp $
.\"
.\" Copyright (c) 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.
.\"
-.Dd $Mdocdate: July 26 2009 $
+.Dd November 11, 2009
.Dt MANUALS 7
.Os
.\" SECTION
to version-control your work. If you wish the last check-in to effect
your document's date, use the following RCS tag for the date macro:
.Pp
-.Dl \&.Dd $Mdocdate: July 26 2009 $
+.Dl \&.Dd $Mdocdate$
.\" SUBSECTION
.Ss Viewing
mdoc documents may be paged to your terminal with
-.\" $Id: mdoc.3,v 1.5 2009/10/20 10:15:04 schwarze Exp $
+.\" $Id: mdoc.3,v 1.35 2009/10/03 16:36:06 kristaps Exp $
.\"
.\" Copyright (c) 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.
.\"
-.Dd $Mdocdate: August 9 2009 $
+.Dd November 11, 2009
.Dt MDOC 3
.Os
.\" SECTION
-.\" $Id: mdoc.7,v 1.18 2009/10/27 21:40:07 schwarze Exp $
+.\" $Id: mdoc.7,v 1.73 2009/11/02 11:39:40 kristaps Exp $
.\"
.\" Copyright (c) 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.
.\"
-.Dd October 29, 2009
+.Dd November 11, 2009
.Dt MDOC 7
.Os
.
.Ss Dates
There are several macros in
.Nm
-that require a date argument. The
-.Em canonical form
-for dates is the American format:
+that require a date argument. The canonical form for dates is the
+American format:
.Pp
.D1 Cm Month Day , Year
.Pp
.Cm Year
value is the full four-digit year.
.Pp
-The
-.Em non-canonical form
-is the same as the canonical form, but without the comma between the
-.Cm Day
-and
-.Cm Year
-field.
+Reduced form dates are broken-down canonical form dates:
.Pp
-Lastly,
-.Em reduced form
-dates range from only a
-.Cm Year
-to the full canonical or non-canonical form.
+.D1 Cm Month , Year
+.D1 Cm Year
.Pp
Some examples of valid dates follow:
.Pp
.D1 "May, 2009" Pq reduced form
.D1 "2009" Pq reduced form
.D1 "May 20, 2009" Pq canonical form
-.D1 "May 20 2009" Pq non-canonical form
.
.Ss Scaling Widths
Many macros support scaled widths for their arguments, such as
.Nm
document are conventionally ordered as they appear above. Sections
should be composed as follows:
-.Bl -tag -width Ds -offset Ds
-.It NAME
-Must contain at least one
+.Bl -ohang -offset Ds
+.It Em NAME
+The name(s) and a short description of the documented material. The
+syntax for this as follows:
+.Bd -literal -offset indent
+\&.Nm name0
+\&.Nm name1
+\&.Nm name2
+\&.Nd a short description
+.Ed
+.Pp
+The
.Sx \&Nm
-followed by
-.Sx \&Nd .
-The name needs re-stating since one
-.Nm
-documents can be used for more than one utility or function, such as
-.Xr grep 1
-also being referenced as
-.Xr egrep 1
-and
-.Xr fgrep 1 .
-.It LIBRARY
-.It SYNOPSIS
-.It DESCRIPTION
-.It IMPLEMENTATION NOTES
-.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
+macro(s) must precede the
+.Sx \&Nd
+macro.
+.
+.It Em LIBRARY
+The name of the library containing the documented material, which is
+assumed to be a function in a section 2 or 3 manual. The syntax for
+this is as follows:
+.Bd -literal -offset indent
+\&.Lb libarm
+.Ed
+.Pp
+See
+.Sx \&Lb
+for details.
+.
+.It Em 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:
+.Bd -literal -offset indent
+\&.Nm foo
+\&.Op Fl v
+\&.Op Fl o Ar file
+\&.Op Ar
+\&.Nm bar
+\&.Op Fl v
+\&.Op Fl o Ar file
+\&.Op Ar
+.Ed
+.Pp
+For the second, function calls (sections 2, 3, 9):
+.Bd -literal -offset indent
+\&.Vt extern const char *global;
+\&.In header.h
+\&.Ft "char *"
+\&.Fn foo "const char *src"
+\&.Ft "char *"
+\&.Fn bar "const char *src"
+.Ed
+.Pp
+And for the third, configurations (section 4):
+.Bd -literal -offset indent
+\&.Cd \*qit* at isa? port 0x2e\*q
+\&.Cd \*qit* at isa? port 0x4e\*q
+.Ed
+.Pp
+Manuals not in these sections generally don't need a
+.Em SYNOPSIS .
+.
+.It Em DESCRIPTION
+This expands upon the brief, one-line description in
+.Em NAME .
+It usually contains a break-down of the options (if documenting a
+command), such as:
+.Bd -literal -offset indent
+The arguments are as follows:
+\&.Bl \-tag \-width Ds
+\&.It Fl v
+Print verbose information.
+\&.El
+.Ed
+Manuals not documenting a command won't include the above fragment.
+.
+.It Em 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 Em EXIT STATUS
+Command exit status for section 1, 6, and 8 manuals. This section is
+the dual of
+.Em RETURN VALUES ,
+which is used for functions. Historically, this information was
+described in
+.Em DIAGNOSTICS ,
+a practise that is now discouraged.
+.Pp
+See
+.Sx \&Ex .
+.
+.It Em RETURN VALUES
+This section is the dual of
+.Em EXIT STATUS ,
+which is used for commands. It documents the return values of functions
+in sections 2, 3, and 9.
+.Pp
+See
+.Sx \&Rv .
+.
+.It Em ENVIRONMENT
+Documents any usages of environment variables, e.g.,
+.Xr environ 7 .
+.Pp
+See
+.Sx \&Ev .
+.
+.It Em FILES
+Documents files used. It's helpful to document both the file and a
+short description of how the file is used (created, modified, etc.).
+.Pp
+See
+.Sx \&Pa .
+.
+.It Em EXAMPLES
+Example usages. This often contains snippets of well-formed,
+well-tested invocations. Make doubly sure that your examples work
+properly!
+.
+.It Em DIAGNOSTICS
+Documents error conditions. This is most useful in section 4 manuals.
+Historically, this section was used in place of
+.Em EXIT STATUS
+for manuals in sections 1, 6, and 8; however, this practise is
+discouraged.
+.Pp
+See
+.Sx \&Bl No \-diag .
+.
+.It Em ERRORS
+Documents error handling in sections 2, 3, and 9.
+.Pp
+See
+.Sx \&Er .
+.
+.It Em SEE ALSO
+References other manuals with related topics. This section should exist
+for most manuals. Cross-references should conventionally be ordered
+first by section, then alphabetically.
+.Pp
+See
+.Sx \&Xr .
+.
+.It Em STANDARDS
+References any standards implemented or used. If not adhering to any
+standards, the
+.Em HISTORY
+section should be used instead.
+.Pp
+See
+.Sx \&St .
+.
+.It Em HISTORY
+The history of any manual without a
+.Em STANDARDS
+section should be described in this section.
+.
+.It Em AUTHORS
+Credits to authors, if applicable, should appear in this section.
+Authors should generally be noted by both name and an e-mail address.
+.Pp
+See
+.Sx \&An .
+.
+.It Em CAVEATS
+Explanations of common misuses and misunderstandings should be explained
+in this section.
+.
+.It Em BUGS
+Extant bugs should be described in this section.
+.
+.It Em SECURITY CONSIDERATIONS
+Documents any security precautions that operators should consider.
+.
.El
.
.
.Ss \&%D
Publication date of an
.Sx \&Rs
-block. This should follow the reduced syntax for
+block. This should follow the reduced or canonical form syntax
+described in
.Sx Dates .
-Canonical or non-canonical form is not necessary since publications are
-often referenced only by year, or month and year.
.
.Ss \&%I
Publisher or issuer name of an
field may be either
.Ar $\&Mdocdate$ ,
which signifies the current manual revision date dictated by
-.Xr cvs 1
+.Xr cvs 1 ,
or instead a valid canonical date as specified by
.Sx Dates .
+If a date does not conform, the current date is used instead.
.Pp
Examples:
.Bd -literal -offset indent
is not provided, it may be used in its place, else it may be used
subsequent that. It, too, is optional. It must be one of
.Ar alpha ,
+.Ar amd64 ,
.Ar amiga ,
.Ar arc ,
.Ar arm ,
.Ar sparc64 ,
.Ar sun3 ,
.Ar vax ,
-.Ar x86_64 ,
or
.Ar zaurus .
.El
.Sx \&Er .
.
.Ss \&Dx
-Format the DragonFlyBSD version provided as an argument, or a default
+Format the DragonFly BSD version provided as an argument, or a default
value if no argument is provided.
.Pp
Examples:
-/* $Id: mdoc.c,v 1.31 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.113 2009/10/30 05:58:38 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <string.h>
#include "libmdoc.h"
+#include "libmandoc.h"
const char *const __mdoc_merrnames[MERRMAX] = {
"trailing whitespace", /* ETAILWS */
"unexpected quoted parameter", /* EQUOTPARM */
"unterminated quoted parameter", /* EQUOTTERM */
- "system: malloc error", /* EMALLOC */
"argument parameter suggested", /* EARGVAL */
"macro disallowed in prologue", /* EBODYPROL */
"macro disallowed in body", /* EPROLBODY */
const char * const *mdoc_argnames = __mdoc_argnames;
static void mdoc_free1(struct mdoc *);
-static int mdoc_alloc1(struct mdoc *);
+static void mdoc_alloc1(struct mdoc *);
static struct mdoc_node *node_alloc(struct mdoc *, int, int,
int, enum mdoc_type);
static int node_append(struct mdoc *,
static int pstring(struct mdoc *, int, int,
const char *, size_t);
+#ifdef __linux__
+extern size_t strlcpy(char *, const char *, size_t);
+#endif
+
const struct mdoc_node *
mdoc_node(const struct mdoc *m)
/*
* Allocate all volatile resources (parse tree, meta-data, fields).
*/
-static int
+static void
mdoc_alloc1(struct mdoc *mdoc)
{
- bzero(&mdoc->meta, sizeof(struct mdoc_meta));
+ memset(&mdoc->meta, 0, sizeof(struct mdoc_meta));
mdoc->flags = 0;
mdoc->lastnamed = mdoc->lastsec = SEC_NONE;
- mdoc->last = calloc(1, sizeof(struct mdoc_node));
- if (NULL == mdoc->last)
- return(0);
-
+ mdoc->last = mandoc_calloc(1, sizeof(struct mdoc_node));
mdoc->first = mdoc->last;
mdoc->last->type = MDOC_ROOT;
mdoc->next = MDOC_NEXT_CHILD;
- return(1);
}
* and the parser is ready for re-invocation on a new tree; however,
* cross-parse non-volatile data is kept intact.
*/
-int
+void
mdoc_reset(struct mdoc *mdoc)
{
mdoc_free1(mdoc);
- return(mdoc_alloc1(mdoc));
+ mdoc_alloc1(mdoc);
}
{
struct mdoc *p;
- if (NULL == (p = calloc(1, sizeof(struct mdoc))))
- return(NULL);
- if (cb)
- (void)memcpy(&p->cb, cb, sizeof(struct mdoc_cb));
+ p = mandoc_calloc(1, sizeof(struct mdoc));
- mdoc_hash_init();
+ if (cb)
+ memcpy(&p->cb, cb, sizeof(struct mdoc_cb));
p->data = data;
p->pflags = pflags;
- if (mdoc_alloc1(p))
- return(p);
-
- free(p);
- return(NULL);
+ mdoc_hash_init();
+ mdoc_alloc1(p);
+ return(p);
}
{
struct mdoc_node *p;
- if (NULL == (p = calloc(1, sizeof(struct mdoc_node)))) {
- (void)mdoc_nerr(m, m->last, EMALLOC);
- return(NULL);
- }
-
+ p = mandoc_calloc(1, sizeof(struct mdoc_node));
p->sec = m->lastsec;
p->line = line;
p->pos = pos;
struct mdoc_node *p;
p = node_alloc(m, line, pos, tok, MDOC_TAIL);
- if (NULL == p)
- return(0);
if ( ! node_append(m, p))
return(0);
m->next = MDOC_NEXT_CHILD;
assert(m->last);
p = node_alloc(m, line, pos, tok, MDOC_HEAD);
- if (NULL == p)
- return(0);
if ( ! node_append(m, p))
return(0);
m->next = MDOC_NEXT_CHILD;
struct mdoc_node *p;
p = node_alloc(m, line, pos, tok, MDOC_BODY);
- if (NULL == p)
- return(0);
if ( ! node_append(m, p))
return(0);
m->next = MDOC_NEXT_CHILD;
struct mdoc_node *p;
p = node_alloc(m, line, pos, tok, MDOC_BLOCK);
- if (NULL == p)
- return(0);
p->args = args;
if (p->args)
(args->refcnt)++;
struct mdoc_node *p;
p = node_alloc(m, line, pos, tok, MDOC_ELEM);
- if (NULL == p)
- return(0);
p->args = args;
if (p->args)
(args->refcnt)++;
size_t sv;
n = node_alloc(m, line, pos, -1, MDOC_TEXT);
- if (NULL == n)
- return(mdoc_nerr(m, m->last, EMALLOC));
-
- n->string = malloc(len + 1);
- if (NULL == n->string) {
- free(n);
- return(mdoc_nerr(m, m->last, EMALLOC));
- }
-
+ n->string = mandoc_malloc(len + 1);
sv = strlcpy(n->string, p, len + 1);
/* Prohibit truncation. */
-/* $Id: mdoc.h,v 1.15 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc.h,v 1.73 2009/10/30 05:58:38 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
void mdoc_free(struct mdoc *);
struct mdoc *mdoc_alloc(void *, int, const struct mdoc_cb *);
-int mdoc_reset(struct mdoc *);
+void mdoc_reset(struct mdoc *);
int mdoc_parseln(struct mdoc *, int, char *buf);
const struct mdoc_node *mdoc_node(const struct mdoc *);
const struct mdoc_meta *mdoc_meta(const struct mdoc *);
-/* $Id: mdoc_action.c,v 1.24 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc_action.c,v 1.49 2009/11/02 06:22:45 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#endif
#include <assert.h>
-#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "libmdoc.h"
+#include "libmandoc.h"
#define POST_ARGS struct mdoc *m, struct mdoc_node *n
#define PRE_ARGS struct mdoc *m, const struct mdoc_node *n
+#define NUMSIZ 32
+#define DATESIZ 32
+
struct actions {
int (*pre)(PRE_ARGS);
int (*post)(POST_ARGS);
};
-static int concat(struct mdoc *,
- const struct mdoc_node *,
- char *, size_t);
+static int concat(struct mdoc *, char *,
+ const struct mdoc_node *, size_t);
static inline int order_rs(int);
+#ifdef __linux__
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
static int post_ar(POST_ARGS);
static int post_at(POST_ARGS);
static int post_bl(POST_ARGS);
static int post_lb(POST_ARGS);
static int post_nm(POST_ARGS);
static int post_os(POST_ARGS);
+static int post_pa(POST_ARGS);
static int post_prol(POST_ARGS);
static int post_rs(POST_ARGS);
static int post_sh(POST_ARGS);
static int post_st(POST_ARGS);
static int post_std(POST_ARGS);
-static int post_tilde(POST_ARGS);
static int pre_bd(PRE_ARGS);
static int pre_bl(PRE_ARGS);
{ NULL, post_nm }, /* Nm */
{ NULL, NULL }, /* Op */
{ NULL, NULL }, /* Ot */
- { NULL, post_tilde }, /* Pa */
+ { NULL, post_pa }, /* Pa */
{ NULL, post_std }, /* Rv */
{ NULL, post_st }, /* St */
{ NULL, NULL }, /* Va */
}
+/*
+ * Concatenate sibling nodes together. All siblings must be of type
+ * MDOC_TEXT or an assertion is raised. Concatenation is separated by a
+ * single whitespace.
+ */
static int
-concat(struct mdoc *m, const struct mdoc_node *n,
- char *buf, size_t sz)
+concat(struct mdoc *m, char *p, const struct mdoc_node *n, size_t sz)
{
+ assert(sz);
+ p[0] = '\0';
for ( ; n; n = n->next) {
assert(MDOC_TEXT == n->type);
- if (strlcat(buf, n->string, sz) >= sz)
+ if (strlcat(p, n->string, sz) >= sz)
return(mdoc_nerr(m, n, ETOOLONG));
if (NULL == n->next)
continue;
- if (strlcat(buf, " ", sz) >= sz)
+ if (strlcat(p, " ", sz) >= sz)
return(mdoc_nerr(m, n, ETOOLONG));
}
}
+/*
+ * Macros accepting `-std' as an argument have the name of the current
+ * document (`Nm') filled in as the argument if it's not provided.
+ */
static int
post_std(POST_ARGS)
{
if ( ! mdoc_word_alloc(m, n->line, n->pos, m->meta.name))
return(0);
m->last = nn;
-
return(1);
}
+/*
+ * The `Nm' macro's first use sets the name of the document. See also
+ * post_std(), etc.
+ */
static int
post_nm(POST_ARGS)
{
- char buf[64];
+ char buf[BUFSIZ];
if (m->meta.name)
return(1);
-
- buf[0] = 0;
- if ( ! concat(m, n->child, buf, sizeof(buf)))
+ if ( ! concat(m, buf, n->child, BUFSIZ))
return(0);
- if (NULL == (m->meta.name = strdup(buf)))
- return(mdoc_nerr(m, n, EMALLOC));
-
+ m->meta.name = mandoc_strdup(buf);
return(1);
}
+/*
+ * Look up the value of `Lb' for matching predefined strings. If it has
+ * one, then substitute the current value for the formatted value. Note
+ * that the lookup may fail (we can provide arbitrary strings).
+ */
+/* ARGSUSED */
static int
post_lb(POST_ARGS)
{
assert(MDOC_TEXT == n->child->type);
p = mdoc_a2lib(n->child->string);
- if (NULL == p) {
- sz = strlen(n->child->string) +
- 2 + strlen("\\(lqlibrary\\(rq");
- buf = malloc(sz);
- if (NULL == buf)
- return(mdoc_nerr(m, n, EMALLOC));
- (void)snprintf(buf, sz, "library \\(lq%s\\(rq",
- n->child->string);
+
+ if (p) {
free(n->child->string);
- n->child->string = buf;
+ n->child->string = mandoc_strdup(p);
return(1);
}
+ sz = strlen(n->child->string) +
+ 2 + strlen("\\(lqlibrary\\(rq");
+ buf = mandoc_malloc(sz);
+ snprintf(buf, sz, "library \\(lq%s\\(rq", n->child->string);
free(n->child->string);
- n->child->string = strdup(p);
- if (NULL == n->child->string)
- return(mdoc_nerr(m, n, EMALLOC));
-
+ n->child->string = buf;
return(1);
}
+/*
+ * Substitute the value of `St' for the corresponding formatted string.
+ * We're guaranteed that this exists (it's been verified during the
+ * validation phase).
+ */
+/* ARGSUSED */
static int
post_st(POST_ARGS)
{
p = mdoc_a2st(n->child->string);
assert(p);
free(n->child->string);
- n->child->string = strdup(p);
- if (NULL == n->child->string)
- return(mdoc_nerr(m, n, EMALLOC));
-
+ n->child->string = mandoc_strdup(p);
return(1);
}
+/*
+ * Look up the standard string in a table. We know that it exists from
+ * the validation phase, so assert on failure. If a standard key wasn't
+ * supplied, supply the default ``AT&T UNIX''.
+ */
static int
post_at(POST_ARGS)
{
p = mdoc_a2att(n->child->string);
assert(p);
free(n->child->string);
- n->child->string = strdup(p);
- if (NULL == n->child->string)
- return(mdoc_nerr(m, n, EMALLOC));
+ n->child->string = mandoc_strdup(p);
return(1);
}
nn = n;
m->next = MDOC_NEXT_CHILD;
-
if ( ! mdoc_word_alloc(m, nn->line, nn->pos, "AT&T UNIX"))
return(0);
m->last = nn;
-
return(1);
}
+/*
+ * Mark the current section. The ``named'' section (lastnamed) is set
+ * whenever the current section isn't a custom section--we use this to
+ * keep track of section ordering. Also check that the section is
+ * allowed within the document's manual section.
+ */
static int
post_sh(POST_ARGS)
{
enum mdoc_sec sec;
- char buf[64];
-
- /*
- * We keep track of the current section /and/ the "named"
- * section, which is one of the conventional ones, in order to
- * check ordering.
- */
+ char buf[BUFSIZ];
if (MDOC_HEAD != n->type)
return(1);
- buf[0] = 0;
- if ( ! concat(m, n->child, buf, sizeof(buf)))
+ if ( ! concat(m, buf, n->child, BUFSIZ))
return(0);
- if (SEC_CUSTOM != (sec = mdoc_atosec(buf)))
+ sec = mdoc_atosec(buf);
+ if (SEC_CUSTOM != sec)
m->lastnamed = sec;
+ /* Some sections only live in certain manual sections. */
+
switch ((m->lastsec = sec)) {
case (SEC_RETURN_VALUES):
/* FALLTHROUGH */
}
+/*
+ * Parse out the contents of `Dt'. See in-line documentation for how we
+ * handle the various fields of this macro.
+ */
static int
post_dt(POST_ARGS)
{
*/
if (NULL == (nn = n->child)) {
- if (NULL == (m->meta.title = strdup("unknown")))
- return(mdoc_nerr(m, n, EMALLOC));
- if (NULL == (m->meta.vol = strdup("local")))
- return(mdoc_nerr(m, n, EMALLOC));
+ /* XXX: make these macro values. */
+ m->meta.title = mandoc_strdup("unknown");
+ m->meta.vol = mandoc_strdup("local");
return(post_prol(m, n));
}
* --> title = TITLE, volume = local, msec = 0, arch = NULL
*/
- if (NULL == (m->meta.title = strdup(nn->string)))
- return(mdoc_nerr(m, n, EMALLOC));
+ m->meta.title = mandoc_strdup(nn->string);
if (NULL == (nn = nn->next)) {
- if (NULL == (m->meta.vol = strdup("local")))
- return(mdoc_nerr(m, n, EMALLOC));
+ /* XXX: make this a macro value. */
+ m->meta.vol = mandoc_strdup("local");
return(post_prol(m, n));
}
cp = mdoc_a2msec(nn->string);
if (cp) {
- if (NULL == (m->meta.vol = strdup(cp)))
- return(mdoc_nerr(m, n, EMALLOC));
- errno = 0;
+ /* FIXME: where is strtonum!? */
+ m->meta.vol = mandoc_strdup(cp);
lval = strtol(nn->string, &ep, 10);
if (nn->string[0] != '\0' && *ep == '\0')
m->meta.msec = (int)lval;
- } else if (NULL == (m->meta.vol = strdup(nn->string)))
- return(mdoc_nerr(m, n, EMALLOC));
+ } else
+ m->meta.vol = mandoc_strdup(nn->string);
if (NULL == (nn = nn->next))
return(post_prol(m, n));
cp = mdoc_a2vol(nn->string);
if (cp) {
free(m->meta.vol);
- if (NULL == (m->meta.vol = strdup(cp)))
- return(mdoc_nerr(m, n, EMALLOC));
+ m->meta.vol = mandoc_strdup(cp);
} else {
cp = mdoc_a2arch(nn->string);
if (NULL == cp) {
free(m->meta.vol);
- if (NULL == (m->meta.vol = strdup(nn->string)))
- return(mdoc_nerr(m, n, EMALLOC));
- } else if (NULL == (m->meta.arch = strdup(cp)))
- return(mdoc_nerr(m, n, EMALLOC));
+ m->meta.vol = mandoc_strdup(nn->string);
+ } else
+ m->meta.arch = mandoc_strdup(cp);
}
/* Ignore any subsequent parameters... */
+ /* FIXME: warn about subsequent parameters. */
return(post_prol(m, n));
}
+/*
+ * Set the operating system by way of the `Os' macro. Note that if an
+ * argument isn't provided and -DOSNAME="\"foo\"" is provided during
+ * compilation, this value will be used instead of filling in "sysname
+ * release" from uname().
+ */
static int
post_os(POST_ARGS)
{
- char buf[64];
-#ifndef OSNAME
+ char buf[BUFSIZ];
+#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);
- buf[0] = 0;
- if ( ! concat(m, n->child, buf, sizeof(buf)))
+ if ( ! concat(m, buf, n->child, BUFSIZ))
return(0);
- if (0 == buf[0]) {
-#ifdef OSNAME
- if (strlcat(buf, OSNAME, 64) >= 64)
+ if ('\0' == buf[0]) {
+#ifdef OSNAME
+ if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ)
return(mdoc_nerr(m, n, EUTSNAME));
-#else
+#else /*!OSNAME */
if (-1 == uname(&utsname))
return(mdoc_nerr(m, n, EUTSNAME));
- if (strlcat(buf, utsname.sysname, 64) >= 64)
+ if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ)
return(mdoc_nerr(m, n, ETOOLONG));
- if (strlcat(buf, " ", 64) >= 64)
+ if (strlcat(buf, " ", 64) >= BUFSIZ)
return(mdoc_nerr(m, n, ETOOLONG));
- if (strlcat(buf, utsname.release, 64) >= 64)
+ if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ)
return(mdoc_nerr(m, n, ETOOLONG));
-#endif
+#endif /*!OSNAME*/
}
- if (NULL == (m->meta.os = strdup(buf)))
- return(mdoc_nerr(m, n, EMALLOC));
-
+ m->meta.os = mandoc_strdup(buf);
return(post_prol(m, n));
}
/*
* Calculate the -width for a `Bl -tag' list if it hasn't been provided.
- * Uses the first head macro.
+ * Uses the first head macro. NOTE AGAIN: this is ONLY if the -width
+ * argument has NOT been provided. See post_bl_width() for converting
+ * the -width string.
*/
static int
post_bl_tagwidth(POST_ARGS)
{
- struct mdoc_node *nn;
- int sz;
- char buf[32];
+ struct mdoc_node *nn;
+ size_t sz;
+ int i;
+ char buf[NUMSIZ];
- /*
- * Use the text width, if a text node, or the default macro
- * width if a macro.
- */
+ /* Defaults to ten ens. */
+ sz = 10; /* XXX: make this a macro value. */
nn = n->body->child;
+
if (nn) {
assert(MDOC_BLOCK == nn->type);
assert(MDOC_It == nn->tok);
nn = nn->head->child;
- }
-
- sz = 10; /* Default size. */
-
- if (nn) {
if (MDOC_TEXT != nn->type) {
- if (0 == (sz = (int)mdoc_macro2len(nn->tok)))
+ sz = mdoc_macro2len(nn->tok);
+ if (sz == 0) {
if ( ! mdoc_nwarn(m, n, ENOWIDTH))
return(0);
+ sz = 10;
+ }
} else
- sz = (int)strlen(nn->string) + 1;
+ sz = strlen(nn->string) + 1;
}
- if (-1 == snprintf(buf, sizeof(buf), "%dn", sz))
- return(mdoc_nerr(m, n, ENUMFMT));
+ snprintf(buf, NUMSIZ, "%zun", sz);
/*
* We have to dynamically add this to the macro's argument list.
nn = n;
assert(nn->args);
- sz = (int)(nn->args->argc)++;
+ i = (int)(nn->args->argc)++;
- nn->args->argv = realloc(nn->args->argv,
+ nn->args->argv = mandoc_realloc(nn->args->argv,
nn->args->argc * sizeof(struct mdoc_argv));
- if (NULL == nn->args->argv)
- return(mdoc_nerr(m, n, EMALLOC));
-
- nn->args->argv[sz].arg = MDOC_Width;
- nn->args->argv[sz].line = n->line;
- nn->args->argv[sz].pos = n->pos;
- nn->args->argv[sz].sz = 1;
- nn->args->argv[sz].value = calloc(1, sizeof(char *));
-
- if (NULL == nn->args->argv[sz].value)
- return(mdoc_nerr(m, n, EMALLOC));
- if (NULL == (nn->args->argv[sz].value[0] = strdup(buf)))
- return(mdoc_nerr(m, n, EMALLOC));
-
+ nn->args->argv[i].arg = MDOC_Width;
+ nn->args->argv[i].line = n->line;
+ nn->args->argv[i].pos = n->pos;
+ nn->args->argv[i].sz = 1;
+ nn->args->argv[i].value = mandoc_malloc(sizeof(char *));
+ nn->args->argv[i].value[0] = mandoc_strdup(buf);
return(1);
}
+/*
+ * Calculate the real width of a list from the -width string, which may
+ * contain a macro (with a known default width), a literal string, or a
+ * scaling width.
+ */
static int
post_bl_width(POST_ARGS)
{
size_t width;
int i, tok;
- char buf[32];
+ char buf[NUMSIZ];
char *p;
if (NULL == n->args)
*/
if (0 == strcmp(p, "Ds"))
+ /* XXX: make into a macro. */
width = 6;
else if (MDOC_MAX == (tok = mdoc_hash_find(p)))
return(1);
/* The value already exists: free and reallocate it. */
- if (-1 == snprintf(buf, sizeof(buf), "%zun", width))
- return(mdoc_nerr(m, n, ENUMFMT));
-
+ snprintf(buf, NUMSIZ, "%zun", width);
free(n->args->argv[i].value[0]);
- n->args->argv[i].value[0] = strdup(buf);
- if (NULL == n->args->argv[i].value[0])
- return(mdoc_nerr(m, n, EMALLOC));
-
+ n->args->argv[i].value[0] = mandoc_strdup(buf);
return(1);
}
+/*
+ * Do processing for -column lists, which can have two distinct styles
+ * of invocation. Merge this two styles into a consistent form.
+ */
/* ARGSUSED */
static int
post_bl_head(POST_ARGS)
if (MDOC_Column == np->args->argv[c].arg)
break;
- /* Only process -column. */
-
if (c == (int)np->args->argc)
return(1);
-
assert(0 == np->args->argv[c].sz);
/*
*/
np->args->argv[c].sz = (size_t)n->nchild;
- np->args->argv[c].value = malloc
+ np->args->argv[c].value = mandoc_malloc
((size_t)n->nchild * sizeof(char *));
for (i = 0, nn = n->child; nn; i++) {
n->nchild = 0;
n->child = NULL;
-
return(1);
}
}
+/*
+ * The `Pa' macro defaults to a tilde if no value is provided as an
+ * argument.
+ */
static int
-post_tilde(POST_ARGS)
+post_pa(POST_ARGS)
{
struct mdoc_node *np;
np = n;
m->next = MDOC_NEXT_CHILD;
-
+ /* XXX: make into macro value. */
if ( ! mdoc_word_alloc(m, n->line, n->pos, "~"))
return(0);
m->last = np;
-
return(1);
}
+/*
+ * The `Ar' macro defaults to two strings "file ..." if no value is
+ * provided as an argument.
+ */
static int
post_ar(POST_ARGS)
{
np = n;
m->next = MDOC_NEXT_CHILD;
+ /* XXX: make into macro values. */
if ( ! mdoc_word_alloc(m, n->line, n->pos, "file"))
return(0);
if ( ! mdoc_word_alloc(m, n->line, n->pos, "..."))
return(0);
m->last = np;
-
return(1);
}
+/*
+ * Parse the date field in `Dd'.
+ */
static int
post_dd(POST_ARGS)
{
- char buf[64];
+ char buf[DATESIZ];
- buf[0] = 0;
- if ( ! concat(m, n->child, buf, sizeof(buf)))
+ if ( ! concat(m, buf, n->child, DATESIZ))
return(0);
- if (0 == (m->meta.date = mdoc_atotime(buf))) {
+ m->meta.date = mandoc_a2time
+ (MTIME_MDOCDATE | MTIME_CANONICAL, buf);
+
+ if (0 == m->meta.date) {
if ( ! mdoc_nwarn(m, n, EBADDATE))
return(0);
m->meta.date = time(NULL);
}
+/*
+ * Remove prologue macros from the document after they're processed.
+ * The final document uses mdoc_meta for these values and discards the
+ * originals.
+ */
static int
post_prol(POST_ARGS)
{
struct mdoc_node *np;
- /* Remove prologue macros from AST. */
-
if (n->parent->child == n)
n->parent->child = n->prev;
if (n->prev)
}
+/*
+ * Trigger a literal context.
+ */
static int
pre_dl(PRE_ARGS)
{
}
+/* ARGSUSED */
static int
pre_offset(PRE_ARGS)
{
break;
assert(1 == n->args->refcnt);
/* If no value set, length of <string>. */
- n->args->argv[i].value =
- calloc(1, sizeof(char *));
- if (NULL == n->args->argv[i].value)
- return(mdoc_nerr(m, n, EMALLOC));
n->args->argv[i].sz++;
- n->args->argv[i].value[0] = strdup("8n");
- if (NULL == n->args->argv[i].value[0])
- return(mdoc_nerr(m, n, EMALLOC));
+ n->args->argv[i].value = mandoc_malloc(sizeof(char *));
+ n->args->argv[i].value[0] = mandoc_strdup("8n");
break;
}
-/* $Id: mdoc_argv.c,v 1.18 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc_argv.c,v 1.32 2009/10/30 05:58:38 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <string.h>
#include "libmdoc.h"
+#include "libmandoc.h"
/*
* Routines to parse arguments of macros. Arguments follow the syntax
if ( ! argv(m, line, &tmp, pos, buf))
return(ARGV_ERROR);
- if (NULL == (arg = *v)) {
- *v = calloc(1, sizeof(struct mdoc_arg));
- if (NULL == *v) {
- (void)mdoc_nerr(m, m->last, EMALLOC);
- return(ARGV_ERROR);
- }
- arg = *v;
- }
+ if (NULL == (arg = *v))
+ arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
arg->argc++;
- arg->argv = realloc(arg->argv, arg->argc *
- sizeof(struct mdoc_argv));
-
- if (NULL == arg->argv) {
- (void)mdoc_nerr(m, m->last, EMALLOC);
- return(ARGV_ERROR);
- }
+ arg->argv = mandoc_realloc
+ (arg->argv, arg->argc * sizeof(struct mdoc_argv));
(void)memcpy(&arg->argv[(int)arg->argc - 1],
&tmp, sizeof(struct mdoc_argv));
else if (ARGS_EOLN == c)
break;
- if (0 == v->sz % MULTI_STEP) {
- v->value = realloc(v->value,
+ if (0 == v->sz % MULTI_STEP)
+ v->value = mandoc_realloc(v->value,
(v->sz + MULTI_STEP) * sizeof(char *));
- if (NULL == v->value) {
- (void)mdoc_nerr(m, m->last, EMALLOC);
- return(ARGV_ERROR);
- }
- }
- if (NULL == (v->value[(int)v->sz] = strdup(p)))
- return(mdoc_nerr(m, m->last, EMALLOC));
+
+ v->value[(int)v->sz] = mandoc_strdup(p);
}
return(1);
return(1);
v->sz = 1;
- if (NULL == (v->value = calloc(1, sizeof(char *))))
- return(mdoc_nerr(m, m->last, EMALLOC));
- if (NULL == (v->value[0] = strdup(p)))
- return(mdoc_nerr(m, m->last, EMALLOC));
+ v->value = mandoc_malloc(sizeof(char *));
+ v->value[0] = mandoc_strdup(p);
return(1);
}
return(mdoc_perr(m, line, ppos, EARGVAL));
v->sz = 1;
- if (NULL == (v->value = calloc(1, sizeof(char *))))
- return(mdoc_nerr(m, m->last, EMALLOC));
- if (NULL == (v->value[0] = strdup(p)))
- return(mdoc_nerr(m, m->last, EMALLOC));
+ v->value = mandoc_malloc(sizeof(char *));
+ v->value[0] = mandoc_strdup(p);
return(1);
}
-/* $Id: mdoc_hash.c,v 1.6 2009/09/21 21:11:37 schwarze Exp $ */
+/* $Id: mdoc_hash.c,v 1.11 2009/09/17 07:41:28 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: mdoc_html.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.46 2009/10/31 08:34:12 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <assert.h>
#include <ctype.h>
-#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int mdoc_xr_pre(MDOC_ARGS);
static int mdoc_xx_pre(MDOC_ARGS);
+#ifdef __linux__
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
static const struct htmlmdoc mdocs[MDOC_MAX] = {
{mdoc_ap_pre, NULL}, /* Ap */
{NULL, NULL}, /* Dd */
static void
mdoc_root_post(MDOC_ARGS)
{
- struct htmlpair tag[2];
+ struct htmlpair tag[3];
struct tag *t, *tt;
char b[DATESIZ];
PAIR_CLASS_INIT(&tag[0], "footer");
bufcat_style(h, "width", "100%");
PAIR_STYLE_INIT(&tag[1], h);
- t = print_otag(h, TAG_TABLE, 2, tag);
+ PAIR_SUMMARY_INIT(&tag[2], "footer");
+
+ t = print_otag(h, TAG_TABLE, 3, tag);
tt = print_otag(h, TAG_TR, 0, NULL);
bufinit(h);
static int
mdoc_root_pre(MDOC_ARGS)
{
- struct htmlpair tag[2];
+ struct htmlpair tag[3];
struct tag *t, *tt;
char b[BUFSIZ], title[BUFSIZ];
PAIR_CLASS_INIT(&tag[0], "header");
bufcat_style(h, "width", "100%");
PAIR_STYLE_INIT(&tag[1], h);
- t = print_otag(h, TAG_TABLE, 2, tag);
+ PAIR_SUMMARY_INIT(&tag[2], "header");
+
+ t = print_otag(h, TAG_TABLE, 3, tag);
+
tt = print_otag(h, TAG_TR, 0, NULL);
bufinit(h);
{
struct htmlpair tag[2];
const struct mdoc_node *nn;
- char lbuf[BUFSIZ];
+ char buf[BUFSIZ];
struct roffsu su;
if (MDOC_BODY == n->type) {
return(1);
}
- lbuf[0] = 0;
+ buf[0] = '\0';
for (nn = n->child; nn; nn = nn->next) {
- (void)strlcat(lbuf, nn->string, BUFSIZ);
+ html_idcat(buf, nn->string, BUFSIZ);
if (nn->next)
- (void)strlcat(lbuf, "_", BUFSIZ);
+ html_idcat(buf, " ", BUFSIZ);
}
/*
PAIR_CLASS_INIT(&tag[0], "sec-head");
tag[1].key = ATTR_ID;
- tag[1].val = lbuf;
+ tag[1].val = buf;
print_otag(h, TAG_DIV, 2, tag);
return(1);
}
static int
mdoc_ss_pre(MDOC_ARGS)
{
- struct htmlpair tag[3];
+ struct htmlpair tag[3];
const struct mdoc_node *nn;
- char lbuf[BUFSIZ];
+ char buf[BUFSIZ];
struct roffsu su;
SCALE_VS_INIT(&su, 1);
/* TODO: see note in mdoc_sh_pre() about duplicates. */
- lbuf[0] = 0;
+ buf[0] = '\0';
for (nn = n->child; nn; nn = nn->next) {
- (void)strlcat(lbuf, nn->string, BUFSIZ);
+ html_idcat(buf, nn->string, BUFSIZ);
if (nn->next)
- (void)strlcat(lbuf, "_", BUFSIZ);
+ html_idcat(buf, " ", BUFSIZ);
}
SCALE_HS_INIT(&su, INDENT - HALFINDENT);
PAIR_CLASS_INIT(&tag[0], "ssec-head");
PAIR_STYLE_INIT(&tag[1], h);
tag[2].key = ATTR_ID;
- tag[2].val = lbuf;
+ tag[2].val = buf;
print_otag(h, TAG_DIV, 3, tag);
return(1);
}
pp = "BSDI BSD/OS";
break;
case (MDOC_Dx):
- pp = "DragonFlyBSD";
+ pp = "DragonFly";
break;
case (MDOC_Fx):
pp = "FreeBSD";
switch (type) {
case (MDOC_Item):
- /* FALLTHROUGH */
+ return(0);
case (MDOC_Ohang):
- print_otag(h, TAG_DIV, 0, NULL);
- break;
+ print_otag(h, TAG_DIV, 0, &tag);
+ return(1);
case (MDOC_Column):
bufcat_su(h, "min-width", width);
bufcat_style(h, "clear", "none");
/* Override width in some cases. */
switch (type) {
+ case (MDOC_Ohang):
+ /* FALLTHROUGH */
case (MDOC_Item):
/* FALLTHROUGH */
case (MDOC_Inset):
return(1);
ord = malloc(sizeof(struct ord));
- if (NULL == ord)
- err(EXIT_FAILURE, "malloc");
+ if (NULL == ord) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
ord->cookie = n;
ord->pos = 1;
ord->next = h->ords.head;
/* FIXME: duplicates? */
- (void)strlcpy(buf, "#", BUFSIZ);
+ strlcpy(buf, "#", BUFSIZ);
for (nn = n->child; nn; nn = nn->next) {
- (void)strlcat(buf, nn->string, BUFSIZ);
+ html_idcat(buf, nn->string, BUFSIZ);
if (nn->next)
- (void)strlcat(buf, "_", BUFSIZ);
+ html_idcat(buf, " ", BUFSIZ);
}
PAIR_CLASS_INIT(&tag[0], "link-sec");
bufcat_su(h, "height", &su);
PAIR_STYLE_INIT(&tag, h);
print_otag(h, TAG_DIV, 1, &tag);
- return(1);
+ /* So the div isn't empty: */
+ print_text(h, "\\~");
+
+ return(0);
}
for (nn = n->child; nn; nn = nn->next) {
PAIR_CLASS_INIT(&tag[0], "link-includes");
i = 1;
+ bufinit(h);
if (h->base_includes) {
buffmt_includes(h, nn->string);
tag[i].key = ATTR_HREF;
-/* $Id: mdoc_macro.c,v 1.25 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.38 2009/10/26 17:05:44 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <time.h>
#include "libmdoc.h"
-/* $Id: mdoc_strings.c,v 1.10 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc_strings.c,v 1.13 2009/11/02 06:22:46 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
}
-time_t
-mdoc_atotime(const char *p)
-{
- struct tm tm;
- char *pp;
-
- bzero(&tm, sizeof(struct tm));
-
- if (0 == strcmp(p, "$" "Mdocdate$"))
- return(time(NULL));
- if ((pp = strptime(p, "$" "Mdocdate: %b %d %Y $", &tm)) && 0 == *pp)
- return(mktime(&tm));
- /* XXX - this matches "June 1999", which is wrong. */
- if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
-
- return(0);
-}
-
-
/* FIXME: move this into an editable .in file. */
size_t
mdoc_macro2len(int macro)
case(MDOC_Em):
return(10);
case(MDOC_Er):
- return(12);
+ return(17);
case(MDOC_Ev):
return(15);
case(MDOC_Fa):
-/* $Id: mdoc_term.c,v 1.62 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.100 2009/10/31 06:50:25 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <assert.h>
#include <ctype.h>
-#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void print_bvspace(struct termp *,
const struct mdoc_node *,
const struct mdoc_node *);
-static void print_node(DECL_ARGS);
+static void print_node(DECL_ARGS);
static void print_head(DECL_ARGS);
static void print_body(DECL_ARGS);
static void print_foot(DECL_ARGS);
+#ifdef __linux__
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
static void termp____post(DECL_ARGS);
static void termp_an_post(DECL_ARGS);
static void termp_aq_post(DECL_ARGS);
bold = p->bold;
under = p->under;
- bzero(&npair, sizeof(struct termpair));
+ memset(&npair, 0, sizeof(struct termpair));
npair.ppair = pair;
if (MDOC_TEXT != n->type) {
static void
print_foot(DECL_ARGS)
{
- char buf[DATESIZ];
- char *os;
+ char buf[DATESIZ], os[BUFSIZ];
/*
* Output the footer in new-groff style, that is, three columns
* SYSTEM DATE SYSTEM
*/
- if (NULL == (os = malloc(p->rmargin)))
- err(EXIT_FAILURE, "malloc");
-
time2a(m->date, buf, DATESIZ);
-
- (void)strlcpy(os, m->os, p->rmargin);
+ strlcpy(os, m->os, BUFSIZ);
term_vspace(p);
p->offset = 0;
p->rmargin = p->maxrmargin;
p->flags = 0;
-
- free(os);
}
static void
print_head(DECL_ARGS)
{
- char *buf, *title;
+ char buf[BUFSIZ], title[BUFSIZ];
p->rmargin = p->maxrmargin;
p->offset = 0;
- if (NULL == (buf = malloc(p->rmargin)))
- err(EXIT_FAILURE, "malloc");
- if (NULL == (title = malloc(p->rmargin)))
- err(EXIT_FAILURE, "malloc");
-
/*
* The header is strange. It has three components, which are
* really two with the first duplicated. It goes like this:
*/
assert(m->vol);
- (void)strlcpy(buf, m->vol, p->rmargin);
+ strlcpy(buf, m->vol, BUFSIZ);
if (m->arch) {
- (void)strlcat(buf, " (", p->rmargin);
- (void)strlcat(buf, m->arch, p->rmargin);
- (void)strlcat(buf, ")", p->rmargin);
+ strlcat(buf, " (", BUFSIZ);
+ strlcat(buf, m->arch, BUFSIZ);
+ strlcat(buf, ")", BUFSIZ);
}
- snprintf(title, p->rmargin, "%s(%d)", m->title, m->msec);
+ snprintf(title, BUFSIZ, "%s(%d)", m->title, m->msec);
p->offset = 0;
p->rmargin = (p->maxrmargin - strlen(buf) + 1) / 2;
p->offset = 0;
p->rmargin = p->maxrmargin;
p->flags &= ~TERMP_NOSPACE;
-
- free(title);
- free(buf);
}
pp = "BSDI BSD/OS";
break;
case (MDOC_Dx):
- pp = "DragonFlyBSD";
+ pp = "DragonFly";
break;
case (MDOC_Fx):
pp = "FreeBSD";
-/* $Id: mdoc_validate.c,v 1.38 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.54 2009/11/02 06:22:46 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include <assert.h>
#include <ctype.h>
-#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
static int err_count(struct mdoc *, const char *,
int, const char *, int);
+#ifdef __linux__
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
static int berr_ge1(POST_ARGS);
static int bwarn_ge1(POST_ARGS);
static int ebool(POST_ARGS);
{ NULL, posts_xr }, /* Xr */
{ NULL, posts_text }, /* %A */
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */
- { NULL, posts_text }, /* %D */
+ { NULL, posts_text }, /* %D */ /* FIXME: check date with mandoc_a2time(). */
{ NULL, posts_text }, /* %I */
{ NULL, posts_text }, /* %J */
{ NULL, posts_text }, /* %N */
/* FALLTHROUGH */
case (MDOC_Diag):
/* FALLTHROUGH */
+ case (MDOC_Ohang):
+ /* FALLTHROUGH */
case (MDOC_Inset):
/* FALLTHROUGH */
case (MDOC_Item):
pre_dt(PRE_ARGS)
{
+ /* FIXME: make sure is capitalised. */
+
if (0 == mdoc->meta.date || mdoc->meta.os)
if ( ! mdoc_nwarn(mdoc, n, EPROLOOO))
return(0);
-/* $Id: msec.c,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: msec.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
*/
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "libmdoc.h"
-/* $Id: out.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: out.c,v 1.7 2009/10/22 18:59:00 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#include "out.h"
+#ifdef __linux__
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
/*
* Convert a `scaling unit' to a consistent form, or fail. Scaling
* units are documented in groff.7, mdoc.7, man.7.
-/* $Id: out.h,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: out.h,v 1.6 2009/10/22 18:55:33 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: st.c,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: st.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
*/
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "libmdoc.h"
-/* $Id: st.in,v 1.5 2009/10/19 20:39:58 schwarze Exp $ */
+/* $Id: st.in,v 1.11 2009/09/27 17:11:48 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
* Be sure to escape strings.
*/
-LINE("-p1003.1-88", "IEEE Std 1003.1-1988 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1-90", "IEEE Std 1003.1-1990 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX\\(rq)")
-LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX\\(rq)")
+LINE("-p1003.1-88", "IEEE Std 1003.1-1988 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-90", "IEEE Std 1003.1-1990 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1\\(rq)")
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1\\(rq)")
LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)")
LINE("-p1387.2-95", "IEEE Std 1387.2-1995 (\\(lqPOSIX.7.2\\(rq)")
-/* $Id: term.c,v 1.18 2009/10/27 21:40:07 schwarze Exp $ */
+/* $Id: term.c,v 1.120 2009/10/31 06:10:58 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
-#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "chars.h"
#include "out.h"
{
struct termp *p;
- if (NULL == (p = malloc(sizeof(struct termp))))
- return(NULL);
- bzero(p, sizeof(struct termp));
+ p = calloc(1, sizeof(struct termp));
+ if (NULL == p) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
p->maxrmargin = 78;
p->enc = enc;
return(p);
* If TERMP_NOBREAK is specified and the line overruns the right
* margin, it will break and pad-right to the right margin after
* writing. If maxrmargin is violated, it will break and continue
- * writing from the right-margin, which will lead to the above
- * scenario upon exit.
- *
- * Otherwise, the line will break at the right margin. Extremely long
- * lines will cause the system to emit a warning (TODO: hyphenate, if
- * possible).
+ * writing from the right-margin, which will lead to the above scenario
+ * upon exit. Otherwise, the line will break at the right margin.
*/
void
term_flushln(struct termp *p)
{
- int i, j;
- size_t vbl, vsz, vis, maxvis, mmax, bp;
+ int i; /* current input position in p->buf */
+ size_t vis; /* current visual position on output */
+ size_t vbl; /* number of blanks to prepend to output */
+ size_t vsz; /* visual characters to write to output */
+ size_t bp; /* visual right border position */
+ int j; /* temporary loop index */
+ size_t maxvis, mmax;
static int overstep = 0;
/*
*/
assert(p->offset < p->rmargin);
- assert((int)(p->rmargin - p->offset) - overstep > 0);
- maxvis = /* LINTED */
- p->rmargin - p->offset - overstep;
- mmax = /* LINTED */
- p->maxrmargin - p->offset - overstep;
+ maxvis = (int)(p->rmargin - p->offset) - overstep < 0 ?
+ /* LINTED */
+ 0 : p->rmargin - p->offset - overstep;
+ mmax = (int)(p->maxrmargin - p->offset) - overstep < 0 ?
+ /* LINTED */
+ 0 : p->maxrmargin - p->offset - overstep;
bp = TERMP_NOBREAK & p->flags ? mmax : maxvis;
+
+ /*
+ * FIXME: if bp is zero, we still output the first word before
+ * breaking the line.
+ */
+
vis = 0;
/*
p->maxcols = 256;
s = p->maxcols * 2;
p->buf = realloc(p->buf, s);
- if (NULL == p->buf)
- err(1, "realloc"); /* FIXME: shouldn't be here! */
+ if (NULL == p->buf) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
p->maxcols = s;
}
p->buf[(int)(p->col)++] = c;
-/* $Id: term.h,v 1.12 2009/10/21 19:13:51 schwarze Exp $ */
+/* $Id: term.h,v 1.49 2009/10/18 19:03:37 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: tree.c,v 1.5 2009/10/21 19:13:51 schwarze Exp $ */
+/* $Id: tree.c,v 1.18 2009/10/30 18:53:09 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
-#include <err.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include "mdoc.h"
#include "man.h"
-/* $Id: vol.c,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: vol.c,v 1.5 2009/10/26 17:05:45 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
*/
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "libmdoc.h"
-/* $Id: vol.in,v 1.2 2009/06/14 23:00:57 schwarze Exp $ */
+/* $Id: vol.in,v 1.5 2009/06/10 20:18:44 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*