From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from krisdoz.my.domain (schwarze@localhost [127.0.0.1]) by krisdoz.my.domain (8.14.5/8.14.5) with ESMTP id r95M8Csc012886 for ; Sat, 5 Oct 2013 18:08:12 -0400 (EDT) Received: (from schwarze@localhost) by krisdoz.my.domain (8.14.5/8.14.3/Submit) id r95M8CSV023230; Sat, 5 Oct 2013 18:08:12 -0400 (EDT) Date: Sat, 5 Oct 2013 18:08:12 -0400 (EDT) Message-Id: <201310052208.r95M8CSV023230@krisdoz.my.domain> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: schwarze@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: Support setting arbitrary roff(7) number registers, preserving X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Support setting arbitrary roff(7) number registers, preserving read support for the ".nr nS" SYNOPSIS state register. Inspired by NetBSD roff.c rev. 1.18 (Christos Zoulas, March 21, 2013), but implemented differently. I don't want to have yet another different implementation of a hash table in mandoc - it would be the second one in roff.c alone and the fifth one in mandoc grand total. Instead, i designed and implemented roff_setreg() and roff_getreg() to be similar to roff_setstrn() and roff_getstrn(). Once we feel the need to optimize, we can introduce one common hash table implementation for everything in mandoc. Modified Files: -------------- mdocml: libmandoc.h mdoc.c mdoc_validate.c roff.c Revision Data ------------- Index: mdoc_validate.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_validate.c,v retrieving revision 1.193 retrieving revision 1.194 diff -Lmdoc_validate.c -Lmdoc_validate.c -u -p -r1.193 -r1.194 --- mdoc_validate.c +++ mdoc_validate.c @@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010, 2011, 2012 Ingo Schwarze + * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -888,8 +888,6 @@ pre_sh(PRE_ARGS) if (MDOC_BLOCK != n->type) return(1); - - roff_regunset(mdoc->roff, REG_nS); return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT)); } @@ -1905,10 +1903,13 @@ post_sh_head(POST_ARGS) /* The SYNOPSIS gets special attention in other areas. */ - if (SEC_SYNOPSIS == sec) + if (SEC_SYNOPSIS == sec) { + roff_setreg(mdoc->roff, "nS", 1); mdoc->flags |= MDOC_SYNOPSIS; - else + } else { + roff_setreg(mdoc->roff, "nS", 0); mdoc->flags &= ~MDOC_SYNOPSIS; + } /* Mark our last section. */ Index: mdoc.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc.c,v retrieving revision 1.203 retrieving revision 1.204 diff -Lmdoc.c -Lmdoc.c -u -p -r1.203 -r1.204 --- mdoc.c +++ mdoc.c @@ -295,12 +295,10 @@ mdoc_parseln(struct mdoc *mdoc, int ln, * whether this mode is on or off. * Note that this mode is also switched by the Sh macro. */ - if (roff_regisset(mdoc->roff, REG_nS)) { - if (roff_regget(mdoc->roff, REG_nS)) - mdoc->flags |= MDOC_SYNOPSIS; - else - mdoc->flags &= ~MDOC_SYNOPSIS; - } + if (roff_getreg(mdoc->roff, "nS")) + mdoc->flags |= MDOC_SYNOPSIS; + else + mdoc->flags &= ~MDOC_SYNOPSIS; return(roff_getcontrol(mdoc->roff, buf, &offs) ? mdoc_pmacro(mdoc, ln, buf, offs) : Index: roff.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v retrieving revision 1.179 retrieving revision 1.180 diff -Lroff.c -Lroff.c -u -p -r1.179 -r1.180 --- roff.c +++ roff.c @@ -79,16 +79,6 @@ enum roffrule { }; /* - * 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. */ struct roffstr { @@ -105,6 +95,16 @@ struct roffkv { 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 { enum mparset parsetype; /* requested parse type */ struct mparse *parse; /* parse point */ @@ -112,7 +112,7 @@ struct roff { enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */ char control; /* control character */ int rstackpos; /* position in rstack */ - struct reg regs[REG__MAX]; + struct roffreg *regtab; /* number registers */ struct roffkv *strtab; /* user-defined strings & macros */ struct roffkv *xmbtab; /* multi-byte trans table (`tr') */ struct roffstr *xtab; /* single-byte trans table (`tr') */ @@ -183,6 +183,7 @@ static enum rofferr roff_cond_sub(ROFF_ static enum rofferr roff_ds(ROFF_ARGS); static enum roffrule roff_evalcond(const char *, int *); static void roff_free1(struct roff *); +static void roff_freereg(struct roffreg *); static void roff_freestr(struct roffkv *); static char *roff_getname(struct roff *, char **, int, int); static const char *roff_getstrn(const struct roff *, @@ -424,6 +425,10 @@ roff_free1(struct roff *r) r->strtab = r->xmbtab = NULL; + roff_freereg(r->regtab); + + r->regtab = NULL; + if (r->xtab) for (i = 0; i < 128; i++) free(r->xtab[i].p); @@ -440,7 +445,6 @@ roff_reset(struct roff *r) roff_free1(r); r->control = 0; - memset(&r->regs, 0, sizeof(struct reg) * REG__MAX); for (i = 0; i < PREDEFS_MAX; i++) roff_setstr(r, predefs[i].name, predefs[i].str, 0); @@ -1258,25 +1262,52 @@ roff_ds(ROFF_ARGS) return(ROFF_IGN); } -int -roff_regisset(const struct roff *r, enum regs reg) +void +roff_setreg(struct roff *r, const char *name, unsigned int val) { + struct roffreg *reg; + + /* Search for an existing register with the same name. */ + reg = r->regtab; + + while (reg && strcmp(name, reg->key.p)) + reg = reg->next; - return(r->regs[(int)reg].set); + 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 -roff_regget(const struct roff *r, enum regs reg) +roff_getreg(const struct roff *r, const char *name) { + struct roffreg *reg; + + for (reg = r->regtab; reg; reg = reg->next) + if (0 == strcmp(name, reg->key.p)) + return(reg->u); - return(r->regs[(int)reg].u); + return(0); } -void -roff_regunset(struct roff *r, enum regs reg) +static void +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 */ @@ -1290,13 +1321,11 @@ roff_nr(ROFF_ARGS) val = *bufp + pos; key = roff_getname(r, &val, ln, pos); - if (0 == strcmp(key, "nS")) { - r->regs[(int)REG_nS].set = 1; - if ((iv = mandoc_strntoi(val, strlen(val), 10)) >= 0) - r->regs[(int)REG_nS].u = (unsigned)iv; - else - r->regs[(int)REG_nS].u = 0u; - } + iv = mandoc_strntoi(val, strlen(val), 10); + if (0 > iv) + iv = 0; + + roff_setreg(r, key, (unsigned)iv); return(ROFF_IGN); } Index: libmandoc.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libmandoc.h,v retrieving revision 1.32 retrieving revision 1.33 diff -Llibmandoc.h -Llibmandoc.h -u -p -r1.32 -r1.33 --- libmandoc.h +++ libmandoc.h @@ -1,6 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons + * Copyright (c) 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,11 +30,6 @@ enum rofferr { ROFF_ERR /* badness: puke and stop */ }; -enum regs { - REG_nS = 0, /* nS register */ - REG__MAX -}; - __BEGIN_DECLS struct roff; @@ -72,9 +68,8 @@ void roff_reset(struct roff *); enum rofferr roff_parseln(struct roff *, int, char **, size_t *, int, int *); void roff_endparse(struct roff *); -int roff_regisset(const struct roff *, enum regs); -unsigned int roff_regget(const struct roff *, enum regs); -void roff_regunset(struct roff *, enum regs); +void roff_setreg(struct roff *, const char *, unsigned int); +unsigned int roff_getreg(const struct roff *, const char *); char *roff_strdup(const struct roff *, const char *); int roff_getcontrol(const struct roff *, const char *, int *); -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv