summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-12-23 13:48:57 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-12-23 13:48:57 +0000
commit4ad53635f5202474c55af90f70bba0ade18962cb (patch)
treeec073e4714b3d859a66a94147789aa077e78dd38
parentf2c1420553b275dd2f792b3a15c8fb0437f58052 (diff)
downloadmandoc-4ad53635f5202474c55af90f70bba0ade18962cb.tar.gz
support negative horizontal widths in man(7);
minus twenty lines of code in spite of enhanced functionality
-rw-r--r--man_term.c176
-rw-r--r--mdoc_html.c8
-rw-r--r--mdoc_man.c4
-rw-r--r--mdoc_term.c3
-rw-r--r--out.c3
-rw-r--r--term.c22
-rw-r--r--term.h6
7 files changed, 93 insertions, 129 deletions
diff --git a/man_term.c b/man_term.c
index 03456b2b..4652cd18 100644
--- a/man_term.c
+++ b/man_term.c
@@ -37,7 +37,7 @@
struct mtermp {
int fl;
#define MANT_LITERAL (1 << 0)
- size_t lmargin[MAXMARGINS]; /* margins (incl. visible page) */
+ int lmargin[MAXMARGINS]; /* margins (incl. vis. page) */
int lmargincur; /* index of current margin */
int lmarginsz; /* actual number of nested margins */
size_t offset; /* default offset to visible page */
@@ -56,8 +56,6 @@ struct termact {
#define MAN_NOTEXT (1 << 0) /* Never has text children. */
};
-static int a2width(const struct termp *, const char *);
-
static void print_man_nodelist(DECL_ARGS);
static void print_man_node(DECL_ARGS);
static void print_man_head(struct termp *, const void *);
@@ -183,17 +181,6 @@ terminal_man(void *arg, const struct man *man)
}
}
-static int
-a2width(const struct termp *p, const char *cp)
-{
- struct roffsu su;
-
- if ( ! a2roffsu(cp, &su, SCALE_EN))
- return(-1);
-
- return((int)term_hspan(p, &su));
-}
-
/*
* Printing leading vertical space before a block.
* This is used for the paragraph macros.
@@ -412,9 +399,10 @@ pre_ft(DECL_ARGS)
static int
pre_in(DECL_ARGS)
{
- int len, less;
- size_t v;
+ struct roffsu su;
const char *cp;
+ size_t v;
+ int less;
term_newln(p);
@@ -433,10 +421,10 @@ pre_in(DECL_ARGS)
else
cp--;
- if ((len = a2width(p, ++cp)) < 0)
+ if ( ! a2roffsu(++cp, &su, SCALE_EN))
return(0);
- v = (size_t)len;
+ v = term_hspan(p, &su);
if (less < 0)
p->offset -= p->offset > v ? v : p->offset;
@@ -452,9 +440,7 @@ static int
pre_sp(DECL_ARGS)
{
struct roffsu su;
- char *s;
- size_t i, len;
- int neg;
+ int i, len;
if ((NULL == n->prev && n->parent)) {
switch (n->parent->tok) {
@@ -474,31 +460,20 @@ pre_sp(DECL_ARGS)
}
}
- neg = 0;
- switch (n->tok) {
- case MAN_br:
+ if (n->tok == MAN_br)
len = 0;
- break;
- default:
- if (NULL == n->child) {
- len = 1;
- break;
- }
- s = n->child->string;
- if ('-' == *s) {
- neg = 1;
- s++;
- }
- if ( ! a2roffsu(s, &su, SCALE_VS))
+ else if (n->child == NULL)
+ len = 1;
+ else {
+ if ( ! a2roffsu(n->child->string, &su, SCALE_VS))
su.scale = 1.0;
len = term_vspan(p, &su);
- break;
}
- if (0 == len)
+ if (len == 0)
term_newln(p);
- else if (neg)
- p->skipvsp += len;
+ else if (len < 0)
+ p->skipvsp -= len;
else
for (i = 0; i < len; i++)
term_vspace(p);
@@ -509,9 +484,9 @@ pre_sp(DECL_ARGS)
static int
pre_HP(DECL_ARGS)
{
- size_t len, one;
- int ival;
+ struct roffsu su;
const struct man_node *nn;
+ int len;
switch (n->type) {
case MAN_BLOCK:
@@ -528,24 +503,20 @@ pre_HP(DECL_ARGS)
p->trailspace = 2;
}
- len = mt->lmargin[mt->lmargincur];
- ival = -1;
-
/* Calculate offset. */
- if (NULL != (nn = n->parent->head->child))
- if ((ival = a2width(p, nn->string)) >= 0)
- len = (size_t)ival;
-
- one = term_len(p, 1);
- if (len < one)
- len = one;
+ if ((nn = n->parent->head->child) != NULL &&
+ a2roffsu(nn->string, &su, SCALE_EN)) {
+ len = term_hspan(p, &su);
+ mt->lmargin[mt->lmargincur] = len;
+ } else
+ len = mt->lmargin[mt->lmargincur];
p->offset = mt->offset;
- p->rmargin = mt->offset + len;
-
- if (ival >= 0)
- mt->lmargin[mt->lmargincur] = (size_t)ival;
+ if (len > 0 || (size_t)(-len) < mt->offset)
+ p->rmargin = mt->offset + len;
+ else
+ p->rmargin = 0;
return(1);
}
@@ -587,9 +558,9 @@ pre_PP(DECL_ARGS)
static int
pre_IP(DECL_ARGS)
{
+ struct roffsu su;
const struct man_node *nn;
- size_t len;
- int savelit, ival;
+ int len, savelit;
switch (n->type) {
case MAN_BODY:
@@ -606,28 +577,22 @@ pre_IP(DECL_ARGS)
return(1);
}
- len = mt->lmargin[mt->lmargincur];
- ival = -1;
-
/* Calculate the offset from the optional second argument. */
- if (NULL != (nn = n->parent->head->child))
- if (NULL != (nn = nn->next))
- if ((ival = a2width(p, nn->string)) >= 0)
- len = (size_t)ival;
+ if ((nn = n->parent->head->child) != NULL &&
+ (nn = nn->next) != NULL &&
+ a2roffsu(nn->string, &su, SCALE_EN)) {
+ len = term_hspan(p, &su);
+ mt->lmargin[mt->lmargincur] = len;
+ if (len < 0 && (size_t)(-len) > mt->offset)
+ len = -mt->offset;
+ } else
+ len = mt->lmargin[mt->lmargincur];
switch (n->type) {
case MAN_HEAD:
- /* Handle zero-width lengths. */
- if (0 == len)
- len = term_len(p, 1);
-
p->offset = mt->offset;
p->rmargin = mt->offset + len;
- /* Set the saved left-margin. */
- if (ival >= 0)
- mt->lmargin[mt->lmargincur] = (size_t)ival;
-
savelit = MANT_LITERAL & mt->fl;
mt->fl &= ~MANT_LITERAL;
@@ -672,9 +637,9 @@ post_IP(DECL_ARGS)
static int
pre_TP(DECL_ARGS)
{
+ struct roffsu su;
const struct man_node *nn;
- size_t len;
- int savelit, ival;
+ int len, savelit;
switch (n->type) {
case MAN_HEAD:
@@ -691,22 +656,20 @@ pre_TP(DECL_ARGS)
return(1);
}
- len = (size_t)mt->lmargin[mt->lmargincur];
- ival = -1;
-
/* Calculate offset. */
- if (NULL != (nn = n->parent->head->child))
- if (nn->string && 0 == (MAN_LINE & nn->flags))
- if ((ival = a2width(p, nn->string)) >= 0)
- len = (size_t)ival;
+ if ((nn = n->parent->head->child) != NULL &&
+ nn->string != NULL && ! (MAN_LINE & nn->flags) &&
+ a2roffsu(nn->string, &su, SCALE_EN)) {
+ len = term_hspan(p, &su);
+ mt->lmargin[mt->lmargincur] = len;
+ if (len < 0 && (size_t)(-len) > mt->offset)
+ len = -mt->offset;
+ } else
+ len = mt->lmargin[mt->lmargincur];
switch (n->type) {
case MAN_HEAD:
- /* Handle zero-length properly. */
- if (0 == len)
- len = term_len(p, 1);
-
p->offset = mt->offset;
p->rmargin = mt->offset + len;
@@ -725,9 +688,6 @@ pre_TP(DECL_ARGS)
if (savelit)
mt->fl |= MANT_LITERAL;
- if (ival >= 0)
- mt->lmargin[mt->lmargincur] = (size_t)ival;
-
return(0);
case MAN_BODY:
p->offset = mt->offset + len;
@@ -872,8 +832,8 @@ post_SH(DECL_ARGS)
static int
pre_RS(DECL_ARGS)
{
- int ival;
- size_t sz;
+ struct roffsu su;
+ int len;
switch (n->type) {
case MAN_BLOCK:
@@ -885,13 +845,16 @@ pre_RS(DECL_ARGS)
break;
}
- sz = term_len(p, p->defindent);
-
- if (NULL != (n = n->parent->head->child))
- if ((ival = a2width(p, n->string)) >= 0)
- sz = (size_t)ival;
+ if ((n = n->parent->head->child) != NULL &&
+ a2roffsu(n->string, &su, SCALE_EN))
+ len = term_hspan(p, &su);
+ else
+ len = term_len(p, p->defindent);
- mt->offset += sz;
+ if (len > 0 || (size_t)(-len) < mt->offset)
+ mt->offset += len;
+ else
+ mt->offset = 0;
p->offset = mt->offset;
p->rmargin = p->maxrmargin;
@@ -905,8 +868,8 @@ pre_RS(DECL_ARGS)
static void
post_RS(DECL_ARGS)
{
- int ival;
- size_t sz;
+ struct roffsu su;
+ int len;
switch (n->type) {
case MAN_BLOCK:
@@ -918,13 +881,16 @@ post_RS(DECL_ARGS)
break;
}
- sz = term_len(p, p->defindent);
-
- if (NULL != (n = n->parent->head->child))
- if ((ival = a2width(p, n->string)) >= 0)
- sz = (size_t)ival;
+ if ((n = n->parent->head->child) != NULL &&
+ a2roffsu(n->string, &su, SCALE_EN))
+ len = term_hspan(p, &su);
+ else
+ len = term_len(p, p->defindent);
- mt->offset = mt->offset < sz ? 0 : mt->offset - sz;
+ if (len < 0 || (size_t)len < mt->offset)
+ mt->offset -= len;
+ else
+ mt->offset = 0;
p->offset = mt->offset;
if (--mt->lmarginsz < MAXMARGINS)
diff --git a/mdoc_html.c b/mdoc_html.c
index 402ee1ad..885565e3 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -282,7 +282,8 @@ a2width(const char *p, struct roffsu *su)
if (a2roffsu(p, su, SCALE_MAX) < 2) {
su->unit = SCALE_EN;
su->scale = html_strlen(p);
- }
+ } else if (su->scale < 0.0)
+ su->scale = 0.0;
}
/*
@@ -1566,9 +1567,12 @@ mdoc_sp_pre(MDOC_ARGS)
SCALE_VS_INIT(&su, 1);
if (MDOC_sp == n->tok) {
- if (NULL != (n = n->child))
+ if (NULL != (n = n->child)) {
if ( ! a2roffsu(n->string, &su, SCALE_VS))
su.scale = 1.0;
+ else if (su.scale < 0.0)
+ su.scale = 0.0;
+ }
} else
su.scale = 0.0;
diff --git a/mdoc_man.c b/mdoc_man.c
index 6995f872..f6ee541d 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -435,6 +435,8 @@ print_offs(const char *v, int keywords)
else if (keywords && !strcmp(v, "indent-two"))
sz = 12;
else if (a2roffsu(v, &su, SCALE_EN) > 1) {
+ if (su.scale < 0.0)
+ su.scale = 0.0;
if (SCALE_EN == su.unit)
sz = su.scale;
else {
@@ -482,6 +484,8 @@ print_width(const char *v, const struct mdoc_node *child, size_t defsz)
if (NULL == v)
sz = defsz;
else if (a2roffsu(v, &su, SCALE_MAX) > 1) {
+ if (su.scale < 0.0)
+ su.scale = 0.0;
if (SCALE_EN == su.unit)
sz = su.scale;
else {
diff --git a/mdoc_term.c b/mdoc_term.c
index 4a8ddb86..d8004b9a 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -533,7 +533,8 @@ a2width(const struct termp *p, const char *v)
if (a2roffsu(v, &su, SCALE_MAX) < 2) {
SCALE_HS_INIT(&su, term_strlen(p, v));
su.scale /= term_strlen(p, "0");
- }
+ } else if (su.scale < 0.0)
+ su.scale = 0.0;
return(term_hspan(p, &su));
}
diff --git a/out.c b/out.c
index f5d36fb1..b0024d3f 100644
--- a/out.c
+++ b/out.c
@@ -94,9 +94,6 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
break;
}
- /* FIXME: do this in the caller. */
- if (dst->scale < 0.0)
- dst->scale = 0.0;
return(*endptr == '\0' ? 2 : 1);
}
diff --git a/term.c b/term.c
index 78dd69f1..ee9f31f3 100644
--- a/term.c
+++ b/term.c
@@ -101,7 +101,6 @@ term_flushln(struct termp *p)
size_t j; /* temporary loop index for p->buf */
size_t jhy; /* last hyph before overflow w/r/t j */
size_t maxvis; /* output position of visible boundary */
- size_t rmargin; /* the rightmost of the two margins */
/*
* First, establish the maximum columns of "visible" content.
@@ -114,8 +113,7 @@ term_flushln(struct termp *p)
* is negative, it gets sign extended. Subtracting that
* very large size_t effectively adds a small number to dv.
*/
- rmargin = p->rmargin > p->offset ? p->rmargin : p->offset;
- dv = p->rmargin - p->offset;
+ dv = p->rmargin > p->offset ? p->rmargin - p->offset : 0;
maxvis = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
if (p->flags & TERMP_NOBREAK) {
@@ -193,8 +191,9 @@ term_flushln(struct termp *p)
(*p->endline)(p);
p->viscol = 0;
if (TERMP_BRIND & p->flags) {
- vbl = rmargin;
- vend += rmargin - p->offset;
+ vbl = p->rmargin;
+ vend += p->rmargin;
+ vend -= p->offset;
} else
vbl = p->offset;
@@ -770,7 +769,7 @@ term_strlen(const struct termp *p, const char *cp)
return(sz);
}
-size_t
+int
term_vspan(const struct termp *p, const struct roffsu *su)
{
double r;
@@ -809,19 +808,14 @@ term_vspan(const struct termp *p, const struct roffsu *su)
abort();
/* NOTREACHED */
}
-
- if (r < 0.0)
- r = 0.0;
- return((size_t)(r + 0.4995));
+ return(r > 0.0 ? r + 0.4995 : r - 0.4995);
}
-size_t
+int
term_hspan(const struct termp *p, const struct roffsu *su)
{
double v;
v = (*p->hspan)(p, su);
- if (v < 0.0)
- v = 0.0;
- return((size_t)(v + 0.0005));
+ return(v > 0.0 ? v + 0.0005 : v - 0.0005);
}
diff --git a/term.h b/term.h
index 40f2bcf9..f9170f0c 100644
--- a/term.h
+++ b/term.h
@@ -121,10 +121,8 @@ void term_begin(struct termp *, term_margin,
void term_end(struct termp *);
void term_setwidth(struct termp *, const char *);
-size_t term_hspan(const struct termp *,
- const struct roffsu *);
-size_t term_vspan(const struct termp *,
- const struct roffsu *);
+int term_hspan(const struct termp *, const struct roffsu *);
+int term_vspan(const struct termp *, const struct roffsu *);
size_t term_strlen(const struct termp *, const char *);
size_t term_len(const struct termp *, size_t);