xref: /illumos-gate/usr/src/cmd/sh/print.c (revision 39e7390a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 /*
32  * UNIX shell
33  *
34  */
35 
36 #include	"defs.h"
37 #include	<sys/param.h>
38 #include	<locale.h>
39 #include	<wctype.h>	/* iswprint() */
40 
41 #define		BUFLEN		256
42 
43 unsigned char numbuf[21];
44 
45 static unsigned char buffer[BUFLEN];
46 static unsigned char *bufp = buffer;
47 static int index = 0;
48 static int buffd = 1;
49 
50 void	prc_buff(unsigned char c);
51 void	prs_buff(unsigned char *s);
52 void	prn_buff(int n);
53 void	prs_cntl(unsigned char *s);
54 void	prs(unsigned char *as);
55 void	itos(int n);
56 
57 /*
58  * printing and io conversion
59  */
60 void
61 prp()
62 {
63 	if ((flags & prompt) == 0 && cmdadr) {
64 		prs_cntl(cmdadr);
65 		prs((unsigned char *)colon);
66 	}
67 }
68 
69 void
70 prs(unsigned char *as)
71 {
72 	if (as) {
73 		write(output, as, length(as) - 1);
74 	}
75 }
76 
77 void
78 prc(unsigned char c)
79 {
80 	if (c) {
81 		write(output, &c, 1);
82 	}
83 }
84 
85 void
86 prwc(wchar_t c)
87 {
88 	char	mb[MB_LEN_MAX + 1];
89 	int	len;
90 
91 	if (c == 0) {
92 		return;
93 	}
94 	if ((len = wctomb(mb, c)) < 0) {
95 		mb[0] = (unsigned char)c;
96 		len = 1;
97 	}
98 	write(output, mb, len);
99 }
100 
101 void
102 prt(long t)
103 {
104 	int hr, min, sec;
105 
106 	t += HZ / 2;
107 	t /= HZ;
108 	sec = t % 60;
109 	t /= 60;
110 	min = t % 60;
111 
112 	if ((hr = t / 60) != 0) {
113 		prn_buff(hr);
114 		prc_buff('h');
115 	}
116 
117 	prn_buff(min);
118 	prc_buff('m');
119 	prn_buff(sec);
120 	prc_buff('s');
121 }
122 
123 void
124 prn(int n)
125 {
126 	itos(n);
127 
128 	prs(numbuf);
129 }
130 
131 void
132 itos(int n)
133 {
134 	unsigned char buf[21];
135 	unsigned char *abuf = &buf[20];
136 	int d;
137 
138 	*--abuf = (unsigned char)'\0';
139 
140 	do {
141 		 *--abuf = (unsigned char)('0' + n - 10 * (d = n / 10));
142 	} while ((n = d) != 0);
143 
144 	strncpy(numbuf, abuf, sizeof (numbuf));
145 }
146 
147 int
148 stoi(unsigned char *icp)
149 {
150 	unsigned char	*cp = icp;
151 	int	r = 0;
152 	unsigned char	c;
153 
154 	while ((c = *cp, digit(c)) && c && r >= 0) {
155 		r = r * 10 + c - '0';
156 		cp++;
157 	}
158 	if (r < 0 || cp == icp) {
159 		failed(icp, badnum);
160 		/* NOTREACHED */
161 	} else {
162 		return (r);
163 	}
164 }
165 
166 int
167 ltos(long n)
168 {
169 	int i;
170 
171 	numbuf[20] = '\0';
172 	for (i = 19; i >= 0; i--) {
173 		numbuf[i] = n % 10 + '0';
174 		if ((n /= 10) == 0) {
175 			break;
176 		}
177 	}
178 	return (i);
179 }
180 
181 static int
182 ulltos(u_longlong_t n)
183 {
184 	int i;
185 
186 	/* The max unsigned long long is 20 characters (+1 for '\0') */
187 	numbuf[20] = '\0';
188 	for (i = 19; i >= 0; i--) {
189 		numbuf[i] = n % 10 + '0';
190 		if ((n /= 10) == 0) {
191 			break;
192 		}
193 	}
194 	return (i);
195 }
196 
197 void
198 flushb()
199 {
200 	if (index) {
201 		bufp[index] = '\0';
202 		write(buffd, bufp, length(bufp) - 1);
203 		index = 0;
204 	}
205 }
206 
207 void
208 prc_buff(unsigned char c)
209 {
210 	if (c) {
211 		if (buffd != -1 && index + 1 >= BUFLEN) {
212 			flushb();
213 		}
214 
215 		bufp[index++] = c;
216 	} else {
217 		flushb();
218 		write(buffd, &c, 1);
219 	}
220 }
221 
222 void
223 prs_buff(unsigned char *s)
224 {
225 	int len = length(s) - 1;
226 
227 	if (buffd != -1 && index + len >= BUFLEN) {
228 		flushb();
229 	}
230 
231 	if (buffd != -1 && len >= BUFLEN) {
232 		write(buffd, s, len);
233 	} else {
234 		movstr(s, &bufp[index]);
235 		index += len;
236 	}
237 }
238 
239 static unsigned char *
240 octal(unsigned char c, unsigned char *ptr)
241 {
242 	*ptr++ = '\\';
243 	*ptr++ = ((unsigned int)c >> 6) + '0';
244 	*ptr++ = (((unsigned int)c >> 3) & 07) + '0';
245 	*ptr++ = (c & 07) + '0';
246 	return (ptr);
247 }
248 
249 void
250 prs_cntl(unsigned char *s)
251 {
252 	int n;
253 	wchar_t wc;
254 	unsigned char *olds = s;
255 	unsigned char *ptr = bufp;
256 	wchar_t c;
257 
258 	if ((n = mbtowc(&wc, (const char *)s, MB_LEN_MAX)) <= 0) {
259 		n = 0;
260 	}
261 	while (n != 0) {
262 		if (n < 0) {
263 			ptr = octal(*s++, ptr);
264 		} else {
265 			c = wc;
266 			s += n;
267 			if (!iswprint(c)) {
268 				if (c < '\040' && c > 0) {
269 					/*
270 					 * assumes ASCII char
271 					 * translate a control character
272 					 * into a printable sequence
273 					 */
274 					*ptr++ = '^';
275 					*ptr++ = (c + 0100);
276 				} else if (c == 0177) {
277 					/* '\0177' does not work */
278 					*ptr++ = '^';
279 					*ptr++ = '?';
280 				} else {
281 					/*
282 					 * unprintable 8-bit byte sequence
283 					 * assumes all legal multibyte
284 					 * sequences are
285 					 * printable
286 					 */
287 					ptr = octal(*olds, ptr);
288 				}
289 			} else {
290 				while (n--) {
291 					*ptr++ = *olds++;
292 				}
293 			}
294 		}
295 		if (buffd != -1 && ptr >= &bufp[BUFLEN-4]) {
296 			*ptr = '\0';
297 			prs(bufp);
298 			ptr = bufp;
299 		}
300 		olds = s;
301 		if ((n = mbtowc(&wc, (const char *)s, MB_LEN_MAX)) <= 0) {
302 			n = 0;
303 		}
304 	}
305 	*ptr = '\0';
306 	prs(bufp);
307 }
308 
309 void
310 prull_buff(u_longlong_t lc)
311 {
312 	prs_buff(&numbuf[ulltos(lc)]);
313 }
314 
315 void
316 prn_buff(int n)
317 {
318 	itos(n);
319 
320 	prs_buff(numbuf);
321 }
322 
323 int
324 setb(int fd)
325 {
326 	int ofd;
327 
328 	if ((ofd = buffd) == -1) {
329 		if (bufp+index+1 >= brkend) {
330 			growstak(bufp+index+1);
331 		}
332 		if (bufp[index-1]) {
333 			bufp[index++] = 0;
334 		}
335 		endstak(bufp+index);
336 	} else {
337 		flushb();
338 	}
339 	if ((buffd = fd) == -1) {
340 		bufp = locstak();
341 	} else {
342 		bufp = buffer;
343 	}
344 	index = 0;
345 	return (ofd);
346 }
347