/*
* Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
/*
* Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
static void roff_freereg(struct roffreg *);
static void roff_freestr(struct roffkv *);
static char *roff_getname(struct roff *, char **, int, int);
static void roff_freereg(struct roffreg *);
static void roff_freestr(struct roffkv *);
static char *roff_getname(struct roff *, char **, int, int);
static int roff_getregn(const struct roff *,
const char *, size_t);
static const char *roff_getstrn(const struct roff *,
static int roff_getregn(const struct roff *,
const char *, size_t);
static const char *roff_getstrn(const struct roff *,
{ "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL },
{ "ds", roff_ds, NULL, NULL, 0, NULL },
{ "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
{ "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL },
{ "ds", roff_ds, NULL, NULL, 0, NULL },
{ "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
+ { "fam", roff_line_ignore, NULL, NULL, 0, NULL },
+ { "hw", roff_line_ignore, NULL, NULL, 0, NULL },
{ "hy", roff_line_ignore, NULL, NULL, 0, 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 },
{ "hy", roff_line_ignore, NULL, NULL, 0, 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 (r->eqn)
- return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
- if (r->tbl)
- return(tbl_read(r->tbl, ln, *bufp, pos));
- return(roff_parsetext(bufp, szp, pos, offs));
- } else if ( ! ctl) {
- if (r->eqn)
- return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
+ }
+ if (r->eqn)
+ return(eqn_read(&r->eqn, ln, *bufp, ppos, offs));
+ if ( ! ctl) {
if (r->tbl)
return(tbl_read(r->tbl, ln, *bufp, pos));
return(roff_parsetext(bufp, szp, pos, offs));
if (r->tbl)
return(tbl_read(r->tbl, ln, *bufp, pos));
return(roff_parsetext(bufp, szp, pos, offs));
+static int
+roff_getnum(const char *v, int *pos, int *res)
+{
+ int p, n;
+
+ p = *pos;
+ n = v[p] == '-';
+ if (n)
+ p++;
+
+ for (*res = 0; isdigit((unsigned char)v[p]); p++)
+ *res += 10 * *res + v[p] - '0';
+ if (p == *pos + n)
+ return 0;
+
+ if (n)
+ *res = -*res;
+
+ *pos = p;
+ return 1;
+}
+
+static int
+roff_getop(const char *v, int *pos, char *res)
+{
+ int e;
+
+ *res = v[*pos];
+ e = v[*pos + 1] == '=';
+
+ switch (*res) {
+ case '=':
+ break;
+ case '>':
+ if (e)
+ *res = 'g';
+ break;
+ case '<':
+ if (e)
+ *res = 'l';
+ break;
+ default:
+ return(0);
+ }
+
+ *pos += 1 + e;
+
+ return(*res);
+}
+
- while (v[*pos] && ' ' != v[*pos])
- (*pos)++;
- return(ROFFRULE_DENY);
+ if (!roff_getnum(v, pos, &lh))
+ return ROFFRULE_DENY;
+ if (!roff_getop(v, pos, &op)) {
+ if (lh < 0)
+ lh = 0;
+ goto out;
+ }
+ if (!roff_getnum(v, pos, &rh))
+ return ROFFRULE_DENY;
+ switch (op) {
+ case 'g':
+ lh = lh >= rh;
+ break;
+ case 'l':
+ lh = lh <= rh;
+ break;
+ case '=':
+ lh = lh == rh;
+ break;
+ case '>':
+ lh = lh > rh;
+ break;
+ case '<':
+ lh = lh < rh;
+ break;
+ default:
+ return ROFFRULE_DENY;
+ }
+out:
+ if (not)
+ lh = !lh;
+ return lh ? ROFFRULE_ALLOW : ROFFRULE_DENY;
-roff_setreg(struct roff *r, const char *name, int val)
+roff_setreg(struct roff *r, const char *name, int val, char sign)
reg = mandoc_malloc(sizeof(struct roffreg));
reg->key.p = mandoc_strdup(name);
reg->key.sz = strlen(name);
reg = mandoc_malloc(sizeof(struct roffreg));
reg->key.p = mandoc_strdup(name);
reg->key.sz = strlen(name);
val = *bufp + pos;
key = roff_getname(r, &val, ln, pos);
val = *bufp + pos;
key = roff_getname(r, &val, ln, pos);
- iv = mandoc_strntoi(val, strlen(val), 10);
+ sign = *val;
+ if ('+' == sign || '-' == sign)
+ val++;
+
+ sz = strspn(val, "0123456789");
+ iv = sz ? mandoc_strntoi(val, sz, 10) : 0;