summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2010-07-07 15:04:54 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2010-07-07 15:04:54 +0000
commitf8c0611295a680d000a73fd31fe26580fa4b4a75 (patch)
treee4b7c328bb59fbbd203bdb3ec68d849b0036f345
parent4c444b6d0742002389376d67d51070f1b5aedadf (diff)
downloadmandoc-f8c0611295a680d000a73fd31fe26580fa4b4a75.tar.gz
Re-constitution of `ds' symbol processing. First, push the
roff_getstr() family of functions into roff.c with the "first_string" directly in struct roff. Second, pre-process each line for reserved words in libroff, splicing and re-running a line if it has one (this allows defined symbols to be macros). Remove term.c's invocation of the roff_getstrn() function. Removed function documentation in roff.3 and added roff.7 `ds' documentation.
-rw-r--r--Makefile2
-rw-r--r--libman.h1
-rw-r--r--libmdoc.h1
-rw-r--r--main.c1
-rw-r--r--man.31
-rw-r--r--man.c1
-rw-r--r--man_html.c1
-rw-r--r--man_term.c1
-rw-r--r--mdoc.31
-rw-r--r--mdoc.c1
-rw-r--r--mdoc_html.c1
-rw-r--r--mdoc_term.c1
-rw-r--r--regs.h30
-rw-r--r--roff.356
-rw-r--r--roff.719
-rw-r--r--roff.c185
-rw-r--r--term.c6
-rw-r--r--tree.c1
18 files changed, 137 insertions, 173 deletions
diff --git a/Makefile b/Makefile
index 9fa19647..3b54486a 100644
--- a/Makefile
+++ b/Makefile
@@ -94,7 +94,7 @@ DATAS = arch.in att.in lib.in msec.in st.in \
HEADS = mdoc.h libmdoc.h man.h libman.h term.h \
libmandoc.h html.h chars.h out.h main.h roff.h \
- mandoc.h regs.h
+ mandoc.h
GSGMLS = mandoc.1.sgml mdoc.3.sgml mdoc.7.sgml \
mandoc_char.7.sgml man.7.sgml man.3.sgml roff.7.sgml \
diff --git a/libman.h b/libman.h
index a0f31fa1..907fa050 100644
--- a/libman.h
+++ b/libman.h
@@ -17,7 +17,6 @@
#ifndef LIBMAN_H
#define LIBMAN_H
-#include "regs.h"
#include "man.h"
enum man_next {
diff --git a/libmdoc.h b/libmdoc.h
index 5cf1f647..500fa57f 100644
--- a/libmdoc.h
+++ b/libmdoc.h
@@ -17,7 +17,6 @@
#ifndef LIBMDOC_H
#define LIBMDOC_H
-#include "regs.h"
#include "mdoc.h"
enum mdoc_next {
diff --git a/main.c b/main.c
index e8c0dd02..8a997e9a 100644
--- a/main.c
+++ b/main.c
@@ -31,7 +31,6 @@
#include <unistd.h>
#include "mandoc.h"
-#include "regs.h"
#include "main.h"
#include "mdoc.h"
#include "man.h"
diff --git a/man.3 b/man.3
index d607a7d2..828acb5f 100644
--- a/man.3
+++ b/man.3
@@ -29,7 +29,6 @@
.Nd man macro compiler library
.Sh SYNOPSIS
.In mandoc.h
-.In regs.h
.In man.h
.Vt extern const char * const * man_macronames;
.Ft "struct man *"
diff --git a/man.c b/man.c
index da3eb3a3..6081d10f 100644
--- a/man.c
+++ b/man.c
@@ -28,7 +28,6 @@
#include <string.h>
#include "mandoc.h"
-#include "regs.h"
#include "libman.h"
#include "libmandoc.h"
diff --git a/man_html.c b/man_html.c
index 47b66063..ce2effe1 100644
--- a/man_html.c
+++ b/man_html.c
@@ -29,7 +29,6 @@
#include "mandoc.h"
#include "out.h"
#include "html.h"
-#include "regs.h"
#include "man.h"
#include "main.h"
diff --git a/man_term.c b/man_term.c
index f9e7aec3..0f09ec01 100644
--- a/man_term.c
+++ b/man_term.c
@@ -28,7 +28,6 @@
#include "mandoc.h"
#include "out.h"
-#include "regs.h"
#include "man.h"
#include "term.h"
#include "chars.h"
diff --git a/mdoc.3 b/mdoc.3
index 2679d2f7..289558c6 100644
--- a/mdoc.3
+++ b/mdoc.3
@@ -30,7 +30,6 @@
.Nd mdoc macro compiler library
.Sh SYNOPSIS
.In mandoc.h
-.In regs.h
.In mdoc.h
.Vt extern const char * const * mdoc_macronames;
.Vt extern const char * const * mdoc_argnames;
diff --git a/mdoc.c b/mdoc.c
index 47252fad..6e997042 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -30,7 +30,6 @@
#include <time.h>
#include "mandoc.h"
-#include "regs.h"
#include "libmdoc.h"
#include "libmandoc.h"
diff --git a/mdoc_html.c b/mdoc_html.c
index 62f917fd..02d99645 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -30,7 +30,6 @@
#include "mandoc.h"
#include "out.h"
#include "html.h"
-#include "regs.h"
#include "mdoc.h"
#include "main.h"
diff --git a/mdoc_term.c b/mdoc_term.c
index cb60e5cd..978b317c 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -31,7 +31,6 @@
#include "mandoc.h"
#include "out.h"
#include "term.h"
-#include "regs.h"
#include "mdoc.h"
#include "chars.h"
#include "main.h"
diff --git a/regs.h b/regs.h
deleted file mode 100644
index 0ea946e2..00000000
--- a/regs.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef REGS_H
-#define REGS_H
-
-__BEGIN_DECLS
-
-char *roff_setstr(const char *, const char *);
-char *roff_getstr(const char *);
-char *roff_getstrn(const char *, size_t);
-void roff_freestr(void);
-
-__END_DECLS
-
-#endif /*!REGS_H*/
diff --git a/roff.3 b/roff.3
index edb05060..89d0cb19 100644
--- a/roff.3
+++ b/roff.3
@@ -28,7 +28,6 @@
.Nd roff macro compiler library
.Sh SYNOPSIS
.In mandoc.h
-.In regs.h
.In roff.h
.Ft "struct roff *"
.Fo roff_alloc
@@ -51,15 +50,6 @@
.Fc
.Ft void
.Fn roff_reset "struct roff *roff"
-.In regs.h
-.Ft "char *"
-.Fn roff_setstr "const char *name" "const char *string"
-.Ft "char *"
-.Fn roff_getstr "const char *name"
-.Ft "char *"
-.Fn roff_getstrn "const char *name" "size_t len"
-.Ft void
-.Fn roff_freestr void
.Sh DESCRIPTION
The
.Nm
@@ -155,52 +145,6 @@ Returns 0 on failure, 1 on success.
Signals that the parse is complete.
Returns 0 on failure, 1 on success.
.El
-.Sh USER-DEFINED STRINGS
-Strings defined by the
-.Xr roff 7
-.Sx \&ds
-instruction are saved using the
-.Fn roff_setstr
-function and retrieved using the
-.Fn roff_getstr
-and
-.Fn roff_getstrn
-functions.
-.Pp
-These functions take the name of the string to be accessed
-as their first argument.
-While
-.Fn roff_getstr
-requires the name to be null-terminated,
-.Fn roff_getstrn
-accepts non-terminated strings, but requires the length of the name
-to be specified.
-.Pp
-The second argument to
-.Fn roff_setstr
-is the new value of the string.
-It will be copied to internal storage, so both pointers to constant
-strings and pointers to volatile storage are acceptable.
-.Pp
-All of these functions return a pointer to the new value of the string
-in internal storage, which should be considered read-only, so use
-.Xr strdup 3
-on it as appropriate.
-The read functions return NULL when a string of the specified name
-is not available or empty, and
-.Fn roff_setstr
-returns NULL when memory allocation fails.
-In the latter case, the string will remain unset.
-.Pp
-The function
-.Fn roff_freestr
-clears all user-defined strings.
-It always succeeds.
-Both
-.Fn roff_reset
-and
-.Fn roff_free
-call it.
.Sh EXAMPLES
See
.Pa main.c
diff --git a/roff.7 b/roff.7
index 4bb1e265..846b7937 100644
--- a/roff.7
+++ b/roff.7
@@ -92,11 +92,20 @@ The syntax of this macro is the same as that of
except that a leading argument must be specified.
It is ignored, as are its children.
.Ss \&ds
-Define a string.
-This macro is intended to have two arguments,
-the name of the string to define and its content.
-Currently, it is ignored including its arguments,
-and the number of arguments is not checked.
+Define a reserved word.
+Its syntax is as follows:
+.Pp
+.D1 Pf \. Sx \&ds No Cm key val
+.Pp
+The
+.Cm key
+and
+.Cm val
+strings are space-separated.
+The
+.Cm key
+values may be invoked in subsequent text by using \e*(NN for two-letter
+pairs, \e*N for one-letter, and \e*[NNN] for arbitrary-length values.
.Ss \&de1
The syntax of this macro is the same as that of
.Sx \&ig ,
diff --git a/roff.c b/roff.c
index c976ae33..ee0b8144 100644
--- a/roff.c
+++ b/roff.c
@@ -28,8 +28,8 @@
#include <stdio.h>
#include "mandoc.h"
-#include "regs.h"
#include "roff.h"
+#include "libmandoc.h"
#define RSTACK_MAX 128
@@ -69,6 +69,13 @@ enum roffrule {
ROFFRULE_DENY
};
+
+struct roffstr {
+ char *name; /* key of symbol */
+ char *string; /* current value */
+ struct roffstr *next; /* next in list */
+};
+
struct roff {
struct roffnode *last; /* leaf of stack */
mandocmsg msg; /* err/warn/fatal messages */
@@ -76,6 +83,7 @@ struct roff {
enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */
int rstackpos; /* position in rstack */
struct regset *regs; /* read/writable registers */
+ struct roffstr *first_string;
};
struct roffnode {
@@ -109,12 +117,6 @@ struct roffmac {
struct roffmac *next;
};
-struct roffstr {
- char *name;
- char *string;
- struct roffstr *next;
-} *first_string;
-
static enum rofferr roff_block(ROFF_ARGS);
static enum rofferr roff_block_text(ROFF_ARGS);
static enum rofferr roff_block_sub(ROFF_ARGS);
@@ -124,9 +126,16 @@ 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 roffrule roff_evalcond(const char *, int *);
+static void roff_freestr(struct roff *);
+static const char *roff_getstrn(const struct roff *,
+ const char *, size_t);
static enum rofferr roff_line(ROFF_ARGS);
static enum rofferr roff_nr(ROFF_ARGS);
-static enum roffrule roff_evalcond(const char *, int *);
+static int roff_res(struct roff *, int,
+ char **, size_t *, int, int *);
+static void roff_setstr(struct roff *,
+ const char *, const char *);
/* See roff_hash_find() */
@@ -276,7 +285,7 @@ roff_free1(struct roff *r)
while (r->last)
roffnode_pop(r);
- roff_freestr();
+ roff_freestr(r);
}
@@ -317,6 +326,74 @@ roff_alloc(struct regset *regs, const mandocmsg msg, void *data)
}
+/*
+ * Pre-filter each and every line for reserved words (one beginning with
+ * `\*', e.g., `\*(ab'). These must be handled before the actual line
+ * is processed.
+ */
+static int
+roff_res(struct roff *r, int ln, char **bufp,
+ size_t *szp, int pos, int *offs)
+{
+ const char *cp, *cpp, *st, *res;
+ int i, maxl;
+ size_t nsz;
+ char *n;
+
+ for (cp = &(*bufp)[pos]; (cpp = strstr(cp, "\\*")); cp++) {
+ cp = cpp + 2;
+ switch (*cp) {
+ case ('('):
+ cp++;
+ maxl = 2;
+ break;
+ case ('['):
+ cp++;
+ maxl = 0;
+ break;
+ default:
+ maxl = 1;
+ break;
+ }
+
+ st = cp;
+
+ for (i = 0; 0 == maxl || i < maxl; i++, cp++) {
+ if ('\0' == *cp)
+ return(1); /* Error. */
+ if (0 == maxl && ']' == *cp)
+ break;
+ }
+
+ res = roff_getstrn(r, st, (size_t)i);
+
+ if (NULL == res) {
+ cp -= maxl ? 1 : 0;
+ continue;
+ }
+
+ ROFF_DEBUG("roff: splicing reserved: [%.*s]\n", i, st);
+
+ nsz = *szp + strlen(res) + 1;
+ n = mandoc_malloc(nsz);
+
+ *n = '\0';
+
+ strlcat(n, *bufp, (size_t)(cpp - *bufp + 1));
+ strlcat(n, res, nsz);
+ strlcat(n, cp + (maxl ? 0 : 1), nsz);
+
+ free(*bufp);
+
+ *bufp = n;
+ *szp = nsz;
+ return(0);
+ }
+
+ return(1);
+}
+
+
enum rofferr
roff_parseln(struct roff *r, int ln, char **bufp,
size_t *szp, int pos, int *offs)
@@ -325,6 +402,14 @@ roff_parseln(struct roff *r, int ln, char **bufp,
int ppos;
/*
+ * Run the reserved-word filter only if we have some reserved
+ * words to fill in.
+ */
+
+ if (r->first_string && ! roff_res(r, ln, bufp, szp, pos, offs))
+ return(ROFF_RERUN);
+
+ /*
* First, if a scope is open and we're not a macro, pass the
* text through the macro's filter. If a scope isn't open and
* we're not a macro, just let it through.
@@ -338,11 +423,8 @@ roff_parseln(struct roff *r, int ln, char **bufp,
return((*roffs[t].text)
(r, t, bufp, szp,
ln, pos, pos, offs));
- } else if ( ! ROFF_CTL((*bufp)[pos])) {
- ROFF_DEBUG("roff: pass non-scoped text: [%s]\n",
- &(*bufp)[pos]);
+ } else if ( ! ROFF_CTL((*bufp)[pos]))
return(ROFF_CONT);
- }
/*
* If a scope is open, go to the child handler for that macro,
@@ -366,11 +448,8 @@ roff_parseln(struct roff *r, int ln, char **bufp,
*/
ppos = pos;
- if (ROFF_MAX == (t = roff_parse(*bufp, &pos))) {
- ROFF_DEBUG("roff: pass non-scoped non-macro: [%s]\n",
- &(*bufp)[pos]);
+ if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
return(ROFF_CONT);
- }
ROFF_DEBUG("roff: intercept new-scope: %s, [%s]\n",
roffs[t].name, &(*bufp)[pos]);
@@ -914,7 +993,7 @@ roff_ds(ROFF_ARGS)
*end = '\0';
}
- roff_setstr(name, string);
+ roff_setstr(r, name, string);
return(ROFF_IGN);
}
@@ -962,73 +1041,53 @@ roff_nr(ROFF_ARGS)
}
-char *
-roff_setstr(const char *name, const char *string)
+static void
+roff_setstr(struct roff *r, const char *name, const char *string)
{
struct roffstr *n;
char *namecopy;
- n = first_string;
+ n = r->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;
+ if (NULL == n) {
+ namecopy = mandoc_strdup(name);
+ n = mandoc_malloc(sizeof(struct roffstr));
+ n->name = namecopy;
+ n->next = r->first_string;
+ r->first_string = n;
+ } else
+ free(n->string);
- n = first_string;
- while (n && strcmp(name, n->name))
- n = n->next;
- if (n)
- return(n->string);
- else
- return(NULL);
+ n->string = string ? strdup(string) : NULL;
}
-char *
-roff_getstrn(const char *name, size_t len)
+
+static const char *
+roff_getstrn(const struct roff *r, const char *name, size_t len)
{
- struct roffstr *n;
+ const struct roffstr *n;
- n = first_string;
+ n = r->first_string;
while (n && (strncmp(name, n->name, len) || '\0' != n->name[len]))
n = n->next;
- if (n)
- return(n->string);
- else
- return(NULL);
+
+ return(n ? n->string : NULL);
}
-void
-roff_freestr(void)
+
+static void
+roff_freestr(struct roff *r)
{
struct roffstr *n, *nn;
- for (n = first_string; n; n = nn) {
+ for (n = r->first_string; n; n = nn) {
free(n->name);
free(n->string);
nn = n->next;
free(n);
}
- first_string = NULL;
+
+ r->first_string = NULL;
}
diff --git a/term.c b/term.c
index e254d07c..03302779 100644
--- a/term.c
+++ b/term.c
@@ -31,7 +31,6 @@
#include "mandoc.h"
#include "chars.h"
#include "out.h"
-#include "regs.h"
#include "term.h"
#include "main.h"
@@ -379,11 +378,6 @@ res(struct termp *p, const char *word, size_t len)
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);
}
diff --git a/tree.c b/tree.c
index a5071b29..f8d433db 100644
--- a/tree.c
+++ b/tree.c
@@ -24,7 +24,6 @@
#include <time.h>
#include "mandoc.h"
-#include "regs.h"
#include "mdoc.h"
#include "man.h"
#include "main.h"