-/* $Id: private.h,v 1.38 2008/12/10 12:09:47 kristaps Exp $ */
+/* $Id: private.h,v 1.39 2008/12/10 13:15:55 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
#define ROFFSec_NMASK (0x07)
-#define ROFFSec_NAME (1 << 0)
-#define ROFFSec_SYNOP (1 << 1)
-#define ROFFSec_DESC (1 << 2)
-#define ROFFSec_RETVAL (1 << 3)
-#define ROFFSec_ENV (1 << 4)
-#define ROFFSec_FILES (1 << 5)
-#define ROFFSec_EX (1 << 6)
-#define ROFFSec_DIAG (1 << 7)
-#define ROFFSec_ERRS (1 << 8)
-#define ROFFSec_SEEALSO (1 << 9)
-#define ROFFSec_STAND (1 << 10)
-#define ROFFSec_HIST (1 << 11)
-#define ROFFSec_AUTH (1 << 12)
-#define ROFFSec_CAVEATS (1 << 13)
-#define ROFFSec_BUGS (1 << 14)
-#define ROFFSec_OTHER (1 << 15)
+#define ROFFSec_PR_Os (1 << 1)
+#define ROFFSec_PR_Dt (1 << 2)
+#define ROFFSec_PR_Dd (1 << 3)
+#define ROFFSec_NAME (1 << 4)
+#define ROFFSec_SYNOP (1 << 5)
+#define ROFFSec_DESC (1 << 6)
+#define ROFFSec_RETVAL (1 << 7)
+#define ROFFSec_ENV (1 << 8)
+#define ROFFSec_FILES (1 << 9)
+#define ROFFSec_EX (1 << 10)
+#define ROFFSec_DIAG (1 << 11)
+#define ROFFSec_ERRS (1 << 12)
+#define ROFFSec_SEEALSO (1 << 13)
+#define ROFFSec_STAND (1 << 14)
+#define ROFFSec_HIST (1 << 15)
+#define ROFFSec_AUTH (1 << 16)
+#define ROFFSec_CAVEATS (1 << 17)
+#define ROFFSec_BUGS (1 << 18)
+#define ROFFSec_OTHER (1 << 19)
struct roffcb {
int (*roffmsg)(void *, enum roffmsg,
-/* $Id: roff.c,v 1.60 2008/12/10 12:09:47 kristaps Exp $ */
+/* $Id: roff.c,v 1.61 2008/12/10 13:15:55 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
char title[64]; /* `Dt' results. */
enum roffmsec section;
enum roffvol volume;
- int state;
-#define ROFF_PRELUDE (1 << 1) /* In roff prelude. */ /* FIXME: put into asec. */
-#define ROFF_PRELUDE_Os (1 << 2) /* `Os' is parsed. */
-#define ROFF_PRELUDE_Dt (1 << 3) /* `Dt' is parsed. */
-#define ROFF_PRELUDE_Dd (1 << 4) /* `Dd' is parsed. */
-#define ROFF_BODY (1 << 5) /* In roff body. */
struct roffcb cb; /* Callbacks. */
void *arg; /* Callbacks' arg. */
int csec; /* Current section. */
static int rofffindcallable(const char *);
static int roffispunct(const char *);
static int roffchecksec(struct rofftree *,
- const char *, int);
+ const char *, int, int);
static int roffargs(const struct rofftree *,
int, char *, char **);
static int roffargok(int, int);
error = 1;
- if (ROFF_PRELUDE & tree->state) {
- (void)roff_err(tree, NULL, "prelude never finished");
- goto end;
- } else if ( ! (ROFFSec_NAME & tree->asec)) {
+ if ( ! (ROFFSec_NAME & tree->asec)) {
(void)roff_err(tree, NULL, "missing `NAME' section");
goto end;
} else if ( ! (ROFFSec_NMASK & tree->asec))
if (NULL == (tree = calloc(1, sizeof(struct rofftree))))
err(1, "calloc");
- tree->state = ROFF_PRELUDE;
tree->arg = args;
tree->section = ROFF_MSEC_MAX;
/* TODO: literal parsing. */
- if ( ! (ROFF_BODY & tree->state))
- return(roff_err(tree, buf, "data not in body"));
+ if ( ! (ROFFSec_NAME & tree->asec))
+ return(roff_err(tree, buf, "data before `NAME' section"));
/* LINTED */
while (*buf) {
* Prelude macros break some assumptions, so branch now.
*/
- if (ROFF_PRELUDE & tree->state) {
+ if ( ! (ROFFSec_PR_Dd & tree->asec)) {
assert(NULL == tree->last);
return(roffcall(tree, tok, argvp));
}
- assert(ROFF_BODY & tree->state);
-
/*
* First check that our possible parents and parent's possible
* children are satisfied.
static int
-roffchecksec(struct rofftree *tree, const char *start, int sec)
+roffchecksec(struct rofftree *tree,
+ const char *start, int sec, int fail)
{
switch (sec) {
+ case(ROFFSec_PR_Dd):
+ return(1);
+ case(ROFFSec_PR_Dt):
+ if (ROFFSec_PR_Dd & tree->asec)
+ return(1);
+ break;
+ case(ROFFSec_PR_Os):
+ if (ROFFSec_PR_Dt & tree->asec)
+ return(1);
+ break;
+ case(ROFFSec_NAME):
+ if (ROFFSec_PR_Os & tree->asec)
+ return(1);
+ break;
case(ROFFSec_SYNOP):
if (ROFFSec_NAME & tree->asec)
return(1);
return(1);
}
+ if (fail)
+ return(0);
return(roff_warnp(tree, start, ROFF_Sh, WRN_SECORD));
}
-/* FIXME: move this into literals.c (or similar). */
static int
roffispunct(const char *p)
{
char *p, buf[32];
size_t sz;
- if (ROFF_BODY & tree->state) {
- assert( ! (ROFF_PRELUDE & tree->state));
- assert(ROFF_PRELUDE_Dd & tree->state);
+ if (ROFFSec_PR_Os & tree->asec)
return(roff_text(tok, tree, argv, type));
- }
-
- assert(ROFF_PRELUDE & tree->state);
- assert( ! (ROFF_BODY & tree->state));
-
- if (ROFF_PRELUDE_Dd & tree->state)
+ if (ROFFSec_PR_Dd & tree->asec)
return(roff_errp(tree, *argv, tok, ERR_PR_REP));
- if (ROFF_PRELUDE_Dt & tree->state)
+ if ( ! roffchecksec(tree, *argv, ROFFSec_PR_Dd, 1))
return(roff_errp(tree, *argv, tok, ERR_PR_OOO));
assert(NULL == tree->last);
-
argv++;
+ tree->asec |= (tree->csec = ROFFSec_PR_Dd);
/*
* This is a bit complex because there are many forms the date
t = time(NULL);
if (NULL == localtime_r(&t, &tree->tm))
err(1, "localtime_r");
- tree->state |= ROFF_PRELUDE_Dd;
return(1);
}
continue;
return(roff_errp(tree, p, tok, ERR_BADARG));
}
- if (strptime(buf, "%b%d,%Y", &tree->tm)) {
- tree->state |= ROFF_PRELUDE_Dd;
+ if (strptime(buf, "%b%d,%Y", &tree->tm))
return(1);
- }
return(roff_errp(tree, p, tok, ERR_BADARG));
}
if (NULL == strptime(buf, "%b %d %Y", &tree->tm))
return(roff_errp(tree, p, tok, ERR_BADARG));
- tree->state |= ROFF_PRELUDE_Dd;
return(1);
}
{
size_t sz;
- if (ROFF_BODY & tree->state) {
- assert( ! (ROFF_PRELUDE & tree->state));
- assert(ROFF_PRELUDE_Dt & tree->state);
+ if (ROFFSec_PR_Os & tree->asec)
return(roff_text(tok, tree, argv, type));
- }
-
- assert(ROFF_PRELUDE & tree->state);
- assert( ! (ROFF_BODY & tree->state));
-
- if ( ! (ROFF_PRELUDE_Dd & tree->state))
- return(roff_errp(tree, *argv, tok, ERR_PR_OOO));
- if (ROFF_PRELUDE_Dt & tree->state)
+ if (ROFFSec_PR_Dt & tree->asec)
return(roff_errp(tree, *argv, tok, ERR_PR_REP));
+ if ( ! roffchecksec(tree, *argv, ROFFSec_PR_Dt, 1))
+ return(roff_errp(tree, *argv, tok, ERR_PR_OOO));
argv++;
+ tree->asec |= (tree->csec = ROFFSec_PR_Dt);
sz = sizeof(tree->title);
if (NULL == *argv)
return(roff_errp(tree, *argv, tok, ERR_BADARG));
assert(NULL == tree->last);
- tree->state |= ROFF_PRELUDE_Dt;
return(1);
}
char *p;
size_t sz;
- if (ROFF_BODY & tree->state) {
- assert( ! (ROFF_PRELUDE & tree->state));
- assert(ROFF_PRELUDE_Os & tree->state);
+ if (ROFFSec_PR_Os & tree->asec)
return(roff_text(tok, tree, argv, type));
- }
-
- assert(ROFF_PRELUDE & tree->state);
- if ( ! (ROFF_PRELUDE_Dt & tree->state) ||
- ! (ROFF_PRELUDE_Dd & tree->state))
+ if ( ! roffchecksec(tree, *argv, ROFFSec_PR_Os, 1))
return(roff_errp(tree, *argv, tok, ERR_PR_OOO));
- tree->os[0] = 0;
-
p = *++argv;
sz = sizeof(tree->os);
+ tree->asec |= (tree->csec = ROFFSec_PR_Os);
+
+ tree->os[0] = 0;
while (*argv)
if (strlcat(tree->os, *argv++, sz) >= sz)
if (strlcpy(tree->os, "LOCAL", sz) >= sz)
return(roff_errp(tree, p, tok, ERR_ARGLEN));
- tree->state |= ROFF_PRELUDE_Os;
- tree->state &= ~ROFF_PRELUDE;
- tree->state |= ROFF_BODY;
-
assert(ROFF_MSEC_MAX != tree->section);
assert(0 != tree->title[0]);
assert(0 != tree->os[0]);
assert( ! (ROFF_CALLABLE & tokens[tok].flags));
- if (ROFF_PRELUDE & tree->state)
+ if ( ! ROFFSec_NAME & tree->asec)
return(roff_errp(tree, *argv, tok, ERR_NOT_PR));
if (ROFF_EXIT == type) {
if (0 == tree->asec && ! (ROFFSec_NAME & tree->csec))
return(roff_err(tree, *argv, "`NAME' section "
"must be first"));
- if ( ! roffchecksec(tree, *argv, tree->csec))
+ if ( ! roffchecksec(tree, *argv, tree->csec, 0))
return(0);
tree->asec |= tree->csec;
* .Xr arg1 arg2 punctuation
*/
- if (ROFF_PRELUDE & tree->state)
+ if ( ! ROFFSec_NAME & tree->asec)
return(roff_errp(tree, *argv, tok, ERR_NOT_PR));
first = (*argv == tree->cur);
* <fl> v W f </fl> ;
*/
- if (ROFF_PRELUDE & tree->state)
+ if ( ! ROFFSec_NAME & tree->asec)
return(roff_errp(tree, *argv, tok, ERR_NOT_PR));
first = (*argv == tree->cur);