xref: /illumos-gate/usr/src/cmd/csh/sh.print.c (revision d2a70789f056fc6c9ce3ab047b52126d80b0e3da)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7 /*	  All Rights Reserved  	*/
8 
9 /*
10  * Copyright (c) 1980 Regents of the University of California.
11  * All rights reserved. The Berkeley Software License Agreement
12  * specifies the terms and conditions for redistribution.
13  */
14 
15 #pragma ident	"%Z%%M%	%I%	%E% SMI"
16 
17 #include "sh.h"
18 
19 void	p2dig_ull(unsigned long long);
20 void	p2dig_int(int);
21 void	flush(void);
22 void	Putchar(tchar);
23 
24 
25 /*
26  * C Shell
27  */
28 
29 void
30 psecs_ull(unsigned long long l)
31 {
32 	unsigned long long i;
33 
34 	i = l / 3600;
35 	if (i) {
36 		printf("%llu:", i);
37 		i = l % 3600;
38 		p2dig_ull(i / 60);
39 		goto minsec;
40 	}
41 	i = l;
42 	printf("%llu", i / 60);
43 minsec:
44 	i %= 60;
45 	printf(":");
46 	p2dig_ull(i);
47 }
48 
49 void
50 psecs_int(int l)
51 {
52 	int i;
53 
54 	i = l / 3600;
55 	if (i) {
56 		printf("%d:", i);
57 		i = l % 3600;
58 		p2dig_int(i / 60);
59 		goto minsec;
60 	}
61 	i = l;
62 	printf("%d", i / 60);
63 minsec:
64 	i %= 60;
65 	printf(":");
66 	p2dig_int(i);
67 }
68 
69 void
70 p2dig_ull(unsigned long long i)
71 {
72 	printf("%llu%llu", i / 10, i % 10);
73 }
74 
75 void
76 p2dig_int(int i)
77 {
78 	printf("%d%d", i / 10, i % 10);
79 }
80 
81 char linbuf[128];
82 char *linp = linbuf;
83 
84 #ifdef MBCHAR
85 
86 /*
87  * putbyte() send a byte to SHOUT.  No interpretation is done
88  * except an un-QUOTE'd control character, which is displayed
89  * as ^x.
90  */
91 void
92 putbyte(int c)
93 {
94 
95 	if ((c & QUOTE) == 0 && (c == 0177 || c < ' ' && c != '\t' &&
96 	    c != '\n')) {
97 		putbyte('^');
98 		if (c == 0177) {
99 			c = '?';
100 		} else {
101 			c |= 'A' - 1;
102 		}
103 	}
104 	c &= TRIM;
105 	*linp++ = c;
106 
107 	if (c == '\n' || linp >= &linbuf[sizeof (linbuf) - 1 - MB_CUR_MAX]) {
108 		/* 'cause the next Putchar() call may overflow the buffer.  */
109 		flush();
110 	}
111 }
112 
113 /*
114  * Putchar(tc) does what putbyte(c) do for a byte c.
115  * Note that putbyte(c) just send the byte c (provided c is not
116  * a control character) as it is, while Putchar(tc) may expand the
117  * character tc to some byte sequnce that represents the character
118  * in EUC form.
119  */
120 void
121 Putchar(tchar tc)
122 {
123 	int	n;
124 
125 	if (isascii(tc&TRIM)) {
126 		putbyte((int)tc);
127 		return;
128 	}
129 	tc &= TRIM;
130 	n = wctomb(linp, tc);
131 	if (n == -1) {
132 		return;
133 	}
134 	linp += n;
135 	if (linp >= &linbuf[sizeof (linbuf) - 1 - MB_CUR_MAX]) {
136 		flush();
137 	}
138 }
139 
140 #else	/* !MBCHAR */
141 
142 /*
143  * putbyte() send a byte to SHOUT.  No interpretation is done
144  * except an un-QUOTE'd control character, which is displayed
145  * as ^x.
146  */
147 void
148 putbyte(int c)
149 {
150 
151 	if ((c & QUOTE) == 0 && (c == 0177 || c < ' ' && c != '\t' &&
152 	    c != '\n')) {
153 		putbyte('^');
154 		if (c == 0177) {
155 			c = '?';
156 		} else {
157 			c |= 'A' - 1;
158 		}
159 	}
160 	c &= TRIM;
161 	*linp++ = c;
162 	if (c == '\n' || linp >= &linbuf[sizeof (linbuf) - 2]) {
163 		flush();
164 	}
165 }
166 
167 /*
168  * Putchar(tc) does what putbyte(c) do for a byte c.
169  * For single-byte character only environment, there is no
170  * difference between Putchar() and putbyte() though.
171  */
172 void
173 Putchar(tchar tc)
174 {
175 	putbyte((int)tc);
176 }
177 
178 #endif	/* !MBCHAR */
179 
180 void
181 draino(void)
182 {
183 	linp = linbuf;
184 }
185 
186 void
187 flush(void)
188 {
189 	int unit;
190 	int lmode;
191 
192 	if (linp == linbuf) {
193 		return;
194 	}
195 	if (haderr) {
196 		unit = didfds ? 2 : SHDIAG;
197 	} else {
198 		unit = didfds ? 1 : SHOUT;
199 	}
200 #ifdef TIOCLGET
201 	if (didfds == 0 && ioctl(unit, TIOCLGET,  (char *)&lmode) == 0 &&
202 	    lmode&LFLUSHO) {
203 		lmode = LFLUSHO;
204 		(void) ioctl(unit, TIOCLBIC,  (char *)&lmode);
205 		(void) write(unit, "\n", 1);
206 	}
207 #endif
208 	(void) write(unit, linbuf, linp - linbuf);
209 	linp = linbuf;
210 }
211 
212 /*
213  * Should not be needed.
214  */
215 void
216 write_string(char *s)
217 {
218 	int unit;
219 	/*
220 	 * First let's make it sure to flush out things.
221 	 */
222 	flush();
223 
224 	if (haderr) {
225 		unit = didfds ? 2 : SHDIAG;
226 	} else {
227 		unit = didfds ? 1 : SHOUT;
228 	}
229 
230 	(void) write(unit, s, strlen(s));
231 }
232