diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-03-25 15:17:49 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-03-25 15:17:49 +0000 |
commit | 12bf2f26f8d476960eba07e14e64fd26661da3b3 (patch) | |
tree | b759d2d2e7467b1cffc89fb98e9d6e4ccb5bdbed /man_validate.c | |
parent | 4b4e799e741ce5040d46930f13430debab688774 (diff) | |
download | mandoc-12bf2f26f8d476960eba07e14e64fd26661da3b3.tar.gz |
Added man validator, renamed mdoc validator.
Diffstat (limited to 'man_validate.c')
-rw-r--r-- | man_validate.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/man_validate.c b/man_validate.c new file mode 100644 index 00000000..357ae37d --- /dev/null +++ b/man_validate.c @@ -0,0 +1,134 @@ +/* $Id$ */ +/* + * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@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. + */ +#include <sys/types.h> + +#include <assert.h> +#include <ctype.h> +#include <stdarg.h> +#include <stdlib.h> + +#include "libman.h" + +/* FIXME: validate text. */ + +#define POSTARGS struct man *m, const struct man_node *n + +typedef int (*v_post)(POSTARGS); + +struct man_valid { + v_post *posts; +}; + +static int count(POSTARGS); +static int check_eq0(POSTARGS); +static int check_ge1(POSTARGS); +static int check_ge2(POSTARGS); +static int check_le1(POSTARGS); +static int check_le2(POSTARGS); +static int check_le5(POSTARGS); + +static v_post posts_le1[] = { check_le1, NULL }; +static v_post posts_le2[] = { check_le2, NULL }; +static v_post posts_ge1[] = { check_ge1, NULL }; +static v_post posts_eq0[] = { check_eq0, NULL }; +static v_post posts_ge2_le5[] = { check_ge2, check_le5, NULL }; + +static const struct man_valid man_valids[MAN_MAX] = { + { NULL }, /* __ */ + { posts_ge2_le5 }, /* TH */ + { posts_ge1 }, /* SH */ + { posts_ge1 }, /* SS */ + { posts_le1 }, /* TP */ + { posts_eq0 }, /* LP */ + { posts_eq0 }, /* PP */ + { posts_eq0 }, /* P */ + { posts_le2 }, /* IP */ + { posts_le1 }, /* HP */ + { NULL }, /* SM */ + { NULL }, /* SB */ + { NULL }, /* BI */ + { NULL }, /* IB */ + { NULL }, /* BR */ + { NULL }, /* RB */ + { NULL }, /* R */ + { NULL }, /* B */ + { NULL }, /* I */ + { NULL }, /* IR */ +}; + + +int +man_valid_post(struct man *m) +{ + v_post *cp; + + if (MAN_VALID & m->last->flags) + return(1); + + m->last->flags |= MAN_VALID; + + switch (m->last->type) { + case (MAN_TEXT): + /* FALLTHROUGH */ + case (MAN_ROOT): + return(1); + default: + break; + } + + if (NULL == (cp = man_valids[m->last->tok].posts)) + return(1); + for ( ; *cp; cp++) + if ( ! (*cp)(m, m->last)) + return(0); + + return(1); +} + + +static inline int +count(POSTARGS) +{ + int i; + + for (i = 0; n; n = n->next, i++) + /* Loop. */ ; + return(i); +} + + +#define INEQ_DEFINE(x, ineq, name) \ +static int \ +check_##name(POSTARGS) \ +{ \ + int c; \ + if ((c = count(m, n->child)) ineq (x)) \ + return(1); \ + return(man_vwarn(m, n->line, n->pos, \ + "expected line arguments %s %d, have %d", \ + #ineq, (x), c)); \ +} + +INEQ_DEFINE(0, ==, eq0) +INEQ_DEFINE(1, >=, ge1) +INEQ_DEFINE(2, >=, ge2) +INEQ_DEFINE(1, <=, le1) +INEQ_DEFINE(2, <=, le2) +INEQ_DEFINE(5, <=, le5) + |