tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: Ingo Schwarze <schwarze@usta.de>
To: tech@mdocml.bsd.lv
Subject: [PATCH] rudimentary .ds support
Date: Sat, 3 Jul 2010 08:39:33 +0200	[thread overview]
Message-ID: <20100703063933.GE6026@iris.usta.de> (raw)

Hi,

a couple of manuals use the roff .ds instruction and the roff \s
escape function.  Here is a rudimentary implementation, just to
get the contents of the manuals right for now.

I'm aware of the following deficiencies:

 * mandoc is just taking the string manually, while groff
   is still interpreting it in some way.
   For strings without special characters, this makes no difference.
 * Quoted string parsing in roff_ds() is not correct,
   but a quick hack.
 * Using a singly linked list for the string table is fine for
   small numbers of user-defined strings, which is currently our
   typical use case.  In the long run, we probably want some
   hash table or tree structure.
 * String inclusion comes too late in term.c, function res().
   This will use the last string defined in the file, not the one
   defined at the right point of the file.
 * I deliberately use the user user-defined strings only when no
   predefined strings are available, while groff allows to override
   predefined strings.  As long as this feature is still rather
   sloppily implemented, this limits the potential breakage.
 * HTML rendering is missing (but trivial).

These aspects can be improved later.
For now, it is important to move on as quickly as possible
and fix as many bugs relevant for the system build as possible.
Not much time is left until the 4.8 release lock.

For examples of manuals fixed by this patch, see terminfo(3),
in particular the .Xr to terminfo(5) below SEE ALSO, and
mdoc.samples(7), using the included patch.

OK to commit?
(Of course, i would then remove the debugging print statements
in roff_freestr.)

Yours,
  Ingo


Index: share/man/man7/mdoc.samples.7
===================================================================
RCS file: /cvs/src/share/man/man7/mdoc.samples.7,v
retrieving revision 1.86
diff -u -p -r1.86 mdoc.samples.7
--- share/man/man7/mdoc.samples.7	26 Mar 2010 19:30:40 -0000	1.86
+++ share/man/man7/mdoc.samples.7	3 Jul 2010 06:38:28 -0000
@@ -43,6 +43,7 @@
 .Ox
 manuals with
 .Nm \-mdoc
+.ds Pu {. , ; : ? ! ( ) [ ]}
 .Sh SYNOPSIS
 .Nm nroff
 .Fl T Ns Ar Name
Index: usr.bin/mandoc/roff.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/roff.c,v
retrieving revision 1.6
diff -u -p -r1.6 roff.c
--- usr.bin/mandoc/roff.c	27 Jun 2010 21:54:42 -0000	1.6
+++ usr.bin/mandoc/roff.c	3 Jul 2010 06:38:28 -0000
@@ -100,6 +100,12 @@ struct	roffmac {
 	struct roffmac	*next;
 };
 
+struct	roffstr {
+	char		*name;
+	char		*string;
+	struct roffstr	*next;
+};
+
 static	enum rofferr	 roff_block(ROFF_ARGS);
 static	enum rofferr	 roff_block_text(ROFF_ARGS);
 static	enum rofferr	 roff_block_sub(ROFF_ARGS);
@@ -108,6 +114,7 @@ static	enum rofferr	 roff_ccond(ROFF_ARG
 static	enum rofferr	 roff_cond(ROFF_ARGS);
 static	enum rofferr	 roff_cond_text(ROFF_ARGS);
 static	enum rofferr	 roff_cond_sub(ROFF_ARGS);
+static	enum rofferr	 roff_ds(ROFF_ARGS);
 static	enum rofferr	 roff_line(ROFF_ARGS);
 static	enum rofferr	 roff_nr(ROFF_ARGS);
 static	enum roffrule	 roff_evalcond(const char *, int *);
@@ -127,7 +134,7 @@ static	struct roffmac	 roffs[ROFF_MAX] =
 	{ "de", roff_block, roff_block_text, roff_block_sub, 0, NULL },
 	{ "dei", roff_block, roff_block_text, roff_block_sub, 0, NULL },
 	{ "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL },
-	{ "ds", roff_line, NULL, NULL, 0, NULL },
+	{ "ds", roff_ds, NULL, NULL, 0, NULL },
 	{ "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
 	{ "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
 	{ "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
@@ -152,6 +159,11 @@ static	int		 roff_parse_nat(const char *
 /* See roff_hash_find() */
 #define	ROFF_HASH(p)	(p[0] - ASCII_LO)
 
+static	struct roffstr	*first_string;
+
+static	char		*roff_setstr(const char *, const char *);
+static	void		 roff_freestr(void);
+
 static void
 roff_hash_init(void)
 {
@@ -260,6 +272,7 @@ roff_free1(struct roff *r)
 
 	while (r->last)
 		roffnode_pop(r);
+	roff_freestr();
 }
 
 
@@ -846,6 +859,39 @@ roff_cond(ROFF_ARGS)
 
 /* ARGSUSED */
 static enum rofferr
+roff_ds(ROFF_ARGS)
+{
+	char *name, *string, *end;
+
+	name = *bufp + pos;
+	if ('\0' == *name)
+		return(ROFF_IGN);
+
+	string = name;
+	while (*string && ' ' != *string)
+		string++;
+	if (*string)
+		*(string++) = NULL;
+	if (*string && '"' == *string)
+		string++;
+	while (*string && ' ' == *string)
+		string++;
+	end = string;
+	while (*end)
+		end++;
+	if (string < end) {
+		end--;
+		if (*end == '"')
+			*end = '\0';
+	}
+
+	roff_setstr(name, string);
+	return(ROFF_IGN);
+}
+
+
+/* ARGSUSED */
+static enum rofferr
 roff_nr(ROFF_ARGS)
 {
 	const char	*key, *val;
@@ -880,4 +926,84 @@ roff_nr(ROFF_ARGS)
 	}
 
 	return(ROFF_IGN);
+}
+
+
+static	struct roffstr	*first_string;
+
+static	char *
+roff_setstr(const char *name, const char *string)
+{
+	struct roffstr	 *n;
+	char		 *namecopy;
+
+	n = first_string;
+	while (n && strcmp(name, n->name))
+		n = n->next;
+	if (n) {
+		free(n->string);
+	} else {
+		if (NULL == (namecopy = strdup(name)))
+			return(NULL);
+		if (NULL == (n = malloc(sizeof(struct roffstr)))) {
+			free(n);
+			return(NULL);
+		}
+		n->name = namecopy;
+		n->next = first_string;
+		first_string = n;
+	}
+	if (string)
+		n->string = strdup(string);
+	else
+		n->string = NULL;
+	return(n->string);
+}
+
+char *
+roff_getstr(const char *name)
+{
+	struct roffstr	 *n;
+
+	n = first_string;
+	while (n && strcmp(name, n->name))
+		n = n->next;
+	if (n)
+		return(n->string);
+	else
+		return(NULL);
+}
+
+char *
+roff_getstrn(const char *name, size_t len)
+{
+	struct roffstr	 *n;
+
+	n = first_string;
+	while (n && (strncmp(name, n->name, len) || '\0' != n->name[len]))
+		n = n->next;
+	if (n)
+		return(n->string);
+	else
+		return(NULL);
+}
+
+static	void
+roff_freestr(void)
+{
+	struct roffstr	 *n, *nn;
+
+	for (n = first_string; n; n = nn) {
+		/* --- start of debugging --- */
+		fprintf(stderr, "%s", n->name);
+		if (n->string)
+			fprintf(stderr, " = %s", n->string);
+		fputc('\n', stderr);
+		/* --- end of debugging --- */
+		free(n->name);
+		free(n->string);
+		nn = n->next;
+		free(n);
+	}
+	first_string = NULL;
 }
Index: usr.bin/mandoc/roff.h
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/roff.h,v
retrieving revision 1.3
diff -u -p -r1.3 roff.h
--- usr.bin/mandoc/roff.h	27 Jun 2010 21:54:42 -0000	1.3
+++ usr.bin/mandoc/roff.h	3 Jul 2010 06:38:28 -0000
@@ -35,6 +35,9 @@ enum	rofferr	  roff_parseln(struct roff 
 			char **, size_t *, int, int *);
 int		  roff_endparse(struct roff *);
 
+char		 *roff_getstr(const char *);
+char		 *roff_getstrn(const char *, size_t);
+
 __END_DECLS
 
 #endif /*!ROFF_H*/
Index: usr.bin/mandoc/term.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/term.c,v
retrieving revision 1.42
diff -u -p -r1.42 term.c
--- usr.bin/mandoc/term.c	29 Jun 2010 14:41:28 -0000	1.42
+++ usr.bin/mandoc/term.c	3 Jul 2010 06:38:28 -0000
@@ -26,6 +26,8 @@
 #include "mandoc.h"
 #include "chars.h"
 #include "out.h"
+#include "regs.h"
+#include "roff.h"
 #include "term.h"
 #include "main.h"
 
@@ -373,6 +375,11 @@ res(struct termp *p, const char *word, s
 	size_t		 sz;
 
 	rhs = chars_a2res(p->symtab, word, len, &sz);
+	if (NULL == rhs) {
+		rhs = roff_getstrn(word, len);
+		if (rhs)
+			sz = strlen(rhs);
+	}
 	if (rhs)
 		encode(p, rhs, sz);
 }
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

             reply	other threads:[~2010-07-03  6:39 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-03  6:39 Ingo Schwarze [this message]
2010-07-03 12:00 ` Kristaps Dzonsons
2010-07-03 15:55   ` Ingo Schwarze

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100703063933.GE6026@iris.usta.de \
    --to=schwarze@usta.de \
    --cc=tech@mdocml.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).