version 1.38, 2009/01/17 20:10:36 |
version 1.42, 2009/01/19 23:11:43 |
Line 29 typedef int (*v_post)(struct mdoc *); |
|
Line 29 typedef int (*v_post)(struct mdoc *); |
|
/* FIXME: math symbols. */ |
/* FIXME: math symbols. */ |
/* FIXME: make sure prologue is complete. */ |
/* FIXME: make sure prologue is complete. */ |
/* FIXME: valid character-escape checks. */ |
/* FIXME: valid character-escape checks. */ |
|
/* FIXME: make sure required sections are included (NAME, ...). */ |
|
|
struct valids { |
struct valids { |
v_pre *pre; |
v_pre *pre; |
Line 43 static int pre_check_msecs(struct mdoc *, struct mdoc_ |
|
Line 44 static int pre_check_msecs(struct mdoc *, struct mdoc_ |
|
int, enum mdoc_msec *); |
int, enum mdoc_msec *); |
static int pre_check_stdarg(struct mdoc *, struct mdoc_node *); |
static int pre_check_stdarg(struct mdoc *, struct mdoc_node *); |
static int post_check_children_count(struct mdoc *); |
static int post_check_children_count(struct mdoc *); |
static int post_check_children_lt(struct mdoc *, int); |
static int post_check_children_lt(struct mdoc *, const char *, int); |
static int post_check_children_gt(struct mdoc *, int); |
static int post_check_children_gt(struct mdoc *, const char *, int); |
static int post_check_children_eq(struct mdoc *, int); |
static int post_check_children_wgt(struct mdoc *, const char *, int); |
|
static int post_check_children_eq(struct mdoc *, const char *, int); |
|
static int post_check_children_weq(struct mdoc *, const char *, int); |
|
|
/* Specific pre-child-parse routines. */ |
/* Specific pre-child-parse routines. */ |
|
|
Line 68 static int pre_prologue(struct mdoc *, struct mdoc_nod |
|
Line 71 static int pre_prologue(struct mdoc *, struct mdoc_nod |
|
/* Specific post-child-parse routines. */ |
/* Specific post-child-parse routines. */ |
|
|
static int herr_ge1(struct mdoc *); |
static int herr_ge1(struct mdoc *); |
|
static int herr_le1(struct mdoc *); |
static int hwarn_ge1(struct mdoc *); |
static int hwarn_ge1(struct mdoc *); |
static int herr_eq0(struct mdoc *); |
static int herr_eq0(struct mdoc *); |
static int eerr_eq0(struct mdoc *); |
static int eerr_eq0(struct mdoc *); |
Line 76 static int eerr_le2(struct mdoc *); |
|
Line 80 static int eerr_le2(struct mdoc *); |
|
static int eerr_eq1(struct mdoc *); |
static int eerr_eq1(struct mdoc *); |
static int eerr_ge1(struct mdoc *); |
static int eerr_ge1(struct mdoc *); |
static int ewarn_eq0(struct mdoc *); |
static int ewarn_eq0(struct mdoc *); |
|
static int ewarn_eq1(struct mdoc *); |
static int bwarn_ge1(struct mdoc *); |
static int bwarn_ge1(struct mdoc *); |
static int berr_eq0(struct mdoc *); |
static int berr_eq0(struct mdoc *); |
static int ewarn_ge1(struct mdoc *); |
static int ewarn_ge1(struct mdoc *); |
Line 88 static int post_an(struct mdoc *); |
|
Line 93 static int post_an(struct mdoc *); |
|
static int post_at(struct mdoc *); |
static int post_at(struct mdoc *); |
static int post_xr(struct mdoc *); |
static int post_xr(struct mdoc *); |
static int post_nm(struct mdoc *); |
static int post_nm(struct mdoc *); |
|
static int post_bf(struct mdoc *); |
static int post_root(struct mdoc *); |
static int post_root(struct mdoc *); |
|
|
/* Collections of pre-child-parse routines. */ |
/* Collections of pre-child-parse routines. */ |
Line 117 static v_post posts_wline[] = { hwarn_ge1, berr_eq0, N |
|
Line 123 static v_post posts_wline[] = { hwarn_ge1, berr_eq0, N |
|
static v_post posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL }; |
static v_post posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL }; |
static v_post posts_bl[] = { herr_eq0, bwarn_ge1, post_bl, NULL }; |
static v_post posts_bl[] = { herr_eq0, bwarn_ge1, post_bl, NULL }; |
static v_post posts_it[] = { post_it, NULL }; |
static v_post posts_it[] = { post_it, NULL }; |
|
static v_post posts_in[] = { ewarn_eq1, NULL }; |
static v_post posts_ss[] = { herr_ge1, NULL }; |
static v_post posts_ss[] = { herr_ge1, NULL }; |
static v_post posts_pp[] = { ewarn_eq0, NULL }; |
static v_post posts_pp[] = { ewarn_eq0, NULL }; |
static v_post posts_d1[] = { herr_ge1, NULL }; |
static v_post posts_d1[] = { herr_ge1, NULL }; |
Line 125 static v_post posts_an[] = { post_an, NULL }; |
|
Line 132 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_xr[] = { eerr_ge1, eerr_le2, post_xr, NULL }; |
static v_post posts_xr[] = { eerr_ge1, eerr_le2, post_xr, NULL }; |
static v_post posts_nm[] = { post_nm, NULL }; |
static v_post posts_nm[] = { post_nm, NULL }; |
|
static v_post posts_bf[] = { herr_le1, post_bf, NULL }; |
|
|
/* Per-macro pre- and post-child-check routine collections. */ |
/* Per-macro pre- and post-child-check routine collections. */ |
|
|
Line 155 const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 163 const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ pres_ex, posts_ex }, /* Ex */ |
{ pres_ex, posts_ex }, /* Ex */ |
{ NULL, posts_text }, /* Fa */ |
{ NULL, posts_text }, /* Fa */ |
/* FIXME: only in SYNOPSIS section. */ |
/* FIXME: only in SYNOPSIS section. */ |
{ NULL, NULL }, /* Fd */ |
{ NULL, posts_wtext }, /* Fd */ |
{ NULL, NULL }, /* Fl */ |
{ NULL, NULL }, /* Fl */ |
{ NULL, posts_text }, /* Fn */ |
{ NULL, posts_text }, /* Fn */ |
{ NULL, NULL }, /* Ft */ |
{ NULL, posts_wtext }, /* Ft */ |
{ NULL, posts_text }, /* Ic */ |
{ NULL, posts_text }, /* Ic */ |
{ NULL, posts_wtext }, /* In */ |
{ NULL, posts_in }, /* In */ |
{ NULL, posts_text }, /* Li */ |
{ NULL, posts_text }, /* Li */ |
{ NULL, posts_wtext }, /* Nd */ |
{ NULL, posts_wtext }, /* Nd */ |
{ NULL, posts_nm }, /* Nm */ |
{ NULL, posts_nm }, /* Nm */ |
Line 188 const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 196 const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, posts_wline }, /* Aq */ |
{ NULL, posts_wline }, /* Aq */ |
{ NULL, posts_at }, /* At */ |
{ NULL, posts_at }, /* At */ |
{ NULL, NULL }, /* Bc */ |
{ NULL, NULL }, /* Bc */ |
{ NULL, NULL }, /* Bf */ |
{ NULL, posts_bf }, /* Bf */ |
{ NULL, NULL }, /* Bo */ |
{ NULL, NULL }, /* Bo */ |
{ NULL, posts_wline }, /* Bq */ |
{ NULL, posts_wline }, /* Bq */ |
{ NULL, NULL }, /* Bsx */ |
{ NULL, NULL }, /* Bsx */ |
Line 253 post_check_children_count(struct mdoc *mdoc) |
|
Line 261 post_check_children_count(struct mdoc *mdoc) |
|
|
|
|
|
static int |
static int |
post_check_children_gt(struct mdoc *mdoc, int sz) |
post_check_children_wgt(struct mdoc *mdoc, const char *p, int sz) |
{ |
{ |
int i; |
int i; |
|
|
if ((i = post_check_children_count(mdoc)) > sz) |
if ((i = post_check_children_count(mdoc)) > sz) |
return(1); |
return(1); |
|
return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests more " |
|
"than %d %s (has %d)", sz, p, i)); |
|
} |
|
|
|
|
|
static int |
|
post_check_children_gt(struct mdoc *mdoc, const char *p, int sz) |
|
{ |
|
int i; |
|
|
|
if ((i = post_check_children_count(mdoc)) > sz) |
|
return(1); |
return(mdoc_err(mdoc, "macro requires more than %d " |
return(mdoc_err(mdoc, "macro requires more than %d " |
"parameters (have %d)", sz, i)); |
"%s (has %d)", sz, p, i)); |
} |
} |
|
|
|
|
static int |
static int |
post_check_children_eq(struct mdoc *mdoc, int sz) |
post_check_children_weq(struct mdoc *mdoc, const char *p, int sz) |
{ |
{ |
int i; |
int i; |
|
|
if ((i = post_check_children_count(mdoc)) == sz) |
if ((i = post_check_children_count(mdoc)) == sz) |
return(1); |
return(1); |
return(mdoc_err(mdoc, "macro requires %d parameters " |
return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests %d " |
"(have %d)", sz, i)); |
"%s (has %d)", sz, p, i)); |
} |
} |
|
|
|
|
static int |
static int |
post_check_children_lt(struct mdoc *mdoc, int sz) |
post_check_children_eq(struct mdoc *mdoc, const char *p, int sz) |
{ |
{ |
int i; |
int i; |
|
|
|
if ((i = post_check_children_count(mdoc)) == sz) |
|
return(1); |
|
return(mdoc_err(mdoc, "macro requires %d %s " |
|
"(have %d)", sz, p, i)); |
|
} |
|
|
|
|
|
static int |
|
post_check_children_lt(struct mdoc *mdoc, const char *p, int sz) |
|
{ |
|
int i; |
|
|
if ((i = post_check_children_count(mdoc)) < sz) |
if ((i = post_check_children_count(mdoc)) < sz) |
return(1); |
return(1); |
return(mdoc_err(mdoc, "macro requires less than %d " |
return(mdoc_err(mdoc, "macro requires less than %d " |
"parameters (have %d)", sz, i)); |
"%s (have %d)", sz, p, i)); |
} |
} |
|
|
|
|
Line 338 berr_eq0(struct mdoc *mdoc) |
|
Line 370 berr_eq0(struct mdoc *mdoc) |
|
|
|
if (MDOC_BODY != mdoc->last->type) |
if (MDOC_BODY != mdoc->last->type) |
return(1); |
return(1); |
if (NULL == mdoc->last->child) |
return(post_check_children_eq(mdoc, "body children", 0)); |
return(1); |
|
return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests no body children")); |
|
} |
} |
|
|
|
|
Line 350 bwarn_ge1(struct mdoc *mdoc) |
|
Line 380 bwarn_ge1(struct mdoc *mdoc) |
|
|
|
if (MDOC_BODY != mdoc->last->type) |
if (MDOC_BODY != mdoc->last->type) |
return(1); |
return(1); |
if (mdoc->last->child) |
return(post_check_children_wgt(mdoc, "body children", 0)); |
return(1); |
|
return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests one or more body children")); |
|
} |
} |
|
|
|
|
static int |
static int |
|
ewarn_eq1(struct mdoc *mdoc) |
|
{ |
|
|
|
assert(MDOC_ELEM == mdoc->last->type); |
|
return(post_check_children_weq(mdoc, "parameters", 1)); |
|
} |
|
|
|
|
|
static int |
ewarn_eq0(struct mdoc *mdoc) |
ewarn_eq0(struct mdoc *mdoc) |
{ |
{ |
|
|
assert(MDOC_ELEM == mdoc->last->type); |
assert(MDOC_ELEM == mdoc->last->type); |
if (NULL == mdoc->last->child) |
return(post_check_children_weq(mdoc, "parameters", 0)); |
return(1); |
|
return(mdoc_pwarn(mdoc, mdoc->last->child->line, |
|
mdoc->last->child->pos, WARN_SYNTAX, "macro suggests no parameters")); |
|
} |
} |
|
|
|
|
Line 373 ewarn_ge1(struct mdoc *mdoc) |
|
Line 407 ewarn_ge1(struct mdoc *mdoc) |
|
{ |
{ |
|
|
assert(MDOC_ELEM == mdoc->last->type); |
assert(MDOC_ELEM == mdoc->last->type); |
if (mdoc->last->child) |
return(post_check_children_wgt(mdoc, "parameters", 0)); |
return(1); |
|
return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests one or more parameters")); |
|
} |
} |
|
|
|
|
Line 384 eerr_eq1(struct mdoc *mdoc) |
|
Line 416 eerr_eq1(struct mdoc *mdoc) |
|
{ |
{ |
|
|
assert(MDOC_ELEM == mdoc->last->type); |
assert(MDOC_ELEM == mdoc->last->type); |
return(post_check_children_eq(mdoc, 1)); |
return(post_check_children_eq(mdoc, "parameters", 1)); |
} |
} |
|
|
|
|
Line 393 eerr_le2(struct mdoc *mdoc) |
|
Line 425 eerr_le2(struct mdoc *mdoc) |
|
{ |
{ |
|
|
assert(MDOC_ELEM == mdoc->last->type); |
assert(MDOC_ELEM == mdoc->last->type); |
return(post_check_children_lt(mdoc, 3)); |
return(post_check_children_lt(mdoc, "parameters", 3)); |
} |
} |
|
|
|
|
Line 402 eerr_le1(struct mdoc *mdoc) |
|
Line 434 eerr_le1(struct mdoc *mdoc) |
|
{ |
{ |
|
|
assert(MDOC_ELEM == mdoc->last->type); |
assert(MDOC_ELEM == mdoc->last->type); |
return(post_check_children_lt(mdoc, 2)); |
return(post_check_children_lt(mdoc, "parameters", 2)); |
} |
} |
|
|
|
|
Line 411 eerr_eq0(struct mdoc *mdoc) |
|
Line 443 eerr_eq0(struct mdoc *mdoc) |
|
{ |
{ |
|
|
assert(MDOC_ELEM == mdoc->last->type); |
assert(MDOC_ELEM == mdoc->last->type); |
return(post_check_children_eq(mdoc, 0)); |
return(post_check_children_eq(mdoc, "parameters", 0)); |
} |
} |
|
|
|
|
Line 420 eerr_ge1(struct mdoc *mdoc) |
|
Line 452 eerr_ge1(struct mdoc *mdoc) |
|
{ |
{ |
|
|
assert(MDOC_ELEM == mdoc->last->type); |
assert(MDOC_ELEM == mdoc->last->type); |
return(post_check_children_gt(mdoc, 0)); |
return(post_check_children_gt(mdoc, "parameters", 0)); |
} |
} |
|
|
|
|
Line 430 herr_eq0(struct mdoc *mdoc) |
|
Line 462 herr_eq0(struct mdoc *mdoc) |
|
|
|
if (MDOC_HEAD != mdoc->last->type) |
if (MDOC_HEAD != mdoc->last->type) |
return(1); |
return(1); |
return(post_check_children_eq(mdoc, 0)); |
return(post_check_children_eq(mdoc, "parameters", 0)); |
} |
} |
|
|
|
|
Line 440 hwarn_ge1(struct mdoc *mdoc) |
|
Line 472 hwarn_ge1(struct mdoc *mdoc) |
|
|
|
if (MDOC_HEAD != mdoc->last->type) |
if (MDOC_HEAD != mdoc->last->type) |
return(1); |
return(1); |
if (mdoc->last->child) |
return(post_check_children_wgt(mdoc, "parameters", 0)); |
|
} |
|
|
|
|
|
static int |
|
herr_le1(struct mdoc *mdoc) |
|
{ |
|
if (MDOC_HEAD != mdoc->last->type) |
return(1); |
return(1); |
return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests one or more parameters")); |
return(post_check_children_lt(mdoc, "parameters", 2)); |
} |
} |
|
|
|
|
Line 452 herr_ge1(struct mdoc *mdoc) |
|
Line 491 herr_ge1(struct mdoc *mdoc) |
|
|
|
if (MDOC_HEAD != mdoc->last->type) |
if (MDOC_HEAD != mdoc->last->type) |
return(1); |
return(1); |
return(post_check_children_gt(mdoc, 0)); |
return(post_check_children_gt(mdoc, "parameters", 0)); |
} |
} |
|
|
|
|
Line 740 pre_prologue(struct mdoc *mdoc, struct mdoc_node *node |
|
Line 779 pre_prologue(struct mdoc *mdoc, struct mdoc_node *node |
|
|
|
|
|
static int |
static int |
|
post_bf(struct mdoc *mdoc) |
|
{ |
|
char *p; |
|
struct mdoc_node *head; |
|
|
|
if (MDOC_BLOCK != mdoc->last->type) |
|
return(1); |
|
assert(MDOC_Bf == mdoc->last->tok); |
|
head = mdoc->last->data.block.head; |
|
assert(head); |
|
|
|
if (0 == mdoc->last->data.block.argc) { |
|
if (head->child) { |
|
assert(MDOC_TEXT == head->child->type); |
|
p = head->child->data.text.string; |
|
if (xstrcmp(p, "Em")) |
|
return(1); |
|
else if (xstrcmp(p, "Li")) |
|
return(1); |
|
else if (xstrcmp(p, "Sm")) |
|
return(1); |
|
return(mdoc_nerr(mdoc, head->child, "invalid font mode")); |
|
} |
|
return(mdoc_err(mdoc, "macro expects an argument or parameter")); |
|
} |
|
if (head->child) |
|
return(mdoc_err(mdoc, "macro expects an argument or parameter")); |
|
if (1 == mdoc->last->data.block.argc) |
|
return(1); |
|
return(mdoc_err(mdoc, "macro expects an argument or parameter")); |
|
} |
|
|
|
|
|
static int |
post_nm(struct mdoc *mdoc) |
post_nm(struct mdoc *mdoc) |
{ |
{ |
|
|
Line 1003 post_root(struct mdoc *mdoc) |
|
Line 1076 post_root(struct mdoc *mdoc) |
|
if (NULL == mdoc->last->child) |
if (NULL == mdoc->last->child) |
return(mdoc_err(mdoc, "document has no data")); |
return(mdoc_err(mdoc, "document has no data")); |
if (NULL == mdoc->meta.title) |
if (NULL == mdoc->meta.title) |
return(mdoc_err(mdoc, "document has no incomplete prologue")); |
return(mdoc_err(mdoc, "document has incomplete prologue")); |
if (NULL == mdoc->meta.os) |
if (NULL == mdoc->meta.os) |
return(mdoc_err(mdoc, "document has no incomplete prologue")); |
return(mdoc_err(mdoc, "document has incomplete prologue")); |
if (0 == mdoc->meta.date) |
if (0 == mdoc->meta.date) |
return(mdoc_err(mdoc, "document has no incomplete prologue")); |
return(mdoc_err(mdoc, "document has incomplete prologue")); |
return(1); |
return(1); |
} |
} |
|
|
|
|
mdoc_valid_post(struct mdoc *mdoc) |
mdoc_valid_post(struct mdoc *mdoc) |
{ |
{ |
v_post *p; |
v_post *p; |
|
|
|
if (MDOC_VALID & mdoc->last->flags) |
|
return(1); |
|
mdoc->last->flags |= MDOC_VALID; |
|
|
if (MDOC_TEXT == mdoc->last->type) |
if (MDOC_TEXT == mdoc->last->type) |
return(1); |
return(1); |