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