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