version 1.51, 2013/07/13 12:51:38 |
version 1.52, 2013/10/03 19:32:25 |
|
|
}; |
}; |
|
|
/* |
/* |
* A single register entity. If "set" is zero, the value of the |
|
* register should be the default one, which is per-register. |
|
* Registers are assumed to be unsigned ints for now. |
|
*/ |
|
struct reg { |
|
int set; /* whether set or not */ |
|
unsigned int u; /* unsigned integer */ |
|
}; |
|
|
|
/* |
|
* An incredibly-simple string buffer. |
* An incredibly-simple string buffer. |
*/ |
*/ |
struct roffstr { |
struct roffstr { |
|
|
struct roffkv *next; /* next in list */ |
struct roffkv *next; /* next in list */ |
}; |
}; |
|
|
|
/* |
|
* A single number register as part of a singly-linked list. |
|
* Registers are assumed to be unsigned ints for now. |
|
*/ |
|
struct roffreg { |
|
struct roffstr key; |
|
unsigned int u; |
|
struct roffreg *next; |
|
}; |
|
|
struct roff { |
struct roff { |
enum mparset parsetype; /* requested parse type */ |
enum mparset parsetype; /* requested parse type */ |
struct mparse *parse; /* parse point */ |
struct mparse *parse; /* parse point */ |
|
|
enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */ |
enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */ |
char control; /* control character */ |
char control; /* control character */ |
int rstackpos; /* position in rstack */ |
int rstackpos; /* position in rstack */ |
struct reg regs[REG__MAX]; |
struct roffreg *regtab; /* number registers */ |
struct roffkv *strtab; /* user-defined strings & macros */ |
struct roffkv *strtab; /* user-defined strings & macros */ |
struct roffkv *xmbtab; /* multi-byte trans table (`tr') */ |
struct roffkv *xmbtab; /* multi-byte trans table (`tr') */ |
struct roffstr *xtab; /* single-byte trans table (`tr') */ |
struct roffstr *xtab; /* single-byte trans table (`tr') */ |
|
|
static enum rofferr roff_ds(ROFF_ARGS); |
static enum rofferr roff_ds(ROFF_ARGS); |
static enum roffrule roff_evalcond(const char *, int *); |
static enum roffrule roff_evalcond(const char *, int *); |
static void roff_free1(struct roff *); |
static void roff_free1(struct roff *); |
|
static void roff_freereg(struct roffreg *); |
static void roff_freestr(struct roffkv *); |
static void roff_freestr(struct roffkv *); |
static char *roff_getname(struct roff *, char **, int, int); |
static char *roff_getname(struct roff *, char **, int, int); |
static const char *roff_getstrn(const struct roff *, |
static const char *roff_getstrn(const struct roff *, |
|
|
|
|
r->strtab = r->xmbtab = NULL; |
r->strtab = r->xmbtab = NULL; |
|
|
|
roff_freereg(r->regtab); |
|
|
|
r->regtab = NULL; |
|
|
if (r->xtab) |
if (r->xtab) |
for (i = 0; i < 128; i++) |
for (i = 0; i < 128; i++) |
free(r->xtab[i].p); |
free(r->xtab[i].p); |
|
|
roff_free1(r); |
roff_free1(r); |
|
|
r->control = 0; |
r->control = 0; |
memset(&r->regs, 0, sizeof(struct reg) * REG__MAX); |
|
|
|
for (i = 0; i < PREDEFS_MAX; i++) |
for (i = 0; i < PREDEFS_MAX; i++) |
roff_setstr(r, predefs[i].name, predefs[i].str, 0); |
roff_setstr(r, predefs[i].name, predefs[i].str, 0); |
|
|
return(ROFF_IGN); |
return(ROFF_IGN); |
} |
} |
|
|
int |
void |
roff_regisset(const struct roff *r, enum regs reg) |
roff_setreg(struct roff *r, const char *name, unsigned int val) |
{ |
{ |
|
struct roffreg *reg; |
|
|
return(r->regs[(int)reg].set); |
/* Search for an existing register with the same name. */ |
|
reg = r->regtab; |
|
|
|
while (reg && strcmp(name, reg->key.p)) |
|
reg = reg->next; |
|
|
|
if (NULL == reg) { |
|
/* Create a new register. */ |
|
reg = mandoc_malloc(sizeof(struct roffreg)); |
|
reg->key.p = mandoc_strdup(name); |
|
reg->key.sz = strlen(name); |
|
reg->next = r->regtab; |
|
r->regtab = reg; |
|
} |
|
|
|
reg->u = val; |
} |
} |
|
|
unsigned int |
unsigned int |
roff_regget(const struct roff *r, enum regs reg) |
roff_getreg(const struct roff *r, const char *name) |
{ |
{ |
|
struct roffreg *reg; |
|
|
return(r->regs[(int)reg].u); |
for (reg = r->regtab; reg; reg = reg->next) |
|
if (0 == strcmp(name, reg->key.p)) |
|
return(reg->u); |
|
|
|
return(0); |
} |
} |
|
|
void |
static void |
roff_regunset(struct roff *r, enum regs reg) |
roff_freereg(struct roffreg *reg) |
{ |
{ |
|
struct roffreg *old_reg; |
|
|
r->regs[(int)reg].set = 0; |
while (NULL != reg) { |
|
free(reg->key.p); |
|
old_reg = reg; |
|
reg = reg->next; |
|
free(old_reg); |
|
} |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
|
|
val = *bufp + pos; |
val = *bufp + pos; |
key = roff_getname(r, &val, ln, pos); |
key = roff_getname(r, &val, ln, pos); |
|
|
if (0 == strcmp(key, "nS")) { |
iv = mandoc_strntoi(val, strlen(val), 10); |
r->regs[(int)REG_nS].set = 1; |
if (0 > iv) |
if ((iv = mandoc_strntoi(val, strlen(val), 10)) >= 0) |
iv = 0; |
r->regs[(int)REG_nS].u = (unsigned)iv; |
|
else |
roff_setreg(r, key, (unsigned)iv); |
r->regs[(int)REG_nS].u = 0u; |
|
} |
|
|
|
return(ROFF_IGN); |
return(ROFF_IGN); |
} |
} |