version 1.341, 2018/08/25 16:53:39 |
version 1.346, 2018/12/13 02:06:07 |
|
|
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
|
|
#include "mandoc.h" |
|
#include "mandoc_aux.h" |
#include "mandoc_aux.h" |
#include "mandoc_ohash.h" |
#include "mandoc_ohash.h" |
|
#include "mandoc.h" |
#include "roff.h" |
#include "roff.h" |
#include "libmandoc.h" |
#include "libmandoc.h" |
#include "roff_int.h" |
#include "roff_int.h" |
#include "libroff.h" |
#include "libroff.h" |
|
#include "tbl_parse.h" |
|
|
/* Maximum number of string expansions per line, to break infinite loops. */ |
/* Maximum number of string expansions per line, to break infinite loops. */ |
#define EXPAND_LIMIT 1000 |
#define EXPAND_LIMIT 1000 |
Line 167 static int roffnode_cleanscope(struct roff *); |
|
Line 168 static int roffnode_cleanscope(struct roff *); |
|
static int roffnode_pop(struct roff *); |
static int roffnode_pop(struct roff *); |
static void roffnode_push(struct roff *, enum roff_tok, |
static void roffnode_push(struct roff *, enum roff_tok, |
const char *, int, int); |
const char *, int, int); |
static void roff_addtbl(struct roff_man *, struct tbl_node *); |
static void roff_addtbl(struct roff_man *, int, struct tbl_node *); |
static int roff_als(ROFF_ARGS); |
static int roff_als(ROFF_ARGS); |
static int roff_block(ROFF_ARGS); |
static int roff_block(ROFF_ARGS); |
static int roff_block_text(ROFF_ARGS); |
static int roff_block_text(ROFF_ARGS); |
Line 717 roffnode_push(struct roff *r, enum roff_tok tok, const |
|
Line 718 roffnode_push(struct roff *r, enum roff_tok tok, const |
|
static void |
static void |
roff_free1(struct roff *r) |
roff_free1(struct roff *r) |
{ |
{ |
struct tbl_node *tbl; |
|
int i; |
int i; |
|
|
while (NULL != (tbl = r->first_tbl)) { |
tbl_free(r->first_tbl); |
r->first_tbl = tbl->next; |
|
tbl_free(tbl); |
|
} |
|
r->first_tbl = r->last_tbl = r->tbl = NULL; |
r->first_tbl = r->last_tbl = r->tbl = NULL; |
|
|
if (r->last_eqn != NULL) |
if (r->last_eqn != NULL) |
Line 1013 roff_body_alloc(struct roff_man *man, int line, int po |
|
Line 1010 roff_body_alloc(struct roff_man *man, int line, int po |
|
} |
} |
|
|
static void |
static void |
roff_addtbl(struct roff_man *man, struct tbl_node *tbl) |
roff_addtbl(struct roff_man *man, int line, struct tbl_node *tbl) |
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
const struct tbl_span *span; |
struct tbl_span *span; |
|
|
if (man->macroset == MACROSET_MAN) |
if (man->macroset == MACROSET_MAN) |
man_breakscope(man, ROFF_TS); |
man_breakscope(man, ROFF_TS); |
while ((span = tbl_span(tbl)) != NULL) { |
while ((span = tbl_span(tbl)) != NULL) { |
n = roff_node_alloc(man, tbl->line, 0, ROFFT_TBL, TOKEN_NONE); |
n = roff_node_alloc(man, line, 0, ROFFT_TBL, TOKEN_NONE); |
n->span = span; |
n->span = span; |
roff_node_append(man, n); |
roff_node_append(man, n); |
n->flags |= NODE_VALID | NODE_ENDED; |
n->flags |= NODE_VALID | NODE_ENDED; |
Line 1067 roff_node_unlink(struct roff_man *man, struct roff_nod |
|
Line 1064 roff_node_unlink(struct roff_man *man, struct roff_nod |
|
} |
} |
|
|
void |
void |
|
roff_node_relink(struct roff_man *man, struct roff_node *n) |
|
{ |
|
roff_node_unlink(man, n); |
|
n->prev = n->next = NULL; |
|
roff_node_append(man, n); |
|
} |
|
|
|
void |
roff_node_free(struct roff_node *n) |
roff_node_free(struct roff_node *n) |
{ |
{ |
|
|
Line 1651 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
Line 1656 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
} |
} |
if (r->tbl != NULL && (ctl == 0 || buf->buf[pos] == '\0')) { |
if (r->tbl != NULL && (ctl == 0 || buf->buf[pos] == '\0')) { |
tbl_read(r->tbl, ln, buf->buf, ppos); |
tbl_read(r->tbl, ln, buf->buf, ppos); |
roff_addtbl(r->man, r->tbl); |
roff_addtbl(r->man, ln, r->tbl); |
return e; |
return e; |
} |
} |
if ( ! ctl) |
if ( ! ctl) |
Line 1695 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
Line 1700 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
while (buf->buf[pos] == ' ') |
while (buf->buf[pos] == ' ') |
pos++; |
pos++; |
tbl_read(r->tbl, ln, buf->buf, pos); |
tbl_read(r->tbl, ln, buf->buf, pos); |
roff_addtbl(r->man, r->tbl); |
roff_addtbl(r->man, ln, r->tbl); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
Line 1758 roff_endparse(struct roff *r) |
|
Line 1763 roff_endparse(struct roff *r) |
|
} |
} |
|
|
if (r->tbl != NULL) { |
if (r->tbl != NULL) { |
mandoc_msg(MANDOCERR_BLK_NOEND, r->parse, |
tbl_end(r->tbl, 1); |
r->tbl->line, r->tbl->pos, "TS"); |
|
tbl_end(r->tbl); |
|
r->tbl = NULL; |
r->tbl = NULL; |
} |
} |
} |
} |
Line 2107 roff_cond_sub(ROFF_ARGS) |
|
Line 2110 roff_cond_sub(ROFF_ARGS) |
|
if (ep[0] == '\\' && ep[1] == '}') |
if (ep[0] == '\\' && ep[1] == '}') |
rr = 0; |
rr = 0; |
|
|
/* Always check for the closing delimiter `\}'. */ |
/* |
|
* The closing delimiter `\}' rewinds the conditional scope |
|
* but is otherwise ignored when interpreting the line. |
|
*/ |
|
|
while ((ep = strchr(ep, '\\')) != NULL) { |
while ((ep = strchr(ep, '\\')) != NULL) { |
switch (ep[1]) { |
switch (ep[1]) { |
Line 2150 roff_cond_text(ROFF_ARGS) |
|
Line 2156 roff_cond_text(ROFF_ARGS) |
|
if (roffnode_cleanscope(r)) |
if (roffnode_cleanscope(r)) |
irc |= endloop; |
irc |= endloop; |
|
|
|
/* |
|
* If `\}' occurs on a text line with neither preceding |
|
* nor following characters, drop the line completely. |
|
*/ |
|
|
ep = buf->buf + pos; |
ep = buf->buf + pos; |
|
if (strcmp(ep, "\\}") == 0) |
|
rr = 0; |
|
|
|
/* |
|
* The closing delimiter `\}' rewinds the conditional scope |
|
* but is otherwise ignored when interpreting the line. |
|
*/ |
|
|
while ((ep = strchr(ep, '\\')) != NULL) { |
while ((ep = strchr(ep, '\\')) != NULL) { |
if (*(++ep) == '}') { |
switch (ep[1]) { |
*ep = '&'; |
case '}': |
if (roff_ccond(r, ln, ep - buf->buf - 1)) |
memmove(ep, ep + 2, strlen(ep + 2) + 1); |
|
if (roff_ccond(r, ln, ep - buf->buf)) |
irc |= endloop; |
irc |= endloop; |
} |
break; |
if (*ep != '\0') |
case '\0': |
++ep; |
++ep; |
|
break; |
|
default: |
|
ep += 2; |
|
break; |
|
} |
} |
} |
if (rr) |
if (rr) |
irc |= ROFF_CONT; |
irc |= ROFF_CONT; |
Line 3029 roff_TE(ROFF_ARGS) |
|
Line 3054 roff_TE(ROFF_ARGS) |
|
ln, ppos, "TE"); |
ln, ppos, "TE"); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
if (tbl_end(r->tbl) == 0) { |
if (tbl_end(r->tbl, 0) == 0) { |
r->tbl = NULL; |
r->tbl = NULL; |
free(buf->buf); |
free(buf->buf); |
buf->buf = mandoc_strdup(".sp"); |
buf->buf = mandoc_strdup(".sp"); |
Line 3170 roff_TS(ROFF_ARGS) |
|
Line 3195 roff_TS(ROFF_ARGS) |
|
if (r->tbl != NULL) { |
if (r->tbl != NULL) { |
mandoc_msg(MANDOCERR_BLK_BROKEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_BROKEN, r->parse, |
ln, ppos, "TS breaks TS"); |
ln, ppos, "TS breaks TS"); |
tbl_end(r->tbl); |
tbl_end(r->tbl, 0); |
} |
} |
r->tbl = tbl_alloc(ppos, ln, r->parse); |
r->tbl = tbl_alloc(ppos, ln, r->parse, r->last_tbl); |
if (r->last_tbl) |
if (r->last_tbl == NULL) |
r->last_tbl->next = r->tbl; |
|
else |
|
r->first_tbl = r->tbl; |
r->first_tbl = r->tbl; |
r->last_tbl = r->tbl; |
r->last_tbl = r->tbl; |
return ROFF_IGN; |
return ROFF_IGN; |
Line 3361 roff_char(ROFF_ARGS) |
|
Line 3384 roff_char(ROFF_ARGS) |
|
case ESCAPE_FONTITALIC: |
case ESCAPE_FONTITALIC: |
case ESCAPE_FONTBOLD: |
case ESCAPE_FONTBOLD: |
case ESCAPE_FONTBI: |
case ESCAPE_FONTBI: |
|
case ESCAPE_FONTCW: |
case ESCAPE_FONTPREV: |
case ESCAPE_FONTPREV: |
font++; |
font++; |
break; |
break; |