diff --git a/bin/ed/ed.h b/bin/ed/ed.h --- a/bin/ed/ed.h +++ b/bin/ed/ed.h @@ -36,6 +36,8 @@ #include #include #include +#include +#include #define ERR (-2) #define EMOD (-3) diff --git a/bin/ed/io.c b/bin/ed/io.c --- a/bin/ed/io.c +++ b/bin/ed/io.c @@ -298,13 +298,49 @@ int col = 0; int lc = 0; char *cp; + wchar_t wc; + mbstate_t mbs; + size_t clen; + int w; if (gflag & GNP) { printf("%ld\t", n); col = 8; } - for (; l--; s++) { - if ((gflag & GLS) && ++col > cols) { + for (; l > 0;) { + if (!(gflag & GLS)) { + putchar(*s++); + l--; + continue; + } + /* GLS mode: try to decode a multibyte character */ + memset(&mbs, 0, sizeof(mbs)); + clen = mbrtowc(&wc, s, l, &mbs); + if (clen != (size_t)-1 && clen != (size_t)-2 && + clen > 1 && iswprint(wc) && (w = wcwidth(wc)) >= 0) { + /* printable multibyte character */ + if (col + w > cols) { + fputs("\\\n", stdout); + col = 0; +#ifndef BACKWARDS + if (!scripted && !isglobal && ++lc > rows) { + lc = 0; + fputs("Press to continue... ", + stdout); + fflush(stdout); + if (get_tty_line() < 0) + return ERR; + } +#endif + } + col += w; + fwrite(s, 1, clen, stdout); + s += clen; + l -= clen; + continue; + } + /* single byte: ASCII printable, escape sequence, or octal */ + if (++col > cols) { fputs("\\\n", stdout); col = 1; #ifndef BACKWARDS @@ -317,24 +353,22 @@ } #endif } - if (gflag & GLS) { - if (31 < *s && *s < 127 && *s != '\\') - putchar(*s); + if (31 < *s && *s < 127 && *s != '\\') + putchar(*s); + else { + putchar('\\'); + col++; + if (*s && (cp = strchr(ESCAPES, *s)) != NULL) + putchar(ESCCHARS[cp - ESCAPES]); else { - putchar('\\'); - col++; - if (*s && (cp = strchr(ESCAPES, *s)) != NULL) - putchar(ESCCHARS[cp - ESCAPES]); - else { - putchar((((unsigned char) *s & 0300) >> 6) + '0'); - putchar((((unsigned char) *s & 070) >> 3) + '0'); - putchar(((unsigned char) *s & 07) + '0'); - col += 2; - } + putchar((((unsigned char) *s & 0300) >> 6) + '0'); + putchar((((unsigned char) *s & 070) >> 3) + '0'); + putchar(((unsigned char) *s & 07) + '0'); + col += 2; } - - } else - putchar(*s); + } + s++; + l--; } #ifndef BACKWARDS if (gflag & GLS)