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
p_setout(fd)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
p_flush()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
p_prp(s1,ch)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
p_time(t,c)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
p_num(n,c)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
p_str(string,c)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
p_nchr(c,n)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
p_list(argn,com)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
p_sub(n,c)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