version 1.200, 2014/01/06 22:39:25 |
version 1.216, 2014/06/20 23:02:31 |
|
|
|
|
#include "mdoc.h" |
#include "mdoc.h" |
#include "mandoc.h" |
#include "mandoc.h" |
|
#include "mandoc_aux.h" |
#include "libmdoc.h" |
#include "libmdoc.h" |
#include "libmandoc.h" |
#include "libmandoc.h" |
|
|
|
|
#define PRE_ARGS struct mdoc *mdoc, struct mdoc_node *n |
#define PRE_ARGS struct mdoc *mdoc, struct mdoc_node *n |
#define POST_ARGS struct mdoc *mdoc |
#define POST_ARGS struct mdoc *mdoc |
|
|
#define NUMSIZ 32 |
|
#define DATESIZE 32 |
|
|
|
enum check_ineq { |
enum check_ineq { |
CHECK_LT, |
CHECK_LT, |
CHECK_GT, |
CHECK_GT, |
|
|
v_post *post; |
v_post *post; |
}; |
}; |
|
|
static int check_count(struct mdoc *, enum mdoc_type, |
static int check_count(struct mdoc *, enum mdoc_type, |
enum check_lvl, enum check_ineq, int); |
enum check_lvl, enum check_ineq, int); |
static int check_parent(PRE_ARGS, enum mdoct, enum mdoc_type); |
static int check_parent(PRE_ARGS, enum mdoct, enum mdoc_type); |
static void check_text(struct mdoc *, int, int, char *); |
static void check_text(struct mdoc *, int, int, char *); |
static void check_argv(struct mdoc *, |
static void check_argv(struct mdoc *, |
struct mdoc_node *, struct mdoc_argv *); |
struct mdoc_node *, struct mdoc_argv *); |
static void check_args(struct mdoc *, struct mdoc_node *); |
static void check_args(struct mdoc *, struct mdoc_node *); |
static int concat(char *, const struct mdoc_node *, size_t); |
|
static enum mdoc_sec a2sec(const char *); |
static enum mdoc_sec a2sec(const char *); |
static size_t macro2len(enum mdoct); |
static size_t macro2len(enum mdoct); |
|
|
Line 187 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 184 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ pres_dd, posts_dd }, /* Dd */ |
{ pres_dd, posts_dd }, /* Dd */ |
{ pres_dt, posts_dt }, /* Dt */ |
{ pres_dt, posts_dt }, /* Dt */ |
{ pres_os, posts_os }, /* Os */ |
{ pres_os, posts_os }, /* Os */ |
{ pres_sh, posts_sh }, /* Sh */ |
{ pres_sh, posts_sh }, /* Sh */ |
{ pres_ss, posts_ss }, /* Ss */ |
{ pres_ss, posts_ss }, /* Ss */ |
{ pres_pp, posts_pp }, /* Pp */ |
{ pres_pp, posts_pp }, /* Pp */ |
{ pres_d1, posts_d1 }, /* D1 */ |
{ pres_d1, posts_d1 }, /* D1 */ |
{ pres_dl, posts_dl }, /* Dl */ |
{ pres_dl, posts_dl }, /* Dl */ |
{ pres_bd, posts_bd }, /* Bd */ |
{ pres_bd, posts_bd }, /* Bd */ |
{ NULL, NULL }, /* Ed */ |
{ NULL, NULL }, /* Ed */ |
{ pres_bl, posts_bl }, /* Bl */ |
{ pres_bl, posts_bl }, /* Bl */ |
{ NULL, NULL }, /* El */ |
{ NULL, NULL }, /* El */ |
{ pres_it, posts_it }, /* It */ |
{ pres_it, posts_it }, /* It */ |
{ NULL, NULL }, /* Ad */ |
{ NULL, NULL }, /* Ad */ |
{ pres_an, posts_an }, /* An */ |
{ pres_an, posts_an }, /* An */ |
{ NULL, posts_defaults }, /* Ar */ |
{ NULL, posts_defaults }, /* Ar */ |
{ NULL, NULL }, /* Cd */ |
{ NULL, NULL }, /* Cd */ |
{ NULL, NULL }, /* Cm */ |
{ NULL, NULL }, /* Cm */ |
{ NULL, NULL }, /* Dv */ |
{ NULL, NULL }, /* Dv */ |
{ NULL, NULL }, /* Er */ |
{ NULL, NULL }, /* Er */ |
{ NULL, NULL }, /* Ev */ |
{ NULL, NULL }, /* Ev */ |
{ pres_std, posts_std }, /* Ex */ |
{ pres_std, posts_std }, /* Ex */ |
{ NULL, NULL }, /* Fa */ |
{ NULL, NULL }, /* Fa */ |
{ NULL, posts_text }, /* Fd */ |
{ NULL, posts_text }, /* Fd */ |
{ NULL, NULL }, /* Fl */ |
{ NULL, NULL }, /* Fl */ |
{ NULL, NULL }, /* Fn */ |
{ NULL, NULL }, /* Fn */ |
{ NULL, NULL }, /* Ft */ |
{ NULL, NULL }, /* Ft */ |
{ NULL, NULL }, /* Ic */ |
{ NULL, NULL }, /* Ic */ |
{ NULL, posts_text1 }, /* In */ |
{ NULL, posts_text1 }, /* In */ |
{ NULL, posts_defaults }, /* Li */ |
{ NULL, posts_defaults }, /* Li */ |
{ NULL, posts_nd }, /* Nd */ |
{ NULL, posts_nd }, /* Nd */ |
{ NULL, posts_nm }, /* Nm */ |
{ NULL, posts_nm }, /* Nm */ |
Line 220 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 217 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, NULL }, /* Ot */ |
{ NULL, NULL }, /* Ot */ |
{ NULL, posts_defaults }, /* Pa */ |
{ NULL, posts_defaults }, /* Pa */ |
{ pres_std, posts_std }, /* Rv */ |
{ pres_std, posts_std }, /* Rv */ |
{ NULL, posts_st }, /* St */ |
{ NULL, posts_st }, /* St */ |
{ NULL, NULL }, /* Va */ |
{ NULL, NULL }, /* Va */ |
{ NULL, posts_vt }, /* Vt */ |
{ NULL, posts_vt }, /* Vt */ |
{ NULL, posts_text }, /* Xr */ |
{ NULL, posts_text }, /* Xr */ |
{ NULL, posts_text }, /* %A */ |
{ NULL, posts_text }, /* %A */ |
{ NULL, posts_hyphtext }, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, posts_hyphtext }, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, posts_text }, /* %D */ |
{ NULL, posts_text }, /* %D */ |
Line 238 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 235 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, NULL }, /* Ac */ |
{ NULL, NULL }, /* Ac */ |
{ NULL, NULL }, /* Ao */ |
{ NULL, NULL }, /* Ao */ |
{ NULL, NULL }, /* Aq */ |
{ NULL, NULL }, /* Aq */ |
{ NULL, posts_at }, /* At */ |
{ NULL, posts_at }, /* At */ |
{ NULL, NULL }, /* Bc */ |
{ NULL, NULL }, /* Bc */ |
{ NULL, posts_bf }, /* Bf */ |
{ NULL, posts_bf }, /* Bf */ |
{ NULL, NULL }, /* Bo */ |
{ NULL, NULL }, /* Bo */ |
Line 250 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 247 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, NULL }, /* Do */ |
{ NULL, NULL }, /* Do */ |
{ NULL, NULL }, /* Dq */ |
{ NULL, NULL }, /* Dq */ |
{ NULL, NULL }, /* Ec */ |
{ NULL, NULL }, /* Ec */ |
{ NULL, NULL }, /* Ef */ |
{ NULL, NULL }, /* Ef */ |
{ NULL, NULL }, /* Em */ |
{ NULL, NULL }, /* Em */ |
{ NULL, NULL }, /* Eo */ |
{ NULL, NULL }, /* Eo */ |
{ NULL, NULL }, /* Fx */ |
{ NULL, NULL }, /* Fx */ |
{ NULL, NULL }, /* Ms */ |
{ NULL, NULL }, /* Ms */ |
{ NULL, posts_notext }, /* No */ |
{ NULL, posts_notext }, /* No */ |
{ NULL, posts_ns }, /* Ns */ |
{ NULL, posts_ns }, /* Ns */ |
{ NULL, NULL }, /* Nx */ |
{ NULL, NULL }, /* Nx */ |
Line 272 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 269 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, NULL }, /* Sc */ |
{ NULL, NULL }, /* Sc */ |
{ NULL, NULL }, /* So */ |
{ NULL, NULL }, /* So */ |
{ NULL, NULL }, /* Sq */ |
{ NULL, NULL }, /* Sq */ |
{ NULL, posts_bool }, /* Sm */ |
{ NULL, posts_bool }, /* Sm */ |
{ NULL, posts_hyph }, /* Sx */ |
{ NULL, posts_hyph }, /* Sx */ |
{ NULL, NULL }, /* Sy */ |
{ NULL, NULL }, /* Sy */ |
{ NULL, NULL }, /* Tn */ |
{ NULL, NULL }, /* Tn */ |
{ NULL, NULL }, /* Ux */ |
{ NULL, NULL }, /* Ux */ |
{ NULL, NULL }, /* Xc */ |
{ NULL, NULL }, /* Xc */ |
{ NULL, NULL }, /* Xo */ |
{ NULL, NULL }, /* Xo */ |
{ NULL, posts_fo }, /* Fo */ |
{ NULL, posts_fo }, /* Fo */ |
{ NULL, NULL }, /* Fc */ |
{ NULL, NULL }, /* Fc */ |
{ NULL, NULL }, /* Oo */ |
{ NULL, NULL }, /* Oo */ |
{ NULL, NULL }, /* Oc */ |
{ NULL, NULL }, /* Oc */ |
{ NULL, posts_bk }, /* Bk */ |
{ NULL, posts_bk }, /* Bk */ |
Line 290 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 287 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, NULL }, /* Fr */ |
{ NULL, NULL }, /* Fr */ |
{ NULL, posts_eoln }, /* Ud */ |
{ NULL, posts_eoln }, /* Ud */ |
{ NULL, posts_lb }, /* Lb */ |
{ NULL, posts_lb }, /* Lb */ |
{ pres_pp, posts_pp }, /* Lp */ |
{ pres_pp, posts_pp }, /* Lp */ |
{ NULL, NULL }, /* Lk */ |
{ NULL, NULL }, /* Lk */ |
{ NULL, posts_defaults }, /* Mt */ |
{ NULL, posts_defaults }, /* Mt */ |
{ NULL, NULL }, /* Brq */ |
{ NULL, NULL }, /* Brq */ |
{ NULL, NULL }, /* Bro */ |
{ NULL, NULL }, /* Bro */ |
{ NULL, NULL }, /* Brc */ |
{ NULL, NULL }, /* Brc */ |
{ NULL, posts_text }, /* %C */ |
{ NULL, posts_text }, /* %C */ |
{ NULL, NULL }, /* Es */ |
{ NULL, NULL }, /* Es */ |
{ NULL, NULL }, /* En */ |
{ NULL, NULL }, /* En */ |
Line 305 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 302 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, posts_sp }, /* sp */ |
{ NULL, posts_sp }, /* sp */ |
{ NULL, posts_text1 }, /* %U */ |
{ NULL, posts_text1 }, /* %U */ |
{ NULL, NULL }, /* Ta */ |
{ NULL, NULL }, /* Ta */ |
|
{ NULL, NULL }, /* ll */ |
}; |
}; |
|
|
#define RSORD_MAX 14 /* Number of `Rs' blocks. */ |
#define RSORD_MAX 14 /* Number of `Rs' blocks. */ |
Line 332 static const char * const secnames[SEC__MAX] = { |
|
Line 330 static const char * const secnames[SEC__MAX] = { |
|
"LIBRARY", |
"LIBRARY", |
"SYNOPSIS", |
"SYNOPSIS", |
"DESCRIPTION", |
"DESCRIPTION", |
|
"CONTEXT", |
"IMPLEMENTATION NOTES", |
"IMPLEMENTATION NOTES", |
"RETURN VALUES", |
"RETURN VALUES", |
"ENVIRONMENT", |
"ENVIRONMENT", |
Line 351 static const char * const secnames[SEC__MAX] = { |
|
Line 350 static const char * const secnames[SEC__MAX] = { |
|
NULL |
NULL |
}; |
}; |
|
|
|
|
int |
int |
mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) |
mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) |
{ |
{ |
Line 359 mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) |
|
Line 359 mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) |
|
char *tp; |
char *tp; |
|
|
switch (n->type) { |
switch (n->type) { |
case (MDOC_TEXT): |
case MDOC_TEXT: |
tp = n->string; |
tp = n->string; |
line = n->line; |
line = n->line; |
pos = n->pos; |
pos = n->pos; |
check_text(mdoc, line, pos, tp); |
check_text(mdoc, line, pos, tp); |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_TBL): |
case MDOC_TBL: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_EQN): |
case MDOC_EQN: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_ROOT): |
case MDOC_ROOT: |
return(1); |
return(1); |
default: |
default: |
break; |
break; |
Line 380 mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) |
|
Line 380 mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) |
|
if (NULL == mdoc_valids[n->tok].pre) |
if (NULL == mdoc_valids[n->tok].pre) |
return(1); |
return(1); |
for (p = mdoc_valids[n->tok].pre; *p; p++) |
for (p = mdoc_valids[n->tok].pre; *p; p++) |
if ( ! (*p)(mdoc, n)) |
if ( ! (*p)(mdoc, n)) |
return(0); |
return(0); |
return(1); |
return(1); |
} |
} |
|
|
|
|
int |
int |
mdoc_valid_post(struct mdoc *mdoc) |
mdoc_valid_post(struct mdoc *mdoc) |
{ |
{ |
Line 396 mdoc_valid_post(struct mdoc *mdoc) |
|
Line 395 mdoc_valid_post(struct mdoc *mdoc) |
|
mdoc->last->flags |= MDOC_VALID; |
mdoc->last->flags |= MDOC_VALID; |
|
|
switch (mdoc->last->type) { |
switch (mdoc->last->type) { |
case (MDOC_TEXT): |
case MDOC_TEXT: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_EQN): |
case MDOC_EQN: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_TBL): |
case MDOC_TBL: |
return(1); |
return(1); |
case (MDOC_ROOT): |
case MDOC_ROOT: |
return(post_root(mdoc)); |
return(post_root(mdoc)); |
default: |
default: |
break; |
break; |
Line 411 mdoc_valid_post(struct mdoc *mdoc) |
|
Line 410 mdoc_valid_post(struct mdoc *mdoc) |
|
if (NULL == mdoc_valids[mdoc->last->tok].post) |
if (NULL == mdoc_valids[mdoc->last->tok].post) |
return(1); |
return(1); |
for (p = mdoc_valids[mdoc->last->tok].post; *p; p++) |
for (p = mdoc_valids[mdoc->last->tok].post; *p; p++) |
if ( ! (*p)(mdoc)) |
if ( ! (*p)(mdoc)) |
return(0); |
return(0); |
|
|
return(1); |
return(1); |
} |
} |
|
|
static int |
static int |
check_count(struct mdoc *mdoc, enum mdoc_type type, |
check_count(struct mdoc *mdoc, enum mdoc_type type, |
enum check_lvl lvl, enum check_ineq ineq, int val) |
enum check_lvl lvl, enum check_ineq ineq, int val) |
{ |
{ |
const char *p; |
const char *p; |
Line 426 check_count(struct mdoc *mdoc, enum mdoc_type type, |
|
Line 425 check_count(struct mdoc *mdoc, enum mdoc_type type, |
|
|
|
if (mdoc->last->type != type) |
if (mdoc->last->type != type) |
return(1); |
return(1); |
|
|
switch (ineq) { |
switch (ineq) { |
case (CHECK_LT): |
case CHECK_LT: |
p = "less than "; |
p = "less than "; |
if (mdoc->last->nchild < val) |
if (mdoc->last->nchild < val) |
return(1); |
return(1); |
break; |
break; |
case (CHECK_GT): |
case CHECK_GT: |
p = "more than "; |
p = "more than "; |
if (mdoc->last->nchild > val) |
if (mdoc->last->nchild > val) |
return(1); |
return(1); |
break; |
break; |
case (CHECK_EQ): |
case CHECK_EQ: |
p = ""; |
p = ""; |
if (val == mdoc->last->nchild) |
if (val == mdoc->last->nchild) |
return(1); |
return(1); |
Line 449 check_count(struct mdoc *mdoc, enum mdoc_type type, |
|
Line 448 check_count(struct mdoc *mdoc, enum mdoc_type type, |
|
} |
} |
|
|
t = lvl == CHECK_WARN ? MANDOCERR_ARGCWARN : MANDOCERR_ARGCOUNT; |
t = lvl == CHECK_WARN ? MANDOCERR_ARGCWARN : MANDOCERR_ARGCOUNT; |
mandoc_vmsg(t, mdoc->parse, mdoc->last->line, mdoc->last->pos, |
mandoc_vmsg(t, mdoc->parse, mdoc->last->line, |
"want %s%d children (have %d)", |
mdoc->last->pos, "want %s%d children (have %d)", |
p, val, mdoc->last->nchild); |
p, val, mdoc->last->nchild); |
return(1); |
return(1); |
} |
} |
|
|
Line 565 check_parent(PRE_ARGS, enum mdoct tok, enum mdoc_type |
|
Line 564 check_parent(PRE_ARGS, enum mdoct tok, enum mdoc_type |
|
(t == n->parent->type)) |
(t == n->parent->type)) |
return(1); |
return(1); |
|
|
mandoc_vmsg(MANDOCERR_SYNTCHILD, mdoc->parse, n->line, |
mandoc_vmsg(MANDOCERR_SYNTCHILD, mdoc->parse, |
n->pos, "want parent %s", MDOC_ROOT == t ? |
n->line, n->pos, "want parent %s", |
"<root>" : mdoc_macronames[tok]); |
MDOC_ROOT == t ? "<root>" : mdoc_macronames[tok]); |
return(0); |
return(0); |
} |
} |
|
|
Line 580 pre_display(PRE_ARGS) |
|
Line 579 pre_display(PRE_ARGS) |
|
if (MDOC_BLOCK != n->type) |
if (MDOC_BLOCK != n->type) |
return(1); |
return(1); |
|
|
for (node = mdoc->last->parent; node; node = node->parent) |
for (node = mdoc->last->parent; node; node = node->parent) |
if (MDOC_BLOCK == node->type) |
if (MDOC_BLOCK == node->type) |
if (MDOC_Bd == node->tok) |
if (MDOC_Bd == node->tok) |
break; |
break; |
Line 591 pre_display(PRE_ARGS) |
|
Line 590 pre_display(PRE_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
pre_bl(PRE_ARGS) |
pre_bl(PRE_ARGS) |
{ |
{ |
Line 613 pre_bl(PRE_ARGS) |
|
Line 611 pre_bl(PRE_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
/* |
/* |
* First figure out which kind of list to use: bind ourselves to |
* First figure out which kind of list to use: bind ourselves to |
* the first mentioned list type and warn about any remaining |
* the first mentioned list type and warn about any remaining |
* ones. If we find no list type, we default to LIST_item. |
* ones. If we find no list type, we default to LIST_item. |
*/ |
*/ |
|
|
/* LINTED */ |
|
for (i = 0; n->args && i < (int)n->args->argc; i++) { |
for (i = 0; n->args && i < (int)n->args->argc; i++) { |
lt = LIST__NONE; |
lt = LIST__NONE; |
dup = comp = 0; |
dup = comp = 0; |
width = offs = NULL; |
width = offs = NULL; |
switch (n->args->argv[i].arg) { |
switch (n->args->argv[i].arg) { |
/* Set list types. */ |
/* Set list types. */ |
case (MDOC_Bullet): |
case MDOC_Bullet: |
lt = LIST_bullet; |
lt = LIST_bullet; |
break; |
break; |
case (MDOC_Dash): |
case MDOC_Dash: |
lt = LIST_dash; |
lt = LIST_dash; |
break; |
break; |
case (MDOC_Enum): |
case MDOC_Enum: |
lt = LIST_enum; |
lt = LIST_enum; |
break; |
break; |
case (MDOC_Hyphen): |
case MDOC_Hyphen: |
lt = LIST_hyphen; |
lt = LIST_hyphen; |
break; |
break; |
case (MDOC_Item): |
case MDOC_Item: |
lt = LIST_item; |
lt = LIST_item; |
break; |
break; |
case (MDOC_Tag): |
case MDOC_Tag: |
lt = LIST_tag; |
lt = LIST_tag; |
break; |
break; |
case (MDOC_Diag): |
case MDOC_Diag: |
lt = LIST_diag; |
lt = LIST_diag; |
break; |
break; |
case (MDOC_Hang): |
case MDOC_Hang: |
lt = LIST_hang; |
lt = LIST_hang; |
break; |
break; |
case (MDOC_Ohang): |
case MDOC_Ohang: |
lt = LIST_ohang; |
lt = LIST_ohang; |
break; |
break; |
case (MDOC_Inset): |
case MDOC_Inset: |
lt = LIST_inset; |
lt = LIST_inset; |
break; |
break; |
case (MDOC_Column): |
case MDOC_Column: |
lt = LIST_column; |
lt = LIST_column; |
break; |
break; |
/* Set list arguments. */ |
/* Set list arguments. */ |
case (MDOC_Compact): |
case MDOC_Compact: |
dup = n->norm->Bl.comp; |
dup = n->norm->Bl.comp; |
comp = 1; |
comp = 1; |
break; |
break; |
case (MDOC_Width): |
case MDOC_Width: |
/* NB: this can be empty! */ |
/* NB: this can be empty! */ |
if (n->args->argv[i].sz) { |
if (n->args->argv[i].sz) { |
width = n->args->argv[i].value[0]; |
width = n->args->argv[i].value[0]; |
Line 673 pre_bl(PRE_ARGS) |
|
Line 670 pre_bl(PRE_ARGS) |
|
} |
} |
mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); |
mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); |
break; |
break; |
case (MDOC_Offset): |
case MDOC_Offset: |
/* NB: this can be empty! */ |
/* NB: this can be empty! */ |
if (n->args->argv[i].sz) { |
if (n->args->argv[i].sz) { |
offs = n->args->argv[i].value[0]; |
offs = n->args->argv[i].value[0]; |
Line 709 pre_bl(PRE_ARGS) |
|
Line 706 pre_bl(PRE_ARGS) |
|
n->norm->Bl.type = lt; |
n->norm->Bl.type = lt; |
/* Set column information, too. */ |
/* Set column information, too. */ |
if (LIST_column == lt) { |
if (LIST_column == lt) { |
n->norm->Bl.ncols = |
n->norm->Bl.ncols = |
n->args->argv[i].sz; |
n->args->argv[i].sz; |
n->norm->Bl.cols = (void *) |
n->norm->Bl.cols = (void *) |
n->args->argv[i].value; |
n->args->argv[i].value; |
} |
} |
} |
} |
|
|
/* The list type should come first. */ |
/* The list type should come first. */ |
|
|
if (n->norm->Bl.type == LIST__NONE) |
if (n->norm->Bl.type == LIST__NONE) |
if (n->norm->Bl.width || |
if (n->norm->Bl.width || |
n->norm->Bl.offs || |
n->norm->Bl.offs || |
n->norm->Bl.comp) |
n->norm->Bl.comp) |
mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST); |
mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST); |
|
|
continue; |
continue; |
Line 734 pre_bl(PRE_ARGS) |
|
Line 731 pre_bl(PRE_ARGS) |
|
n->norm->Bl.type = LIST_item; |
n->norm->Bl.type = LIST_item; |
} |
} |
|
|
/* |
/* |
* Validate the width field. Some list types don't need width |
* Validate the width field. Some list types don't need width |
* types and should be warned about them. Others should have it |
* types and should be warned about them. Others should have it |
* and must also be warned. Yet others have a default and need |
* and must also be warned. Yet others have a default and need |
Line 742 pre_bl(PRE_ARGS) |
|
Line 739 pre_bl(PRE_ARGS) |
|
*/ |
*/ |
|
|
switch (n->norm->Bl.type) { |
switch (n->norm->Bl.type) { |
case (LIST_tag): |
case LIST_tag: |
if (NULL == n->norm->Bl.width) |
if (NULL == n->norm->Bl.width) |
mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG); |
mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG); |
break; |
break; |
case (LIST_column): |
case LIST_column: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_diag): |
case LIST_diag: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_ohang): |
case LIST_ohang: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_inset): |
case LIST_inset: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_item): |
case LIST_item: |
if (n->norm->Bl.width) |
if (n->norm->Bl.width) |
mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); |
mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); |
break; |
break; |
case (LIST_bullet): |
case LIST_bullet: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_dash): |
case LIST_dash: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_hyphen): |
case LIST_hyphen: |
if (NULL == n->norm->Bl.width) |
if (NULL == n->norm->Bl.width) |
n->norm->Bl.width = "2n"; |
n->norm->Bl.width = "2n"; |
break; |
break; |
case (LIST_enum): |
case LIST_enum: |
if (NULL == n->norm->Bl.width) |
if (NULL == n->norm->Bl.width) |
n->norm->Bl.width = "3n"; |
n->norm->Bl.width = "3n"; |
break; |
break; |
Line 777 pre_bl(PRE_ARGS) |
|
Line 774 pre_bl(PRE_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
pre_bd(PRE_ARGS) |
pre_bd(PRE_ARGS) |
{ |
{ |
int i, dup, comp; |
int i, dup, comp; |
enum mdoc_disp dt; |
enum mdoc_disp dt; |
const char *offs; |
const char *offs; |
struct mdoc_node *np; |
struct mdoc_node *np; |
|
|
Line 799 pre_bd(PRE_ARGS) |
|
Line 795 pre_bd(PRE_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
/* LINTED */ |
|
for (i = 0; n->args && i < (int)n->args->argc; i++) { |
for (i = 0; n->args && i < (int)n->args->argc; i++) { |
dt = DISP__NONE; |
dt = DISP__NONE; |
dup = comp = 0; |
dup = comp = 0; |
offs = NULL; |
offs = NULL; |
|
|
switch (n->args->argv[i].arg) { |
switch (n->args->argv[i].arg) { |
case (MDOC_Centred): |
case MDOC_Centred: |
dt = DISP_centred; |
dt = DISP_centred; |
break; |
break; |
case (MDOC_Ragged): |
case MDOC_Ragged: |
dt = DISP_ragged; |
dt = DISP_ragged; |
break; |
break; |
case (MDOC_Unfilled): |
case MDOC_Unfilled: |
dt = DISP_unfilled; |
dt = DISP_unfilled; |
break; |
break; |
case (MDOC_Filled): |
case MDOC_Filled: |
dt = DISP_filled; |
dt = DISP_filled; |
break; |
break; |
case (MDOC_Literal): |
case MDOC_Literal: |
dt = DISP_literal; |
dt = DISP_literal; |
break; |
break; |
case (MDOC_File): |
case MDOC_File: |
mdoc_nmsg(mdoc, n, MANDOCERR_BADDISP); |
mdoc_nmsg(mdoc, n, MANDOCERR_BADDISP); |
return(0); |
return(0); |
case (MDOC_Offset): |
case MDOC_Offset: |
/* NB: this can be empty! */ |
/* NB: this can be empty! */ |
if (n->args->argv[i].sz) { |
if (n->args->argv[i].sz) { |
offs = n->args->argv[i].value[0]; |
offs = n->args->argv[i].value[0]; |
Line 833 pre_bd(PRE_ARGS) |
|
Line 828 pre_bd(PRE_ARGS) |
|
} |
} |
mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); |
mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); |
break; |
break; |
case (MDOC_Compact): |
case MDOC_Compact: |
comp = 1; |
comp = 1; |
dup = n->norm->Bd.comp; |
dup = n->norm->Bd.comp; |
break; |
break; |
Line 873 pre_bd(PRE_ARGS) |
|
Line 868 pre_bd(PRE_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
pre_ss(PRE_ARGS) |
pre_ss(PRE_ARGS) |
{ |
{ |
Line 883 pre_ss(PRE_ARGS) |
|
Line 877 pre_ss(PRE_ARGS) |
|
return(check_parent(mdoc, n, MDOC_Sh, MDOC_BODY)); |
return(check_parent(mdoc, n, MDOC_Sh, MDOC_BODY)); |
} |
} |
|
|
|
|
static int |
static int |
pre_sh(PRE_ARGS) |
pre_sh(PRE_ARGS) |
{ |
{ |
Line 893 pre_sh(PRE_ARGS) |
|
Line 886 pre_sh(PRE_ARGS) |
|
return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT)); |
return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT)); |
} |
} |
|
|
|
|
static int |
static int |
pre_it(PRE_ARGS) |
pre_it(PRE_ARGS) |
{ |
{ |
Line 904 pre_it(PRE_ARGS) |
|
Line 896 pre_it(PRE_ARGS) |
|
return(check_parent(mdoc, n, MDOC_Bl, MDOC_BODY)); |
return(check_parent(mdoc, n, MDOC_Bl, MDOC_BODY)); |
} |
} |
|
|
|
|
static int |
static int |
pre_an(PRE_ARGS) |
pre_an(PRE_ARGS) |
{ |
{ |
Line 912 pre_an(PRE_ARGS) |
|
Line 903 pre_an(PRE_ARGS) |
|
|
|
if (NULL == n->args) |
if (NULL == n->args) |
return(1); |
return(1); |
|
|
for (i = 1; i < (int)n->args->argc; i++) |
for (i = 1; i < (int)n->args->argc; i++) |
mdoc_pmsg(mdoc, n->args->argv[i].line, |
mdoc_pmsg(mdoc, n->args->argv[i].line, |
n->args->argv[i].pos, MANDOCERR_IGNARGV); |
n->args->argv[i].pos, MANDOCERR_IGNARGV); |
|
|
if (MDOC_Split == n->args->argv[0].arg) |
if (MDOC_Split == n->args->argv[0].arg) |
n->norm->An.auth = AUTH_split; |
n->norm->An.auth = AUTH_split; |
Line 944 pre_dt(PRE_ARGS) |
|
Line 935 pre_dt(PRE_ARGS) |
|
{ |
{ |
|
|
if (NULL == mdoc->meta.date || mdoc->meta.os) |
if (NULL == mdoc->meta.date || mdoc->meta.os) |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO); |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_ORDER); |
|
|
if (mdoc->meta.title) |
if (mdoc->meta.title) |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP); |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_REP); |
|
|
return(1); |
return(1); |
} |
} |
Line 957 pre_os(PRE_ARGS) |
|
Line 948 pre_os(PRE_ARGS) |
|
{ |
{ |
|
|
if (NULL == mdoc->meta.title || NULL == mdoc->meta.date) |
if (NULL == mdoc->meta.title || NULL == mdoc->meta.date) |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO); |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_ORDER); |
|
|
if (mdoc->meta.os) |
if (mdoc->meta.os) |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP); |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_REP); |
|
|
return(1); |
return(1); |
} |
} |
Line 970 pre_dd(PRE_ARGS) |
|
Line 961 pre_dd(PRE_ARGS) |
|
{ |
{ |
|
|
if (mdoc->meta.title || mdoc->meta.os) |
if (mdoc->meta.title || mdoc->meta.os) |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO); |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_ORDER); |
|
|
if (mdoc->meta.date) |
if (mdoc->meta.date) |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP); |
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOG_REP); |
|
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
post_bf(POST_ARGS) |
post_bf(POST_ARGS) |
{ |
{ |
Line 996 post_bf(POST_ARGS) |
|
Line 986 post_bf(POST_ARGS) |
|
np = mdoc->last->pending->parent->head; |
np = mdoc->last->pending->parent->head; |
} else if (MDOC_BLOCK != mdoc->last->type) { |
} else if (MDOC_BLOCK != mdoc->last->type) { |
np = mdoc->last->parent->head; |
np = mdoc->last->parent->head; |
} else |
} else |
np = mdoc->last->head; |
np = mdoc->last->head; |
|
|
assert(np); |
assert(np); |
Line 1009 post_bf(POST_ARGS) |
|
Line 999 post_bf(POST_ARGS) |
|
assert(MDOC_BLOCK == np->parent->type); |
assert(MDOC_BLOCK == np->parent->type); |
assert(MDOC_Bf == np->parent->tok); |
assert(MDOC_Bf == np->parent->tok); |
|
|
/* |
/* |
* Cannot have both argument and parameter. |
* Cannot have both argument and parameter. |
* If neither is specified, let it through with a warning. |
* If neither is specified, let it through with a warning. |
*/ |
*/ |
|
|
if (np->parent->args && np->child) { |
if (np->parent->args && np->child) { |
Line 1023 post_bf(POST_ARGS) |
|
Line 1013 post_bf(POST_ARGS) |
|
} |
} |
|
|
/* Extract argument into data. */ |
/* Extract argument into data. */ |
|
|
if (np->parent->args) { |
if (np->parent->args) { |
arg = np->parent->args->argv[0].arg; |
arg = np->parent->args->argv[0].arg; |
if (MDOC_Emphasis == arg) |
if (MDOC_Emphasis == arg) |
Line 1045 post_bf(POST_ARGS) |
|
Line 1035 post_bf(POST_ARGS) |
|
np->norm->Bf.font = FONT_Li; |
np->norm->Bf.font = FONT_Li; |
else if (0 == strcmp(np->child->string, "Sy")) |
else if (0 == strcmp(np->child->string, "Sy")) |
np->norm->Bf.font = FONT_Sy; |
np->norm->Bf.font = FONT_Sy; |
else |
else |
mdoc_nmsg(mdoc, np, MANDOCERR_FONTTYPE); |
mdoc_nmsg(mdoc, np, MANDOCERR_FONTTYPE); |
|
|
return(1); |
return(1); |
Line 1054 post_bf(POST_ARGS) |
|
Line 1044 post_bf(POST_ARGS) |
|
static int |
static int |
post_lb(POST_ARGS) |
post_lb(POST_ARGS) |
{ |
{ |
const char *p; |
struct mdoc_node *n; |
char *buf; |
const char *stdlibname; |
size_t sz; |
char *libname; |
|
|
check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1); |
check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1); |
|
|
assert(mdoc->last->child); |
n = mdoc->last->child; |
assert(MDOC_TEXT == mdoc->last->child->type); |
|
|
|
p = mdoc_a2lib(mdoc->last->child->string); |
assert(n); |
|
assert(MDOC_TEXT == n->type); |
|
|
/* If lookup ok, replace with table value. */ |
if (NULL == (stdlibname = mdoc_a2lib(n->string))) |
|
mandoc_asprintf(&libname, |
|
"library \\(lq%s\\(rq", n->string); |
|
else |
|
libname = mandoc_strdup(stdlibname); |
|
|
if (p) { |
free(n->string); |
free(mdoc->last->child->string); |
n->string = libname; |
mdoc->last->child->string = mandoc_strdup(p); |
|
return(1); |
|
} |
|
|
|
/* If not, use "library ``xxxx''. */ |
|
|
|
sz = strlen(mdoc->last->child->string) + |
|
2 + strlen("\\(lqlibrary\\(rq"); |
|
buf = mandoc_malloc(sz); |
|
snprintf(buf, sz, "library \\(lq%s\\(rq", |
|
mdoc->last->child->string); |
|
free(mdoc->last->child->string); |
|
mdoc->last->child->string = buf; |
|
return(1); |
return(1); |
} |
} |
|
|
Line 1094 post_eoln(POST_ARGS) |
|
Line 1075 post_eoln(POST_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
post_vt(POST_ARGS) |
post_vt(POST_ARGS) |
{ |
{ |
Line 1110 post_vt(POST_ARGS) |
|
Line 1090 post_vt(POST_ARGS) |
|
|
|
if (MDOC_BODY != mdoc->last->type) |
if (MDOC_BODY != mdoc->last->type) |
return(1); |
return(1); |
|
|
for (n = mdoc->last->child; n; n = n->next) |
for (n = mdoc->last->child; n; n = n->next) |
if (MDOC_TEXT != n->type) |
if (MDOC_TEXT != n->type) |
mdoc_nmsg(mdoc, n, MANDOCERR_CHILD); |
mdoc_nmsg(mdoc, n, MANDOCERR_CHILD); |
|
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
post_nm(POST_ARGS) |
post_nm(POST_ARGS) |
{ |
{ |
char buf[BUFSIZ]; |
|
int c; |
|
|
|
if (NULL != mdoc->meta.name) |
if (NULL != mdoc->meta.name) |
return(1); |
return(1); |
|
|
/* Try to use our children for setting the meta name. */ |
mdoc_deroff(&mdoc->meta.name, mdoc->last); |
|
|
if (NULL != mdoc->last->child) { |
if (NULL == mdoc->meta.name) { |
buf[0] = '\0'; |
|
c = concat(buf, mdoc->last->child, BUFSIZ); |
|
} else |
|
c = 0; |
|
|
|
switch (c) { |
|
case (-1): |
|
mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM); |
|
return(0); |
|
case (0): |
|
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME); |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME); |
mdoc->meta.name = mandoc_strdup("UNKNOWN"); |
mdoc->meta.name = mandoc_strdup("UNKNOWN"); |
break; |
|
default: |
|
mdoc->meta.name = mandoc_strdup(buf); |
|
break; |
|
} |
} |
return(1); |
return(1); |
} |
} |
Line 1154 post_nm(POST_ARGS) |
|
Line 1117 post_nm(POST_ARGS) |
|
static int |
static int |
post_literal(POST_ARGS) |
post_literal(POST_ARGS) |
{ |
{ |
|
|
/* |
/* |
* The `Dl' (note "el" not "one") and `Bd' macros unset the |
* The `Dl' (note "el" not "one") and `Bd' macros unset the |
* MDOC_LITERAL flag as they leave. Note that `Bd' only sets |
* MDOC_LITERAL flag as they leave. Note that `Bd' only sets |
Line 1181 post_defaults(POST_ARGS) |
|
Line 1144 post_defaults(POST_ARGS) |
|
|
|
if (mdoc->last->child) |
if (mdoc->last->child) |
return(1); |
return(1); |
|
|
nn = mdoc->last; |
nn = mdoc->last; |
mdoc->next = MDOC_NEXT_CHILD; |
mdoc->next = MDOC_NEXT_CHILD; |
|
|
switch (nn->tok) { |
switch (nn->tok) { |
case (MDOC_Ar): |
case MDOC_Ar: |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "file")) |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "file")) |
return(0); |
return(0); |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "...")) |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "...")) |
return(0); |
return(0); |
break; |
break; |
case (MDOC_At): |
case MDOC_At: |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "AT&T")) |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "AT&T")) |
return(0); |
return(0); |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "UNIX")) |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "UNIX")) |
return(0); |
return(0); |
break; |
break; |
case (MDOC_Li): |
case MDOC_Li: |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "")) |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "")) |
return(0); |
return(0); |
break; |
break; |
case (MDOC_Pa): |
case MDOC_Pa: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_Mt): |
case MDOC_Mt: |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "~")) |
if ( ! mdoc_word_alloc(mdoc, nn->line, nn->pos, "~")) |
return(0); |
return(0); |
break; |
break; |
default: |
default: |
abort(); |
abort(); |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
|
|
mdoc->last = nn; |
mdoc->last = nn; |
return(1); |
return(1); |
Line 1220 post_defaults(POST_ARGS) |
|
Line 1183 post_defaults(POST_ARGS) |
|
static int |
static int |
post_at(POST_ARGS) |
post_at(POST_ARGS) |
{ |
{ |
const char *p, *q; |
struct mdoc_node *n; |
char *buf; |
const char *std_att; |
size_t sz; |
char *att; |
|
|
/* |
/* |
* If we have a child, look it up in the standard keys. If a |
* If we have a child, look it up in the standard keys. If a |
* key exist, use that instead of the child; if it doesn't, |
* key exist, use that instead of the child; if it doesn't, |
* prefix "AT&T UNIX " to the existing data. |
* prefix "AT&T UNIX " to the existing data. |
*/ |
*/ |
|
|
if (NULL == mdoc->last->child) |
if (NULL == (n = mdoc->last->child)) |
return(1); |
return(1); |
|
|
assert(MDOC_TEXT == mdoc->last->child->type); |
assert(MDOC_TEXT == n->type); |
p = mdoc_a2att(mdoc->last->child->string); |
if (NULL == (std_att = mdoc_a2att(n->string))) { |
|
|
if (p) { |
|
free(mdoc->last->child->string); |
|
mdoc->last->child->string = mandoc_strdup(p); |
|
} else { |
|
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADATT); |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADATT); |
p = "AT&T UNIX "; |
mandoc_asprintf(&att, "AT&T UNIX %s", n->string); |
q = mdoc->last->child->string; |
} else |
sz = strlen(p) + strlen(q) + 1; |
att = mandoc_strdup(std_att); |
buf = mandoc_malloc(sz); |
|
strlcpy(buf, p, sz); |
|
strlcat(buf, q, sz); |
|
free(mdoc->last->child->string); |
|
mdoc->last->child->string = buf; |
|
} |
|
|
|
|
free(n->string); |
|
n->string = att; |
return(1); |
return(1); |
} |
} |
|
|
Line 1269 post_an(POST_ARGS) |
|
Line 1223 post_an(POST_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
post_it(POST_ARGS) |
post_it(POST_ARGS) |
{ |
{ |
Line 1290 post_it(POST_ARGS) |
|
Line 1243 post_it(POST_ARGS) |
|
} |
} |
|
|
switch (lt) { |
switch (lt) { |
case (LIST_tag): |
case LIST_tag: |
if (mdoc->last->head->child) |
if (mdoc->last->head->child) |
break; |
break; |
/* FIXME: give this a dummy value. */ |
/* FIXME: give this a dummy value. */ |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS); |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS); |
break; |
break; |
case (LIST_hang): |
case LIST_hang: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_ohang): |
case LIST_ohang: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_inset): |
case LIST_inset: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_diag): |
case LIST_diag: |
if (NULL == mdoc->last->head->child) |
if (NULL == mdoc->last->head->child) |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS); |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS); |
break; |
break; |
case (LIST_bullet): |
case LIST_bullet: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_dash): |
case LIST_dash: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_enum): |
case LIST_enum: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_hyphen): |
case LIST_hyphen: |
if (NULL == mdoc->last->body->child) |
if (NULL == mdoc->last->body->child) |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY); |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY); |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (LIST_item): |
case LIST_item: |
if (mdoc->last->head->child) |
if (mdoc->last->head->child) |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGSLOST); |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGSLOST); |
break; |
break; |
case (LIST_column): |
case LIST_column: |
cols = (int)n->norm->Bl.ncols; |
cols = (int)n->norm->Bl.ncols; |
|
|
assert(NULL == mdoc->last->head->child); |
assert(NULL == mdoc->last->head->child); |
Line 1339 post_it(POST_ARGS) |
|
Line 1292 post_it(POST_ARGS) |
|
else |
else |
er = MANDOCERR_SYNTARGCOUNT; |
er = MANDOCERR_SYNTARGCOUNT; |
|
|
mandoc_vmsg(er, mdoc->parse, mdoc->last->line, |
mandoc_vmsg(er, mdoc->parse, |
mdoc->last->pos, |
mdoc->last->line, mdoc->last->pos, |
"columns == %d (have %d)", cols, i); |
"columns == %d (have %d)", cols, i); |
return(MANDOCERR_ARGCOUNT == er); |
return(MANDOCERR_ARGCOUNT == er); |
default: |
default: |
break; |
break; |
Line 1351 post_it(POST_ARGS) |
|
Line 1304 post_it(POST_ARGS) |
|
} |
} |
|
|
static int |
static int |
post_bl_block(POST_ARGS) |
post_bl_block(POST_ARGS) |
{ |
{ |
struct mdoc_node *n, *ni, *nc; |
struct mdoc_node *n, *ni, *nc; |
|
|
Line 1365 post_bl_block(POST_ARGS) |
|
Line 1318 post_bl_block(POST_ARGS) |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
if (LIST_tag == n->norm->Bl.type && |
if (LIST_tag == n->norm->Bl.type && |
NULL == n->norm->Bl.width) { |
NULL == n->norm->Bl.width) { |
if ( ! post_bl_block_tag(mdoc)) |
if ( ! post_bl_block_tag(mdoc)) |
return(0); |
return(0); |
assert(n->norm->Bl.width); |
assert(n->norm->Bl.width); |
Line 1382 post_bl_block(POST_ARGS) |
|
Line 1335 post_bl_block(POST_ARGS) |
|
nc = ni->body->last; |
nc = ni->body->last; |
while (NULL != nc) { |
while (NULL != nc) { |
switch (nc->tok) { |
switch (nc->tok) { |
case (MDOC_Pp): |
case MDOC_Pp: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_Lp): |
case MDOC_Lp: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_br): |
case MDOC_br: |
break; |
break; |
default: |
default: |
nc = NULL; |
nc = NULL; |
Line 1415 post_bl_block_width(POST_ARGS) |
|
Line 1368 post_bl_block_width(POST_ARGS) |
|
int i; |
int i; |
enum mdoct tok; |
enum mdoct tok; |
struct mdoc_node *n; |
struct mdoc_node *n; |
char buf[NUMSIZ]; |
char buf[24]; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
Line 1441 post_bl_block_width(POST_ARGS) |
|
Line 1394 post_bl_block_width(POST_ARGS) |
|
|
|
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 (MDOC_Width == n->args->argv[i].arg) |
if (MDOC_Width == n->args->argv[i].arg) |
break; |
break; |
|
|
assert(i < (int)n->args->argc); |
assert(i < (int)n->args->argc); |
|
|
snprintf(buf, NUMSIZ, "%un", (unsigned int)width); |
(void)snprintf(buf, sizeof(buf), "%un", (unsigned int)width); |
free(n->args->argv[i].value[0]); |
free(n->args->argv[i].value[0]); |
n->args->argv[i].value[0] = mandoc_strdup(buf); |
n->args->argv[i].value[0] = mandoc_strdup(buf); |
|
|
Line 1462 post_bl_block_tag(POST_ARGS) |
|
Line 1415 post_bl_block_tag(POST_ARGS) |
|
struct mdoc_node *n, *nn; |
struct mdoc_node *n, *nn; |
size_t sz, ssz; |
size_t sz, ssz; |
int i; |
int i; |
char buf[NUMSIZ]; |
char buf[24]; |
|
|
/* |
/* |
* Calculate the -width for a `Bl -tag' list if it hasn't been |
* Calculate the -width for a `Bl -tag' list if it hasn't been |
Line 1493 post_bl_block_tag(POST_ARGS) |
|
Line 1446 post_bl_block_tag(POST_ARGS) |
|
sz = ssz; |
sz = ssz; |
|
|
break; |
break; |
} |
} |
|
|
/* Defaults to ten ens. */ |
/* Defaults to ten ens. */ |
|
|
snprintf(buf, NUMSIZ, "%un", (unsigned int)sz); |
(void)snprintf(buf, sizeof(buf), "%un", (unsigned int)sz); |
|
|
/* |
/* |
* We have to dynamically add this to the macro's argument list. |
* We have to dynamically add this to the macro's argument list. |
Line 1507 post_bl_block_tag(POST_ARGS) |
|
Line 1460 post_bl_block_tag(POST_ARGS) |
|
assert(n->args); |
assert(n->args); |
i = (int)(n->args->argc)++; |
i = (int)(n->args->argc)++; |
|
|
n->args->argv = mandoc_realloc(n->args->argv, |
n->args->argv = mandoc_reallocarray(n->args->argv, |
n->args->argc * sizeof(struct mdoc_argv)); |
n->args->argc, sizeof(struct mdoc_argv)); |
|
|
n->args->argv[i].arg = MDOC_Width; |
n->args->argv[i].arg = MDOC_Width; |
n->args->argv[i].line = n->line; |
n->args->argv[i].line = n->line; |
Line 1522 post_bl_block_tag(POST_ARGS) |
|
Line 1475 post_bl_block_tag(POST_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
post_bl_head(POST_ARGS) |
post_bl_head(POST_ARGS) |
{ |
{ |
struct mdoc_node *np, *nn, *nnp; |
struct mdoc_node *np, *nn, *nnp; |
int i, j; |
int i, j; |
Line 1541 post_bl_head(POST_ARGS) |
|
Line 1493 post_bl_head(POST_ARGS) |
|
|
|
/* First, disallow both types and allow normal-form. */ |
/* First, disallow both types and allow normal-form. */ |
|
|
/* |
/* |
* TODO: technically, we can accept both and just merge the two |
* TODO: technically, we can accept both and just merge the two |
* lists, but I'll leave that for another day. |
* lists, but I'll leave that for another day. |
*/ |
*/ |
Line 1555 post_bl_head(POST_ARGS) |
|
Line 1507 post_bl_head(POST_ARGS) |
|
np = mdoc->last->parent; |
np = mdoc->last->parent; |
assert(np->args); |
assert(np->args); |
|
|
for (j = 0; j < (int)np->args->argc; j++) |
for (j = 0; j < (int)np->args->argc; j++) |
if (MDOC_Column == np->args->argv[j].arg) |
if (MDOC_Column == np->args->argv[j].arg) |
break; |
break; |
|
|
Line 1569 post_bl_head(POST_ARGS) |
|
Line 1521 post_bl_head(POST_ARGS) |
|
*/ |
*/ |
|
|
np->args->argv[j].sz = (size_t)mdoc->last->nchild; |
np->args->argv[j].sz = (size_t)mdoc->last->nchild; |
np->args->argv[j].value = mandoc_malloc |
np->args->argv[j].value = mandoc_reallocarray(NULL, |
((size_t)mdoc->last->nchild * sizeof(char *)); |
(size_t)mdoc->last->nchild, sizeof(char *)); |
|
|
mdoc->last->norm->Bl.ncols = np->args->argv[j].sz; |
mdoc->last->norm->Bl.ncols = np->args->argv[j].sz; |
mdoc->last->norm->Bl.cols = (void *)np->args->argv[j].value; |
mdoc->last->norm->Bl.cols = (void *)np->args->argv[j].value; |
Line 1598 post_bl(POST_ARGS) |
|
Line 1550 post_bl(POST_ARGS) |
|
|
|
nbody = mdoc->last; |
nbody = mdoc->last; |
switch (nbody->type) { |
switch (nbody->type) { |
case (MDOC_BLOCK): |
case MDOC_BLOCK: |
return(post_bl_block(mdoc)); |
return(post_bl_block(mdoc)); |
case (MDOC_HEAD): |
case MDOC_HEAD: |
return(post_bl_head(mdoc)); |
return(post_bl_head(mdoc)); |
case (MDOC_BODY): |
case MDOC_BODY: |
break; |
break; |
default: |
default: |
return(1); |
return(1); |
Line 1693 ebool(struct mdoc *mdoc) |
|
Line 1645 ebool(struct mdoc *mdoc) |
|
static int |
static int |
post_root(POST_ARGS) |
post_root(POST_ARGS) |
{ |
{ |
int erc; |
int ret; |
struct mdoc_node *n; |
struct mdoc_node *n; |
|
|
erc = 0; |
ret = 1; |
|
|
/* Check that we have a finished prologue. */ |
/* Check that we have a finished prologue. */ |
|
|
if ( ! (MDOC_PBODY & mdoc->flags)) { |
if ( ! (MDOC_PBODY & mdoc->flags)) { |
erc++; |
ret = 0; |
mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCPROLOG); |
mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCPROLOG); |
} |
} |
|
|
n = mdoc->first; |
n = mdoc->first; |
assert(n); |
assert(n); |
|
|
/* Check that we begin with a proper `Sh'. */ |
/* Check that we begin with a proper `Sh'. */ |
|
|
if (NULL == n->child) { |
if (NULL == n->child) |
erc++; |
mdoc_nmsg(mdoc, n, MANDOCERR_DOC_EMPTY); |
mdoc_nmsg(mdoc, n, MANDOCERR_NODOCBODY); |
else if (MDOC_BLOCK != n->child->type || |
} else if (MDOC_BLOCK != n->child->type || |
MDOC_Sh != n->child->tok) |
MDOC_Sh != n->child->tok) { |
mdoc_nmsg(mdoc, n->child, MANDOCERR_SEC_BEFORE); |
erc++; |
|
/* Can this be lifted? See rxdebug.1 for example. */ |
|
mdoc_nmsg(mdoc, n, MANDOCERR_NODOCBODY); |
|
} |
|
|
|
return(erc ? 0 : 1); |
return(ret); |
} |
} |
|
|
static int |
static int |
Line 1755 post_rs(POST_ARGS) |
|
Line 1703 post_rs(POST_ARGS) |
|
int i, j; |
int i, j; |
|
|
switch (mdoc->last->type) { |
switch (mdoc->last->type) { |
case (MDOC_HEAD): |
case MDOC_HEAD: |
check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0); |
check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0); |
return(1); |
return(1); |
case (MDOC_BODY): |
case MDOC_BODY: |
if (mdoc->last->child) |
if (mdoc->last->child) |
break; |
break; |
check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0); |
check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0); |
Line 1812 post_rs(POST_ARGS) |
|
Line 1760 post_rs(POST_ARGS) |
|
if (rsord[i] == nn->tok) |
if (rsord[i] == nn->tok) |
break; |
break; |
|
|
/* |
/* |
* Remove `nn' from the chain. This somewhat |
* Remove `nn' from the chain. This somewhat |
* repeats mdoc_node_unlink(), but since we're |
* repeats mdoc_node_unlink(), but since we're |
* just re-ordering, there's no need for the |
* just re-ordering, there's no need for the |
* full unlink process. |
* full unlink process. |
*/ |
*/ |
|
|
if (NULL != (next = nn->next)) |
if (NULL != (next = nn->next)) |
next->prev = nn->prev; |
next->prev = nn->prev; |
|
|
Line 1827 post_rs(POST_ARGS) |
|
Line 1775 post_rs(POST_ARGS) |
|
|
|
nn->prev = nn->next = NULL; |
nn->prev = nn->next = NULL; |
|
|
/* |
/* |
* Scan back until we reach a node that's |
* Scan back until we reach a node that's |
* ordered before `nn'. |
* ordered before `nn'. |
*/ |
*/ |
Line 1876 post_hyph(POST_ARGS) |
|
Line 1824 post_hyph(POST_ARGS) |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
switch (n->type) { |
switch (n->type) { |
case (MDOC_HEAD): |
case MDOC_HEAD: |
if (MDOC_Sh == n->tok || MDOC_Ss == n->tok) |
if (MDOC_Sh == n->tok || MDOC_Ss == n->tok) |
break; |
break; |
return(1); |
return(1); |
case (MDOC_BODY): |
case MDOC_BODY: |
if (MDOC_D1 == n->tok || MDOC_Nd == n->tok) |
if (MDOC_D1 == n->tok || MDOC_Nd == n->tok) |
break; |
break; |
return(1); |
return(1); |
case (MDOC_ELEM): |
case MDOC_ELEM: |
break; |
break; |
default: |
default: |
return(1); |
return(1); |
Line 1894 post_hyph(POST_ARGS) |
|
Line 1842 post_hyph(POST_ARGS) |
|
if (MDOC_TEXT != nch->type) |
if (MDOC_TEXT != nch->type) |
continue; |
continue; |
cp = nch->string; |
cp = nch->string; |
if (3 > strnlen(cp, 3)) |
if ('\0' == *cp) |
continue; |
continue; |
while ('\0' != *(++cp)) |
while ('\0' != *(++cp)) |
if ('-' == *cp && |
if ('-' == *cp && |
Line 1964 post_sh_body(POST_ARGS) |
|
Line 1912 post_sh_body(POST_ARGS) |
|
static int |
static int |
post_sh_head(POST_ARGS) |
post_sh_head(POST_ARGS) |
{ |
{ |
char buf[BUFSIZ]; |
|
struct mdoc_node *n; |
struct mdoc_node *n; |
|
char *secname; |
enum mdoc_sec sec; |
enum mdoc_sec sec; |
int c; |
|
|
|
/* |
/* |
* Process a new section. Sections are either "named" or |
* Process a new section. Sections are either "named" or |
Line 1976 post_sh_head(POST_ARGS) |
|
Line 1923 post_sh_head(POST_ARGS) |
|
* manual sections. |
* manual sections. |
*/ |
*/ |
|
|
|
secname = NULL; |
sec = SEC_CUSTOM; |
sec = SEC_CUSTOM; |
buf[0] = '\0'; |
mdoc_deroff(&secname, mdoc->last); |
if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) { |
sec = NULL == secname ? SEC_CUSTOM : a2sec(secname); |
mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM); |
|
return(0); |
|
} else if (1 == c) |
|
sec = a2sec(buf); |
|
|
|
/* The NAME should be first. */ |
/* The NAME should be first. */ |
|
|
Line 2019 post_sh_head(POST_ARGS) |
|
Line 1963 post_sh_head(POST_ARGS) |
|
|
|
/* We don't care about custom sections after this. */ |
/* We don't care about custom sections after this. */ |
|
|
if (SEC_CUSTOM == sec) |
if (SEC_CUSTOM == sec) { |
|
free(secname); |
return(1); |
return(1); |
|
} |
|
|
/* |
/* |
* Check whether our non-custom section is being repeated or is |
* Check whether our non-custom section is being repeated or is |
Line 2042 post_sh_head(POST_ARGS) |
|
Line 1988 post_sh_head(POST_ARGS) |
|
assert(mdoc->meta.msec); |
assert(mdoc->meta.msec); |
|
|
switch (sec) { |
switch (sec) { |
case (SEC_RETURN_VALUES): |
case SEC_ERRORS: |
|
if (*mdoc->meta.msec == '4') |
|
break; |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (SEC_ERRORS): |
case SEC_RETURN_VALUES: |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (SEC_LIBRARY): |
case SEC_LIBRARY: |
if (*mdoc->meta.msec == '2') |
if (*mdoc->meta.msec == '2') |
break; |
break; |
if (*mdoc->meta.msec == '3') |
if (*mdoc->meta.msec == '3') |
break; |
break; |
|
/* FALLTHROUGH */ |
|
case SEC_CONTEXT: |
if (*mdoc->meta.msec == '9') |
if (*mdoc->meta.msec == '9') |
break; |
break; |
mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse, |
mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse, |
mdoc->last->line, mdoc->last->pos, buf); |
mdoc->last->line, mdoc->last->pos, secname); |
break; |
break; |
default: |
default: |
break; |
break; |
} |
} |
|
|
|
free(secname); |
return(1); |
return(1); |
} |
} |
|
|
Line 2095 pre_par(PRE_ARGS) |
|
Line 2046 pre_par(PRE_ARGS) |
|
if (MDOC_ELEM != n->type && MDOC_BLOCK != n->type) |
if (MDOC_ELEM != n->type && MDOC_BLOCK != n->type) |
return(1); |
return(1); |
|
|
/* |
/* |
* Don't allow prior `Lp' or `Pp' prior to a paragraph-type |
* Don't allow prior `Lp' or `Pp' prior to a paragraph-type |
* block: `Lp', `Pp', or non-compact `Bd' or `Bl'. |
* block: `Lp', `Pp', or non-compact `Bd' or `Bl'. |
*/ |
*/ |
Line 2155 pre_literal(PRE_ARGS) |
|
Line 2106 pre_literal(PRE_ARGS) |
|
*/ |
*/ |
|
|
switch (n->tok) { |
switch (n->tok) { |
case (MDOC_Dl): |
case MDOC_Dl: |
mdoc->flags |= MDOC_LITERAL; |
mdoc->flags |= MDOC_LITERAL; |
break; |
break; |
case (MDOC_Bd): |
case MDOC_Bd: |
if (DISP_literal == n->norm->Bd.type) |
if (DISP_literal == n->norm->Bd.type) |
mdoc->flags |= MDOC_LITERAL; |
mdoc->flags |= MDOC_LITERAL; |
if (DISP_unfilled == n->norm->Bd.type) |
if (DISP_unfilled == n->norm->Bd.type) |
Line 2168 pre_literal(PRE_ARGS) |
|
Line 2119 pre_literal(PRE_ARGS) |
|
abort(); |
abort(); |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
|
|
return(1); |
return(1); |
} |
} |
|
|
static int |
static int |
post_dd(POST_ARGS) |
post_dd(POST_ARGS) |
{ |
{ |
char buf[DATESIZE]; |
|
struct mdoc_node *n; |
struct mdoc_node *n; |
int c; |
char *datestr; |
|
|
if (mdoc->meta.date) |
if (mdoc->meta.date) |
free(mdoc->meta.date); |
free(mdoc->meta.date); |
Line 2189 post_dd(POST_ARGS) |
|
Line 2139 post_dd(POST_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
buf[0] = '\0'; |
datestr = NULL; |
if (-1 == (c = concat(buf, n->child, DATESIZE))) { |
mdoc_deroff(&datestr, n); |
mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM); |
if (mdoc->quick) |
return(0); |
mdoc->meta.date = datestr; |
|
else { |
|
mdoc->meta.date = mandoc_normdate(mdoc->parse, |
|
datestr, n->line, n->pos); |
|
free(datestr); |
} |
} |
|
|
assert(c); |
|
mdoc->meta.date = mdoc->quick ? mandoc_strdup(buf) : |
|
mandoc_normdate(mdoc->parse, buf, n->line, n->pos); |
|
|
|
return(1); |
return(1); |
} |
} |
|
|
Line 2227 post_dt(POST_ARGS) |
|
Line 2176 post_dt(POST_ARGS) |
|
if (toupper((unsigned char)*p) == *p) |
if (toupper((unsigned char)*p) == *p) |
continue; |
continue; |
|
|
/* |
/* |
* FIXME: don't be lazy: have this make all |
* FIXME: don't be lazy: have this make all |
* characters be uppercase and just warn once. |
* characters be uppercase and just warn once. |
*/ |
*/ |
mdoc_nmsg(mdoc, nn, MANDOCERR_UPPERCASE); |
mdoc_nmsg(mdoc, nn, MANDOCERR_TITLE_CASE); |
break; |
break; |
} |
} |
|
|
/* Handles: `.Dt' |
/* Handles: `.Dt' |
* --> title = unknown, volume = local, msec = 0, arch = NULL |
* title = unknown, volume = local, msec = 0, arch = NULL |
*/ |
*/ |
|
|
if (NULL == (nn = n->child)) { |
if (NULL == (nn = n->child)) { |
Line 2248 post_dt(POST_ARGS) |
|
Line 2197 post_dt(POST_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
/* Handles: `.Dt TITLE' |
/* Handles: `.Dt TITLE' |
* --> title = TITLE, volume = local, msec = 0, arch = NULL |
* title = TITLE, volume = local, msec = 0, arch = NULL |
*/ |
*/ |
|
|
mdoc->meta.title = mandoc_strdup |
mdoc->meta.title = mandoc_strdup( |
('\0' == nn->string[0] ? "UNKNOWN" : nn->string); |
'\0' == nn->string[0] ? "UNKNOWN" : nn->string); |
|
|
if (NULL == (nn = nn->next)) { |
if (NULL == (nn = nn->next)) { |
/* FIXME: warn about missing msec. */ |
/* FIXME: warn about missing msec. */ |
Line 2264 post_dt(POST_ARGS) |
|
Line 2213 post_dt(POST_ARGS) |
|
} |
} |
|
|
/* Handles: `.Dt TITLE SEC' |
/* Handles: `.Dt TITLE SEC' |
* --> title = TITLE, volume = SEC is msec ? |
* title = TITLE, |
* format(msec) : SEC, |
* volume = SEC is msec ? format(msec) : SEC, |
* msec = SEC is msec ? atoi(msec) : 0, |
* msec = SEC is msec ? atoi(msec) : 0, |
* arch = NULL |
* arch = NULL |
*/ |
*/ |
|
|
cp = mandoc_a2msec(nn->string); |
cp = mandoc_a2msec(nn->string); |
Line 2275 post_dt(POST_ARGS) |
|
Line 2224 post_dt(POST_ARGS) |
|
mdoc->meta.vol = mandoc_strdup(cp); |
mdoc->meta.vol = mandoc_strdup(cp); |
mdoc->meta.msec = mandoc_strdup(nn->string); |
mdoc->meta.msec = mandoc_strdup(nn->string); |
} else { |
} else { |
mdoc_nmsg(mdoc, n, MANDOCERR_BADMSEC); |
mdoc_nmsg(mdoc, n, MANDOCERR_MSEC_BAD); |
mdoc->meta.vol = mandoc_strdup(nn->string); |
mdoc->meta.vol = mandoc_strdup(nn->string); |
mdoc->meta.msec = mandoc_strdup(nn->string); |
mdoc->meta.msec = mandoc_strdup(nn->string); |
} |
} |
|
|
if (NULL == (nn = nn->next)) |
if (NULL == (nn = nn->next)) |
return(1); |
return(1); |
|
|
/* Handles: `.Dt TITLE SEC VOL' |
/* Handles: `.Dt TITLE SEC VOL' |
* --> title = TITLE, volume = VOL is vol ? |
* title = TITLE, |
* format(VOL) : |
* volume = VOL is vol ? format(VOL) : |
* VOL is arch ? format(arch) : |
* VOL is arch ? format(arch) : |
* VOL |
* VOL |
*/ |
*/ |
|
|
cp = mdoc_a2vol(nn->string); |
cp = mdoc_a2vol(nn->string); |
Line 2297 post_dt(POST_ARGS) |
|
Line 2246 post_dt(POST_ARGS) |
|
} else { |
} else { |
cp = mdoc_a2arch(nn->string); |
cp = mdoc_a2arch(nn->string); |
if (NULL == cp) { |
if (NULL == cp) { |
mdoc_nmsg(mdoc, nn, MANDOCERR_BADVOLARCH); |
mdoc_nmsg(mdoc, nn, MANDOCERR_ARCH_BAD); |
free(mdoc->meta.vol); |
free(mdoc->meta.vol); |
mdoc->meta.vol = mandoc_strdup(nn->string); |
mdoc->meta.vol = mandoc_strdup(nn->string); |
} else |
} else |
mdoc->meta.arch = mandoc_strdup(cp); |
mdoc->meta.arch = mandoc_strdup(cp); |
} |
} |
|
|
/* Ignore any subsequent parameters... */ |
/* Ignore any subsequent parameters... */ |
/* FIXME: warn about subsequent parameters. */ |
/* FIXME: warn about subsequent parameters. */ |
Line 2331 post_bx(POST_ARGS) |
|
Line 2280 post_bx(POST_ARGS) |
|
{ |
{ |
struct mdoc_node *n; |
struct mdoc_node *n; |
|
|
/* |
/* |
* Make `Bx's second argument always start with an uppercase |
* Make `Bx's second argument always start with an uppercase |
* letter. Groff checks if it's an "accepted" term, but we just |
* letter. Groff checks if it's an "accepted" term, but we just |
* uppercase blindly. |
* uppercase blindly. |
Line 2339 post_bx(POST_ARGS) |
|
Line 2288 post_bx(POST_ARGS) |
|
|
|
n = mdoc->last->child; |
n = mdoc->last->child; |
if (n && NULL != (n = n->next)) |
if (n && NULL != (n = n->next)) |
*n->string = (char)toupper |
*n->string = (char)toupper((unsigned char)*n->string); |
((unsigned char)*n->string); |
|
|
|
return(1); |
return(1); |
} |
} |
Line 2348 post_bx(POST_ARGS) |
|
Line 2296 post_bx(POST_ARGS) |
|
static int |
static int |
post_os(POST_ARGS) |
post_os(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
|
char buf[BUFSIZ]; |
|
int c; |
|
#ifndef OSNAME |
#ifndef OSNAME |
struct utsname utsname; |
struct utsname utsname; |
|
static char *defbuf; |
#endif |
#endif |
|
struct mdoc_node *n; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
Line 2364 post_os(POST_ARGS) |
|
Line 2311 post_os(POST_ARGS) |
|
* 2. the -Ios=foo command line argument, if provided |
* 2. the -Ios=foo command line argument, if provided |
* 3. -DOSNAME="\"foo\"", if provided during compilation |
* 3. -DOSNAME="\"foo\"", if provided during compilation |
* 4. "sysname release" from uname(3) |
* 4. "sysname release" from uname(3) |
*/ |
*/ |
|
|
free(mdoc->meta.os); |
free(mdoc->meta.os); |
|
mdoc->meta.os = NULL; |
|
mdoc_deroff(&mdoc->meta.os, n); |
|
if (mdoc->meta.os) |
|
return(1); |
|
|
buf[0] = '\0'; |
if (mdoc->defos) { |
if (-1 == (c = concat(buf, n->child, BUFSIZ))) { |
mdoc->meta.os = mandoc_strdup(mdoc->defos); |
mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM); |
return(1); |
return(0); |
|
} |
} |
|
|
assert(c); |
|
|
|
if ('\0' == buf[0]) { |
|
if (mdoc->defos) { |
|
mdoc->meta.os = mandoc_strdup(mdoc->defos); |
|
return(1); |
|
} |
|
#ifdef OSNAME |
#ifdef OSNAME |
if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) { |
mdoc->meta.os = mandoc_strdup(OSNAME); |
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
|
#else /*!OSNAME */ |
#else /*!OSNAME */ |
|
if (NULL == defbuf) { |
if (-1 == uname(&utsname)) { |
if (-1 == uname(&utsname)) { |
mdoc_nmsg(mdoc, n, MANDOCERR_UNAME); |
mdoc_nmsg(mdoc, n, MANDOCERR_UNAME); |
mdoc->meta.os = mandoc_strdup("UNKNOWN"); |
defbuf = mandoc_strdup("UNKNOWN"); |
return(post_prol(mdoc)); |
} else |
} |
mandoc_asprintf(&defbuf, "%s %s", |
|
utsname.sysname, utsname.release); |
if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) { |
|
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
|
if (strlcat(buf, " ", BUFSIZ) >= BUFSIZ) { |
|
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
|
if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) { |
|
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
|
#endif /*!OSNAME*/ |
|
} |
} |
|
mdoc->meta.os = mandoc_strdup(defbuf); |
mdoc->meta.os = mandoc_strdup(buf); |
#endif /*!OSNAME*/ |
return(1); |
return(1); |
} |
} |
|
|
Line 2430 post_std(POST_ARGS) |
|
Line 2358 post_std(POST_ARGS) |
|
|
|
if (NULL == mdoc->meta.name) |
if (NULL == mdoc->meta.name) |
return(1); |
return(1); |
|
|
nn = n; |
nn = n; |
mdoc->next = MDOC_NEXT_CHILD; |
mdoc->next = MDOC_NEXT_CHILD; |
|
|
Line 2441 post_std(POST_ARGS) |
|
Line 2369 post_std(POST_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
/* |
static enum mdoc_sec |
* Concatenate a node, stopping at the first non-text. |
|
* Concatenation is separated by a single whitespace. |
|
* Returns -1 on fatal (string overrun) error, 0 if child nodes were |
|
* encountered, 1 otherwise. |
|
*/ |
|
static int |
|
concat(char *p, const struct mdoc_node *n, size_t sz) |
|
{ |
|
|
|
for ( ; NULL != n; n = n->next) { |
|
if (MDOC_TEXT != n->type) |
|
return(0); |
|
if ('\0' != p[0] && strlcat(p, " ", sz) >= sz) |
|
return(-1); |
|
if (strlcat(p, n->string, sz) >= sz) |
|
return(-1); |
|
concat(p, n->child, sz); |
|
} |
|
|
|
return(1); |
|
} |
|
|
|
static enum mdoc_sec |
|
a2sec(const char *p) |
a2sec(const char *p) |
{ |
{ |
int i; |
int i; |
|
|
for (i = 0; i < (int)SEC__MAX; i++) |
for (i = 0; i < (int)SEC__MAX; i++) |
if (secnames[i] && 0 == strcmp(p, secnames[i])) |
if (secnames[i] && 0 == strcmp(p, secnames[i])) |
return((enum mdoc_sec)i); |
return((enum mdoc_sec)i); |
|
|
Line 2481 macro2len(enum mdoct macro) |
|
Line 2386 macro2len(enum mdoct macro) |
|
{ |
{ |
|
|
switch (macro) { |
switch (macro) { |
case(MDOC_Ad): |
case MDOC_Ad: |
return(12); |
return(12); |
case(MDOC_Ao): |
case MDOC_Ao: |
return(12); |
return(12); |
case(MDOC_An): |
case MDOC_An: |
return(12); |
return(12); |
case(MDOC_Aq): |
case MDOC_Aq: |
return(12); |
return(12); |
case(MDOC_Ar): |
case MDOC_Ar: |
return(12); |
return(12); |
case(MDOC_Bo): |
case MDOC_Bo: |
return(12); |
return(12); |
case(MDOC_Bq): |
case MDOC_Bq: |
return(12); |
return(12); |
case(MDOC_Cd): |
case MDOC_Cd: |
return(12); |
return(12); |
case(MDOC_Cm): |
case MDOC_Cm: |
return(10); |
return(10); |
case(MDOC_Do): |
case MDOC_Do: |
return(10); |
return(10); |
case(MDOC_Dq): |
case MDOC_Dq: |
return(12); |
return(12); |
case(MDOC_Dv): |
case MDOC_Dv: |
return(12); |
return(12); |
case(MDOC_Eo): |
case MDOC_Eo: |
return(12); |
return(12); |
case(MDOC_Em): |
case MDOC_Em: |
return(10); |
return(10); |
case(MDOC_Er): |
case MDOC_Er: |
return(17); |
return(17); |
case(MDOC_Ev): |
case MDOC_Ev: |
return(15); |
return(15); |
case(MDOC_Fa): |
case MDOC_Fa: |
return(12); |
return(12); |
case(MDOC_Fl): |
case MDOC_Fl: |
return(10); |
return(10); |
case(MDOC_Fo): |
case MDOC_Fo: |
return(16); |
return(16); |
case(MDOC_Fn): |
case MDOC_Fn: |
return(16); |
return(16); |
case(MDOC_Ic): |
case MDOC_Ic: |
return(10); |
return(10); |
case(MDOC_Li): |
case MDOC_Li: |
return(16); |
return(16); |
case(MDOC_Ms): |
case MDOC_Ms: |
return(6); |
return(6); |
case(MDOC_Nm): |
case MDOC_Nm: |
return(10); |
return(10); |
case(MDOC_No): |
case MDOC_No: |
return(12); |
return(12); |
case(MDOC_Oo): |
case MDOC_Oo: |
return(10); |
return(10); |
case(MDOC_Op): |
case MDOC_Op: |
return(14); |
return(14); |
case(MDOC_Pa): |
case MDOC_Pa: |
return(32); |
return(32); |
case(MDOC_Pf): |
case MDOC_Pf: |
return(12); |
return(12); |
case(MDOC_Po): |
case MDOC_Po: |
return(12); |
return(12); |
case(MDOC_Pq): |
case MDOC_Pq: |
return(12); |
return(12); |
case(MDOC_Ql): |
case MDOC_Ql: |
return(16); |
return(16); |
case(MDOC_Qo): |
case MDOC_Qo: |
return(12); |
return(12); |
case(MDOC_So): |
case MDOC_So: |
return(12); |
return(12); |
case(MDOC_Sq): |
case MDOC_Sq: |
return(12); |
return(12); |
case(MDOC_Sy): |
case MDOC_Sy: |
return(6); |
return(6); |
case(MDOC_Sx): |
case MDOC_Sx: |
return(16); |
return(16); |
case(MDOC_Tn): |
case MDOC_Tn: |
return(10); |
return(10); |
case(MDOC_Va): |
case MDOC_Va: |
return(12); |
return(12); |
case(MDOC_Vt): |
case MDOC_Vt: |
return(12); |
return(12); |
case(MDOC_Xr): |
case MDOC_Xr: |
return(10); |
return(10); |
default: |
default: |
break; |
break; |