1 /* $Header: /src/pub/tcsh/sh.print.c,v 3.28 2005/03/03 17:19:35 kim Exp $ */ 2 /* 3 * sh.print.c: Primitive Output routines. 4 */ 5 /*- 6 * Copyright (c) 1980, 1991 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 #include "sh.h" 34 35 RCSID("$Id: sh.print.c,v 3.28 2005/03/03 17:19:35 kim Exp $") 36 37 #include "ed.h" 38 39 extern int Tty_eight_bit; 40 41 int lbuffed = 1; /* true if line buffered */ 42 43 static void p2dig __P((unsigned int)); 44 45 /* 46 * C Shell 47 */ 48 49 #if defined(BSDLIMIT) || defined(RLIMIT_CPU) 50 void 51 psecs(l) 52 unsigned long l; 53 { 54 int i; 55 56 i = (int) (l / 3600); 57 if (i) { 58 xprintf("%d:", i); 59 i = (int) (l % 3600); 60 p2dig(i / 60); 61 goto minsec; 62 } 63 i = (int) l; 64 xprintf("%d", i / 60); 65 minsec: 66 i %= 60; 67 xprintf(":"); 68 p2dig(i); 69 } 70 71 #endif 72 73 void 74 pcsecs(l) /* PWP: print mm:ss.dd, l is in sec*100 */ 75 #ifdef BSDTIMES 76 unsigned long l; 77 #else /* BSDTIMES */ 78 # ifndef POSIX 79 time_t l; 80 # else /* POSIX */ 81 clock_t l; 82 # endif /* POSIX */ 83 #endif /* BSDTIMES */ 84 { 85 int i; 86 87 i = (int) (l / 360000); 88 if (i) { 89 xprintf("%d:", i); 90 i = (int) ((l % 360000) / 100); 91 p2dig(i / 60); 92 goto minsec; 93 } 94 i = (int) (l / 100); 95 xprintf("%d", i / 60); 96 minsec: 97 i %= 60; 98 xprintf(":"); 99 p2dig(i); 100 xprintf("."); 101 p2dig((int) (l % 100)); 102 } 103 104 static void 105 p2dig(i) 106 unsigned int i; 107 { 108 109 xprintf("%u%u", i / 10, i % 10); 110 } 111 112 char linbuf[2048]; /* was 128 */ 113 char *linp = linbuf; 114 int output_raw = 0; /* PWP */ 115 int xlate_cr = 0; /* HE */ 116 117 #ifdef WIDE_STRINGS 118 void 119 putwraw(Char c) 120 { 121 char buf[MB_LEN_MAX]; 122 size_t i, len; 123 124 len = one_wctomb(buf, c & CHAR); 125 for (i = 0; i < len; i++) 126 putraw((unsigned char)buf[i] | (c & ~CHAR)); 127 } 128 129 void 130 xputwchar(Char c) 131 { 132 char buf[MB_LEN_MAX]; 133 size_t i, len; 134 135 len = one_wctomb(buf, c & CHAR); 136 for (i = 0; i < len; i++) 137 xputchar((unsigned char)buf[i] | (c & ~CHAR)); 138 } 139 #endif 140 141 void 142 xputchar(c) 143 int c; 144 { 145 int atr = 0; 146 147 atr |= c & ATTRIBUTES & TRIM; 148 c &= CHAR | QUOTE; 149 if (!output_raw && (c & QUOTE) == 0) { 150 if (iscntrl(c) && (c < 0x80 || MB_CUR_MAX == 1)) { 151 #ifdef COLORCAT 152 if (c != '\t' && c != '\n' && !(adrof(STRcolorcat) && c=='\033') && (xlate_cr || c != '\r')) 153 #else 154 if (c != '\t' && c != '\n' && (xlate_cr || c != '\r')) 155 #endif 156 { 157 xputchar('^' | atr); 158 #ifdef IS_ASCII 159 if (c == 0177) 160 c = '?'; 161 else 162 c |= 0100; 163 #else 164 if (c == CTL_ESC('\177')) 165 c = '?'; 166 else 167 c =_toebcdic[_toascii[c]|0100]; 168 #endif 169 170 } 171 } 172 else if (!isprint(c) && (c < 0x80 || MB_CUR_MAX == 1)) { 173 xputchar('\\' | atr); 174 xputchar((((c >> 6) & 7) + '0') | atr); 175 xputchar((((c >> 3) & 7) + '0') | atr); 176 c = (c & 7) + '0'; 177 } 178 (void) putraw(c | atr); 179 } 180 else { 181 c &= TRIM; 182 if (haderr ? (didfds ? is2atty : isdiagatty) : 183 (didfds ? is1atty : isoutatty)) 184 SetAttributes(c | atr); 185 (void) putpure(c); 186 } 187 if (lbuffed && (c & CHAR) == '\n') 188 flush(); 189 } 190 191 int 192 putraw(c) 193 int c; 194 { 195 if (haderr ? (didfds ? is2atty : isdiagatty) : 196 (didfds ? is1atty : isoutatty)) { 197 if (Tty_eight_bit == -1) 198 ed_set_tty_eight_bit(); 199 if (!Tty_eight_bit && (c & META)) { 200 c = (c & ~META) | STANDOUT; 201 } 202 SetAttributes(c); 203 } 204 return putpure(c); 205 } 206 207 int 208 putpure(c) 209 int c; 210 { 211 c &= CHAR; 212 213 *linp++ = (char) c; 214 if (linp >= &linbuf[sizeof linbuf - 10]) 215 flush(); 216 return (1); 217 } 218 219 void 220 drainoline() 221 { 222 linp = linbuf; 223 } 224 225 void 226 flush() 227 { 228 int unit; 229 static int interrupted = 0; 230 size_t sz; 231 232 /* int lmode; */ 233 234 if (linp == linbuf) 235 return; 236 if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10]) 237 return; 238 if (interrupted) { 239 interrupted = 0; 240 linp = linbuf; /* avoid resursion as stderror calls flush */ 241 stderror(ERR_SILENT); 242 } 243 interrupted = 1; 244 if (haderr) 245 unit = didfds ? 2 : SHDIAG; 246 else 247 unit = didfds ? 1 : SHOUT; 248 #ifdef COMMENT 249 #ifdef TIOCLGET 250 if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 && 251 lmode & LFLUSHO) { 252 lmode = LFLUSHO; 253 (void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode); 254 (void) write(unit, "\n", 1); 255 } 256 #endif 257 #endif 258 sz = (size_t) (linp - linbuf); 259 if (write(unit, linbuf, sz) == -1) 260 switch (errno) { 261 #ifdef EIO 262 /* We lost our tty */ 263 case EIO: 264 #endif 265 #ifdef ENXIO 266 /* 267 * Deal with Digital Unix 4.0D bogocity, returning ENXIO when 268 * we lose our tty. 269 */ 270 case ENXIO: 271 #endif 272 /* 273 * IRIX 6.4 bogocity? 274 */ 275 #ifdef ENOTTY 276 case ENOTTY: 277 #endif 278 #ifdef EBADF 279 case EBADF: 280 #endif 281 #ifdef ESTALE 282 /* 283 * Lost our file descriptor, exit (IRIS4D) 284 */ 285 case ESTALE: 286 #endif 287 /* 288 * Over our quota, writing the history file 289 */ 290 #ifdef EDQUOT 291 case EDQUOT: 292 #endif 293 /* Nothing to do, but die */ 294 xexit(1); 295 break; 296 default: 297 stderror(ERR_SILENT); 298 break; 299 } 300 301 linp = linbuf; 302 interrupted = 0; 303 } 304