version 1.97, 2010/07/27 19:56:50 |
version 1.101, 2010/09/04 18:31:44 |
|
|
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 136 static int roff_res(struct roff *, |
|
Line 136 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 168 static void roff_free1(struct roff *); |
|
Line 169 static void roff_free1(struct roff *); |
|
static enum rofft roff_hash_find(const char *); |
static enum rofft roff_hash_find(const char *); |
static void roff_hash_init(void); |
static void roff_hash_init(void); |
static void roffnode_cleanscope(struct roff *); |
static void roffnode_cleanscope(struct roff *); |
static int roffnode_push(struct roff *, |
static void roffnode_push(struct roff *, |
enum rofft, int, int); |
enum rofft, int, int); |
static void roffnode_pop(struct roff *); |
static void roffnode_pop(struct roff *); |
static enum rofft roff_parse(const char *, int *); |
static enum rofft roff_parse(const char *, int *); |
Line 247 roffnode_pop(struct roff *r) |
|
Line 248 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 258 roffnode_pop(struct roff *r) |
|
Line 260 roffnode_pop(struct roff *r) |
|
* Push a roff node onto the instruction stack. This must later be |
* Push a roff node onto the instruction stack. This must later be |
* removed with roffnode_pop(). |
* removed with roffnode_pop(). |
*/ |
*/ |
static int |
static void |
roffnode_push(struct roff *r, enum rofft tok, int line, int col) |
roffnode_push(struct roff *r, enum rofft tok, int line, int col) |
{ |
{ |
struct roffnode *p; |
struct roffnode *p; |
|
|
if (NULL == (p = calloc(1, sizeof(struct roffnode)))) { |
p = mandoc_calloc(1, sizeof(struct roffnode)); |
(*r->msg)(MANDOCERR_MEM, r->data, line, col, NULL); |
|
return(0); |
|
} |
|
|
|
p->tok = tok; |
p->tok = tok; |
p->parent = r->last; |
p->parent = r->last; |
p->line = line; |
p->line = line; |
Line 275 roffnode_push(struct roff *r, enum rofft tok, int line |
|
Line 273 roffnode_push(struct roff *r, enum rofft tok, int line |
|
p->rule = p->parent ? p->parent->rule : ROFFRULE_DENY; |
p->rule = p->parent ? p->parent->rule : ROFFRULE_DENY; |
|
|
r->last = p; |
r->last = p; |
return(1); |
|
} |
} |
|
|
|
|
Line 307 roff_free(struct roff *r) |
|
Line 304 roff_free(struct roff *r) |
|
|
|
|
|
struct roff * |
struct roff * |
roff_alloc(struct regset *regs, const mandocmsg msg, void *data) |
roff_alloc(struct regset *regs, void *data, const mandocmsg msg) |
{ |
{ |
struct roff *r; |
struct roff *r; |
|
|
if (NULL == (r = calloc(1, sizeof(struct roff)))) { |
r = mandoc_calloc(1, sizeof(struct roff)); |
(*msg)(MANDOCERR_MEM, data, 0, 0, NULL); |
|
return(0); |
|
} |
|
|
|
r->regs = regs; |
r->regs = regs; |
r->msg = msg; |
r->msg = msg; |
r->data = data; |
r->data = data; |
Line 434 roff_parseln(struct roff *r, int ln, char **bufp, |
|
Line 427 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 650 roff_block(ROFF_ARGS) |
|
Line 643 roff_block(ROFF_ARGS) |
|
pos++; |
pos++; |
} |
} |
|
|
if ( ! roffnode_push(r, tok, ln, ppos)) |
roffnode_push(r, tok, ln, ppos); |
return(ROFF_ERR); |
|
|
|
if ('\0' == (*bufp)[pos]) |
if ('\0' == (*bufp)[pos]) |
return(ROFF_IGN); |
return(ROFF_IGN); |
Line 673 roff_block(ROFF_ARGS) |
|
Line 665 roff_block(ROFF_ARGS) |
|
if (1 == sz && '.' == (*bufp)[sv]) |
if (1 == sz && '.' == (*bufp)[sv]) |
return(ROFF_IGN); |
return(ROFF_IGN); |
|
|
r->last->end = malloc(sz + 1); |
r->last->end = mandoc_malloc(sz + 1); |
|
|
if (NULL == r->last->end) { |
|
(*r->msg)(MANDOCERR_MEM, r->data, ln, pos, NULL); |
|
return(ROFF_ERR); |
|
} |
|
|
|
memcpy(r->last->end, *bufp + sv, sz); |
memcpy(r->last->end, *bufp + sv, sz); |
r->last->end[(int)sz] = '\0'; |
r->last->end[(int)sz] = '\0'; |
|
|
Line 775 roff_cond_sub(ROFF_ARGS) |
|
Line 762 roff_cond_sub(ROFF_ARGS) |
|
l = r->last; |
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 811 roff_cond_text(ROFF_ARGS) |
|
Line 800 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 905 roff_cond(ROFF_ARGS) |
|
Line 896 roff_cond(ROFF_ARGS) |
|
return(ROFF_ERR); |
return(ROFF_ERR); |
} |
} |
|
|
if ( ! roffnode_push(r, tok, ln, ppos)) |
roffnode_push(r, tok, ln, ppos); |
return(ROFF_ERR); |
|
|
|
r->last->rule = rule; |
r->last->rule = rule; |
|
|
Line 1051 roff_nr(ROFF_ARGS) |
|
Line 1041 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 1070 roff_setstr(struct roff *r, const char *name, const ch |
|
Line 1081 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); |
} |
} |
|
|
|
|