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