sh.print.c revision 167466
133965Sjdp/* $Header: /p/tcsh/cvsroot/tcsh/sh.print.c,v 3.33 2006/08/23 15:03:14 christos Exp $ */
2218822Sdim/*
378828Sobrien * sh.print.c: Primitive Output routines.
433965Sjdp */
533965Sjdp/*-
633965Sjdp * Copyright (c) 1980, 1991 The Regents of the University of California.
733965Sjdp * All rights reserved.
833965Sjdp *
933965Sjdp * Redistribution and use in source and binary forms, with or without
1033965Sjdp * modification, are permitted provided that the following conditions
1133965Sjdp * are met:
1233965Sjdp * 1. Redistributions of source code must retain the above copyright
1333965Sjdp *    notice, this list of conditions and the following disclaimer.
1433965Sjdp * 2. Redistributions in binary form must reproduce the above copyright
1533965Sjdp *    notice, this list of conditions and the following disclaimer in the
1633965Sjdp *    documentation and/or other materials provided with the distribution.
1733965Sjdp * 3. Neither the name of the University nor the names of its contributors
1833965Sjdp *    may be used to endorse or promote products derived from this software
1933965Sjdp *    without specific prior written permission.
2033965Sjdp *
2133965Sjdp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2233965Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23218822Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2433965Sjdp * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2533965Sjdp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2633965Sjdp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2733965Sjdp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2833965Sjdp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2978828Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3033965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3160484Sobrien * SUCH DAMAGE.
3233965Sjdp */
3333965Sjdp#include "sh.h"
3433965Sjdp
3533965SjdpRCSID("$tcsh: sh.print.c,v 3.33 2006/08/23 15:03:14 christos Exp $")
3633965Sjdp
3733965Sjdp#include "ed.h"
3833965Sjdp
3933965Sjdpextern int Tty_eight_bit;
4033965Sjdp
4133965Sjdpint     lbuffed = 1;		/* true if line buffered */
4233965Sjdp
4333965Sjdpstatic	void	p2dig	(unsigned int);
4433965Sjdp
4533965Sjdp/*
4633965Sjdp * C Shell
4733965Sjdp */
4833965Sjdp
4933965Sjdp#if defined(BSDLIMIT) || defined(RLIMIT_CPU)
5033965Sjdpvoid
5133965Sjdppsecs(unsigned long l)
5233965Sjdp{
5333965Sjdp    int i;
5433965Sjdp
5533965Sjdp    i = (int) (l / 3600);
5633965Sjdp    if (i) {
5733965Sjdp	xprintf("%d:", i);
5833965Sjdp	i = (int) (l % 3600);
5933965Sjdp	p2dig(i / 60);
6033965Sjdp	goto minsec;
6133965Sjdp    }
6233965Sjdp    i = (int) l;
6333965Sjdp    xprintf("%d", i / 60);
6433965Sjdpminsec:
6533965Sjdp    i %= 60;
6633965Sjdp    xprintf(":");
6733965Sjdp    p2dig(i);
6833965Sjdp}
6933965Sjdp
7033965Sjdp#endif
7133965Sjdp
7233965Sjdpvoid			/* PWP: print mm:ss.dd, l is in sec*100 */
7333965Sjdp#ifdef BSDTIMES
7433965Sjdppcsecs(unsigned long l)
7533965Sjdp#else /* BSDTIMES */
7633965Sjdp# ifndef POSIX
7733965Sjdppcsecs(time_t l)
7833965Sjdp# else /* POSIX */
7933965Sjdppcsecs(clock_t l)
8033965Sjdp# endif /* POSIX */
8133965Sjdp#endif /* BSDTIMES */
8233965Sjdp{
8333965Sjdp    int i;
8433965Sjdp
8533965Sjdp    i = (int) (l / 360000);
8633965Sjdp    if (i) {
8733965Sjdp	xprintf("%d:", i);
8833965Sjdp	i = (int) ((l % 360000) / 100);
8933965Sjdp	p2dig(i / 60);
9033965Sjdp	goto minsec;
9133965Sjdp    }
9233965Sjdp    i = (int) (l / 100);
9333965Sjdp    xprintf("%d", i / 60);
9433965Sjdpminsec:
9533965Sjdp    i %= 60;
9633965Sjdp    xprintf(":");
9733965Sjdp    p2dig(i);
9833965Sjdp    xprintf(".");
9933965Sjdp    p2dig((int) (l % 100));
10033965Sjdp}
10133965Sjdp
10233965Sjdpstatic void
10333965Sjdpp2dig(unsigned i)
10433965Sjdp{
10533965Sjdp
10633965Sjdp    xprintf("%u%u", i / 10, i % 10);
10733965Sjdp}
10833965Sjdp
10933965Sjdpchar    linbuf[2048];		/* was 128 */
11033965Sjdpchar   *linp = linbuf;
11133965Sjdpint    output_raw = 0;		/* PWP */
11233965Sjdpint    xlate_cr   = 0;		/* HE */
11333965Sjdp
11433965Sjdp/* For cleanup_push() */
11533965Sjdpvoid
11633965Sjdpoutput_raw_restore(void *xorig)
11733965Sjdp{
11833965Sjdp    int *orig;
11933965Sjdp
12033965Sjdp    orig = xorig;
12133965Sjdp    output_raw = *orig;
12233965Sjdp}
12333965Sjdp
12433965Sjdp#ifdef WIDE_STRINGS
12533965Sjdpvoid
12633965Sjdpputwraw(Char c)
12733965Sjdp{
12833965Sjdp    char buf[MB_LEN_MAX];
12933965Sjdp    size_t i, len;
13033965Sjdp
13133965Sjdp    len = one_wctomb(buf, c & CHAR);
13233965Sjdp    for (i = 0; i < len; i++)
13333965Sjdp	putraw((unsigned char)buf[i] | (c & ~CHAR));
13433965Sjdp}
13533965Sjdp
13633965Sjdpvoid
13733965Sjdpxputwchar(Char c)
13833965Sjdp{
13933965Sjdp    char buf[MB_LEN_MAX];
14033965Sjdp    size_t i, len;
14133965Sjdp
14233965Sjdp    len = one_wctomb(buf, c & CHAR);
14333965Sjdp    for (i = 0; i < len; i++)
14433965Sjdp	xputchar((unsigned char)buf[i] | (c & ~CHAR));
14533965Sjdp}
14689857Sobrien#endif
14789857Sobrien
14889857Sobrienvoid
14989857Sobrienxputchar(int c)
15033965Sjdp{
15133965Sjdp    int     atr;
15233965Sjdp
15333965Sjdp    atr = c & ATTRIBUTES & TRIM;
15433965Sjdp    c &= CHAR | QUOTE;
15533965Sjdp    if (!output_raw && (c & QUOTE) == 0) {
15633965Sjdp	if (iscntrl(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
15733965Sjdp	    if (c != '\t' && c != '\n'
15833965Sjdp#ifdef COLORCAT
15933965Sjdp	        && !(adrof(STRcolorcat) && c == CTL_ESC('\033'))
16033965Sjdp#endif
16133965Sjdp		&& (xlate_cr || c != '\r'))
16233965Sjdp	    {
16333965Sjdp		xputchar('^' | atr);
16433965Sjdp		if (c == CTL_ESC('\177'))
16533965Sjdp		    c = '?';
16633965Sjdp		else
16733965Sjdp		    /* Note: for IS_ASCII, this compiles to: c = c | 0100 */
16833965Sjdp		    c = CTL_ESC(ASC(c)|0100);
16933965Sjdp	    }
17033965Sjdp	}
17133965Sjdp	else if (!isprint(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
17233965Sjdp	    xputchar('\\' | atr);
17333965Sjdp	    xputchar((((c >> 6) & 7) + '0') | atr);
17433965Sjdp	    xputchar((((c >> 3) & 7) + '0') | atr);
17533965Sjdp	    c = (c & 7) + '0';
17633965Sjdp	}
17733965Sjdp	(void) putraw(c | atr);
17833965Sjdp    }
17933965Sjdp    else {
18033965Sjdp	c &= TRIM;
18133965Sjdp	if (haderr ? (didfds ? is2atty : isdiagatty) :
18233965Sjdp	    (didfds ? is1atty : isoutatty))
18333965Sjdp	    SetAttributes(c | atr);
18433965Sjdp	(void) putpure(c);
18533965Sjdp    }
18633965Sjdp    if (lbuffed && (c & CHAR) == '\n')
18733965Sjdp	flush();
18833965Sjdp}
18933965Sjdp
19033965Sjdpint
19133965Sjdpputraw(int c)
19233965Sjdp{
19333965Sjdp    if (haderr ? (didfds ? is2atty : isdiagatty) :
19433965Sjdp	(didfds ? is1atty : isoutatty)) {
19533965Sjdp	if (Tty_eight_bit == -1)
19633965Sjdp	    ed_set_tty_eight_bit();
19733965Sjdp	if (!Tty_eight_bit && (c & META)) {
19833965Sjdp	    c = (c & ~META) | STANDOUT;
19933965Sjdp	}
20033965Sjdp	SetAttributes(c);
20133965Sjdp    }
20233965Sjdp    return putpure(c);
20333965Sjdp}
20433965Sjdp
20533965Sjdpint
20633965Sjdpputpure(int c)
20733965Sjdp{
20833965Sjdp    c &= CHAR;
20933965Sjdp
21033965Sjdp    *linp++ = (char) c;
21133965Sjdp    if (linp >= &linbuf[sizeof linbuf - 10])
21233965Sjdp	flush();
21333965Sjdp    return (1);
21433965Sjdp}
21533965Sjdp
21633965Sjdpvoid
21733965Sjdpdrainoline(void)
21833965Sjdp{
21933965Sjdp    linp = linbuf;
22033965Sjdp}
22133965Sjdp
22233965Sjdpvoid
22333965Sjdpflush(void)
22433965Sjdp{
22533965Sjdp    int unit;
22633965Sjdp    static int interrupted = 0;
22733965Sjdp
22833965Sjdp    /* int lmode; */
22933965Sjdp
23033965Sjdp    if (linp == linbuf)
23133965Sjdp	return;
23233965Sjdp    if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10])
23333965Sjdp	return;
23433965Sjdp    if (interrupted) {
23533965Sjdp	interrupted = 0;
23633965Sjdp	linp = linbuf;		/* avoid recursion as stderror calls flush */
23733965Sjdp	stderror(ERR_SILENT);
23833965Sjdp    }
23933965Sjdp    interrupted = 1;
24033965Sjdp    if (haderr)
24133965Sjdp	unit = didfds ? 2 : SHDIAG;
24233965Sjdp    else
24333965Sjdp	unit = didfds ? 1 : SHOUT;
24433965Sjdp#ifdef COMMENT
24533965Sjdp#ifdef TIOCLGET
24633965Sjdp    if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 &&
24733965Sjdp	lmode & LFLUSHO) {
248218822Sdim	lmode = LFLUSHO;
24933965Sjdp	(void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode);
25060484Sobrien	(void) xwrite(unit, "\n", 1);
25160484Sobrien    }
25260484Sobrien#endif
25360484Sobrien#endif
25460484Sobrien    if (xwrite(unit, linbuf, linp - linbuf) == -1)
25560484Sobrien	switch (errno) {
25660484Sobrien#ifdef EIO
257130561Sobrien	/* We lost our tty */
258130561Sobrien	case EIO:
259130561Sobrien#endif
260130561Sobrien#ifdef ENXIO
261130561Sobrien	/*
262130561Sobrien	 * Deal with Digital Unix 4.0D bogocity, returning ENXIO when
263130561Sobrien	 * we lose our tty.
264130561Sobrien	 */
265130561Sobrien	case ENXIO:
266130561Sobrien#endif
267130561Sobrien	/*
268130561Sobrien	 * IRIX 6.4 bogocity?
269130561Sobrien	 */
270130561Sobrien#ifdef ENOTTY
271218822Sdim	case ENOTTY:
272130561Sobrien#endif
273218822Sdim#ifdef EBADF
274218822Sdim	case EBADF:
27533965Sjdp#endif
276#ifdef ESTALE
277	/*
278	 * Lost our file descriptor, exit (IRIS4D)
279	 */
280	case ESTALE:
281#endif
282	/*
283	 * Over our quota, writing the history file
284	 */
285#ifdef EDQUOT
286	case EDQUOT:
287#endif
288	/* Nothing to do, but die */
289	    xexit(1);
290	    break;
291	default:
292	    stderror(ERR_SILENT);
293	    break;
294	}
295
296    linp = linbuf;
297    interrupted = 0;
298}
299