xref: /original-bsd/local/toolchest/ksh/sh/print.c (revision 048a349a)
1 /*
2 
3  *      Copyright (c) 1984, 1985, 1986 AT&T
4  *      All Rights Reserved
5 
6  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7  *      CODE OF AT&T.
8  *      The copyright notice above does not
9  *      evidence any actual or intended
10  *      publication of such source code.
11 
12  */
13 /* @(#)print.c	1.1 */
14 /*
15  * UNIX shell
16  *
17  * S. R. Bourne
18  * Rewritten by David Korn
19  * AT&T Bell Laboratories
20  *
21  */
22 
23 #include	"flags.h"
24 #include	"defs.h"
25 #include	"io.h"
26 #include	"shtype.h"
27 #ifndef BSD
28 # ifdef XENIX
29 # include	<sys/types.h>
30 # endif /* XENIX */
31 #include	<sys/param.h>
32 #endif /* BSD */
33 #include	"name.h"
34 #include	"builtins.h"
35 
36 /* This module defines the following routines */
37 void	p_flush();
38 void	p_list();
39 void	p_nchr();
40 void	p_num();
41 void	p_prp();
42 void	p_setout();
43 void	p_str();
44 void	p_sub();
45 void	p_time();
46 
47 /* This module references the following externals */
48 extern char	*itos();
49 extern char	*qvalup();
50 extern void	rjust();
51 extern void	setbuf();
52 extern char	*strcpy();
53 
54 /* printing and io conversion */
55 #ifdef BSD
56 #define TIC_SEC		60	/* number of ticks per second */
57 #else
58 #define TIC_SEC		HZ	/* number of ticks per second */
59 #endif /* BSD */
60 
61 
62 /*
63  *  flush the output queue and reset the output stream
64  */
65 
66 void	p_setout(fd)
67 register FILE *fd;
68 {
69 	if(output==fd)
70 		return;
71 	p_flush();
72 	output = fd;
73 	setbuf(fd,(char*)_sobuf);
74 }
75 
76 /*
77  * flush the output if necessary and null terminate the buffer
78  */
79 
80 void p_flush()
81 {
82 	register FILE *oldfd = output;
83 	register char *cp;
84 	if(oldfd)
85 	{
86 		if((cp=(char*)(oldfd->_ptr)) > (char*)(oldfd->_base))
87 		{
88 			fflush(oldfd);
89 			/* leave the previous buffer as a null terminated string */
90 		}
91 		if(cp)
92 			*cp = 0;
93 	}
94 }
95 
96 /*
97  * print a message preceded by the command name
98  */
99 
100 void p_prp(s1,ch)
101 char *s1;
102 {
103 	register unsigned char *cp;
104 	register int c;
105 	register FILE *fd = output;
106 	if(cp=(unsigned char *)cmdadr)
107 	{
108 		if(*cp=='-')
109 			cp++;
110 		c = ((cmdline>1&&ch!=SP)?0:':');
111 		p_str(cp,c);
112 		if(c==0)
113 			p_sub(cmdline,':');
114 		putc(SP,fd);
115 	}
116 	for(cp=(unsigned char *)s1;c= *cp;cp++)
117 	{
118 		if(!isprint(c))
119 		{
120 			putc(HAT,fd);
121 			c ^= TO_PRINT;
122 		}
123 		putc(c,fd);
124 	}
125 	if(ch)
126 		putc(ch,fd);
127 }
128 
129 /*
130  * print a time and a separator
131  */
132 
133 void	p_time(t,c)
134 long int  t;
135 char c;
136 {
137 	register int  min, sec, frac;
138 	register int hr;
139 	frac = t%TIC_SEC;
140 	frac = (frac*100)/TIC_SEC;
141 	t /= TIC_SEC;
142 	sec=t%60; t /= 60;
143 	min=t%60;
144 	if(hr=t/60)
145 	{
146 		p_num(hr,'h');
147 	}
148 	p_num(min,'m');
149 	p_num(sec,'.');
150 	if(frac<10)
151 		putc('0',output);
152 	p_num(frac,'s');
153 	putc(c,output);
154 }
155 
156 /*
157  * print a number optionally followed by a character
158  */
159 
160 void	p_num(n,c)
161 int 	n;
162 char c;
163 {
164 	p_str(itos(n),c);
165 }
166 
167 /*
168  * print a string optionally followed by a character
169  */
170 
171 void	p_str(string,c)
172 register char *string;
173 register int c;
174 {
175 	register FILE *fd = output;
176 	fputs(string,fd);
177 	if(c)
178 		putc(c,fd);
179 }
180 
181 /*
182  * print a given character a given number of times
183  */
184 
185 void	p_nchr(c,n)
186 register int c,n;
187 {
188 	register FILE *fd = output;
189 	while(n-- > 0)
190 		putc(c,fd);
191 }
192 
193 /*
194  * print a list of arguments in columns
195  */
196 #define NROW	15	/* number of rows in output before going to multi-columns */
197 #define LBLSIZ	3	/* size of label field and interfield spacing */
198 
199 void	p_list(argn,com)
200 char *com[];
201 {
202 	register int i,j;
203 	register char **arg;
204 	char a1[12];
205 	int nrow = NROW;
206 	int ncol = 1;
207 	int ndigits = 1;
208 	int fldsize;
209 #if ESH || VSH
210 	int wsize = e_window();
211 #else
212 	int wsize = 80;
213 #endif
214 	char *cp = qvalup(LINES);
215 	nrow = (cp?1+2*(atoi(cp)/3):NROW);
216 	for(i=argn;i >= 10;i /= 10)
217 		ndigits++;
218 	if(argn < nrow)
219 	{
220 		nrow = argn;
221 		goto skip;
222 	}
223 	i = 0;
224 	for(arg=com; *arg;arg++)
225 	{
226 		i = max(i,strlen(*arg));
227 	}
228 	i += (ndigits+LBLSIZ);
229 	if(i < wsize)
230 		ncol = wsize/i;
231 	if(argn > nrow*ncol)
232 	{
233 		nrow = 1 + (argn-1)/ncol;
234 	}
235 	else
236 	{
237 		ncol = 1 + (argn-1)/nrow;
238 		nrow = 1 + (argn-1)/ncol;
239 	}
240 skip:
241 	fldsize = (wsize/ncol)-(ndigits+LBLSIZ);
242 	for(i=0;i<nrow;i++)
243 	{
244 		j = i;
245 		while(1)
246 		{
247 			arg = com+j;
248 			strcpy(a1,itos(j+1));
249 			rjust(a1,ndigits,' ');
250 			p_str(a1,')');
251 			putc(SP,output);
252 			fputs(*arg,output);
253 			j += nrow;
254 			if(j >= argn)
255 				break;
256 			p_nchr(SP,fldsize-strlen(*arg));
257 		}
258 		newline();
259 	}
260 }
261 
262 /*
263  * Print a number enclosed in [] followed by a character
264  */
265 
266 void	p_sub(n,c)
267 register int n;
268 register int c;
269 {
270 	register FILE *fd=output;
271 	putc('[',fd);
272 	p_num(n,']');
273 	putc(c,fd);
274 }
275