=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/term.c,v retrieving revision 1.92 retrieving revision 1.93 diff -c -r1.92 -r1.93 *** src/usr.bin/mandoc/term.c 2014/10/28 18:48:56 1.92 --- src/usr.bin/mandoc/term.c 2014/10/29 00:17:01 1.93 *************** *** 1,4 **** ! /* $OpenBSD: term.c,v 1.92 2014/10/28 18:48:56 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: term.c,v 1.93 2014/10/29 00:17:01 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze *************** *** 389,395 **** { const char nbrsp[2] = { ASCII_NBRSP, 0 }; const char *seq, *cp; - char c; int sz, uc; size_t ssz; enum mandoc_esc esc; --- 389,394 ---- *************** *** 441,456 **** switch (esc) { case ESCAPE_UNICODE: uc = mchars_num2uc(seq + 1, sz - 1); - if (p->enc == TERMENC_ASCII) { - cp = ascii_uc2str(uc); - encode(p, cp, strlen(cp)); - } else - encode1(p, uc); break; case ESCAPE_NUMBERED: ! c = mchars_num2char(seq, sz); ! if ('\0' != c) ! encode(p, &c, 1); break; case ESCAPE_SPECIAL: if (p->enc == TERMENC_ASCII) { --- 440,450 ---- switch (esc) { case ESCAPE_UNICODE: uc = mchars_num2uc(seq + 1, sz - 1); break; case ESCAPE_NUMBERED: ! uc = mchars_num2char(seq, sz); ! if (uc < 0) ! continue; break; case ESCAPE_SPECIAL: if (p->enc == TERMENC_ASCII) { *************** *** 463,498 **** if (uc > 0) encode1(p, uc); } ! break; case ESCAPE_FONTBOLD: term_fontrepl(p, TERMFONT_BOLD); ! break; case ESCAPE_FONTITALIC: term_fontrepl(p, TERMFONT_UNDER); ! break; case ESCAPE_FONTBI: term_fontrepl(p, TERMFONT_BI); ! break; case ESCAPE_FONT: /* FALLTHROUGH */ case ESCAPE_FONTROMAN: term_fontrepl(p, TERMFONT_NONE); ! break; case ESCAPE_FONTPREV: term_fontlast(p); ! break; case ESCAPE_NOSPACE: if (TERMP_SKIPCHAR & p->flags) p->flags &= ~TERMP_SKIPCHAR; else if ('\0' == *word) p->flags |= TERMP_NOSPACE; ! break; case ESCAPE_SKIPCHAR: p->flags |= TERMP_SKIPCHAR; ! break; default: ! break; } } p->flags &= ~TERMP_NBRWORD; } --- 457,507 ---- if (uc > 0) encode1(p, uc); } ! continue; case ESCAPE_FONTBOLD: term_fontrepl(p, TERMFONT_BOLD); ! continue; case ESCAPE_FONTITALIC: term_fontrepl(p, TERMFONT_UNDER); ! continue; case ESCAPE_FONTBI: term_fontrepl(p, TERMFONT_BI); ! continue; case ESCAPE_FONT: /* FALLTHROUGH */ case ESCAPE_FONTROMAN: term_fontrepl(p, TERMFONT_NONE); ! continue; case ESCAPE_FONTPREV: term_fontlast(p); ! continue; case ESCAPE_NOSPACE: if (TERMP_SKIPCHAR & p->flags) p->flags &= ~TERMP_SKIPCHAR; else if ('\0' == *word) p->flags |= TERMP_NOSPACE; ! continue; case ESCAPE_SKIPCHAR: p->flags |= TERMP_SKIPCHAR; ! continue; default: ! continue; } + + /* + * Common handling for Unicode and numbered + * character escape sequences. + */ + + if (p->enc == TERMENC_ASCII) { + cp = ascii_uc2str(uc); + encode(p, cp, strlen(cp)); + } else { + if ((uc < 0x20 && uc != 0x09) || + (uc > 0x7E && uc < 0xA0)) + uc = 0xFFFD; + encode1(p, uc); + } } p->flags &= ~TERMP_NBRWORD; } *************** *** 643,649 **** term_strlen(const struct termp *p, const char *cp) { size_t sz, rsz, i; ! int ssz, skip, c; const char *seq, *rhs; enum mandoc_esc esc; static const char rej[] = { '\\', ASCII_NBRSP, ASCII_HYPH, --- 652,658 ---- term_strlen(const struct termp *p, const char *cp) { size_t sz, rsz, i; ! int ssz, skip, uc; const char *seq, *rhs; enum mandoc_esc esc; static const char rej[] = { '\\', ASCII_NBRSP, ASCII_HYPH, *************** *** 673,715 **** switch (esc) { case ESCAPE_UNICODE: ! c = mchars_num2uc(seq + 1, sz - 1); ! if (p->enc == TERMENC_ASCII) { ! rhs = ascii_uc2str(c); ! rsz = strlen(rhs); ! } else ! sz += cond_width(p, c, &skip); break; case ESCAPE_NUMBERED: ! c = mchars_num2char(seq, ssz); ! if ('\0' != c) ! sz += cond_width(p, c, &skip); break; case ESCAPE_SPECIAL: ! if (p->enc == TERMENC_ASCII) rhs = mchars_spec2str(p->symtab, seq, ssz, &rsz); ! else { ! c = mchars_spec2cp(p->symtab, seq, ssz); ! if (c > 0) ! sz += cond_width(p, c, &skip); } ! break; case ESCAPE_SKIPCHAR: skip = 1; ! break; default: ! break; } ! if (NULL == rhs) ! break; if (skip) { skip = 0; break; } for (i = 0; i < rsz; i++) sz += (*p->width)(p, *rhs++); --- 682,741 ---- switch (esc) { case ESCAPE_UNICODE: ! uc = mchars_num2uc(seq + 1, sz - 1); break; case ESCAPE_NUMBERED: ! uc = mchars_num2char(seq, ssz); ! if (uc < 0) ! continue; break; case ESCAPE_SPECIAL: ! if (p->enc == TERMENC_ASCII) { rhs = mchars_spec2str(p->symtab, seq, ssz, &rsz); ! if (rhs != NULL) ! break; ! } else { ! uc = mchars_spec2cp(p->symtab, seq, ssz); ! if (uc > 0) ! sz += cond_width(p, uc, &skip); } ! continue; case ESCAPE_SKIPCHAR: skip = 1; ! continue; default: ! continue; } ! /* ! * Common handling for Unicode and numbered ! * character escape sequences. ! */ + if (rhs == NULL) { + if (p->enc == TERMENC_ASCII) { + rhs = ascii_uc2str(uc); + rsz = strlen(rhs); + } else { + if ((uc < 0x20 && uc != 0x09) || + (uc > 0x7E && uc < 0xA0)) + uc = 0xFFFD; + sz += cond_width(p, uc, &skip); + continue; + } + } + if (skip) { skip = 0; break; } + + /* + * Common handling for all escape sequences + * printing more than one character. + */ for (i = 0; i < rsz; i++) sz += (*p->width)(p, *rhs++);