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