aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/term.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-04-09 15:29:40 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-04-09 15:29:40 +0000
commitdc6820cf87c36506f7d235493e75c1520231e9d9 (patch)
treee5c60975fd48bf07a47693f981a0ff9991db03b9 /term.c
parent0383763dbd62d52405be4dc65ae9aaff035c8f79 (diff)
downloadmandoc-dc6820cf87c36506f7d235493e75c1520231e9d9.tar.gz
mandoc-dc6820cf87c36506f7d235493e75c1520231e9d9.tar.zst
mandoc-dc6820cf87c36506f7d235493e75c1520231e9d9.zip
Remove a2roffdeco() and mandoc_special() functions and replace them with
a public (mandoc.h) function mandoc_escape(), which merges the functionality of both prior functions. Reason: code duplication. The a2roffdeco() and mandoc_special() functions were pretty much the same thing and both quite complex. This allows one function to receive improvements in (e.g.) subexpression handling and performance, instead of having to replicate functionality. As such, the mandoc_escape() function already handles a superset of the escapes handled in previous versions and has improvements in performance (using strcspn(), for example) and reliable handling of subexpressions. This code Works For Me, but may need work to catch any regressions. Since the benefits are great (leaner code, simpler API), I'd rather have it in-tree than floating as a patch.
Diffstat (limited to 'term.c')
-rw-r--r--term.c109
1 files changed, 60 insertions, 49 deletions
diff --git a/term.c b/term.c
index b0ddd1ed..12722b97 100644
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.183 2011/04/04 21:14:12 kristaps Exp $ */
+/* $Id: term.c,v 1.184 2011/04/09 15:29:40 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -33,8 +33,7 @@
#include "term.h"
#include "main.h"
-static void spec(struct termp *, enum roffdeco,
- const char *, size_t);
+static void spec(struct termp *, const char *, size_t);
static void res(struct termp *, const char *, size_t);
static void bufferc(struct termp *, char);
static void adjbuf(struct termp *p, size_t);
@@ -358,7 +357,7 @@ numbered(struct termp *p, const char *word, size_t len)
static void
-spec(struct termp *p, enum roffdeco d, const char *word, size_t len)
+spec(struct termp *p, const char *word, size_t len)
{
const char *rhs;
size_t sz;
@@ -366,7 +365,7 @@ spec(struct termp *p, enum roffdeco d, const char *word, size_t len)
rhs = chars_spec2str(p->symtab, word, len, &sz);
if (rhs)
encode(p, rhs, sz);
- else if (DECO_SSPECIAL == d)
+ else if (1 == len)
encode(p, word, len);
}
@@ -457,8 +456,9 @@ void
term_word(struct termp *p, const char *word)
{
const char *seq;
+ int sz;
size_t ssz;
- enum roffdeco deco;
+ enum mandoc_esc esc;
if ( ! (TERMP_NOSPACE & p->flags)) {
if ( ! (TERMP_KEEP & p->flags)) {
@@ -478,7 +478,7 @@ term_word(struct termp *p, const char *word)
p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM);
- while (*word) {
+ while ('\0' != *word) {
if ((ssz = strcspn(word, "\\")) > 0)
encode(p, word, ssz);
@@ -486,39 +486,40 @@ term_word(struct termp *p, const char *word)
if ('\\' != *word)
continue;
- seq = ++word;
- word += a2roffdeco(&deco, &seq, &ssz);
+ word++;
+ esc = mandoc_escape(&word, &seq, &sz);
+ if (ESCAPE_ERROR == esc)
+ break;
- switch (deco) {
- case (DECO_NUMBERED):
- numbered(p, seq, ssz);
+ switch (esc) {
+ case (ESCAPE_NUMBERED):
+ numbered(p, seq, sz);
break;
- case (DECO_RESERVED):
- res(p, seq, ssz);
+ case (ESCAPE_PREDEF):
+ res(p, seq, sz);
break;
- case (DECO_SPECIAL):
- /* FALLTHROUGH */
- case (DECO_SSPECIAL):
- spec(p, deco, seq, ssz);
+ case (ESCAPE_SPECIAL):
+ spec(p, seq, sz);
break;
- case (DECO_BOLD):
+ case (ESCAPE_FONTBOLD):
term_fontrepl(p, TERMFONT_BOLD);
break;
- case (DECO_ITALIC):
+ case (ESCAPE_FONTITALIC):
term_fontrepl(p, TERMFONT_UNDER);
break;
- case (DECO_ROMAN):
+ case (ESCAPE_FONTROMAN):
term_fontrepl(p, TERMFONT_NONE);
break;
- case (DECO_PREVIOUS):
+ case (ESCAPE_FONTPREV):
term_fontlast(p);
break;
+ case (ESCAPE_NOSPACE):
+ if ('\0' == *word)
+ p->flags |= TERMP_NOSPACE;
+ break;
default:
break;
}
-
- if (DECO_NOSPACE == deco && '\0' == *word)
- p->flags |= TERMP_NOSPACE;
}
}
@@ -600,33 +601,36 @@ term_len(const struct termp *p, size_t sz)
size_t
term_strlen(const struct termp *p, const char *cp)
{
- size_t sz, ssz, rsz, i;
- enum roffdeco d;
+ size_t sz, rsz, i;
+ int ssz;
+ enum mandoc_esc esc;
const char *seq, *rhs;
- for (sz = 0; '\0' != *cp; )
- /*
- * Account for escaped sequences within string length
- * calculations. This follows the logic in term_word()
- * as we must calculate the width of produced strings.
- */
- if ('\\' == *cp) {
- seq = ++cp;
- cp += a2roffdeco(&d, &seq, &ssz);
+ /*
+ * Account for escaped sequences within string length
+ * calculations. This follows the logic in term_word() as we
+ * must calculate the width of produced strings.
+ */
- switch (d) {
- case (DECO_RESERVED):
+ sz = 0;
+ while ('\0' != *cp)
+ switch (*cp) {
+ case ('\\'):
+ ++cp;
+ esc = mandoc_escape(&cp, &seq, &ssz);
+ if (ESCAPE_ERROR == esc)
+ return(sz);
+
+ switch (esc) {
+ case (ESCAPE_PREDEF):
rhs = chars_res2str
(p->symtab, seq, ssz, &rsz);
break;
- case (DECO_SPECIAL):
- /* FALLTHROUGH */
- case (DECO_SSPECIAL):
+ case (ESCAPE_SPECIAL):
rhs = chars_spec2str
(p->symtab, seq, ssz, &rsz);
- /* Allow for one-char escapes. */
- if (DECO_SSPECIAL != d || rhs)
+ if (ssz != 1 || rhs)
break;
rhs = seq;
@@ -637,17 +641,24 @@ term_strlen(const struct termp *p, const char *cp)
break;
}
- if (rhs)
- for (i = 0; i < rsz; i++)
- sz += (*p->width)(p, *rhs++);
- } else if (ASCII_NBRSP == *cp) {
+ if (NULL == rhs)
+ break;
+
+ for (i = 0; i < rsz; i++)
+ sz += (*p->width)(p, *rhs++);
+ break;
+ case (ASCII_NBRSP):
sz += (*p->width)(p, ' ');
cp++;
- } else if (ASCII_HYPH == *cp) {
+ break;
+ case (ASCII_HYPH):
sz += (*p->width)(p, '-');
cp++;
- } else
+ break;
+ default:
sz += (*p->width)(p, *cp++);
+ break;
+ }
return(sz);
}