version 1.55, 2010/01/01 15:14:03 |
version 1.70, 2010/05/08 07:30:19 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
*/ |
*/ |
|
#ifdef HAVE_CONFIG_H |
|
#include "config.h" |
|
#endif |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
|
#include <assert.h> |
#include <assert.h> |
|
|
v_post *post; |
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_msec(PRE_ARGS, ...); |
static int check_sec(PRE_ARGS, ...); |
static int check_sec(PRE_ARGS, ...); |
static int check_stdarg(PRE_ARGS); |
static int check_stdarg(PRE_ARGS); |
Line 62 static int warn_count(struct mdoc *, const char *, |
|
Line 66 static int warn_count(struct mdoc *, const char *, |
|
static int err_count(struct mdoc *, const char *, |
static int err_count(struct mdoc *, const char *, |
int, const char *, int); |
int, const char *, int); |
|
|
#ifdef __linux__ |
|
extern size_t strlcat(char *, const char *, size_t); |
|
#endif |
|
|
|
static int berr_ge1(POST_ARGS); |
static int berr_ge1(POST_ARGS); |
static int bwarn_ge1(POST_ARGS); |
static int bwarn_ge1(POST_ARGS); |
static int ebool(POST_ARGS); |
static int ebool(POST_ARGS); |
static int eerr_eq0(POST_ARGS); |
static int eerr_eq0(POST_ARGS); |
static int eerr_eq1(POST_ARGS); |
static int eerr_eq1(POST_ARGS); |
static int eerr_ge1(POST_ARGS); |
static int eerr_ge1(POST_ARGS); |
static int eerr_le2(POST_ARGS); |
|
static int eerr_le1(POST_ARGS); |
static int eerr_le1(POST_ARGS); |
static int ewarn_ge1(POST_ARGS); |
static int ewarn_ge1(POST_ARGS); |
static int herr_eq0(POST_ARGS); |
static int herr_eq0(POST_ARGS); |
static int herr_ge1(POST_ARGS); |
static int herr_ge1(POST_ARGS); |
static int hwarn_eq1(POST_ARGS); |
static int hwarn_eq1(POST_ARGS); |
|
static int hwarn_eq0(POST_ARGS); |
static int hwarn_le1(POST_ARGS); |
static int hwarn_le1(POST_ARGS); |
|
|
static int post_an(POST_ARGS); |
static int post_an(POST_ARGS); |
Line 94 static int post_sh(POST_ARGS); |
|
Line 94 static int post_sh(POST_ARGS); |
|
static int post_sh_body(POST_ARGS); |
static int post_sh_body(POST_ARGS); |
static int post_sh_head(POST_ARGS); |
static int post_sh_head(POST_ARGS); |
static int post_st(POST_ARGS); |
static int post_st(POST_ARGS); |
|
static int post_vt(POST_ARGS); |
static int pre_an(PRE_ARGS); |
static int pre_an(PRE_ARGS); |
static int pre_bd(PRE_ARGS); |
static int pre_bd(PRE_ARGS); |
static int pre_bl(PRE_ARGS); |
static int pre_bl(PRE_ARGS); |
static int pre_cd(PRE_ARGS); |
|
static int pre_dd(PRE_ARGS); |
static int pre_dd(PRE_ARGS); |
static int pre_display(PRE_ARGS); |
static int pre_display(PRE_ARGS); |
static int pre_dt(PRE_ARGS); |
static int pre_dt(PRE_ARGS); |
static int pre_er(PRE_ARGS); |
|
static int pre_ex(PRE_ARGS); |
static int pre_ex(PRE_ARGS); |
static int pre_fd(PRE_ARGS); |
static int pre_fd(PRE_ARGS); |
static int pre_it(PRE_ARGS); |
static int pre_it(PRE_ARGS); |
Line 113 static int pre_ss(PRE_ARGS); |
|
Line 112 static int pre_ss(PRE_ARGS); |
|
|
|
static v_post posts_an[] = { post_an, NULL }; |
static v_post posts_an[] = { post_an, NULL }; |
static v_post posts_at[] = { post_at, 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_bf[] = { hwarn_le1, post_bf, NULL }; |
static v_post posts_bl[] = { bwarn_ge1, post_bl, NULL }; |
static v_post posts_bl[] = { bwarn_ge1, post_bl, NULL }; |
static v_post posts_bool[] = { eerr_eq1, ebool, NULL }; |
static v_post posts_bool[] = { eerr_eq1, ebool, NULL }; |
Line 130 static v_post posts_ss[] = { herr_ge1, NULL }; |
|
Line 129 static v_post posts_ss[] = { herr_ge1, NULL }; |
|
static v_post posts_st[] = { eerr_eq1, post_st, NULL }; |
static v_post posts_st[] = { eerr_eq1, post_st, NULL }; |
static v_post posts_text[] = { eerr_ge1, NULL }; |
static v_post posts_text[] = { eerr_ge1, NULL }; |
static v_post posts_text1[] = { eerr_eq1, NULL }; |
static v_post posts_text1[] = { eerr_eq1, NULL }; |
|
static v_post posts_vt[] = { post_vt, NULL }; |
static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL }; |
static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL }; |
static v_post posts_wtext[] = { ewarn_ge1, NULL }; |
static v_post posts_wtext[] = { ewarn_ge1, NULL }; |
static v_post posts_xr[] = { eerr_ge1, eerr_le2, NULL }; |
static v_post posts_xr[] = { ewarn_ge1, NULL }; |
static v_pre pres_an[] = { pre_an, NULL }; |
static v_pre pres_an[] = { pre_an, NULL }; |
static v_pre pres_bd[] = { pre_display, pre_bd, NULL }; |
static v_pre pres_bd[] = { pre_display, pre_bd, NULL }; |
static v_pre pres_bl[] = { pre_bl, 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_d1[] = { pre_display, NULL }; |
static v_pre pres_dd[] = { pre_dd, NULL }; |
static v_pre pres_dd[] = { pre_dd, NULL }; |
static v_pre pres_dt[] = { pre_dt, 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_ex[] = { pre_ex, NULL }; |
static v_pre pres_fd[] = { pre_fd, NULL }; |
static v_pre pres_fd[] = { pre_fd, NULL }; |
static v_pre pres_it[] = { pre_it, NULL }; |
static v_pre pres_it[] = { pre_it, NULL }; |
Line 168 const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 167 const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, posts_text }, /* Ad */ |
{ NULL, posts_text }, /* Ad */ |
{ pres_an, posts_an }, /* An */ |
{ pres_an, posts_an }, /* An */ |
{ NULL, NULL }, /* Ar */ |
{ NULL, NULL }, /* Ar */ |
{ pres_cd, posts_text }, /* Cd */ |
{ NULL, posts_text }, /* Cd */ |
{ NULL, NULL }, /* Cm */ |
{ NULL, NULL }, /* Cm */ |
{ NULL, NULL }, /* Dv */ |
{ NULL, NULL }, /* Dv */ |
{ pres_er, posts_text }, /* Er */ |
{ pres_er, posts_text }, /* Er */ |
Line 190 const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 189 const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ pres_rv, NULL }, /* Rv */ |
{ pres_rv, NULL }, /* Rv */ |
{ NULL, posts_st }, /* St */ |
{ NULL, posts_st }, /* St */ |
{ NULL, NULL }, /* Va */ |
{ NULL, NULL }, /* Va */ |
{ NULL, posts_text }, /* Vt */ |
{ NULL, posts_vt }, /* Vt */ |
{ NULL, posts_xr }, /* Xr */ |
{ NULL, posts_xr }, /* Xr */ |
{ NULL, posts_text }, /* %A */ |
{ NULL, posts_text }, /* %A */ |
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
Line 406 CHECK_BODY_DEFN(ge1, warn, warn_child_gt, 0) /* bwarn_ |
|
Line 405 CHECK_BODY_DEFN(ge1, warn, warn_child_gt, 0) /* bwarn_ |
|
CHECK_BODY_DEFN(ge1, err, err_child_gt, 0) /* berr_ge1() */ |
CHECK_BODY_DEFN(ge1, err, err_child_gt, 0) /* berr_ge1() */ |
CHECK_ELEM_DEFN(ge1, warn, warn_child_gt, 0) /* ewarn_gt1() */ |
CHECK_ELEM_DEFN(ge1, warn, warn_child_gt, 0) /* ewarn_gt1() */ |
CHECK_ELEM_DEFN(eq1, err, err_child_eq, 1) /* eerr_eq1() */ |
CHECK_ELEM_DEFN(eq1, err, err_child_eq, 1) /* eerr_eq1() */ |
CHECK_ELEM_DEFN(le2, err, err_child_lt, 3) /* eerr_le2() */ |
|
CHECK_ELEM_DEFN(le1, err, err_child_lt, 2) /* eerr_le1() */ |
CHECK_ELEM_DEFN(le1, err, err_child_lt, 2) /* eerr_le1() */ |
CHECK_ELEM_DEFN(eq0, err, err_child_eq, 0) /* eerr_eq0() */ |
CHECK_ELEM_DEFN(eq0, err, err_child_eq, 0) /* eerr_eq0() */ |
CHECK_ELEM_DEFN(ge1, err, err_child_gt, 0) /* eerr_ge1() */ |
CHECK_ELEM_DEFN(ge1, err, err_child_gt, 0) /* eerr_ge1() */ |
Line 414 CHECK_HEAD_DEFN(eq0, err, err_child_eq, 0) /* herr_eq0 |
|
Line 412 CHECK_HEAD_DEFN(eq0, err, err_child_eq, 0) /* herr_eq0 |
|
CHECK_HEAD_DEFN(le1, warn, warn_child_lt, 2) /* hwarn_le1() */ |
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(ge1, err, err_child_gt, 0) /* herr_ge1() */ |
CHECK_HEAD_DEFN(eq1, warn, warn_child_eq, 1) /* hwarn_eq1() */ |
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 |
Line 547 check_text(struct mdoc *mdoc, int line, int pos, const |
|
Line 546 check_text(struct mdoc *mdoc, int line, int pos, const |
|
|
|
|
|
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); |
assert(n->parent); |
Line 621 pre_bl(PRE_ARGS) |
|
Line 620 pre_bl(PRE_ARGS) |
|
case (MDOC_Inset): |
case (MDOC_Inset): |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_Column): |
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; |
type = n->args->argv[pos].arg; |
break; |
break; |
case (MDOC_Compact): |
case (MDOC_Compact): |
Line 735 pre_sh(PRE_ARGS) |
|
Line 747 pre_sh(PRE_ARGS) |
|
|
|
if (MDOC_BLOCK != n->type) |
if (MDOC_BLOCK != n->type) |
return(1); |
return(1); |
return(check_parent(mdoc, n, -1, MDOC_ROOT)); |
return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT)); |
} |
} |
|
|
|
|
|
|
pre_rv(PRE_ARGS) |
pre_rv(PRE_ARGS) |
{ |
{ |
|
|
if ( ! check_msec(mdoc, n, 2, 3, 0)) |
|
return(0); |
|
return(check_stdarg(mdoc, n)); |
return(check_stdarg(mdoc, n)); |
} |
} |
|
|
Line 789 pre_ex(PRE_ARGS) |
|
Line 799 pre_ex(PRE_ARGS) |
|
|
|
|
|
static int |
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) |
pre_dt(PRE_ARGS) |
{ |
{ |
|
|
Line 891 post_lb(POST_ARGS) |
|
Line 885 post_lb(POST_ARGS) |
|
|
|
|
|
static int |
static int |
|
post_vt(POST_ARGS) |
|
{ |
|
const struct mdoc_node *n; |
|
|
|
/* |
|
* The Vt macro comes in both ELEM and BLOCK form, both of which |
|
* have different syntaxes (yet more context-sensitive |
|
* behaviour). ELEM types must have a child; BLOCK types, |
|
* specifically the BODY, should only have TEXT children. |
|
*/ |
|
|
|
if (MDOC_ELEM == mdoc->last->type) |
|
return(eerr_ge1(mdoc)); |
|
if (MDOC_BODY != mdoc->last->type) |
|
return(1); |
|
|
|
for (n = mdoc->last->child; n; n = n->next) |
|
if (MDOC_TEXT != n->type) |
|
if ( ! mdoc_nwarn(mdoc, n, EBADCHILD)) |
|
return(0); |
|
|
|
return(1); |
|
} |
|
|
|
|
|
static int |
post_nm(POST_ARGS) |
post_nm(POST_ARGS) |
{ |
{ |
|
|
Line 1056 post_bl_head(POST_ARGS) |
|
Line 1076 post_bl_head(POST_ARGS) |
|
{ |
{ |
int i; |
int i; |
const struct mdoc_node *n; |
const struct mdoc_node *n; |
|
const struct mdoc_argv *a; |
|
|
n = mdoc->last->parent; |
n = mdoc->last->parent; |
assert(n->args); |
assert(n->args); |
|
|
for (i = 0; i < (int)n->args->argc; i++) |
for (i = 0; i < (int)n->args->argc; i++) { |
if (n->args->argv[i].arg == MDOC_Column) |
a = &n->args->argv[i]; |
break; |
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); |
return(1); |
|
return(warn_count(mdoc, "==", 0, "line arguments", i)); |
if (n->args->argv[i].sz && mdoc->last->child) |
|
return(mdoc_nerr(mdoc, n, ECOLMIS)); |
|
|
|
return(1); |
|
} |
} |
|
|
|
|
Line 1282 post_sh_head(POST_ARGS) |
|
Line 1304 post_sh_head(POST_ARGS) |
|
* non-CUSTOM has a conventional order to be followed. |
* non-CUSTOM has a conventional order to be followed. |
*/ |
*/ |
|
|
if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) |
if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed && |
return(mdoc_nerr(mdoc, mdoc->last, ESECNAME)); |
! mdoc_nwarn(mdoc, mdoc->last, ESECNAME)) |
|
return(0); |
if (SEC_CUSTOM == sec) |
if (SEC_CUSTOM == sec) |
return(1); |
return(1); |
if (sec == mdoc->lastnamed) |
if (sec == mdoc->lastnamed) |