=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/roff.c,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** src/usr.bin/mandoc/roff.c 2010/06/26 17:56:43 1.5 --- src/usr.bin/mandoc/roff.c 2010/06/27 21:54:42 1.6 *************** *** 1,4 **** ! /* $Id: roff.c,v 1.5 2010/06/26 17:56:43 schwarze Exp $ */ /* * Copyright (c) 2010 Kristaps Dzonsons * --- 1,4 ---- ! /* $Id: roff.c,v 1.6 2010/06/27 21:54:42 schwarze Exp $ */ /* * Copyright (c) 2010 Kristaps Dzonsons * *************** *** 19,30 **** --- 19,33 ---- #endif #include + #include #include + #include #include #include #include #include "mandoc.h" + #include "regs.h" #include "roff.h" #define RSTACK_MAX 128 *************** *** 48,53 **** --- 51,57 ---- ROFF_tr, ROFF_cblock, ROFF_ccond, + ROFF_nr, ROFF_MAX }; *************** *** 62,67 **** --- 66,72 ---- void *data; /* privdata for messages */ enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */ int rstackpos; /* position in rstack */ + struct regset *regs; /* read/writable registers */ }; struct roffnode { *************** *** 103,110 **** static enum rofferr roff_cond(ROFF_ARGS); static enum rofferr roff_cond_text(ROFF_ARGS); static enum rofferr roff_cond_sub(ROFF_ARGS); - static enum roffrule roff_evalcond(const char *, int *); static enum rofferr roff_line(ROFF_ARGS); /* See roff_hash_find() */ --- 108,116 ---- static enum rofferr roff_cond(ROFF_ARGS); static enum rofferr roff_cond_text(ROFF_ARGS); static enum rofferr roff_cond_sub(ROFF_ARGS); static enum rofferr roff_line(ROFF_ARGS); + static enum rofferr roff_nr(ROFF_ARGS); + static enum roffrule roff_evalcond(const char *, int *); /* See roff_hash_find() */ *************** *** 130,135 **** --- 136,142 ---- { "tr", roff_line, NULL, NULL, 0, NULL }, { ".", roff_cblock, NULL, NULL, 0, NULL }, { "\\}", roff_ccond, NULL, NULL, 0, NULL }, + { "nr", roff_nr, NULL, NULL, 0, NULL }, }; static void roff_free1(struct roff *); *************** *** 140,145 **** --- 147,153 ---- enum rofft, int, int); static void roffnode_pop(struct roff *); static enum rofft roff_parse(const char *, int *); + static int roff_parse_nat(const char *, unsigned int *); /* See roff_hash_find() */ #define ROFF_HASH(p) (p[0] - ASCII_LO) *************** *** 273,279 **** struct roff * ! roff_alloc(const mandocmsg msg, void *data) { struct roff *r; --- 281,287 ---- struct roff * ! roff_alloc(struct regset *regs, const mandocmsg msg, void *data) { struct roff *r; *************** *** 282,287 **** --- 290,296 ---- return(0); } + r->regs = regs; r->msg = msg; r->data = data; r->rstackpos = -1; *************** *** 292,299 **** enum rofferr ! roff_parseln(struct roff *r, int ln, ! char **bufp, size_t *szp, int pos, int *offs) { enum rofft t; int ppos; --- 301,308 ---- enum rofferr ! roff_parseln(struct roff *r, int ln, char **bufp, ! size_t *szp, int pos, int *offs) { enum rofft t; int ppos; *************** *** 392,397 **** --- 401,426 ---- } + static int + roff_parse_nat(const char *buf, unsigned int *res) + { + char *ep; + long lval; + + errno = 0; + lval = strtol(buf, &ep, 10); + if (buf[0] == '\0' || *ep != '\0') + return(0); + if ((errno == ERANGE && + (lval == LONG_MAX || lval == LONG_MIN)) || + (lval > INT_MAX || lval < 0)) + return(0); + + *res = (unsigned int)lval; + return(1); + } + + /* ARGSUSED */ static enum rofferr roff_cblock(ROFF_ARGS) *************** *** 602,609 **** return(ROFF_IGN); assert(roffs[t].proc); ! return((*roffs[t].proc)(r, t, bufp, ! szp, ln, ppos, pos, offs)); } --- 631,638 ---- return(ROFF_IGN); assert(roffs[t].proc); ! return((*roffs[t].proc)(r, t, bufp, szp, ! ln, ppos, pos, offs)); } *************** *** 652,659 **** return(ROFF_IGN); assert(roffs[t].proc); ! return((*roffs[t].proc) ! (r, t, bufp, szp, ln, ppos, pos, offs)); } --- 681,688 ---- return(ROFF_IGN); assert(roffs[t].proc); ! return((*roffs[t].proc)(r, t, bufp, szp, ! ln, ppos, pos, offs)); } *************** *** 712,717 **** --- 741,755 ---- /* ARGSUSED */ static enum rofferr + roff_line(ROFF_ARGS) + { + + return(ROFF_IGN); + } + + + /* ARGSUSED */ + static enum rofferr roff_cond(ROFF_ARGS) { int sv; *************** *** 808,815 **** /* ARGSUSED */ static enum rofferr ! roff_line(ROFF_ARGS) { return(ROFF_IGN); } --- 846,883 ---- /* ARGSUSED */ static enum rofferr ! roff_nr(ROFF_ARGS) { + const char *key, *val; + struct reg *rg; + + key = &(*bufp)[pos]; + rg = r->regs->regs; + + /* Parse register request. */ + while ((*bufp)[pos] && ' ' != (*bufp)[pos]) + pos++; + + /* + * Set our nil terminator. Because this line is going to be + * ignored anyway, we can munge it as we please. + */ + if ((*bufp)[pos]) + (*bufp)[pos++] = '\0'; + + /* Skip whitespace to register token. */ + while ((*bufp)[pos] && ' ' == (*bufp)[pos]) + pos++; + + val = &(*bufp)[pos]; + + /* Process register token. */ + + if (0 == strcmp(key, "nS")) { + rg[(int)REG_nS].set = 1; + if ( ! roff_parse_nat(val, &rg[(int)REG_nS].v.u)) + rg[(int)REG_nS].v.u = 0; + } return(ROFF_IGN); }