/* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. */ /* from Unix 32V /usr/src/cmd/col.c */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * Redistributions of source code and documentation must retain the * above copyright notice, this list of conditions and the following * disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed or owned by Caldera * International, Inc. * Neither the name of Caldera International, Inc. nor the names of * other contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 #define USED __attribute__ ((used)) #elif defined __GNUC__ #define USED __attribute__ ((unused)) #else #define USED #endif static const char sccsid[] USED = "@(#)col.sl 1.9 (gritter) 5/29/05"; # include # include # include # include # include # include # include # include # include # include # if defined (__GLIBC__) && defined (_IO_putc_unlocked) # undef putchar # define putchar(c) _IO_putc_unlocked(c, stdout) # endif # define PL 256 # define ESC '\033' # define RLF '\013' # define SI '\017' # define SO '\016' # define CMASK 0x00000000ffffffffLL # define EOFC 0x0000010000000000LL # define TRANS 0x1000000000000000LL # define GREEK 0x2000000000000000LL # define ILLSEQ 0x4000000000000000LL # define ISPRNT 0x8000000000000000LL # define COLMSK 0x0f00000000000000LL # define COLSHF 56 # define CHRMSK 0x000000ff00000000LL # define CHRSHF 32 # define nextc(c, cp, m) (mb_cur_max > 1 ? \ ((cp) = ib_getw(input, &(c), &(m)), \ (cp) == NULL ? EOFC : \ (c) == WEOF ? ((long long)(*(cp)&0377)<= LINELN ? growsbuff((n)+128) : lbuff); static long long *page[PL]; static long long *lbuff; static long line, LINELN; static int bflag, xflag, fflag, pflag; static int half; static int cp, lp; static int ll, llh, mustwr; static int pcp = 0; static char *pgmname; static struct iblok *input; static int mb_cur_max; static long long space[] = { ' ' | (1LL< 0) { incr(); incr(); half -= 2; } } break; default: if (pflag) { outc(ESC); cp++; if (c != EOFC) { outc(c); cp += (c&COLMSK)>>COLSHF; } } } continue; case SO: greek = GREEK; continue; case SI: greek = 0; continue; case RLF: decr(); decr(); continue; case '\r': cp = 0; continue; case '\t': cp = (cp + 8) & -8; continue; case '\b': if (cp > 0) cp--; continue; case ' ': cp++; continue; default: if (c & ISPRNT) {/* if printable */ outc(c | greek); cp += (c&COLMSK)>>COLSHF; } continue; } } for (i=0; i cp) { line = 0; lp = 0; } while (lp < cp) { slbuff(0); switch (lbuff[line]) { case '\0': lbuff[line] = ' ' | ISPRNT | (1LL<>COLSHF; if (lp > cp) continue; } line++; } slbuff(0); while ((lbuff[line] & CMASK) == '\b') { line += 2; slbuff(0); } if (bflag || lbuff[line] == '\0' || (lbuff[line]&CMASK) == ' ' && (lbuff[line]&TRANS) == 0) { w = (lbuff[line]&COLMSK)>>COLSHF; if (lp > cp) { w -= lp-cp; n = lllen(&lbuff[line]) + 1; slbuff(lp-cp+n); memmove(&lbuff[line+lp-cp], &lbuff[line], n * sizeof *lbuff); n = lp - cp; while (n--) lbuff[line++] = ' '|ISPRNT|(1LL<>COLSHF; lbuff[line] = c; if (w > v) { n = lllen(&lbuff[line+w-v]) + 1; slbuff(w-v+n); memmove(&lbuff[line+w-v], &lbuff[line], n * sizeof *lbuff); n = w - v; while (n--) lbuff[++line] = ' '|ISPRNT|(1LL< cp) line++; slbuff(1); w = (lbuff[line++]&COLMSK)>>COLSHF; if (lp > cp) { w += lp - cp; lp = cp; } v = (c&COLMSK)>>COLSHF; n = lllen(&lbuff[line]) + 1; slbuff(w+1+n); memmove(&lbuff[line+w+1], &lbuff[line], n * sizeof *lbuff); for (i = 0; i < w; i++) { slbuff(0); lbuff[line++] = '\b'; } slbuff(0); lbuff[line++] = c; if (w > v) { n = lllen(&lbuff[line+w-v]) + 1; slbuff(w-v+n); memmove(&lbuff[line+w-v], &lbuff[line], n * sizeof *lbuff); n = w - v; while (n--) lbuff[++line] = ' '|ISPRNT|(1LL<>CHRSHF); else if (mb_cur_max == 1) putchar(*p & 0377); else { char mb[MB_LEN_MAX]; int n; n = wctomb(mb, *p&CMASK); for (i = 0; i < n; i++) putchar(mb[i] & 0377); } if ((*p&CMASK) == '\b') { pcp--; } else pcp += (*p&COLMSK)>>COLSHF; p++; } } } static void incr(void) { store (ll++); if (ll > llh) llh = ll; if (ll >= mustwr && page[ll%PL]) { emit (page[ll%PL], ll - PL); mustwr++; free (page[ll%PL]); page[ll%PL] = 0; } fetch (ll); } static void decr(void) { if (ll > mustwr - PL) { store (ll--); fetch (ll); } } static size_t lllen(const long long *lp) { size_t n = 0; while (*lp++) n++; return n; } static long long *llcpy(long long *dst, const long long *sp) { long long *dp = dst; while (*dp++ = *sp++); return dst; } static long long * growsbuff(size_t n) { if ((lbuff = realloc(lbuff, (line+n) * sizeof *lbuff)) == NULL) { write(2, "no memory\n", 10); _exit(077); } memset(&lbuff[LINELN], 0, (line+n-LINELN)*sizeof *lbuff); LINELN = line + n; return lbuff; }