xref: /freebsd/contrib/tcsh/sh.print.c (revision 6560ac57ce879857203bc456cdc3849808dc0700)
1c80476e4SDavid E. O'Brien /*
2c80476e4SDavid E. O'Brien  * sh.print.c: Primitive Output routines.
3c80476e4SDavid E. O'Brien  */
4c80476e4SDavid E. O'Brien /*-
5c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
6c80476e4SDavid E. O'Brien  * All rights reserved.
7c80476e4SDavid E. O'Brien  *
8c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
9c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
10c80476e4SDavid E. O'Brien  * are met:
11c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
12c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
13c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
14c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
15c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
1629301572SMark Peek  * 3. Neither the name of the University nor the names of its contributors
17c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
18c80476e4SDavid E. O'Brien  *    without specific prior written permission.
19c80476e4SDavid E. O'Brien  *
20c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
31c80476e4SDavid E. O'Brien  */
32c80476e4SDavid E. O'Brien #include "sh.h"
33c80476e4SDavid E. O'Brien #include "ed.h"
34c80476e4SDavid E. O'Brien 
35c80476e4SDavid E. O'Brien extern int Tty_eight_bit;
36c80476e4SDavid E. O'Brien 
37c80476e4SDavid E. O'Brien int     lbuffed = 1;		/* true if line buffered */
38c80476e4SDavid E. O'Brien 
3945e5710bSMark Peek static	void	p2dig	(unsigned int);
40c80476e4SDavid E. O'Brien 
41c80476e4SDavid E. O'Brien /*
42c80476e4SDavid E. O'Brien  * C Shell
43c80476e4SDavid E. O'Brien  */
44c80476e4SDavid E. O'Brien 
45c80476e4SDavid E. O'Brien #if defined(BSDLIMIT) || defined(RLIMIT_CPU)
46c80476e4SDavid E. O'Brien void
psecs(unsigned long l)4745e5710bSMark Peek psecs(unsigned long l)
48c80476e4SDavid E. O'Brien {
4923338178SMark Peek     int i;
50c80476e4SDavid E. O'Brien 
51c80476e4SDavid E. O'Brien     i = (int) (l / 3600);
52c80476e4SDavid E. O'Brien     if (i) {
53c80476e4SDavid E. O'Brien 	xprintf("%d:", i);
54c80476e4SDavid E. O'Brien 	i = (int) (l % 3600);
55c80476e4SDavid E. O'Brien 	p2dig(i / 60);
56c80476e4SDavid E. O'Brien 	goto minsec;
57c80476e4SDavid E. O'Brien     }
58c80476e4SDavid E. O'Brien     i = (int) l;
59c80476e4SDavid E. O'Brien     xprintf("%d", i / 60);
60c80476e4SDavid E. O'Brien minsec:
61c80476e4SDavid E. O'Brien     i %= 60;
62c80476e4SDavid E. O'Brien     xprintf(":");
63c80476e4SDavid E. O'Brien     p2dig(i);
64c80476e4SDavid E. O'Brien }
65c80476e4SDavid E. O'Brien 
66c80476e4SDavid E. O'Brien #endif
67c80476e4SDavid E. O'Brien 
6845e5710bSMark Peek void			/* PWP: print mm:ss.dd, l is in sec*100 */
69c80476e4SDavid E. O'Brien #ifdef BSDTIMES
pcsecs(unsigned long l)7045e5710bSMark Peek pcsecs(unsigned long l)
71c80476e4SDavid E. O'Brien #else /* BSDTIMES */
72c80476e4SDavid E. O'Brien # ifndef POSIX
7345e5710bSMark Peek pcsecs(time_t l)
74c80476e4SDavid E. O'Brien # else /* POSIX */
7545e5710bSMark Peek pcsecs(clock_t l)
76c80476e4SDavid E. O'Brien # endif /* POSIX */
77c80476e4SDavid E. O'Brien #endif /* BSDTIMES */
78c80476e4SDavid E. O'Brien {
7923338178SMark Peek     int i;
80c80476e4SDavid E. O'Brien 
81c80476e4SDavid E. O'Brien     i = (int) (l / 360000);
82c80476e4SDavid E. O'Brien     if (i) {
83c80476e4SDavid E. O'Brien 	xprintf("%d:", i);
84c80476e4SDavid E. O'Brien 	i = (int) ((l % 360000) / 100);
85c80476e4SDavid E. O'Brien 	p2dig(i / 60);
86c80476e4SDavid E. O'Brien 	goto minsec;
87c80476e4SDavid E. O'Brien     }
88c80476e4SDavid E. O'Brien     i = (int) (l / 100);
89c80476e4SDavid E. O'Brien     xprintf("%d", i / 60);
90c80476e4SDavid E. O'Brien minsec:
91c80476e4SDavid E. O'Brien     i %= 60;
92c80476e4SDavid E. O'Brien     xprintf(":");
93c80476e4SDavid E. O'Brien     p2dig(i);
94c80476e4SDavid E. O'Brien     xprintf(".");
95c80476e4SDavid E. O'Brien     p2dig((int) (l % 100));
96c80476e4SDavid E. O'Brien }
97c80476e4SDavid E. O'Brien 
98c80476e4SDavid E. O'Brien static void
p2dig(unsigned i)9945e5710bSMark Peek p2dig(unsigned i)
100c80476e4SDavid E. O'Brien {
101c80476e4SDavid E. O'Brien 
10223338178SMark Peek     xprintf("%u%u", i / 10, i % 10);
103c80476e4SDavid E. O'Brien }
104c80476e4SDavid E. O'Brien 
105c80476e4SDavid E. O'Brien char    linbuf[2048];		/* was 128 */
106c80476e4SDavid E. O'Brien char   *linp = linbuf;
10723338178SMark Peek int    output_raw = 0;		/* PWP */
10823338178SMark Peek int    xlate_cr   = 0;		/* HE */
10923338178SMark Peek 
11045e5710bSMark Peek /* For cleanup_push() */
11145e5710bSMark Peek void
output_raw_restore(void * xorig)11245e5710bSMark Peek output_raw_restore(void *xorig)
11345e5710bSMark Peek {
11445e5710bSMark Peek     int *orig;
11545e5710bSMark Peek 
11645e5710bSMark Peek     orig = xorig;
11745e5710bSMark Peek     output_raw = *orig;
11845e5710bSMark Peek }
11945e5710bSMark Peek 
12023338178SMark Peek #ifdef WIDE_STRINGS
12123338178SMark Peek void
putwraw(Char c)12223338178SMark Peek putwraw(Char c)
12323338178SMark Peek {
12423338178SMark Peek     char buf[MB_LEN_MAX];
12523338178SMark Peek     size_t i, len;
12623338178SMark Peek 
12723338178SMark Peek     len = one_wctomb(buf, c & CHAR);
12823338178SMark Peek     for (i = 0; i < len; i++)
12923338178SMark Peek 	putraw((unsigned char)buf[i] | (c & ~CHAR));
13023338178SMark Peek }
13123338178SMark Peek 
13223338178SMark Peek void
xputwchar(Char c)13323338178SMark Peek xputwchar(Char c)
13423338178SMark Peek {
13523338178SMark Peek     char buf[MB_LEN_MAX];
13623338178SMark Peek     size_t i, len;
13723338178SMark Peek 
13823338178SMark Peek     len = one_wctomb(buf, c & CHAR);
13923338178SMark Peek     for (i = 0; i < len; i++)
14023338178SMark Peek 	xputchar((unsigned char)buf[i] | (c & ~CHAR));
14123338178SMark Peek }
14223338178SMark Peek #endif
143c80476e4SDavid E. O'Brien 
144c80476e4SDavid E. O'Brien void
xputchar(int c)14545e5710bSMark Peek xputchar(int c)
146c80476e4SDavid E. O'Brien {
14745e5710bSMark Peek     int     atr;
148c80476e4SDavid E. O'Brien 
14945e5710bSMark Peek     atr = c & ATTRIBUTES & TRIM;
150c80476e4SDavid E. O'Brien     c &= CHAR | QUOTE;
151c80476e4SDavid E. O'Brien     if (!output_raw && (c & QUOTE) == 0) {
15245e5710bSMark Peek 	if (iscntrl(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
15345e5710bSMark Peek 	    if (c != '\t' && c != '\n'
154c80476e4SDavid E. O'Brien #ifdef COLORCAT
15545e5710bSMark Peek 	        && !(adrof(STRcolorcat) && c == CTL_ESC('\033'))
156c80476e4SDavid E. O'Brien #endif
15745e5710bSMark Peek 		&& (xlate_cr || c != '\r'))
15823338178SMark Peek 	    {
159c80476e4SDavid E. O'Brien 		xputchar('^' | atr);
160c80476e4SDavid E. O'Brien 		if (c == CTL_ESC('\177'))
161c80476e4SDavid E. O'Brien 		    c = '?';
162c80476e4SDavid E. O'Brien 		else
16345e5710bSMark Peek 		    /* Note: for IS_ASCII, this compiles to: c = c | 0100 */
16445e5710bSMark Peek 		    c = CTL_ESC(ASC(c)|0100);
165c80476e4SDavid E. O'Brien 	    }
166c80476e4SDavid E. O'Brien 	}
16745e5710bSMark Peek 	else if (!isprint(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
168c80476e4SDavid E. O'Brien 	    xputchar('\\' | atr);
169c80476e4SDavid E. O'Brien 	    xputchar((((c >> 6) & 7) + '0') | atr);
170c80476e4SDavid E. O'Brien 	    xputchar((((c >> 3) & 7) + '0') | atr);
171c80476e4SDavid E. O'Brien 	    c = (c & 7) + '0';
172c80476e4SDavid E. O'Brien 	}
173c80476e4SDavid E. O'Brien 	(void) putraw(c | atr);
174c80476e4SDavid E. O'Brien     }
175c80476e4SDavid E. O'Brien     else {
176c80476e4SDavid E. O'Brien 	c &= TRIM;
177c80476e4SDavid E. O'Brien 	if (haderr ? (didfds ? is2atty : isdiagatty) :
178c80476e4SDavid E. O'Brien 	    (didfds ? is1atty : isoutatty))
179c80476e4SDavid E. O'Brien 	    SetAttributes(c | atr);
180c80476e4SDavid E. O'Brien 	(void) putpure(c);
181c80476e4SDavid E. O'Brien     }
182c80476e4SDavid E. O'Brien     if (lbuffed && (c & CHAR) == '\n')
183c80476e4SDavid E. O'Brien 	flush();
184c80476e4SDavid E. O'Brien }
185c80476e4SDavid E. O'Brien 
186c80476e4SDavid E. O'Brien int
putraw(int c)18745e5710bSMark Peek putraw(int c)
188c80476e4SDavid E. O'Brien {
189c80476e4SDavid E. O'Brien     if (haderr ? (didfds ? is2atty : isdiagatty) :
190c80476e4SDavid E. O'Brien 	(didfds ? is1atty : isoutatty)) {
191c80476e4SDavid E. O'Brien 	if (Tty_eight_bit == -1)
192c80476e4SDavid E. O'Brien 	    ed_set_tty_eight_bit();
193c80476e4SDavid E. O'Brien 	if (!Tty_eight_bit && (c & META)) {
194c80476e4SDavid E. O'Brien 	    c = (c & ~META) | STANDOUT;
195c80476e4SDavid E. O'Brien 	}
196c80476e4SDavid E. O'Brien 	SetAttributes(c);
197c80476e4SDavid E. O'Brien     }
198c80476e4SDavid E. O'Brien     return putpure(c);
199c80476e4SDavid E. O'Brien }
200c80476e4SDavid E. O'Brien 
201c80476e4SDavid E. O'Brien int
putpure(int c)20245e5710bSMark Peek putpure(int c)
203c80476e4SDavid E. O'Brien {
204c80476e4SDavid E. O'Brien     c &= CHAR;
205c80476e4SDavid E. O'Brien 
206c80476e4SDavid E. O'Brien     *linp++ = (char) c;
207c80476e4SDavid E. O'Brien     if (linp >= &linbuf[sizeof linbuf - 10])
208c80476e4SDavid E. O'Brien 	flush();
209c80476e4SDavid E. O'Brien     return (1);
210c80476e4SDavid E. O'Brien }
211c80476e4SDavid E. O'Brien 
212c80476e4SDavid E. O'Brien void
drainoline(void)21345e5710bSMark Peek drainoline(void)
214c80476e4SDavid E. O'Brien {
215c80476e4SDavid E. O'Brien     linp = linbuf;
216c80476e4SDavid E. O'Brien }
217c80476e4SDavid E. O'Brien 
218c80476e4SDavid E. O'Brien void
flush(void)21945e5710bSMark Peek flush(void)
220c80476e4SDavid E. O'Brien {
2219ccc37e3SMark Peek     int unit, oldexitset = exitset;
222c80476e4SDavid E. O'Brien     static int interrupted = 0;
223c80476e4SDavid E. O'Brien 
224c80476e4SDavid E. O'Brien     /* int lmode; */
225c80476e4SDavid E. O'Brien 
226c80476e4SDavid E. O'Brien     if (linp == linbuf)
227c80476e4SDavid E. O'Brien 	return;
228c80476e4SDavid E. O'Brien     if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10])
229c80476e4SDavid E. O'Brien 	return;
230*19d2e3deSDmitry Chagin     if (handle_interrupt)
2319ccc37e3SMark Peek        exitset = 1;
2329ccc37e3SMark Peek 
233c80476e4SDavid E. O'Brien     if (interrupted) {
234c80476e4SDavid E. O'Brien 	interrupted = 0;
23545e5710bSMark Peek 	linp = linbuf;		/* avoid recursion as stderror calls flush */
236*19d2e3deSDmitry Chagin 	if (handle_interrupt)
2379ccc37e3SMark Peek 	    fixerror();
2389ccc37e3SMark Peek 	else
239c80476e4SDavid E. O'Brien 	    stderror(ERR_SILENT);
240c80476e4SDavid E. O'Brien     }
241c80476e4SDavid E. O'Brien     interrupted = 1;
242c80476e4SDavid E. O'Brien     if (haderr)
243c80476e4SDavid E. O'Brien 	unit = didfds ? 2 : SHDIAG;
244c80476e4SDavid E. O'Brien     else
245c80476e4SDavid E. O'Brien 	unit = didfds ? 1 : SHOUT;
246c80476e4SDavid E. O'Brien #ifdef COMMENT
247c80476e4SDavid E. O'Brien #ifdef TIOCLGET
248c80476e4SDavid E. O'Brien     if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 &&
249c80476e4SDavid E. O'Brien 	lmode & LFLUSHO) {
250c80476e4SDavid E. O'Brien 	lmode = LFLUSHO;
251c80476e4SDavid E. O'Brien 	(void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode);
25245e5710bSMark Peek 	(void) xwrite(unit, "\n", 1);
253c80476e4SDavid E. O'Brien     }
254c80476e4SDavid E. O'Brien #endif
255c80476e4SDavid E. O'Brien #endif
25645e5710bSMark Peek     if (xwrite(unit, linbuf, linp - linbuf) == -1)
257c80476e4SDavid E. O'Brien 	switch (errno) {
258c80476e4SDavid E. O'Brien #ifdef EIO
259c80476e4SDavid E. O'Brien 	/* We lost our tty */
260c80476e4SDavid E. O'Brien 	case EIO:
261c80476e4SDavid E. O'Brien #endif
262c80476e4SDavid E. O'Brien #ifdef ENXIO
263c80476e4SDavid E. O'Brien 	/*
264c80476e4SDavid E. O'Brien 	 * Deal with Digital Unix 4.0D bogocity, returning ENXIO when
265c80476e4SDavid E. O'Brien 	 * we lose our tty.
266c80476e4SDavid E. O'Brien 	 */
267c80476e4SDavid E. O'Brien 	case ENXIO:
268c80476e4SDavid E. O'Brien #endif
269c80476e4SDavid E. O'Brien 	/*
270c80476e4SDavid E. O'Brien 	 * IRIX 6.4 bogocity?
271c80476e4SDavid E. O'Brien 	 */
272c80476e4SDavid E. O'Brien #ifdef ENOTTY
273c80476e4SDavid E. O'Brien 	case ENOTTY:
274c80476e4SDavid E. O'Brien #endif
275c80476e4SDavid E. O'Brien #ifdef EBADF
276c80476e4SDavid E. O'Brien 	case EBADF:
277c80476e4SDavid E. O'Brien #endif
2788e66bd9eSDavid E. O'Brien #ifdef ESTALE
2798e66bd9eSDavid E. O'Brien 	/*
2808e66bd9eSDavid E. O'Brien 	 * Lost our file descriptor, exit (IRIS4D)
2818e66bd9eSDavid E. O'Brien 	 */
2828e66bd9eSDavid E. O'Brien 	case ESTALE:
2838e66bd9eSDavid E. O'Brien #endif
2849ccc37e3SMark Peek #ifdef ENOENT
2859ccc37e3SMark Peek 	/*
2869ccc37e3SMark Peek 	 * Deal with SoFS bogocity: returns ENOENT instead of ESTALE.
2879ccc37e3SMark Peek 	 */
2889ccc37e3SMark Peek 	case ENOENT:
2899ccc37e3SMark Peek #endif
290c80476e4SDavid E. O'Brien 	/*
291c80476e4SDavid E. O'Brien 	 * Over our quota, writing the history file
292c80476e4SDavid E. O'Brien 	 */
293c80476e4SDavid E. O'Brien #ifdef EDQUOT
294c80476e4SDavid E. O'Brien 	case EDQUOT:
295c80476e4SDavid E. O'Brien #endif
296c80476e4SDavid E. O'Brien 	/* Nothing to do, but die */
297*19d2e3deSDmitry Chagin 	    if (handle_interrupt == 0)
298c80476e4SDavid E. O'Brien 		xexit(1);
2999ccc37e3SMark Peek 	    /*FALLTHROUGH*/
300c80476e4SDavid E. O'Brien 	default:
301*19d2e3deSDmitry Chagin 	    if (handle_interrupt)
3029ccc37e3SMark Peek 		fixerror();
3039ccc37e3SMark Peek 	    else
304c80476e4SDavid E. O'Brien 		stderror(ERR_SILENT);
305c80476e4SDavid E. O'Brien 	    break;
306c80476e4SDavid E. O'Brien 	}
307c80476e4SDavid E. O'Brien 
3089ccc37e3SMark Peek     exitset = oldexitset;
309c80476e4SDavid E. O'Brien     linp = linbuf;
310c80476e4SDavid E. O'Brien     interrupted = 0;
311c80476e4SDavid E. O'Brien }
312