sh.print.c revision 145479
1145479Smp/* $Header: /src/pub/tcsh/sh.print.c,v 3.28 2005/03/03 17:19:35 kim Exp $ */
259243Sobrien/*
359243Sobrien * sh.print.c: Primitive Output routines.
459243Sobrien */
559243Sobrien/*-
659243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California.
759243Sobrien * All rights reserved.
859243Sobrien *
959243Sobrien * Redistribution and use in source and binary forms, with or without
1059243Sobrien * modification, are permitted provided that the following conditions
1159243Sobrien * are met:
1259243Sobrien * 1. Redistributions of source code must retain the above copyright
1359243Sobrien *    notice, this list of conditions and the following disclaimer.
1459243Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1559243Sobrien *    notice, this list of conditions and the following disclaimer in the
1659243Sobrien *    documentation and/or other materials provided with the distribution.
17100616Smp * 3. Neither the name of the University nor the names of its contributors
1859243Sobrien *    may be used to endorse or promote products derived from this software
1959243Sobrien *    without specific prior written permission.
2059243Sobrien *
2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2459243Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3159243Sobrien * SUCH DAMAGE.
3259243Sobrien */
3359243Sobrien#include "sh.h"
3459243Sobrien
35145479SmpRCSID("$Id: sh.print.c,v 3.28 2005/03/03 17:19:35 kim Exp $")
3659243Sobrien
3759243Sobrien#include "ed.h"
3859243Sobrien
3959243Sobrienextern int Tty_eight_bit;
4059243Sobrien
4159243Sobrienint     lbuffed = 1;		/* true if line buffered */
4259243Sobrien
43145479Smpstatic	void	p2dig	__P((unsigned int));
4459243Sobrien
4559243Sobrien/*
4659243Sobrien * C Shell
4759243Sobrien */
4859243Sobrien
4959243Sobrien#if defined(BSDLIMIT) || defined(RLIMIT_CPU)
5059243Sobrienvoid
5159243Sobrienpsecs(l)
52145479Smp    unsigned long    l;
5359243Sobrien{
54145479Smp    int i;
5559243Sobrien
5659243Sobrien    i = (int) (l / 3600);
5759243Sobrien    if (i) {
5859243Sobrien	xprintf("%d:", i);
5959243Sobrien	i = (int) (l % 3600);
6059243Sobrien	p2dig(i / 60);
6159243Sobrien	goto minsec;
6259243Sobrien    }
6359243Sobrien    i = (int) l;
6459243Sobrien    xprintf("%d", i / 60);
6559243Sobrienminsec:
6659243Sobrien    i %= 60;
6759243Sobrien    xprintf(":");
6859243Sobrien    p2dig(i);
6959243Sobrien}
7059243Sobrien
7159243Sobrien#endif
7259243Sobrien
7359243Sobrienvoid
7459243Sobrienpcsecs(l)			/* PWP: print mm:ss.dd, l is in sec*100 */
7559243Sobrien#ifdef BSDTIMES
76145479Smp    unsigned long    l;
7759243Sobrien#else /* BSDTIMES */
7859243Sobrien# ifndef POSIX
7959243Sobrien    time_t  l;
8059243Sobrien# else /* POSIX */
8159243Sobrien    clock_t l;
8259243Sobrien# endif /* POSIX */
8359243Sobrien#endif /* BSDTIMES */
8459243Sobrien{
85145479Smp    int i;
8659243Sobrien
8759243Sobrien    i = (int) (l / 360000);
8859243Sobrien    if (i) {
8959243Sobrien	xprintf("%d:", i);
9059243Sobrien	i = (int) ((l % 360000) / 100);
9159243Sobrien	p2dig(i / 60);
9259243Sobrien	goto minsec;
9359243Sobrien    }
9459243Sobrien    i = (int) (l / 100);
9559243Sobrien    xprintf("%d", i / 60);
9659243Sobrienminsec:
9759243Sobrien    i %= 60;
9859243Sobrien    xprintf(":");
9959243Sobrien    p2dig(i);
10059243Sobrien    xprintf(".");
10159243Sobrien    p2dig((int) (l % 100));
10259243Sobrien}
10359243Sobrien
10459243Sobrienstatic void
10559243Sobrienp2dig(i)
106145479Smp    unsigned int i;
10759243Sobrien{
10859243Sobrien
109145479Smp    xprintf("%u%u", i / 10, i % 10);
11059243Sobrien}
11159243Sobrien
11259243Sobrienchar    linbuf[2048];		/* was 128 */
11359243Sobrienchar   *linp = linbuf;
114145479Smpint    output_raw = 0;		/* PWP */
115145479Smpint    xlate_cr   = 0;		/* HE */
11659243Sobrien
117145479Smp#ifdef WIDE_STRINGS
11859243Sobrienvoid
119145479Smpputwraw(Char c)
120145479Smp{
121145479Smp    char buf[MB_LEN_MAX];
122145479Smp    size_t i, len;
123145479Smp
124145479Smp    len = one_wctomb(buf, c & CHAR);
125145479Smp    for (i = 0; i < len; i++)
126145479Smp	putraw((unsigned char)buf[i] | (c & ~CHAR));
127145479Smp}
128145479Smp
129145479Smpvoid
130145479Smpxputwchar(Char c)
131145479Smp{
132145479Smp    char buf[MB_LEN_MAX];
133145479Smp    size_t i, len;
134145479Smp
135145479Smp    len = one_wctomb(buf, c & CHAR);
136145479Smp    for (i = 0; i < len; i++)
137145479Smp	xputchar((unsigned char)buf[i] | (c & ~CHAR));
138145479Smp}
139145479Smp#endif
140145479Smp
141145479Smpvoid
14259243Sobrienxputchar(c)
143145479Smp    int c;
14459243Sobrien{
14559243Sobrien    int     atr = 0;
14659243Sobrien
14759243Sobrien    atr |= c & ATTRIBUTES & TRIM;
14859243Sobrien    c &= CHAR | QUOTE;
14959243Sobrien    if (!output_raw && (c & QUOTE) == 0) {
150145479Smp	if (iscntrl(c) && (c < 0x80 || MB_CUR_MAX == 1)) {
15159243Sobrien#ifdef COLORCAT
152145479Smp	    if (c != '\t' && c != '\n' && !(adrof(STRcolorcat) && c=='\033') && (xlate_cr || c != '\r'))
15359243Sobrien#else
154145479Smp	    if (c != '\t' && c != '\n' && (xlate_cr || c != '\r'))
15559243Sobrien#endif
156145479Smp	    {
15759243Sobrien		xputchar('^' | atr);
15869408Sache#ifdef IS_ASCII
159145479Smp		if (c == 0177)
16059243Sobrien		    c = '?';
16159243Sobrien		else
16259243Sobrien		    c |= 0100;
16369408Sache#else
16459243Sobrien		if (c == CTL_ESC('\177'))
16559243Sobrien		    c = '?';
16659243Sobrien		else
16759243Sobrien		    c =_toebcdic[_toascii[c]|0100];
16869408Sache#endif
16959243Sobrien
17059243Sobrien	    }
17159243Sobrien	}
172145479Smp	else if (!isprint(c) && (c < 0x80 || MB_CUR_MAX == 1)) {
17359243Sobrien	    xputchar('\\' | atr);
17459243Sobrien	    xputchar((((c >> 6) & 7) + '0') | atr);
17559243Sobrien	    xputchar((((c >> 3) & 7) + '0') | atr);
17659243Sobrien	    c = (c & 7) + '0';
17759243Sobrien	}
17859243Sobrien	(void) putraw(c | atr);
17959243Sobrien    }
18059243Sobrien    else {
18159243Sobrien	c &= TRIM;
18259243Sobrien	if (haderr ? (didfds ? is2atty : isdiagatty) :
18359243Sobrien	    (didfds ? is1atty : isoutatty))
18459243Sobrien	    SetAttributes(c | atr);
18559243Sobrien	(void) putpure(c);
18659243Sobrien    }
18759243Sobrien    if (lbuffed && (c & CHAR) == '\n')
18859243Sobrien	flush();
18959243Sobrien}
19059243Sobrien
19159243Sobrienint
19259243Sobrienputraw(c)
193145479Smp    int c;
19459243Sobrien{
19559243Sobrien    if (haderr ? (didfds ? is2atty : isdiagatty) :
19659243Sobrien	(didfds ? is1atty : isoutatty)) {
19759243Sobrien	if (Tty_eight_bit == -1)
19859243Sobrien	    ed_set_tty_eight_bit();
19959243Sobrien	if (!Tty_eight_bit && (c & META)) {
20059243Sobrien	    c = (c & ~META) | STANDOUT;
20159243Sobrien	}
20259243Sobrien	SetAttributes(c);
20359243Sobrien    }
20459243Sobrien    return putpure(c);
20559243Sobrien}
20659243Sobrien
20759243Sobrienint
20859243Sobrienputpure(c)
209145479Smp    int c;
21059243Sobrien{
21159243Sobrien    c &= CHAR;
21259243Sobrien
21359243Sobrien    *linp++ = (char) c;
21459243Sobrien    if (linp >= &linbuf[sizeof linbuf - 10])
21559243Sobrien	flush();
21659243Sobrien    return (1);
21759243Sobrien}
21859243Sobrien
21959243Sobrienvoid
22059243Sobriendrainoline()
22159243Sobrien{
22259243Sobrien    linp = linbuf;
22359243Sobrien}
22459243Sobrien
22559243Sobrienvoid
22659243Sobrienflush()
22759243Sobrien{
22859243Sobrien    int unit;
22959243Sobrien    static int interrupted = 0;
23059243Sobrien    size_t sz;
23159243Sobrien
23259243Sobrien    /* int lmode; */
23359243Sobrien
23459243Sobrien    if (linp == linbuf)
23559243Sobrien	return;
23659243Sobrien    if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10])
23759243Sobrien	return;
23859243Sobrien    if (interrupted) {
23959243Sobrien	interrupted = 0;
24059243Sobrien	linp = linbuf;		/* avoid resursion as stderror calls flush */
24159243Sobrien	stderror(ERR_SILENT);
24259243Sobrien    }
24359243Sobrien    interrupted = 1;
24459243Sobrien    if (haderr)
24559243Sobrien	unit = didfds ? 2 : SHDIAG;
24659243Sobrien    else
24759243Sobrien	unit = didfds ? 1 : SHOUT;
24859243Sobrien#ifdef COMMENT
24959243Sobrien#ifdef TIOCLGET
25059243Sobrien    if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 &&
25159243Sobrien	lmode & LFLUSHO) {
25259243Sobrien	lmode = LFLUSHO;
25359243Sobrien	(void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode);
25459243Sobrien	(void) write(unit, "\n", 1);
25559243Sobrien    }
25659243Sobrien#endif
25759243Sobrien#endif
25859243Sobrien    sz = (size_t) (linp - linbuf);
25959243Sobrien    if (write(unit, linbuf, sz) == -1)
26059243Sobrien	switch (errno) {
26159243Sobrien#ifdef EIO
26259243Sobrien	/* We lost our tty */
26359243Sobrien	case EIO:
26459243Sobrien#endif
26559243Sobrien#ifdef ENXIO
26659243Sobrien	/*
26759243Sobrien	 * Deal with Digital Unix 4.0D bogocity, returning ENXIO when
26859243Sobrien	 * we lose our tty.
26959243Sobrien	 */
27059243Sobrien	case ENXIO:
27159243Sobrien#endif
27259243Sobrien	/*
27359243Sobrien	 * IRIX 6.4 bogocity?
27459243Sobrien	 */
27559243Sobrien#ifdef ENOTTY
27659243Sobrien	case ENOTTY:
27759243Sobrien#endif
27859243Sobrien#ifdef EBADF
27959243Sobrien	case EBADF:
28059243Sobrien#endif
28159415Sobrien#ifdef ESTALE
28259243Sobrien	/*
28359415Sobrien	 * Lost our file descriptor, exit (IRIS4D)
28459415Sobrien	 */
28559415Sobrien	case ESTALE:
28659415Sobrien#endif
28759415Sobrien	/*
28859243Sobrien	 * Over our quota, writing the history file
28959243Sobrien	 */
29059243Sobrien#ifdef EDQUOT
29159243Sobrien	case EDQUOT:
29259243Sobrien#endif
29359243Sobrien	/* Nothing to do, but die */
29459243Sobrien	    xexit(1);
29559243Sobrien	    break;
29659243Sobrien	default:
29759243Sobrien	    stderror(ERR_SILENT);
29859243Sobrien	    break;
29959243Sobrien	}
30059243Sobrien
30159243Sobrien    linp = linbuf;
30259243Sobrien    interrupted = 0;
30359243Sobrien}
304