=================================================================== RCS file: /cvs/mandoc/man_macro.c,v retrieving revision 1.5 retrieving revision 1.12 diff -u -p -r1.5 -r1.12 --- mandoc/man_macro.c 2009/03/25 15:17:49 1.5 +++ mandoc/man_macro.c 2009/04/02 06:51:44 1.12 @@ -1,4 +1,4 @@ -/* $Id: man_macro.c,v 1.5 2009/03/25 15:17:49 kristaps Exp $ */ +/* $Id: man_macro.c,v 1.12 2009/04/02 06:51:44 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -18,16 +18,42 @@ */ #include #include -#include /* XXX */ #include -#include #include #include "libman.h" +#define FL_NLINE (1 << 0) +#define FL_TLINE (1 << 1) + static int man_args(struct man *, int, int *, char *, char **); +static int man_flags[MAN_MAX] = { + 0, /* __ */ + 0, /* TH */ + 0, /* SH */ + 0, /* SS */ + FL_TLINE, /* TP */ + 0, /* LP */ + 0, /* PP */ + 0, /* P */ + 0, /* IP */ + 0, /* HP */ + FL_NLINE, /* SM */ + FL_NLINE, /* SB */ + FL_NLINE, /* BI */ + FL_NLINE, /* IB */ + FL_NLINE, /* BR */ + FL_NLINE, /* RB */ + FL_NLINE, /* R */ + FL_NLINE, /* B */ + FL_NLINE, /* I */ + FL_NLINE, /* IR */ + FL_NLINE, /* RI */ + 0, /* br */ + 0, /* na */ +}; int man_macro(struct man *man, int tok, int line, @@ -56,15 +82,50 @@ man_macro(struct man *man, int tok, int line, man->next = MAN_NEXT_SIBLING; } - for ( ; man->last && man->last != n; - man->last = man->last->parent) + if (n == man->last && (FL_NLINE & man_flags[tok])) { + if (MAN_NLINE & man->flags) + return(man_verr(man, line, ppos, + "next-line scope already open")); + man->flags |= MAN_NLINE; + return(1); + } + + if (FL_TLINE & man_flags[tok]) { + if (MAN_NLINE & man->flags) + return(man_verr(man, line, ppos, + "next-line scope already open")); + man->flags |= MAN_NLINE; + return(1); + } + + /* + * Note that when TH is pruned, we'll be back at the root, so + * make sure that we don't clobber as its sibling. + */ + + for ( ; man->last; man->last = man->last->parent) { + if (man->last == n) + break; + if (man->last->type == MAN_ROOT) + break; if ( ! man_valid_post(man)) return(0); + if ( ! man_action_post(man)) + return(0); + } assert(man->last); - if ( ! man_valid_post(man)) + + /* + * Same here regarding whether we're back at the root. + */ + + if (man->last->type != MAN_ROOT && ! man_valid_post(man)) return(0); - man->next = MAN_NEXT_SIBLING; + if (man->last->type != MAN_ROOT && ! man_action_post(man)) + return(0); + if (man->last->type != MAN_ROOT) + man->next = MAN_NEXT_SIBLING; return(1); } @@ -74,14 +135,27 @@ int man_macroend(struct man *m) { - /* TODO: validate & actions. */ + for ( ; m->last && m->last != m->first; + m->last = m->last->parent) { + if ( ! man_valid_post(m)) + return(0); + if ( ! man_action_post(m)) + return(0); + } + assert(m->last == m->first); + + if ( ! man_valid_post(m)) + return(0); + if ( ! man_action_post(m)) + return(0); + return(1); } /* ARGSUSED */ static int -man_args(struct man *man, int line, +man_args(struct man *m, int line, int *pos, char *buf, char **v) { @@ -114,8 +188,10 @@ man_args(struct man *man, int line, if (buf[*pos]) return(1); - warnx("tail whitespace"); - return(-1); + if ( ! man_vwarn(m, line, *pos, "trailing spaces")) + return(-1); + + return(1); } /* @@ -130,8 +206,9 @@ man_args(struct man *man, int line, (*pos)++; if (0 == buf[*pos]) { - warnx("unterminated quotation"); - return(-1); + if ( ! man_vwarn(m, line, *pos, "unterminated quote")) + return(-1); + return(1); } buf[(*pos)++] = 0; @@ -144,6 +221,7 @@ man_args(struct man *man, int line, if (buf[*pos]) return(1); - warnx("tail whitespace"); - return(-1); + if ( ! man_vwarn(m, line, *pos, "trailing spaces")) + return(-1); + return(1); }