tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
* [PATCH] rudimentary .ds support
@ 2010-07-03  6:39 Ingo Schwarze
  2010-07-03 12:00 ` Kristaps Dzonsons
  0 siblings, 1 reply; 3+ messages in thread
From: Ingo Schwarze @ 2010-07-03  6:39 UTC (permalink / raw)
  To: tech

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] rudimentary .ds support
  2010-07-03  6:39 [PATCH] rudimentary .ds support Ingo Schwarze
@ 2010-07-03 12:00 ` Kristaps Dzonsons
  2010-07-03 15:55   ` Ingo Schwarze
  0 siblings, 1 reply; 3+ messages in thread
From: Kristaps Dzonsons @ 2010-07-03 12:00 UTC (permalink / raw)
  To: tech

> 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.)

Ingo,

I see the utility of this, but would like the functions accessed through 
regs.h, either within struct regset itself or as its own structure with 
setters and getters.  This is just a mechanical change, of course.  In 
general, roff.h should not propogate into libmdoc or libman; they are 
distinct namespaces.  regs.h is poorly-named, in this regard, but that 
can be switched later.

Other than that, it looks fine.  Needs bits in html.c (I can do this, if 
you don't want to muck around in there) and roff.3 (including the 
current short-comings).

Thanks,

Kristaps
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] rudimentary .ds support
  2010-07-03 12:00 ` Kristaps Dzonsons
@ 2010-07-03 15:55   ` Ingo Schwarze
  0 siblings, 0 replies; 3+ messages in thread
From: Ingo Schwarze @ 2010-07-03 15:55 UTC (permalink / raw)
  To: tech

Hi Kristaps,

> I see the utility of this, but would like the functions accessed
> through regs.h,

Yes, that makes sense, thanks for the suggestion.

> either within struct regset itself or as its own
> structure with setters and getters.

I prefer the latter.
The singly linked list won't be the last word on this,
so the interface should allow reimplementation in terms
of more efficient data structures.

[...]
> Other than that, it looks fine.  Needs bits in html.c (I can do
> this, if you don't want to muck around in there)

Yes, that would be kind, thanks.

> and roff.3 (including the current short-comings).

Done.
Of course, i have only documented those parts relevant for
section 3, not the frontend issues.

Thanks for checking,
  Ingo
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-07-03 15:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-03  6:39 [PATCH] rudimentary .ds support Ingo Schwarze
2010-07-03 12:00 ` Kristaps Dzonsons
2010-07-03 15:55   ` Ingo Schwarze

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).