version 1.98, 2010/08/20 01:02:07 |
version 1.103, 2010/12/01 10:21:25 |
|
|
#endif |
#endif |
|
|
enum rofft { |
enum rofft { |
|
ROFF_ad, |
ROFF_am, |
ROFF_am, |
ROFF_ami, |
ROFF_ami, |
ROFF_am1, |
ROFF_am1, |
|
|
ROFF_de1, |
ROFF_de1, |
ROFF_ds, |
ROFF_ds, |
ROFF_el, |
ROFF_el, |
|
ROFF_hy, |
ROFF_ie, |
ROFF_ie, |
ROFF_if, |
ROFF_if, |
ROFF_ig, |
ROFF_ig, |
|
ROFF_ne, |
|
ROFF_nh, |
ROFF_rm, |
ROFF_rm, |
ROFF_tr, |
ROFF_tr, |
ROFF_cblock, |
ROFF_cblock, |
ROFF_ccond, |
ROFF_ccond, /* FIXME: remove this. */ |
ROFF_nr, |
ROFF_nr, |
ROFF_MAX |
ROFF_MAX |
}; |
}; |
Line 130 static enum roffrule roff_evalcond(const char *, int |
|
Line 134 static enum roffrule roff_evalcond(const char *, int |
|
static void roff_freestr(struct roff *); |
static void roff_freestr(struct roff *); |
static const char *roff_getstrn(const struct roff *, |
static const char *roff_getstrn(const struct roff *, |
const char *, size_t); |
const char *, size_t); |
static enum rofferr roff_line(ROFF_ARGS); |
static enum rofferr roff_line_ignore(ROFF_ARGS); |
static enum rofferr roff_nr(ROFF_ARGS); |
static enum rofferr roff_nr(ROFF_ARGS); |
static int roff_res(struct roff *, |
static int roff_res(struct roff *, |
char **, size_t *, int); |
char **, size_t *, int); |
static void roff_setstr(struct roff *, |
static void roff_setstr(struct roff *, |
const char *, const char *); |
const char *, const char *); |
|
static char *roff_strdup(const char *); |
|
|
/* See roff_hash_find() */ |
/* See roff_hash_find() */ |
|
|
Line 146 static void roff_setstr(struct roff *, |
|
Line 151 static void roff_setstr(struct roff *, |
|
static struct roffmac *hash[HASHWIDTH]; |
static struct roffmac *hash[HASHWIDTH]; |
|
|
static struct roffmac roffs[ROFF_MAX] = { |
static struct roffmac roffs[ROFF_MAX] = { |
|
{ "ad", roff_line_ignore, NULL, NULL, 0, NULL }, |
{ "am", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "am", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "ami", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "ami", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "am1", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "am1", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
Line 154 static struct roffmac roffs[ROFF_MAX] = { |
|
Line 160 static struct roffmac roffs[ROFF_MAX] = { |
|
{ "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "ds", roff_ds, NULL, NULL, 0, NULL }, |
{ "ds", roff_ds, NULL, NULL, 0, NULL }, |
{ "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, |
{ "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, |
|
{ "hy", roff_line_ignore, NULL, NULL, 0, NULL }, |
{ "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, |
{ "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, |
{ "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, |
{ "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, |
{ "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL }, |
{ "rm", roff_line, NULL, NULL, 0, NULL }, |
{ "ne", roff_line_ignore, NULL, NULL, 0, NULL }, |
{ "tr", roff_line, NULL, NULL, 0, NULL }, |
{ "nh", roff_line_ignore, NULL, NULL, 0, NULL }, |
|
{ "rm", roff_line_ignore, NULL, NULL, 0, NULL }, |
|
{ "tr", roff_line_ignore, NULL, NULL, 0, NULL }, |
{ ".", roff_cblock, NULL, NULL, 0, NULL }, |
{ ".", roff_cblock, NULL, NULL, 0, NULL }, |
{ "\\}", roff_ccond, NULL, NULL, 0, NULL }, |
{ "\\}", roff_ccond, NULL, NULL, 0, NULL }, |
{ "nr", roff_nr, NULL, NULL, 0, NULL }, |
{ "nr", roff_nr, NULL, NULL, 0, NULL }, |
Line 247 roffnode_pop(struct roff *r) |
|
Line 256 roffnode_pop(struct roff *r) |
|
if (r->rstackpos > -1) |
if (r->rstackpos > -1) |
r->rstackpos--; |
r->rstackpos--; |
|
|
|
ROFF_DEBUG("roff: popping scope\n"); |
r->last = r->last->parent; |
r->last = r->last->parent; |
if (p->end) |
if (p->end) |
free(p->end); |
free(p->end); |
Line 425 roff_parseln(struct roff *r, int ln, char **bufp, |
|
Line 435 roff_parseln(struct roff *r, int ln, char **bufp, |
|
if (r->last) { |
if (r->last) { |
t = r->last->tok; |
t = r->last->tok; |
assert(roffs[t].sub); |
assert(roffs[t].sub); |
ROFF_DEBUG("roff: intercept scoped context: %s\n", |
ROFF_DEBUG("roff: intercept scoped context: %s, [%s]\n", |
roffs[t].name); |
roffs[t].name, &(*bufp)[pos]); |
return((*roffs[t].sub) |
return((*roffs[t].sub) |
(r, t, bufp, szp, |
(r, t, bufp, szp, |
ln, pos, pos, offs)); |
ln, pos, pos, offs)); |
Line 747 roff_cond_sub(ROFF_ARGS) |
|
Line 757 roff_cond_sub(ROFF_ARGS) |
|
{ |
{ |
enum rofft t; |
enum rofft t; |
enum roffrule rr; |
enum roffrule rr; |
struct roffnode *l; |
|
|
|
ppos = pos; |
ppos = pos; |
rr = r->last->rule; |
rr = r->last->rule; |
Line 757 roff_cond_sub(ROFF_ARGS) |
|
Line 766 roff_cond_sub(ROFF_ARGS) |
|
* continue. |
* continue. |
*/ |
*/ |
|
|
l = r->last; |
|
roffnode_cleanscope(r); |
roffnode_cleanscope(r); |
|
|
if (l != r->last) |
if (ROFF_MAX == (t = roff_parse(*bufp, &pos))) { |
|
if ('\\' == (*bufp)[pos] && '}' == (*bufp)[pos + 1]) |
|
return(roff_ccond |
|
(r, ROFF_ccond, bufp, szp, |
|
ln, pos, pos + 2, offs)); |
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); |
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); |
|
} |
|
|
if (ROFF_MAX == (t = roff_parse(*bufp, &pos))) |
|
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); |
|
|
|
/* |
/* |
* A denied conditional must evaluate its children if and only |
* A denied conditional must evaluate its children if and only |
* if they're either structurally required (such as loops and |
* if they're either structurally required (such as loops and |
Line 796 roff_cond_text(ROFF_ARGS) |
|
Line 806 roff_cond_text(ROFF_ARGS) |
|
* scope permits us to do so. |
* scope permits us to do so. |
*/ |
*/ |
|
|
|
/* FIXME: use roff_ccond? */ |
|
|
st = &(*bufp)[pos]; |
st = &(*bufp)[pos]; |
if (NULL == (ep = strstr(st, "\\}"))) { |
if (NULL == (ep = strstr(st, "\\}"))) { |
roffnode_cleanscope(r); |
roffnode_cleanscope(r); |
Line 837 roff_evalcond(const char *v, int *pos) |
|
Line 849 roff_evalcond(const char *v, int *pos) |
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
static enum rofferr |
static enum rofferr |
roff_line(ROFF_ARGS) |
roff_line_ignore(ROFF_ARGS) |
{ |
{ |
|
|
return(ROFF_IGN); |
return(ROFF_IGN); |
Line 1035 roff_nr(ROFF_ARGS) |
|
Line 1047 roff_nr(ROFF_ARGS) |
|
} |
} |
|
|
|
|
|
static char * |
|
roff_strdup(const char *name) |
|
{ |
|
char *namecopy, *sv; |
|
|
|
/* |
|
* This isn't a nice simple mandoc_strdup() because we must |
|
* handle roff's stupid double-escape rule. |
|
*/ |
|
sv = namecopy = mandoc_malloc(strlen(name) + 1); |
|
while (*name) { |
|
if ('\\' == *name && '\\' == *(name + 1)) |
|
name++; |
|
*namecopy++ = *name++; |
|
} |
|
|
|
*namecopy = '\0'; |
|
return(sv); |
|
} |
|
|
|
|
static void |
static void |
roff_setstr(struct roff *r, const char *name, const char *string) |
roff_setstr(struct roff *r, const char *name, const char *string) |
{ |
{ |
Line 1054 roff_setstr(struct roff *r, const char *name, const ch |
|
Line 1087 roff_setstr(struct roff *r, const char *name, const ch |
|
} else |
} else |
free(n->string); |
free(n->string); |
|
|
ROFF_DEBUG("roff: new symbol: [%s] = [%s]\n", name, string); |
/* Don't use mandoc_strdup: clean out double-escapes. */ |
n->string = string ? strdup(string) : NULL; |
n->string = string ? roff_strdup(string) : NULL; |
|
ROFF_DEBUG("roff: new symbol: [%s] = [%s]\n", name, n->string); |
} |
} |
|
|
|
|