version 1.158, 2014/12/18 03:10:11 |
version 1.164, 2015/02/01 23:56:37 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
Line 363 rew_dohalt(enum mdoct tok, enum mdoc_type type, |
|
Line 363 rew_dohalt(enum mdoct tok, enum mdoc_type type, |
|
* When starting to rewind, skip plain text |
* When starting to rewind, skip plain text |
* and nodes that have already been rewound. |
* and nodes that have already been rewound. |
*/ |
*/ |
if (MDOC_TEXT == p->type || MDOC_VALID & p->flags) |
if (p->type == MDOC_TEXT || p->flags & (MDOC_VALID | MDOC_BREAK)) |
return(REWIND_MORE); |
return(REWIND_MORE); |
|
|
/* |
/* |
|
|
rew_sub(enum mdoc_type t, struct mdoc *mdoc, |
rew_sub(enum mdoc_type t, struct mdoc *mdoc, |
enum mdoct tok, int line, int ppos) |
enum mdoct tok, int line, int ppos) |
{ |
{ |
struct mdoc_node *n; |
struct mdoc_node *n, *to; |
|
|
|
to = NULL; |
n = mdoc->last; |
n = mdoc->last; |
while (n) { |
while (n) { |
switch (rew_dohalt(tok, t, n)) { |
switch (rew_dohalt(tok, t, n)) { |
case REWIND_NONE: |
case REWIND_NONE: |
return; |
if (to == NULL) |
|
return; |
|
n = to; |
|
break; |
case REWIND_THIS: |
case REWIND_THIS: |
n->lastline = line - |
n->lastline = line - |
(mdoc->flags & MDOC_NEWLINE && |
(mdoc->flags & MDOC_NEWLINE && |
Line 571 rew_sub(enum mdoc_type t, struct mdoc *mdoc, |
|
Line 575 rew_sub(enum mdoc_type t, struct mdoc *mdoc, |
|
case REWIND_MORE: |
case REWIND_MORE: |
n->lastline = line - |
n->lastline = line - |
(mdoc->flags & MDOC_NEWLINE ? 1 : 0); |
(mdoc->flags & MDOC_NEWLINE ? 1 : 0); |
|
to = n; |
n = n->parent; |
n = n->parent; |
continue; |
continue; |
case REWIND_LATER: |
case REWIND_LATER: |
Line 713 blk_exp_close(MACRO_PROT_ARGS) |
|
Line 718 blk_exp_close(MACRO_PROT_ARGS) |
|
struct mdoc_node *later; /* A sub-block starting later. */ |
struct mdoc_node *later; /* A sub-block starting later. */ |
struct mdoc_node *n; /* For searching backwards. */ |
struct mdoc_node *n; /* For searching backwards. */ |
|
|
int j, lastarg, maxargs, flushed, nl; |
int flushed, have_it, j, lastarg, maxargs, nl; |
enum margserr ac; |
enum margserr ac; |
enum mdoct atok, ntok; |
enum mdoct atok, ntok; |
char *p; |
char *p; |
Line 737 blk_exp_close(MACRO_PROT_ARGS) |
|
Line 742 blk_exp_close(MACRO_PROT_ARGS) |
|
* both of our own and of pending sub-blocks. |
* both of our own and of pending sub-blocks. |
*/ |
*/ |
|
|
|
have_it = 0; |
atok = rew_alt(tok); |
atok = rew_alt(tok); |
body = endbody = later = NULL; |
body = endbody = later = NULL; |
for (n = mdoc->last; n; n = n->parent) { |
for (n = mdoc->last; n; n = n->parent) { |
if (n->flags & MDOC_VALID) |
if (n->flags & (MDOC_VALID | MDOC_BREAK)) |
continue; |
continue; |
|
|
/* Remember the start of our own body. */ |
/* Remember the start of our own body. */ |
Line 753 blk_exp_close(MACRO_PROT_ARGS) |
|
Line 759 blk_exp_close(MACRO_PROT_ARGS) |
|
|
|
if (n->type != MDOC_BLOCK || n->tok == MDOC_Nm) |
if (n->type != MDOC_BLOCK || n->tok == MDOC_Nm) |
continue; |
continue; |
|
|
|
if (n->tok == MDOC_It) { |
|
have_it = 1; |
|
continue; |
|
} |
|
|
if (atok == n->tok) { |
if (atok == n->tok) { |
assert(body); |
assert(body); |
|
|
Line 762 blk_exp_close(MACRO_PROT_ARGS) |
|
Line 774 blk_exp_close(MACRO_PROT_ARGS) |
|
* just proceed to closing out. |
* just proceed to closing out. |
*/ |
*/ |
|
|
if (later == NULL) |
if (later == NULL || |
|
(tok == MDOC_El && !have_it)) |
break; |
break; |
|
|
/* |
/* |
Line 801 blk_exp_close(MACRO_PROT_ARGS) |
|
Line 814 blk_exp_close(MACRO_PROT_ARGS) |
|
* implicit ones, the first open implicit block. |
* implicit ones, the first open implicit block. |
*/ |
*/ |
|
|
if (later && |
if (later == NULL || |
mdoc_macros[later->tok].flags & MDOC_EXPLICIT) |
! (mdoc_macros[later->tok].flags & MDOC_EXPLICIT)) |
continue; |
|
if (n->tok != MDOC_It) |
|
later = n; |
later = n; |
} |
} |
rew_sub(MDOC_BODY, mdoc, tok, line, ppos); |
rew_sub(MDOC_BODY, mdoc, tok, line, ppos); |
Line 1126 blk_full(MACRO_PROT_ARGS) |
|
Line 1137 blk_full(MACRO_PROT_ARGS) |
|
|
|
if (tok == MDOC_Nd) { |
if (tok == MDOC_Nd) { |
head = mdoc_head_alloc(mdoc, line, ppos, tok); |
head = mdoc_head_alloc(mdoc, line, ppos, tok); |
rew_sub(MDOC_HEAD, mdoc, tok, line, ppos); |
rew_last(mdoc, head); |
body = mdoc_body_alloc(mdoc, line, ppos, tok); |
body = mdoc_body_alloc(mdoc, line, ppos, tok); |
} |
} |
|
|
Line 1263 blk_part_imp(MACRO_PROT_ARGS) |
|
Line 1274 blk_part_imp(MACRO_PROT_ARGS) |
|
*/ |
*/ |
|
|
blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL); |
blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL); |
mdoc_head_alloc(mdoc, line, ppos, tok); |
rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok)); |
rew_sub(MDOC_HEAD, mdoc, tok, line, ppos); |
|
|
|
/* |
/* |
* Open the body scope "on-demand", that is, after we've |
* Open the body scope "on-demand", that is, after we've |
Line 1311 blk_part_imp(MACRO_PROT_ARGS) |
|
Line 1321 blk_part_imp(MACRO_PROT_ARGS) |
|
} |
} |
} |
} |
assert(n == body); |
assert(n == body); |
rew_sub(MDOC_BODY, mdoc, tok, line, ppos); |
rew_last(mdoc, body); |
if (nl) |
if (nl) |
append_delims(mdoc, line, pos, buf); |
append_delims(mdoc, line, pos, buf); |
rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos); |
rew_last(mdoc, blk); |
|
|
|
/* |
|
* The current block extends an enclosing block. |
|
* Now that the current block ends, close the enclosing block, too. |
|
*/ |
|
|
|
while ((blk = blk->pending) != NULL) { |
|
rew_last(mdoc, blk); |
|
if (blk->type == MDOC_HEAD) |
|
mdoc_body_alloc(mdoc, blk->line, blk->pos, blk->tok); |
|
} |
|
|
/* Move trailing .Ns out of scope. */ |
/* Move trailing .Ns out of scope. */ |
|
|
for (n = body->child; n && n->next; n = n->next) |
for (n = body->child; n && n->next; n = n->next) |
Line 1330 blk_part_exp(MACRO_PROT_ARGS) |
|
Line 1351 blk_part_exp(MACRO_PROT_ARGS) |
|
int la, nl; |
int la, nl; |
enum margserr ac; |
enum margserr ac; |
struct mdoc_node *head; /* keep track of head */ |
struct mdoc_node *head; /* keep track of head */ |
struct mdoc_node *body; /* keep track of body */ |
|
char *p; |
char *p; |
|
|
nl = MDOC_NEWLINE & mdoc->flags; |
nl = MDOC_NEWLINE & mdoc->flags; |
Line 1342 blk_part_exp(MACRO_PROT_ARGS) |
|
Line 1362 blk_part_exp(MACRO_PROT_ARGS) |
|
*/ |
*/ |
|
|
mdoc_block_alloc(mdoc, line, ppos, tok, NULL); |
mdoc_block_alloc(mdoc, line, ppos, tok, NULL); |
for (head = body = NULL; ; ) { |
head = NULL; |
|
for (;;) { |
la = *pos; |
la = *pos; |
ac = mdoc_args(mdoc, line, pos, buf, tok, &p); |
ac = mdoc_args(mdoc, line, pos, buf, tok, &p); |
if (ac == ARGS_PUNCT || ac == ARGS_EOLN) |
if (ac == ARGS_PUNCT || ac == ARGS_EOLN) |
Line 1352 blk_part_exp(MACRO_PROT_ARGS) |
|
Line 1373 blk_part_exp(MACRO_PROT_ARGS) |
|
|
|
if (head == NULL && ac != ARGS_QWORD && |
if (head == NULL && ac != ARGS_QWORD && |
mdoc_isdelim(p) == DELIM_OPEN) { |
mdoc_isdelim(p) == DELIM_OPEN) { |
assert(NULL == body); |
|
dword(mdoc, line, la, p, DELIM_OPEN, 0); |
dword(mdoc, line, la, p, DELIM_OPEN, 0); |
continue; |
continue; |
} |
} |
|
|
if (head == NULL) { |
if (head == NULL) { |
assert(body == NULL); |
|
head = mdoc_head_alloc(mdoc, line, ppos, tok); |
head = mdoc_head_alloc(mdoc, line, ppos, tok); |
} |
if (tok == MDOC_Eo) /* Not parsed. */ |
|
|
/* |
|
* `Eo' gobbles any data into the head, but most other |
|
* macros just immediately close out and begin the body. |
|
*/ |
|
|
|
if (body == NULL) { |
|
assert(head); |
|
/* No check whether it's a macro! */ |
|
if (tok == MDOC_Eo) |
|
dword(mdoc, line, la, p, DELIM_MAX, 0); |
dword(mdoc, line, la, p, DELIM_MAX, 0); |
rew_sub(MDOC_HEAD, mdoc, tok, line, ppos); |
rew_last(mdoc, head); |
body = mdoc_body_alloc(mdoc, line, ppos, tok); |
mdoc_body_alloc(mdoc, line, ppos, tok); |
if (tok == MDOC_Eo) |
if (tok == MDOC_Eo) |
continue; |
continue; |
} |
} |
assert(head != NULL && body != NULL); |
|
|
|
if (macro_or_word(mdoc, tok, line, la, pos, buf, 1)) |
if (macro_or_word(mdoc, tok, line, la, pos, buf, 1)) |
break; |
break; |
Line 1385 blk_part_exp(MACRO_PROT_ARGS) |
|
Line 1393 blk_part_exp(MACRO_PROT_ARGS) |
|
|
|
/* Clean-up to leave in a consistent state. */ |
/* Clean-up to leave in a consistent state. */ |
|
|
if (head == NULL) |
if (head == NULL) { |
mdoc_head_alloc(mdoc, line, ppos, tok); |
rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok)); |
|
|
if (body == NULL) { |
|
rew_sub(MDOC_HEAD, mdoc, tok, line, ppos); |
|
mdoc_body_alloc(mdoc, line, ppos, tok); |
mdoc_body_alloc(mdoc, line, ppos, tok); |
} |
} |
if (nl) |
if (nl) |
Line 1559 phrase_ta(MACRO_PROT_ARGS) |
|
Line 1564 phrase_ta(MACRO_PROT_ARGS) |
|
/* Make sure we are in a column list or ignore this macro. */ |
/* Make sure we are in a column list or ignore this macro. */ |
|
|
n = mdoc->last; |
n = mdoc->last; |
while (n != NULL && n->tok != MDOC_Bl) |
while (n != NULL && |
|
(n->tok != MDOC_Bl || n->flags & (MDOC_VALID | MDOC_BREAK))) |
n = n->parent; |
n = n->parent; |
if (n == NULL || n->norm->Bl.type != LIST_column) { |
if (n == NULL || n->norm->Bl.type != LIST_column) { |
mandoc_msg(MANDOCERR_TA_STRAY, mdoc->parse, |
mandoc_msg(MANDOCERR_TA_STRAY, mdoc->parse, |