-/* $Id: mdoc_validate.c,v 1.58 2010/02/17 19:28:11 kristaps Exp $ */
+/* $Id: mdoc_validate.c,v 1.69 2010/04/07 19:35:42 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
v_post *post;
};
-static int check_parent(PRE_ARGS, int, enum mdoc_type);
+static int check_parent(PRE_ARGS, enum mdoct, enum mdoc_type);
static int check_msec(PRE_ARGS, ...);
static int check_sec(PRE_ARGS, ...);
static int check_stdarg(PRE_ARGS);
static int herr_eq0(POST_ARGS);
static int herr_ge1(POST_ARGS);
static int hwarn_eq1(POST_ARGS);
+static int hwarn_eq0(POST_ARGS);
static int hwarn_le1(POST_ARGS);
static int post_an(POST_ARGS);
static int pre_an(PRE_ARGS);
static int pre_bd(PRE_ARGS);
static int pre_bl(PRE_ARGS);
-static int pre_cd(PRE_ARGS);
static int pre_dd(PRE_ARGS);
static int pre_display(PRE_ARGS);
static int pre_dt(PRE_ARGS);
-static int pre_er(PRE_ARGS);
static int pre_ex(PRE_ARGS);
static int pre_fd(PRE_ARGS);
static int pre_it(PRE_ARGS);
static v_post posts_an[] = { post_an, NULL };
static v_post posts_at[] = { post_at, NULL };
-static v_post posts_bd[] = { herr_eq0, bwarn_ge1, NULL };
+static v_post posts_bd[] = { hwarn_eq0, bwarn_ge1, NULL };
static v_post posts_bf[] = { hwarn_le1, post_bf, NULL };
static v_post posts_bl[] = { bwarn_ge1, post_bl, NULL };
static v_post posts_bool[] = { eerr_eq1, ebool, NULL };
static v_post posts_vt[] = { post_vt, NULL };
static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL };
static v_post posts_wtext[] = { ewarn_ge1, NULL };
-static v_post posts_xr[] = { eerr_ge1, NULL };
+static v_post posts_xr[] = { ewarn_ge1, NULL };
static v_pre pres_an[] = { pre_an, NULL };
static v_pre pres_bd[] = { pre_display, pre_bd, NULL };
static v_pre pres_bl[] = { pre_bl, NULL };
-static v_pre pres_cd[] = { pre_cd, NULL };
static v_pre pres_d1[] = { pre_display, NULL };
static v_pre pres_dd[] = { pre_dd, NULL };
static v_pre pres_dt[] = { pre_dt, NULL };
-static v_pre pres_er[] = { pre_er, NULL };
+static v_pre pres_er[] = { NULL, NULL };
static v_pre pres_ex[] = { pre_ex, NULL };
static v_pre pres_fd[] = { pre_fd, NULL };
static v_pre pres_it[] = { pre_it, NULL };
{ NULL, posts_text }, /* Ad */
{ pres_an, posts_an }, /* An */
{ NULL, NULL }, /* Ar */
- { pres_cd, posts_text }, /* Cd */
+ { NULL, posts_text }, /* Cd */
{ NULL, NULL }, /* Cm */
{ NULL, NULL }, /* Dv */
{ pres_er, posts_text }, /* Er */
CHECK_HEAD_DEFN(le1, warn, warn_child_lt, 2) /* hwarn_le1() */
CHECK_HEAD_DEFN(ge1, err, err_child_gt, 0) /* herr_ge1() */
CHECK_HEAD_DEFN(eq1, warn, warn_child_eq, 1) /* hwarn_eq1() */
+CHECK_HEAD_DEFN(eq0, warn, warn_child_eq, 0) /* hwarn_eq0() */
static int
static int
-check_parent(PRE_ARGS, int tok, enum mdoc_type t)
+check_parent(PRE_ARGS, enum mdoct tok, enum mdoc_type t)
{
assert(n->parent);
case (MDOC_Inset):
/* FALLTHROUGH */
case (MDOC_Column):
- if (type >= 0)
- return(mdoc_nerr(mdoc, n, EMULTILIST));
+ /*
+ * Note that if a duplicate is detected, we
+ * remove the duplicate instead of passing it
+ * over. If we don't do this, mdoc_action will
+ * become confused when it scans over multiple
+ * types whilst setting its bitmasks.
+ *
+ * FIXME: this should occur in mdoc_action.c.
+ */
+ if (type >= 0) {
+ if ( ! mdoc_nwarn(mdoc, n, EMULTILIST))
+ return(0);
+ mdoc_argn_free(n->args, pos);
+ break;
+ }
type = n->args->argv[pos].arg;
break;
case (MDOC_Compact):
pre_rv(PRE_ARGS)
{
- if ( ! check_msec(mdoc, n, 2, 3, 0))
- return(0);
return(check_stdarg(mdoc, n));
}
}
-static int
-pre_er(PRE_ARGS)
-{
-
- return(check_msec(mdoc, n, 2, 3, 9, 0));
-}
-
-
-static int
-pre_cd(PRE_ARGS)
-{
-
- return(check_msec(mdoc, n, 4, 0));
-}
-
-
static int
pre_dt(PRE_ARGS)
{
{
int i;
const struct mdoc_node *n;
+ const struct mdoc_argv *a;
n = mdoc->last->parent;
assert(n->args);
- for (i = 0; i < (int)n->args->argc; i++)
- if (n->args->argv[i].arg == MDOC_Column)
- break;
+ for (i = 0; i < (int)n->args->argc; i++) {
+ a = &n->args->argv[i];
+ if (a->arg == MDOC_Column) {
+ if (a->sz && mdoc->last->nchild)
+ return(mdoc_nerr(mdoc, n, ECOLMIS));
+ return(1);
+ }
+ }
- if (i == (int)n->args->argc)
+ if (0 == (i = mdoc->last->nchild))
return(1);
-
- if (n->args->argv[i].sz && mdoc->last->child)
- return(mdoc_nerr(mdoc, n, ECOLMIS));
-
- return(1);
+ return(warn_count(mdoc, "==", 0, "line arguments", i));
}
* non-CUSTOM has a conventional order to be followed.
*/
- if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed)
- return(mdoc_nerr(mdoc, mdoc->last, ESECNAME));
+ if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed &&
+ ! mdoc_nwarn(mdoc, mdoc->last, ESECNAME))
+ return(0);
if (SEC_CUSTOM == sec)
return(1);
if (sec == mdoc->lastnamed)