summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--macro.c174
-rw-r--r--mdoc.c21
-rw-r--r--mdoc.h31
-rw-r--r--mdocml.c44
-rw-r--r--private.h17
-rw-r--r--strings.c195
6 files changed, 441 insertions, 41 deletions
diff --git a/macro.c b/macro.c
index 6b8e5365..16d74306 100644
--- a/macro.c
+++ b/macro.c
@@ -1,4 +1,4 @@
-/* $Id: macro.c,v 1.4 2008/12/15 03:13:01 kristaps Exp $ */
+/* $Id: macro.c,v 1.5 2008/12/17 17:18:38 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -20,11 +20,15 @@
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include "private.h"
#define _CC(p) ((const char **)p)
+static int xstrlcat(char *, const char *, size_t);
+static int xstrlcpy(char *, const char *, size_t);
+static int xstrcmp(const char *, const char *);
static int append_text(struct mdoc *, int,
int, int, char *[]);
static int append_scoped(struct mdoc *, int,
@@ -81,10 +85,25 @@ static int
append_scoped(struct mdoc *mdoc, int tok,
int pos, int sz, char *args[])
{
+ enum mdoc_sec sec;
+
+ if (0 == sz)
+ return(mdoc_err(mdoc, tok, pos, ERR_ARGS_GE1));
switch (tok) {
/* ======= ADD MORE MACRO CHECKS BELOW. ======= */
case (MDOC_Sh):
+ sec = mdoc_atosec((size_t)sz, _CC(args));
+ if (SEC_CUSTOM != sec && sec < mdoc->sec_lastn)
+ if ( ! mdoc_warn(mdoc, tok, pos, WARN_SEC_OO))
+ return(0);
+
+ if (SEC_BODY == mdoc->sec_last && SEC_NAME != sec)
+ return(mdoc_err(mdoc, tok, pos, ERR_SEC_NAME));
+
+ if (SEC_CUSTOM != sec)
+ mdoc->sec_lastn = sec;
+ mdoc->sec_last = sec;
break;
case (MDOC_Ss):
break;
@@ -166,7 +185,7 @@ append_text(struct mdoc *mdoc, int tok,
int
-macro_text(struct mdoc *mdoc, int tok, int ppos, int *pos, char *buf)
+macro_text(MACRO_PROT_ARGS)
{
int lastarg, c, lasttok, lastpunct, j;
char *args[MDOC_LINEARG_MAX], *p;
@@ -175,6 +194,9 @@ macro_text(struct mdoc *mdoc, int tok, int ppos, int *pos, char *buf)
lastpunct = 0;
j = 0;
+ if (SEC_PROLOGUE == mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
+
again:
lastarg = *pos;
@@ -224,19 +246,131 @@ again:
int
-macro_scoped_implicit(struct mdoc *mdoc,
- int tok, int ppos, int *pos, char *buf)
+macro_prologue_dtitle(MACRO_PROT_ARGS)
+{
+ int c, lastarg, j;
+ char *args[MDOC_LINEARG_MAX];
+
+ if (SEC_PROLOGUE != mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
+ if (0 == mdoc->meta.date)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
+ if (mdoc->meta.title[0])
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
+
+ j = -1;
+
+again:
+ lastarg = *pos;
+ c = args_next(mdoc, tok, pos, buf, &args[++j]);
+
+ if (0 == c) {
+ mdoc->sec_lastn = mdoc->sec_last = SEC_BODY; /* FIXME */
+ if (mdoc->meta.title)
+ return(1);
+ if ( ! mdoc_warn(mdoc, tok, ppos, WARN_ARGS_GE1))
+ return(0);
+ (void)xstrlcpy(mdoc->meta.title,
+ "UNTITLED", META_TITLE_SZ);
+ return(1);
+ } else if (-1 == c)
+ return(0);
+
+ if (MDOC_MAX != mdoc_find(mdoc, args[j]) && ! mdoc_warn
+ (mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
+ return(0);
+
+ if (0 == j) {
+ if (xstrlcpy(mdoc->meta.title, args[0], META_TITLE_SZ))
+ goto again;
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGS));
+
+ } else if (1 == j) {
+ mdoc->meta.msec = mdoc_atomsec(args[1]);
+ if (MSEC_DEFAULT != mdoc->meta.msec)
+ goto again;
+ return(mdoc_err(mdoc, tok, -1, ERR_SYNTAX_ARGS));
+
+ } else if (2 == j) {
+ mdoc->meta.vol = mdoc_atovol(args[2]);
+ if (VOL_DEFAULT != mdoc->meta.vol)
+ goto again;
+ mdoc->meta.arch = mdoc_atoarch(args[2]);
+ if (ARCH_DEFAULT != mdoc->meta.arch)
+ goto again;
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGS));
+ }
+
+ return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
+}
+
+
+int
+macro_prologue_ddate(MACRO_PROT_ARGS)
+{
+ int c, lastarg, j;
+ char *args[MDOC_LINEARG_MAX], date[64];
+
+ if (SEC_PROLOGUE != mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
+ if (mdoc->meta.title[0])
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
+ if (mdoc->meta.date)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
+
+ j = -1;
+ date[0] = 0;
+
+again:
+
+ lastarg = *pos;
+ c = args_next(mdoc, tok, pos, buf, &args[++j]);
+ if (0 == c) {
+ if (mdoc->meta.date)
+ return(1);
+ mdoc->meta.date = mdoc_atotime(date);
+ if (mdoc->meta.date)
+ return(1);
+ return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGS));
+ } else if (-1 == c)
+ return(0);
+
+ if (MDOC_MAX != mdoc_find(mdoc, args[j]) && ! mdoc_warn
+ (mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
+ return(0);
+
+ if (0 == j) {
+ if (xstrcmp("$Mdocdate: December 17 2008 $", args[j])) {
+ mdoc->meta.date = time(NULL);
+ goto again;
+ } else if (xstrcmp("$Mdocdate:", args[j]))
+ goto again;
+ } else if (4 == j)
+ if ( ! xstrcmp("$", args[j]))
+ goto again;
+
+ if ( ! xstrlcat(date, args[j], sizeof(date)))
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGS));
+ if ( ! xstrlcat(date, " ", sizeof(date)))
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGS));
+
+ goto again;
+ /* NOTREACHED */
+}
+
+
+int
+macro_scoped_implicit(MACRO_PROT_ARGS)
{
int t, c, lastarg, j;
char *args[MDOC_LINEARG_MAX];
struct mdoc_node *n;
- /*
- * Look for an implicit parent.
- */
-
assert( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags));
+ if (SEC_PROLOGUE == mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
+
/* LINTED */
for (n = mdoc->last; n; n = n->parent) {
if (MDOC_BLOCK != n->type)
@@ -281,3 +415,27 @@ again:
/* NOTREACHED */
}
+
+
+static int
+xstrcmp(const char *p1, const char *p2)
+{
+
+ return(0 == strcmp(p1, p2));
+}
+
+
+static int
+xstrlcat(char *dst, const char *src, size_t sz)
+{
+
+ return(strlcat(dst, src, sz) < sz);
+}
+
+
+static int
+xstrlcpy(char *dst, const char *src, size_t sz)
+{
+
+ return(strlcpy(dst, src, sz) < sz);
+}
diff --git a/mdoc.c b/mdoc.c
index 4bdc32f0..1fcdc833 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.2 2008/12/15 02:23:12 kristaps Exp $ */
+/* $Id: mdoc.c,v 1.3 2008/12/17 17:18:38 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -26,10 +26,6 @@
#include "private.h"
-extern int macro_text(struct mdoc *, int, int, int *, char *);
-extern int macro_scoped_implicit(struct mdoc *,
- int, int, int *, char *);
-
const char *const __mdoc_macronames[MDOC_MAX] = {
"\\\"", "Dd", "Dt", "Os",
"Sh", "Ss", "Pp", "D1",
@@ -88,8 +84,8 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ NULL, 0 }, /* \" */
- { NULL, 0 }, /* Dd */
- { NULL, 0 }, /* Dt */
+ { macro_prologue_ddate, 0 }, /* Dd */
+ { macro_prologue_dtitle, 0 }, /* Dt */
{ NULL, 0 }, /* Os */
{ macro_scoped_implicit, 0 }, /* Sh */
{ macro_scoped_implicit, 0 }, /* Ss */
@@ -310,12 +306,7 @@ mdoc_parseln(struct mdoc *mdoc, char *buf)
while (buf[i] && isspace(buf[i]))
i++;
- if (NULL == (mdoc_macros[c].fp)) {
- (void)mdoc_err(mdoc, c, 1, ERR_MACRO_NOTSUP);
- return(0);
- }
-
- return((*mdoc_macros[c].fp)(mdoc, c, 1, &i, buf));
+ return(mdoc_macro(mdoc, c, 1, &i, buf));
}
@@ -363,7 +354,9 @@ mdoc_macro(struct mdoc *mdoc, int tok, int ppos, int *pos, char *buf)
if (NULL == (mdoc_macros[tok].fp)) {
(void)mdoc_err(mdoc, tok, ppos, ERR_MACRO_NOTSUP);
return(0);
- } else if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
+ }
+
+ if (1 != ppos && ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
(void)mdoc_err(mdoc, tok, ppos, ERR_MACRO_NOTCALL);
return(0);
}
diff --git a/mdoc.h b/mdoc.h
index 14478cf4..532fa9c6 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -1,4 +1,4 @@
-/* $Id: mdoc.h,v 1.2 2008/12/15 03:13:01 kristaps Exp $ */
+/* $Id: mdoc.h,v 1.3 2008/12/17 17:18:38 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -194,15 +194,23 @@
enum mdoc_err {
ERR_SYNTAX_QUOTE,
ERR_SYNTAX_WS,
+ ERR_SYNTAX_ARGS,
ERR_MACRO_NOTSUP,
ERR_MACRO_NOTCALL,
ERR_SCOPE_BREAK,
- ERR_ARGS_GE1
+ ERR_SEC_PROLOGUE,
+ ERR_SEC_NPROLOGUE,
+ ERR_SEC_PROLOGUE_OO,
+ ERR_SEC_PROLOGUE_REP,
+ ERR_SEC_NAME,
+ ERR_ARGS_GE1,
+ ERR_ARGS_MANY
};
enum mdoc_warn {
WARN_SYNTAX_WS_EOLN,
WARN_SYNTAX_MACLIKE,
+ WARN_SEC_OO,
WARN_ARGS_GE1
};
@@ -221,6 +229,7 @@ enum mdoc_type {
};
enum mdoc_msec {
+ MSEC_DEFAULT = 0,
MSEC_1,
MSEC_2,
MSEC_3,
@@ -238,12 +247,12 @@ enum mdoc_msec {
MSEC_n,
MSEC_unass,
MSEC_draft,
- MSEC_paper,
- MSEC_NONE
+ MSEC_paper
};
enum mdoc_sec {
- SEC_PROLOGUE,
+ SEC_PROLOGUE = 0,
+ SEC_BODY,
SEC_NAME,
SEC_SYNOPSIS,
SEC_DESCRIPTION,
@@ -263,6 +272,7 @@ enum mdoc_sec {
};
enum mdoc_vol {
+ VOL_DEFAULT = 0,
VOL_AMD,
VOL_IND,
VOL_KM,
@@ -271,11 +281,11 @@ enum mdoc_vol {
VOL_PS1,
VOL_SMM,
VOL_URM,
- VOL_USD,
- VOL_DEFAULT
+ VOL_USD
};
enum mdoc_arch {
+ ARCH_DEFAULT = 0,
ARCH_alpha,
ARCH_amd64,
ARCH_amiga,
@@ -300,15 +310,16 @@ enum mdoc_arch {
ARCH_sparc64,
ARCH_sun3,
ARCH_vax,
- ARCH_zaurus,
- ARCH_DEFAULT
+ ARCH_zaurus
};
struct mdoc_meta {
enum mdoc_msec msec;
enum mdoc_vol vol;
enum mdoc_arch arch;
- struct tm tm;
+ time_t date;
+#define META_TITLE_SZ (64)
+ char title[META_TITLE_SZ];
};
struct mdoc_text {
diff --git a/mdocml.c b/mdocml.c
index 60bf8943..3829dc54 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -1,4 +1,4 @@
-/* $Id: mdocml.c,v 1.22 2008/12/15 02:23:12 kristaps Exp $ */
+/* $Id: mdocml.c,v 1.23 2008/12/17 17:18:38 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -265,9 +265,9 @@ parse_begin(struct md_parse *p)
for (i = 0; i < sz; i++) {
if ('\n' != p->buf[i]) {
if (pos < sizeof(line)) {
- /* LINTED */
- sv[pos] = p->buf[i];
- line[pos++] = p->buf[i];
+ sv[(int)pos] = p->buf[(int)i];
+ line[(int)pos++] =
+ p->buf[(int)i];
continue;
}
warnx("%s: line %d too long",
@@ -306,6 +306,9 @@ msg_err(void *arg, int tok, int col, enum mdoc_err type)
case (ERR_SYNTAX_WS):
lit = "syntax: whitespace in argument";
break;
+ case (ERR_SYNTAX_ARGS):
+ fmt = "syntax: macro `%s' arguments malformed";
+ break;
case (ERR_SCOPE_BREAK):
/* Which scope is broken? */
fmt = "macro `%s' breaks prior explicit scope";
@@ -316,9 +319,27 @@ msg_err(void *arg, int tok, int col, enum mdoc_err type)
case (ERR_MACRO_NOTCALL):
fmt = "macro `%s' not callable";
break;
+ case (ERR_SEC_PROLOGUE):
+ fmt = "macro `%s' cannot be called in the prologue";
+ break;
+ case (ERR_SEC_NPROLOGUE):
+ fmt = "macro `%s' called outside of prologue";
+ break;
case (ERR_ARGS_GE1):
fmt = "macro `%s' expects one or more arguments";
break;
+ case (ERR_ARGS_MANY):
+ fmt = "macro `%s' has too many arguments";
+ break;
+ case (ERR_SEC_PROLOGUE_OO):
+ fmt = "prologue macro `%s' is out-of-order";
+ break;
+ case (ERR_SEC_PROLOGUE_REP):
+ fmt = "prologue macro `%s' repeated";
+ break;
+ case (ERR_SEC_NAME):
+ lit = "`NAME' section must be first";
+ break;
default:
abort();
/* NOTREACHED */
@@ -333,7 +354,11 @@ msg_err(void *arg, int tok, int col, enum mdoc_err type)
p->name, p->lnn, lit);
if (p->dbg < 1) {
- (void)fprintf(stderr, " (column %d)\n", col);
+ if (-1 != col)
+ (void)fprintf(stderr, " (column %d)\n", col);
+ return(0);
+ } else if (-1 == col) {
+ (void)fprintf(stderr, "\nFrom: %s", p->line);
return(0);
}
@@ -360,7 +385,11 @@ msg_msg(void *arg, int col, const char *msg)
(void)printf("%s:%d: %s", p->name, p->lnn, msg);
if (p->dbg < 3) {
- (void)printf(" (column %d)\n", col);
+ if (-1 != col)
+ (void)printf(" (column %d)\n", col);
+ return;
+ } else if (-1 == col) {
+ (void)printf("\nFrom %s\n", p->line);
return;
}
@@ -393,6 +422,9 @@ msg_warn(void *arg, int tok, int col, enum mdoc_warn type)
case (WARN_SYNTAX_MACLIKE):
lit = "syntax: macro-like argument";
break;
+ case (WARN_SEC_OO):
+ lit = "section is out of conventional order";
+ break;
case (WARN_ARGS_GE1):
fmt = "macro `%s' suggests one or more arguments";
break;
diff --git a/private.h b/private.h
index fd763152..cc6585ff 100644
--- a/private.h
+++ b/private.h
@@ -1,4 +1,4 @@
-/* $Id: private.h,v 1.42 2008/12/15 03:13:01 kristaps Exp $ */
+/* $Id: private.h,v 1.43 2008/12/17 17:18:38 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -27,7 +27,7 @@ struct mdoc {
void *htab;
struct mdoc_node *last;
struct mdoc_node *first;
-
+ struct mdoc_meta meta;
enum mdoc_sec sec_lastn;
enum mdoc_sec sec_last;
};
@@ -41,6 +41,9 @@ struct mdoc_macro {
extern const struct mdoc_macro *const mdoc_macros;
+#define MACRO_PROT_ARGS struct mdoc *mdoc, int tok, \
+ int ppos, int *pos, char *buf
+
__BEGIN_DECLS
int mdoc_err(struct mdoc *, int, int, enum mdoc_err);
@@ -64,6 +67,16 @@ void *mdoc_hash_alloc(void);
int mdoc_hash_find(const void *, const char *);
void mdoc_hash_free(void *);
int mdoc_isdelim(const char *);
+enum mdoc_sec mdoc_atosec(size_t, const char **);
+enum mdoc_msec mdoc_atomsec(const char *);
+enum mdoc_vol mdoc_atovol(const char *);
+enum mdoc_arch mdoc_atoarch(const char *);
+time_t mdoc_atotime(const char *);
+
+int macro_text(MACRO_PROT_ARGS);
+int macro_scoped_implicit(MACRO_PROT_ARGS);
+int macro_prologue_ddate(MACRO_PROT_ARGS);
+int macro_prologue_dtitle(MACRO_PROT_ARGS);
__END_DECLS
diff --git a/strings.c b/strings.c
index 1380bf7d..0125671d 100644
--- a/strings.c
+++ b/strings.c
@@ -1,4 +1,4 @@
-/* $Id: strings.c,v 1.1 2008/12/15 03:13:01 kristaps Exp $ */
+/* $Id: strings.c,v 1.2 2008/12/17 17:18:38 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -20,6 +20,7 @@
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include "private.h"
@@ -64,3 +65,195 @@ mdoc_isdelim(const char *p)
return(0);
}
+
+enum mdoc_sec
+mdoc_atosec(size_t sz, const char **p)
+{
+
+ assert(sz > 0);
+ if (sz > 2)
+ return(SEC_CUSTOM);
+ if (sz == 2) {
+ if (0 == strcmp(*p, "RETURN") &&
+ 0 == strcmp(*(p + 1), "VALUES"))
+ return(SEC_RETURN_VALUES);
+ if (0 == strcmp(*p, "SEE") &&
+ 0 == strcmp(*(p + 1), "ALSO"))
+ return(SEC_SEE_ALSO);
+ return(SEC_CUSTOM);
+ }
+
+ if (0 == strcmp(*p, "NAME"))
+ return(SEC_NAME);
+ else if (0 == strcmp(*p, "SYNOPSIS"))
+ return(SEC_SYNOPSIS);
+ else if (0 == strcmp(*p, "DESCRIPTION"))
+ return(SEC_DESCRIPTION);
+ else if (0 == strcmp(*p, "ENVIRONMENT"))
+ return(SEC_ENVIRONMENT);
+ else if (0 == strcmp(*p, "FILES"))
+ return(SEC_FILES);
+ else if (0 == strcmp(*p, "EXAMPLES"))
+ return(SEC_EXAMPLES);
+ else if (0 == strcmp(*p, "DIAGNOSTICS"))
+ return(SEC_DIAGNOSTICS);
+ else if (0 == strcmp(*p, "ERRORS"))
+ return(SEC_ERRORS);
+ else if (0 == strcmp(*p, "STANDARDS"))
+ return(SEC_STANDARDS);
+ else if (0 == strcmp(*p, "HISTORY"))
+ return(SEC_HISTORY);
+ else if (0 == strcmp(*p, "AUTHORS"))
+ return(SEC_AUTHORS);
+ else if (0 == strcmp(*p, "CAVEATS"))
+ return(SEC_CAVEATS);
+ else if (0 == strcmp(*p, "BUGS"))
+ return(SEC_BUGS);
+
+ return(SEC_CUSTOM);
+}
+
+
+time_t
+mdoc_atotime(const char *p)
+{
+ struct tm tm;
+
+ if (strptime(p, "%b %d %Y", &tm))
+ return(mktime(&tm));
+ if (strptime(p, "%b %d, %Y", &tm))
+ return(mktime(&tm));
+
+ return(0);
+}
+
+
+enum mdoc_msec
+mdoc_atomsec(const char *p)
+{
+
+ if (0 == strcmp(p, "1"))
+ return(MSEC_1);
+ else if (0 == strcmp(p, "2"))
+ return(MSEC_2);
+ else if (0 == strcmp(p, "3"))
+ return(MSEC_3);
+ else if (0 == strcmp(p, "3f"))
+ return(MSEC_3f);
+ else if (0 == strcmp(p, "3p"))
+ return(MSEC_3p);
+ else if (0 == strcmp(p, "4"))
+ return(MSEC_4);
+ else if (0 == strcmp(p, "5"))
+ return(MSEC_5);
+ else if (0 == strcmp(p, "6"))
+ return(MSEC_6);
+ else if (0 == strcmp(p, "7"))
+ return(MSEC_7);
+ else if (0 == strcmp(p, "8"))
+ return(MSEC_8);
+ else if (0 == strcmp(p, "9"))
+ return(MSEC_9);
+ else if (0 == strcmp(p, "X11"))
+ return(MSEC_X11);
+ else if (0 == strcmp(p, "X11R6"))
+ return(MSEC_X11R6);
+ else if (0 == strcmp(p, "local"))
+ return(MSEC_local);
+ else if (0 == strcmp(p, "n"))
+ return(MSEC_n);
+ else if (0 == strcmp(p, "unass"))
+ return(MSEC_unass);
+ else if (0 == strcmp(p, "draft"))
+ return(MSEC_draft);
+ else if (0 == strcmp(p, "paper"))
+ return(MSEC_paper);
+
+ return(MSEC_DEFAULT);
+}
+
+
+enum mdoc_vol
+mdoc_atovol(const char *p)
+{
+
+ if (0 == strcmp(p, "AMD"))
+ return(VOL_AMD);
+ else if (0 == strcmp(p, "IND"))
+ return(VOL_IND);
+ else if (0 == strcmp(p, "KM"))
+ return(VOL_KM);
+ else if (0 == strcmp(p, "LOCAL"))
+ return(VOL_LOCAL);
+ else if (0 == strcmp(p, "PRM"))
+ return(VOL_PRM);
+ else if (0 == strcmp(p, "PS1"))
+ return(VOL_PS1);
+ else if (0 == strcmp(p, "SMM"))
+ return(VOL_SMM);
+ else if (0 == strcmp(p, "URM"))
+ return(VOL_URM);
+ else if (0 == strcmp(p, "USD"))
+ return(VOL_USD);
+
+ return(VOL_DEFAULT);
+}
+
+
+enum mdoc_arch
+mdoc_atoarch(const char *p)
+{
+
+ if (0 == strcmp(p, "alpha"))
+ return(ARCH_alpha);
+ else if (0 == strcmp(p, "amd64"))
+ return(ARCH_amd64);
+ else if (0 == strcmp(p, "amiga"))
+ return(ARCH_amiga);
+ else if (0 == strcmp(p, "arc"))
+ return(ARCH_arc);
+ else if (0 == strcmp(p, "armish"))
+ return(ARCH_armish);
+ else if (0 == strcmp(p, "aviion"))
+ return(ARCH_aviion);
+ else if (0 == strcmp(p, "hp300"))
+ return(ARCH_hp300);
+ else if (0 == strcmp(p, "hppa"))
+ return(ARCH_hppa);
+ else if (0 == strcmp(p, "hppa64"))
+ return(ARCH_hppa64);
+ else if (0 == strcmp(p, "i386"))
+ return(ARCH_i386);
+ else if (0 == strcmp(p, "landisk"))
+ return(ARCH_landisk);
+ else if (0 == strcmp(p, "luna88k"))
+ return(ARCH_luna88k);
+ else if (0 == strcmp(p, "mac68k"))
+ return(ARCH_mac68k);
+ else if (0 == strcmp(p, "macppc"))
+ return(ARCH_macppc);
+ else if (0 == strcmp(p, "mvme68k"))
+ return(ARCH_mvme68k);
+ else if (0 == strcmp(p, "mvme88k"))
+ return(ARCH_mvme88k);
+ else if (0 == strcmp(p, "mvmeppc"))
+ return(ARCH_mvmeppc);
+ else if (0 == strcmp(p, "pmax"))
+ return(ARCH_pmax);
+ else if (0 == strcmp(p, "sgi"))
+ return(ARCH_sgi);
+ else if (0 == strcmp(p, "socppc"))
+ return(ARCH_socppc);
+ else if (0 == strcmp(p, "sparc"))
+ return(ARCH_sparc);
+ else if (0 == strcmp(p, "sparc64"))
+ return(ARCH_sparc64);
+ else if (0 == strcmp(p, "sun3"))
+ return(ARCH_sun3);
+ else if (0 == strcmp(p, "vax"))
+ return(ARCH_vax);
+ else if (0 == strcmp(p, "zaurus"))
+ return(ARCH_zaurus);
+
+ return(ARCH_DEFAULT);
+}