Merge branch 'vendor/MDOCML'
[dragonfly.git] / contrib / tcsh-6 / sh.print.c
1 /* $Header: /p/tcsh/cvsroot/tcsh/sh.print.c,v 3.33 2006/08/23 15:03:14 christos 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("$tcsh: sh.print.c,v 3.33 2006/08/23 15:03:14 christos 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   (unsigned int);
44
45 /*
46  * C Shell
47  */
48
49 #if defined(BSDLIMIT) || defined(RLIMIT_CPU)
50 void
51 psecs(unsigned long l)
52 {
53     int i;
54
55     i = (int) (l / 3600);
56     if (i) {
57         xprintf("%d:", i);
58         i = (int) (l % 3600);
59         p2dig(i / 60);
60         goto minsec;
61     }
62     i = (int) l;
63     xprintf("%d", i / 60);
64 minsec:
65     i %= 60;
66     xprintf(":");
67     p2dig(i);
68 }
69
70 #endif
71
72 void                    /* PWP: print mm:ss.dd, l is in sec*100 */
73 #ifdef BSDTIMES
74 pcsecs(unsigned long l)
75 #else /* BSDTIMES */
76 # ifndef POSIX
77 pcsecs(time_t l)
78 # else /* POSIX */
79 pcsecs(clock_t l)
80 # endif /* POSIX */
81 #endif /* BSDTIMES */
82 {
83     int i;
84
85     i = (int) (l / 360000);
86     if (i) {
87         xprintf("%d:", i);
88         i = (int) ((l % 360000) / 100);
89         p2dig(i / 60);
90         goto minsec;
91     }
92     i = (int) (l / 100);
93     xprintf("%d", i / 60);
94 minsec:
95     i %= 60;
96     xprintf(":");
97     p2dig(i);
98     xprintf(".");
99     p2dig((int) (l % 100));
100 }
101
102 static void 
103 p2dig(unsigned i)
104 {
105
106     xprintf("%u%u", i / 10, i % 10);
107 }
108
109 char    linbuf[2048];           /* was 128 */
110 char   *linp = linbuf;
111 int    output_raw = 0;          /* PWP */
112 int    xlate_cr   = 0;          /* HE */
113
114 /* For cleanup_push() */
115 void
116 output_raw_restore(void *xorig)
117 {
118     int *orig;
119
120     orig = xorig;
121     output_raw = *orig;
122 }
123
124 #ifdef WIDE_STRINGS
125 void
126 putwraw(Char c)
127 {
128     char buf[MB_LEN_MAX];
129     size_t i, len;
130     
131     len = one_wctomb(buf, c & CHAR);
132     for (i = 0; i < len; i++)
133         putraw((unsigned char)buf[i] | (c & ~CHAR));
134 }
135
136 void
137 xputwchar(Char c)
138 {
139     char buf[MB_LEN_MAX];
140     size_t i, len;
141     
142     len = one_wctomb(buf, c & CHAR);
143     for (i = 0; i < len; i++)
144         xputchar((unsigned char)buf[i] | (c & ~CHAR));
145 }
146 #endif
147
148 void
149 xputchar(int c)
150 {
151     int     atr;
152
153     atr = c & ATTRIBUTES & TRIM;
154     c &= CHAR | QUOTE;
155     if (!output_raw && (c & QUOTE) == 0) {
156         if (iscntrl(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
157             if (c != '\t' && c != '\n'
158 #ifdef COLORCAT
159                 && !(adrof(STRcolorcat) && c == CTL_ESC('\033'))
160 #endif
161                 && (xlate_cr || c != '\r'))
162             {
163                 xputchar('^' | atr);
164                 if (c == CTL_ESC('\177'))
165                     c = '?';
166                 else
167                     /* Note: for IS_ASCII, this compiles to: c = c | 0100 */
168                     c = CTL_ESC(ASC(c)|0100);
169             }
170         }
171         else if (!isprint(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
172             xputchar('\\' | atr);
173             xputchar((((c >> 6) & 7) + '0') | atr);
174             xputchar((((c >> 3) & 7) + '0') | atr);
175             c = (c & 7) + '0';
176         }
177         (void) putraw(c | atr);
178     }
179     else {
180         c &= TRIM;
181         if (haderr ? (didfds ? is2atty : isdiagatty) :
182             (didfds ? is1atty : isoutatty))
183             SetAttributes(c | atr);
184         (void) putpure(c);
185     }
186     if (lbuffed && (c & CHAR) == '\n')
187         flush();
188 }
189
190 int
191 putraw(int c)
192 {
193     if (haderr ? (didfds ? is2atty : isdiagatty) :
194         (didfds ? is1atty : isoutatty)) {
195         if (Tty_eight_bit == -1)
196             ed_set_tty_eight_bit();
197         if (!Tty_eight_bit && (c & META)) {
198             c = (c & ~META) | STANDOUT;
199         }
200         SetAttributes(c);
201     }
202     return putpure(c);
203 }
204
205 int
206 putpure(int c)
207 {
208     c &= CHAR;
209
210     *linp++ = (char) c;
211     if (linp >= &linbuf[sizeof linbuf - 10])
212         flush();
213     return (1);
214 }
215
216 void
217 drainoline(void)
218 {
219     linp = linbuf;
220 }
221
222 void
223 flush(void)
224 {
225     int unit;
226     static int interrupted = 0;
227
228     /* int lmode; */
229
230     if (linp == linbuf)
231         return;
232     if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10])
233         return;
234     if (interrupted) {
235         interrupted = 0;
236         linp = linbuf;          /* avoid recursion as stderror calls flush */
237         stderror(ERR_SILENT);
238     }
239     interrupted = 1;
240     if (haderr)
241         unit = didfds ? 2 : SHDIAG;
242     else
243         unit = didfds ? 1 : SHOUT;
244 #ifdef COMMENT
245 #ifdef TIOCLGET
246     if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 &&
247         lmode & LFLUSHO) {
248         lmode = LFLUSHO;
249         (void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode);
250         (void) xwrite(unit, "\n", 1);
251     }
252 #endif
253 #endif
254     if (xwrite(unit, linbuf, linp - linbuf) == -1)
255         switch (errno) {
256 #ifdef EIO
257         /* We lost our tty */
258         case EIO:
259 #endif
260 #ifdef ENXIO
261         /*
262          * Deal with Digital Unix 4.0D bogocity, returning ENXIO when
263          * we lose our tty.
264          */
265         case ENXIO:
266 #endif
267         /*
268          * IRIX 6.4 bogocity?
269          */
270 #ifdef ENOTTY
271         case ENOTTY:
272 #endif
273 #ifdef EBADF
274         case EBADF:
275 #endif
276 #ifdef ESTALE
277         /*
278          * Lost our file descriptor, exit (IRIS4D)
279          */
280         case ESTALE:
281 #endif
282         /*
283          * Over our quota, writing the history file
284          */
285 #ifdef EDQUOT
286         case EDQUOT:
287 #endif
288         /* Nothing to do, but die */
289             xexit(1);
290             break;
291         default:
292             stderror(ERR_SILENT);
293             break;
294         }
295
296     linp = linbuf;
297     interrupted = 0;
298 }