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