diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2014-12-23 13:48:57 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2014-12-23 13:48:57 +0000 |
commit | 4ad53635f5202474c55af90f70bba0ade18962cb (patch) | |
tree | ec073e4714b3d859a66a94147789aa077e78dd38 | |
parent | f2c1420553b275dd2f792b3a15c8fb0437f58052 (diff) | |
download | mandoc-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.c | 176 | ||||
-rw-r--r-- | mdoc_html.c | 8 | ||||
-rw-r--r-- | mdoc_man.c | 4 | ||||
-rw-r--r-- | mdoc_term.c | 3 | ||||
-rw-r--r-- | out.c | 3 | ||||
-rw-r--r-- | term.c | 22 | ||||
-rw-r--r-- | term.h | 6 |
7 files changed, 93 insertions, 129 deletions
@@ -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; @@ -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)); } @@ -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); } @@ -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); } @@ -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); |