X-Git-Url: https://git.cameronkatri.com/mandoc.git/blobdiff_plain/95356d6189f5e5d41011a7cb60176f147e1fff7d..0b78a3a44f37b7427013aaf51e6cc2b8888b6406:/man.c

diff --git a/man.c b/man.c
index 4a4b27b2..147662e9 100644
--- a/man.c
+++ b/man.c
@@ -1,6 +1,6 @@
-/*	$Id: man.c,v 1.74 2010/05/17 22:11:42 kristaps Exp $ */
+/*	$Id: man.c,v 1.92 2010/12/08 10:58:22 kristaps Exp $ */
 /*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 
 #include <assert.h>
-#include <ctype.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -37,10 +36,10 @@ const	char *const __man_macronames[MAN_MAX] = {
 	"IP",		"HP",		"SM",		"SB",
 	"BI",		"IB",		"BR",		"RB",
 	"R",		"B",		"I",		"IR",
-	"RI",		"na",		"i",		"sp",
-	"nf",		"fi",		"r",		"RE",
-	"RS",		"DT",		"UC",		"PD",
-	"Sp",		"Vb",		"Ve",		"AT",
+	"RI",		"na",		"sp",		"nf",
+	"fi",		"RE",		"RS",		"DT",
+	"UC",		"PD",		"AT",		"in",
+	"ft"
 	};
 
 const	char * const *man_macronames = __man_macronames;
@@ -56,7 +55,6 @@ static	int		 man_ptext(struct man *, int, char *, int);
 static	int		 man_pmacro(struct man *, int, char *, int);
 static	void		 man_free1(struct man *);
 static	void		 man_alloc1(struct man *);
-static	int		 macrowarn(struct man *, int, const char *, int);
 
 
 const struct man_node *
@@ -94,7 +92,7 @@ man_free(struct man *man)
 
 
 struct man *
-man_alloc(void *data, int pflags, mandocmsg msg)
+man_alloc(struct regset *regs, void *data, mandocmsg msg)
 {
 	struct man	*p;
 
@@ -102,8 +100,8 @@ man_alloc(void *data, int pflags, mandocmsg msg)
 
 	man_hash_init();
 	p->data = data;
-	p->pflags = pflags;
 	p->msg = msg;
+	p->regs = regs;
 
 	man_alloc1(p);
 	return(p);
@@ -146,6 +144,8 @@ man_free1(struct man *man)
 		free(man->meta.title);
 	if (man->meta.source)
 		free(man->meta.source);
+	if (man->meta.rawdate)
+		free(man->meta.rawdate);
 	if (man->meta.vol)
 		free(man->meta.vol);
 	if (man->meta.msec)
@@ -215,8 +215,6 @@ man_node_append(struct man *man, struct man_node *p)
 	case (MAN_TEXT):
 		if ( ! man_valid_post(man))
 			return(0);
-		if ( ! man_action_post(man))
-			return(0);
 		break;
 	default:
 		break;
@@ -405,7 +403,7 @@ man_ptext(struct man *m, int line, char *buf, int offs)
 	 */
 
 	assert(i);
-	if (mandoc_eos(buf, (size_t)i))
+	if (mandoc_eos(buf, (size_t)i, 0))
 		m->last->flags |= MAN_EOS;
 
 descope:
@@ -431,19 +429,6 @@ descope:
 }
 
 
-static int
-macrowarn(struct man *m, int ln, const char *buf, int offs)
-{
-	int		 rc;
-
-	rc = man_vmsg(m, MANDOCERR_MACRO, ln, offs, 
-			"unknown macro: %s%s",
-			buf, strlen(buf) > 3 ? "..." : "");
-
-	return(MAN_IGN_MACRO & m->pflags ? rc : 0);
-}
-
-
 int
 man_pmacro(struct man *m, int ln, char *buf, int offs)
 {
@@ -476,34 +461,19 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
 
 	ppos = i;
 
-	/* Copy the first word into a nil-terminated buffer. */
-
-	for (j = 0; j < 4; j++, i++) {
-		if ('\0' == (mac[j] = buf[i]))
-			break;
-		else if (' ' == buf[i])
-			break;
-
-		/* Check for invalid characters. */
-
-		if (isgraph((u_char)buf[i]))
-			continue;
-		if ( ! man_pmsg(m, ln, i, MANDOCERR_BADCHAR))
-			return(0);
-		i--;
-	}
+	/*
+	 * Copy the first word into a nil-terminated buffer.
+	 * Stop copying when a tab, space, or eoln is encountered.
+	 */
 
+	j = 0;
+	while (j < 4 && '\0' != buf[i] && ' ' != buf[i] && '\t' != buf[i])
+		mac[j++] = buf[i++];
 	mac[j] = '\0';
 
-	if (j == 4 || j < 1) {
-		if ( ! macrowarn(m, ln, mac, ppos))
-			goto err;
-		return(1);
-	}
-	
-	if (MAN_MAX == (tok = man_hash_find(mac))) {
-		if ( ! macrowarn(m, ln, mac, ppos))
-			goto err;
+	tok = (j > 0 && j < 4) ? man_hash_find(mac) : MAN_MAX;
+	if (MAN_MAX == tok) {
+		man_vmsg(m, MANDOCERR_MACRO, ln, ppos, "%s", buf + ppos - 1);
 		return(1);
 	}
 
@@ -522,37 +492,23 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
 			goto err;
 
 	/* 
-	 * Remove prior ELINE macro, as it's being clobbering by a new
+	 * Remove prior ELINE macro, as it's being clobbered by a new
 	 * macro.  Note that NSCOPED macros do not close out ELINE
 	 * macros---they don't print text---so we let those slip by.
 	 */
 
 	if ( ! (MAN_NSCOPED & man_macros[tok].flags) &&
 			m->flags & MAN_ELINE) {
-		assert(MAN_TEXT != m->last->type);
-
-		/*
-		 * This occurs in the following construction:
-		 *   .B
-		 *   .br
-		 *   .B
-		 *   .br
-		 *   I hate man macros.
-		 * Flat-out disallow this madness.
-		 */
-		if (MAN_NSCOPED & man_macros[m->last->tok].flags) {
-			man_pmsg(m, ln, ppos, MANDOCERR_SYNTLINESCOPE);
-			return(0);
-		}
-
 		n = m->last;
+		assert(MAN_TEXT != n->type);
 
-		assert(n);
-		assert(NULL == n->child);
-		assert(0 == n->nchild);
+		/* Remove repeated NSCOPED macros causing ELINE. */
 
-		if ( ! man_nmsg(m, n, MANDOCERR_LINESCOPE))
-			return(0);
+		if (MAN_NSCOPED & man_macros[n->tok].flags)
+			n = n->parent;
+
+		man_vmsg(m, MANDOCERR_LINESCOPE, n->line, n->pos,
+				"%s", man_macronames[n->tok]);
 
 		man_node_delete(m, n);
 		m->flags &= ~MAN_ELINE;