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
psecs_ull(unsigned long long l)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
psecs_int(int l)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
p2dig_ull(unsigned long long i)68 p2dig_ull(unsigned long long i)
69 {
70 printf("%llu%llu", i / 10, i % 10);
71 }
72
73 void
p2dig_int(int i)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
putbyte(int c)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
Putchar(tchar tc)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
putbyte(int c)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
Putchar(tchar tc)171 Putchar(tchar tc)
172 {
173 putbyte((int)tc);
174 }
175
176 #endif /* !MBCHAR */
177
178 void
draino(void)179 draino(void)
180 {
181 linp = linbuf;
182 }
183
184 void
flush(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
write_string(char * s)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