version 1.88, 2014/01/06 22:39:25 |
version 1.97, 2014/07/04 16:12:08 |
|
|
|
|
#include "man.h" |
#include "man.h" |
#include "mandoc.h" |
#include "mandoc.h" |
|
#include "mandoc_aux.h" |
#include "libman.h" |
#include "libman.h" |
#include "libmandoc.h" |
#include "libmandoc.h" |
|
|
Line 123 static const struct man_valid man_valids[MAN_MAX] = { |
|
Line 124 static const struct man_valid man_valids[MAN_MAX] = { |
|
{ NULL, posts_fi }, /* EE */ |
{ NULL, posts_fi }, /* EE */ |
{ NULL, posts_ur }, /* UR */ |
{ NULL, posts_ur }, /* UR */ |
{ NULL, NULL }, /* UE */ |
{ NULL, NULL }, /* UE */ |
|
{ NULL, NULL }, /* ll */ |
}; |
}; |
|
|
|
|
Line 132 man_valid_pre(struct man *man, struct man_node *n) |
|
Line 134 man_valid_pre(struct man *man, struct man_node *n) |
|
v_check *cp; |
v_check *cp; |
|
|
switch (n->type) { |
switch (n->type) { |
case (MAN_TEXT): |
case MAN_TEXT: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MAN_ROOT): |
case MAN_ROOT: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MAN_EQN): |
case MAN_EQN: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MAN_TBL): |
case MAN_TBL: |
return(1); |
return(1); |
default: |
default: |
break; |
break; |
Line 147 man_valid_pre(struct man *man, struct man_node *n) |
|
Line 149 man_valid_pre(struct man *man, struct man_node *n) |
|
if (NULL == (cp = man_valids[n->tok].pres)) |
if (NULL == (cp = man_valids[n->tok].pres)) |
return(1); |
return(1); |
for ( ; *cp; cp++) |
for ( ; *cp; cp++) |
if ( ! (*cp)(man, n)) |
if ( ! (*cp)(man, n)) |
return(0); |
return(0); |
return(1); |
return(1); |
} |
} |
|
|
|
|
int |
int |
man_valid_post(struct man *man) |
man_valid_post(struct man *man) |
{ |
{ |
Line 163 man_valid_post(struct man *man) |
|
Line 164 man_valid_post(struct man *man) |
|
man->last->flags |= MAN_VALID; |
man->last->flags |= MAN_VALID; |
|
|
switch (man->last->type) { |
switch (man->last->type) { |
case (MAN_TEXT): |
case MAN_TEXT: |
check_text(man, man->last); |
check_text(man, man->last); |
return(1); |
return(1); |
case (MAN_ROOT): |
case MAN_ROOT: |
return(check_root(man, man->last)); |
return(check_root(man, man->last)); |
case (MAN_EQN): |
case MAN_EQN: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MAN_TBL): |
case MAN_TBL: |
return(1); |
return(1); |
default: |
default: |
break; |
break; |
Line 185 man_valid_post(struct man *man) |
|
Line 186 man_valid_post(struct man *man) |
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
check_root(CHKARGS) |
check_root(CHKARGS) |
{ |
{ |
|
|
if (MAN_BLINE & man->flags) |
if (MAN_BLINE & man->flags) |
Line 198 check_root(CHKARGS) |
|
Line 198 check_root(CHKARGS) |
|
man->flags &= ~MAN_BLINE; |
man->flags &= ~MAN_BLINE; |
man->flags &= ~MAN_ELINE; |
man->flags &= ~MAN_ELINE; |
|
|
if (NULL == man->first->child) { |
if (NULL == man->first->child) |
man_nmsg(man, n, MANDOCERR_NODOCBODY); |
man_nmsg(man, n, MANDOCERR_DOC_EMPTY); |
return(0); |
else |
} else if (NULL == man->meta.title) { |
man->meta.hasbody = 1; |
man_nmsg(man, n, MANDOCERR_NOTITLE); |
|
|
|
|
if (NULL == man->meta.title) { |
|
man_nmsg(man, n, MANDOCERR_TH_MISSING); |
|
|
/* |
/* |
* If a title hasn't been set, do so now (by |
* If a title hasn't been set, do so now (by |
* implication, date and section also aren't set). |
* implication, date and section also aren't set). |
*/ |
*/ |
|
|
man->meta.title = mandoc_strdup("unknown"); |
man->meta.title = mandoc_strdup("unknown"); |
man->meta.msec = mandoc_strdup("1"); |
man->meta.msec = mandoc_strdup("1"); |
man->meta.date = man->quick ? mandoc_strdup("") : |
man->meta.date = man->quick ? mandoc_strdup("") : |
mandoc_normdate(man->parse, NULL, n->line, n->pos); |
mandoc_normdate(man->parse, NULL, n->line, n->pos); |
Line 238 check_##name(CHKARGS) \ |
|
Line 240 check_##name(CHKARGS) \ |
|
if (n->nchild ineq (x)) \ |
if (n->nchild ineq (x)) \ |
return(1); \ |
return(1); \ |
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, \ |
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, \ |
"line arguments %s %d (have %d)", \ |
"line arguments %s %d (have %d)", \ |
#ineq, (x), n->nchild); \ |
#ineq, (x), n->nchild); \ |
return(1); \ |
return(1); \ |
} |
} |
|
|
Line 272 post_ft(CHKARGS) |
|
Line 274 post_ft(CHKARGS) |
|
ok = 0; |
ok = 0; |
cp = n->child->string; |
cp = n->child->string; |
switch (*cp) { |
switch (*cp) { |
case ('1'): |
case '1': |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case ('2'): |
case '2': |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case ('3'): |
case '3': |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case ('4'): |
case '4': |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case ('I'): |
case 'I': |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case ('P'): |
case 'P': |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case ('R'): |
case 'R': |
if ('\0' == cp[1]) |
if ('\0' == cp[1]) |
ok = 1; |
ok = 1; |
break; |
break; |
case ('B'): |
case 'B': |
if ('\0' == cp[1] || ('I' == cp[1] && '\0' == cp[2])) |
if ('\0' == cp[1] || ('I' == cp[1] && '\0' == cp[2])) |
ok = 1; |
ok = 1; |
break; |
break; |
case ('C'): |
case 'C': |
if ('W' == cp[1] && '\0' == cp[2]) |
if ('W' == cp[1] && '\0' == cp[2]) |
ok = 1; |
ok = 1; |
break; |
break; |
Line 301 post_ft(CHKARGS) |
|
Line 303 post_ft(CHKARGS) |
|
} |
} |
|
|
if (0 == ok) { |
if (0 == ok) { |
mandoc_vmsg |
mandoc_vmsg(MANDOCERR_BADFONT, man->parse, n->line, |
(MANDOCERR_BADFONT, man->parse, |
n->pos, "%s", cp); |
n->line, n->pos, "%s", cp); |
|
*cp = '\0'; |
*cp = '\0'; |
} |
} |
|
|
if (1 < n->nchild) |
if (1 < n->nchild) |
mandoc_vmsg |
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, |
(MANDOCERR_ARGCOUNT, man->parse, n->line, |
n->pos, "want one child (have %d)", n->nchild); |
n->pos, "want one child (have %d)", |
|
n->nchild); |
|
|
|
return(1); |
return(1); |
} |
} |
|
|
post_sec(CHKARGS) |
post_sec(CHKARGS) |
{ |
{ |
|
|
if ( ! (MAN_HEAD == n->type && 0 == n->nchild)) |
if ( ! (MAN_HEAD == n->type && 0 == n->nchild)) |
return(1); |
return(1); |
|
|
man_nmsg(man, n, MANDOCERR_SYNTARGCOUNT); |
man_nmsg(man, n, MANDOCERR_SYNTARGCOUNT); |
Line 341 check_part(CHKARGS) |
|
Line 340 check_part(CHKARGS) |
|
{ |
{ |
|
|
if (MAN_BODY == n->type && 0 == n->nchild) |
if (MAN_BODY == n->type && 0 == n->nchild) |
mandoc_msg(MANDOCERR_ARGCWARN, man->parse, n->line, |
mandoc_msg(MANDOCERR_ARGCWARN, man->parse, n->line, |
n->pos, "want children (have none)"); |
n->pos, "want children (have none)"); |
|
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
check_par(CHKARGS) |
check_par(CHKARGS) |
{ |
{ |
|
|
switch (n->type) { |
switch (n->type) { |
case (MAN_BLOCK): |
case MAN_BLOCK: |
if (0 == n->body->nchild) |
if (0 == n->body->nchild) |
man_node_delete(man, n); |
man_node_delete(man, n); |
break; |
break; |
case (MAN_BODY): |
case MAN_BODY: |
if (0 == n->nchild) |
if (0 == n->nchild) |
man_nmsg(man, n, MANDOCERR_IGNPAR); |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
|
man->parse, n->line, n->pos, |
|
"%s empty", man_macronames[n->tok]); |
break; |
break; |
case (MAN_HEAD): |
case MAN_HEAD: |
if (n->nchild) |
if (n->nchild) |
man_nmsg(man, n, MANDOCERR_ARGSLOST); |
mandoc_vmsg(MANDOCERR_ARG_SKIP, |
|
man->parse, n->line, n->pos, |
|
"%s %s%s", man_macronames[n->tok], |
|
n->child->string, |
|
n->nchild > 1 ? " ..." : ""); |
break; |
break; |
default: |
default: |
break; |
break; |
Line 377 post_IP(CHKARGS) |
|
Line 381 post_IP(CHKARGS) |
|
{ |
{ |
|
|
switch (n->type) { |
switch (n->type) { |
case (MAN_BLOCK): |
case MAN_BLOCK: |
if (0 == n->head->nchild && 0 == n->body->nchild) |
if (0 == n->head->nchild && 0 == n->body->nchild) |
man_node_delete(man, n); |
man_node_delete(man, n); |
break; |
break; |
case (MAN_BODY): |
case MAN_BODY: |
if (0 == n->parent->head->nchild && 0 == n->nchild) |
if (0 == n->parent->head->nchild && 0 == n->nchild) |
man_nmsg(man, n, MANDOCERR_IGNPAR); |
mandoc_vmsg(MANDOCERR_PAR_SKIP, |
|
man->parse, n->line, n->pos, |
|
"%s empty", man_macronames[n->tok]); |
break; |
break; |
default: |
default: |
break; |
break; |
Line 394 post_IP(CHKARGS) |
|
Line 400 post_IP(CHKARGS) |
|
static int |
static int |
post_TH(CHKARGS) |
post_TH(CHKARGS) |
{ |
{ |
|
struct man_node *nb; |
const char *p; |
const char *p; |
|
|
free(man->meta.title); |
free(man->meta.title); |
Line 403 post_TH(CHKARGS) |
|
Line 410 post_TH(CHKARGS) |
|
free(man->meta.date); |
free(man->meta.date); |
|
|
man->meta.title = man->meta.vol = man->meta.date = |
man->meta.title = man->meta.vol = man->meta.date = |
man->meta.msec = man->meta.source = NULL; |
man->meta.msec = man->meta.source = NULL; |
|
|
|
nb = n; |
|
|
/* ->TITLE<- MSEC DATE SOURCE VOL */ |
/* ->TITLE<- MSEC DATE SOURCE VOL */ |
|
|
n = n->child; |
n = n->child; |
if (n && n->string) { |
if (n && n->string) { |
for (p = n->string; '\0' != *p; p++) { |
for (p = n->string; '\0' != *p; p++) { |
/* Only warn about this once... */ |
/* Only warn about this once... */ |
if (isalpha((unsigned char)*p) && |
if (isalpha((unsigned char)*p) && |
! isupper((unsigned char)*p)) { |
! isupper((unsigned char)*p)) { |
man_nmsg(man, n, MANDOCERR_UPPERCASE); |
mandoc_msg(MANDOCERR_TITLE_CASE, |
|
man->parse, n->line, |
|
n->pos + (p - n->string), |
|
n->string); |
break; |
break; |
} |
} |
} |
} |
Line 439 post_TH(CHKARGS) |
|
Line 451 post_TH(CHKARGS) |
|
mandoc_strdup(n->string) : |
mandoc_strdup(n->string) : |
mandoc_normdate(man->parse, n->string, |
mandoc_normdate(man->parse, n->string, |
n->line, n->pos); |
n->line, n->pos); |
} else |
} else { |
man->meta.date = mandoc_strdup(""); |
man->meta.date = mandoc_strdup(""); |
|
man_nmsg(man, n ? n : nb, MANDOCERR_DATE_MISSING); |
|
} |
|
|
/* TITLE MSEC DATE ->SOURCE<- VOL */ |
/* TITLE MSEC DATE ->SOURCE<- VOL */ |
|
|
Line 469 post_nf(CHKARGS) |
|
Line 483 post_nf(CHKARGS) |
|
{ |
{ |
|
|
if (MAN_LITERAL & man->flags) |
if (MAN_LITERAL & man->flags) |
man_nmsg(man, n, MANDOCERR_SCOPEREP); |
man_nmsg(man, n, MANDOCERR_NF_SKIP); |
|
|
man->flags |= MAN_LITERAL; |
man->flags |= MAN_LITERAL; |
return(1); |
return(1); |
Line 480 post_fi(CHKARGS) |
|
Line 494 post_fi(CHKARGS) |
|
{ |
{ |
|
|
if ( ! (MAN_LITERAL & man->flags)) |
if ( ! (MAN_LITERAL & man->flags)) |
man_nmsg(man, n, MANDOCERR_WNOSCOPE); |
man_nmsg(man, n, MANDOCERR_FI_SKIP); |
|
|
man->flags &= ~MAN_LITERAL; |
man->flags &= ~MAN_LITERAL; |
return(1); |
return(1); |
Line 570 post_vs(CHKARGS) |
|
Line 584 post_vs(CHKARGS) |
|
return(1); |
return(1); |
|
|
switch (n->parent->tok) { |
switch (n->parent->tok) { |
case (MAN_SH): |
case MAN_SH: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MAN_SS): |
case MAN_SS: |
man_nmsg(man, n, MANDOCERR_IGNPAR); |
mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos, |
|
"%s after %s", man_macronames[n->tok], |
|
man_macronames[n->parent->tok]); |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MAN_MAX): |
case MAN_MAX: |
/* |
/* |
* Don't warn about this because it occurs in pod2man |
* Don't warn about this because it occurs in pod2man |
* and would cause considerable (unfixable) warnage. |
* and would cause considerable (unfixable) warnage. |
*/ |
*/ |