output.c revision 1.3 1 /* $NetBSD: output.c,v 1.3 1998/01/09 08:03:33 perry Exp $ */
2
3 /*
4 * Copyright (c) 1988 Mark Nudleman
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #ifndef lint
38 static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 4/27/95";
39 #endif /* not lint */
40
41 /*
42 * High level routines dealing with the output to the screen.
43 */
44
45 #include <stdio.h>
46 #include <string.h>
47 #include <less.h>
48
49 int errmsgs; /* Count of messages displayed by error() */
50
51 extern int sigs;
52 extern int sc_width, sc_height;
53 extern int ul_width, ue_width;
54 extern int so_width, se_width;
55 extern int bo_width, be_width;
56 extern int tabstop;
57 extern int screen_trashed;
58 extern int any_display;
59 extern char *line;
60
61 /* display the line which is in the line buffer. */
62 put_line()
63 {
64 register char *p;
65 register int c;
66 register int column;
67 extern int auto_wrap, ignaw;
68
69 if (sigs)
70 {
71 /*
72 * Don't output if a signal is pending.
73 */
74 screen_trashed = 1;
75 return;
76 }
77
78 if (line == NULL)
79 line = "";
80
81 column = 0;
82 for (p = line; *p != '\0'; p++)
83 {
84 switch (c = *p)
85 {
86 case UL_CHAR:
87 ul_enter();
88 column += ul_width +1;
89 break;
90 case UE_CHAR:
91 ul_exit();
92 column += ue_width;
93 break;
94 case BO_CHAR:
95 bo_enter();
96 column += bo_width +1;
97 break;
98 case BE_CHAR:
99 bo_exit();
100 column += be_width;
101 break;
102 case '\t':
103 do
104 {
105 putchr(' ');
106 column++;
107 } while ((column % tabstop) != 0);
108 break;
109 case '\b':
110 putbs();
111 column--;
112 break;
113 default:
114 if (c & 0200)
115 {
116 /*
117 * Control characters arrive here as the
118 * normal character [CARAT_CHAR(c)] with
119 * the 0200 bit set. See pappend().
120 */
121 putchr('^');
122 putchr(c & 0177);
123 column += 2;
124 } else
125 {
126 putchr(c);
127 column++;
128 }
129 }
130 }
131 if (column < sc_width || !auto_wrap || ignaw)
132 putchr('\n');
133 }
134
135 static char obuf[1024];
136 static char *ob = obuf;
137
138 /*
139 * Flush buffered output.
140 */
141 flush()
142 {
143 register int n;
144
145 n = ob - obuf;
146 if (n == 0)
147 return;
148 if (write(1, obuf, n) != n)
149 screen_trashed = 1;
150 ob = obuf;
151 }
152
153 /*
154 * Purge any pending output.
155 */
156 purge()
157 {
158
159 ob = obuf;
160 }
161
162 /*
163 * Output a character.
164 */
165 putchr(c)
166 int c;
167 {
168 if (ob >= &obuf[sizeof(obuf)])
169 flush();
170 *ob++ = c;
171 }
172
173 /*
174 * Output a string.
175 */
176 putstr(s)
177 register char *s;
178 {
179 while (*s != '\0')
180 putchr(*s++);
181 }
182
183 int cmdstack;
184 static char return_to_continue[] = "(press RETURN)";
185
186 /*
187 * Output a message in the lower left corner of the screen
188 * and wait for carriage return.
189 */
190 error(s)
191 char *s;
192 {
193 int ch;
194
195 ++errmsgs;
196 if (!any_display) {
197 /*
198 * Nothing has been displayed yet. Output this message on
199 * error output (file descriptor 2) and don't wait for a
200 * keystroke to continue.
201 *
202 * This has the desirable effect of producing all error
203 * messages on error output if standard output is directed
204 * to a file. It also does the same if we never produce
205 * any real output; for example, if the input file(s) cannot
206 * be opened. If we do eventually produce output, code in
207 * edit() makes sure these messages can be seen before they
208 * are overwritten or scrolled away.
209 */
210 if (s != NULL) {
211 (void)write(2, s, strlen(s));
212 (void)write(2, "\n", 1);
213 }
214 return;
215 }
216
217 lower_left();
218 clear_eol();
219 so_enter();
220 if (s != NULL) {
221 putstr(s);
222 putstr(" ");
223 }
224 putstr(return_to_continue);
225 so_exit();
226
227 if ((ch = getchr()) != '\n') {
228 if (ch == 'q')
229 quit();
230 cmdstack = ch;
231 }
232 lower_left();
233
234 if ((s != NULL ? strlen(s) : 0) + sizeof(return_to_continue) +
235 so_width + se_width + 1 > sc_width)
236 /*
237 * Printing the message has probably scrolled the screen.
238 * {{ Unless the terminal doesn't have auto margins,
239 * in which case we just hammered on the right margin. }}
240 */
241 repaint();
242 flush();
243 }
244
245 static char intr_to_abort[] = "... (interrupt to abort)";
246
247 ierror(s)
248 char *s;
249 {
250 lower_left();
251 clear_eol();
252 so_enter();
253 putstr(s);
254 putstr(intr_to_abort);
255 so_exit();
256 flush();
257 }
258