update copyright notice
[unix-history] / usr / src / usr.bin / more / output.c
CommitLineData
bfe13c81
KB
1/*
2 * Copyright (c) 1988 Mark Nudleman
3 * Copyright (c) 1988 Regents of the University of California.
4 * All rights reserved.
5 *
bfe13c81
KB
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
a942b40b
KB
11 * by Mark Nudleman and the University of California, Berkeley. The
12 * name of Mark Nudleman or the
bfe13c81
KB
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20#ifndef lint
a942b40b 21static char sccsid[] = "@(#)output.c 5.4 (Berkeley) %G%";
bfe13c81
KB
22#endif /* not lint */
23
24/*
25 * High level routines dealing with the output to the screen.
26 */
27
28#include "less.h"
29
30public int errmsgs; /* Count of messages displayed by error() */
31
32extern int sigs;
33extern int sc_width, sc_height;
34extern int ul_width, ue_width;
35extern int so_width, se_width;
36extern int bo_width, be_width;
37extern int tabstop;
38extern int twiddle;
39extern int screen_trashed;
40extern int any_display;
41extern char *line;
42extern char *first_cmd;
43
44/*
45 * Display the line which is in the line buffer.
46 */
47 public void
48put_line()
49{
50 register char *p;
51 register int c;
52 register int column;
53 extern int auto_wrap, ignaw;
54
55 if (sigs)
56 {
57 /*
58 * Don't output if a signal is pending.
59 */
60 screen_trashed = 1;
61 return;
62 }
63
64 if (line == NULL)
65 line = (twiddle) ? "~" : "";
66
67 column = 0;
68 for (p = line; *p != '\0'; p++)
69 {
70 switch (c = *p)
71 {
72 case UL_CHAR:
73 ul_enter();
74 column += ul_width;
75 break;
76 case UE_CHAR:
77 ul_exit();
78 column += ue_width;
79 break;
80 case BO_CHAR:
81 bo_enter();
82 column += bo_width;
83 break;
84 case BE_CHAR:
85 bo_exit();
86 column += be_width;
87 break;
88 case '\t':
89 do
90 {
91 putchr(' ');
92 column++;
93 } while ((column % tabstop) != 0);
94 break;
95 case '\b':
96 putbs();
97 column--;
98 break;
99 default:
100 if (c & 0200)
101 {
102 /*
103 * Control characters arrive here as the
104 * normal character [carat_char(c)] with
105 * the 0200 bit set. See pappend().
106 */
107 putchr('^');
108 putchr(c & 0177);
109 column += 2;
110 } else
111 {
112 putchr(c);
113 column++;
114 }
115 }
116 }
117 if (column < sc_width || !auto_wrap || ignaw)
118 putchr('\n');
119}
120
121/*
122 * Is a given character a "control" character?
123 * {{ ASCII DEPENDENT }}
124 */
125 public int
126control_char(c)
127 int c;
128{
129 return (c < ' ' || c == '\177');
130}
131
132/*
133 * Return the printable character used to identify a control character
134 * (printed after a carat; e.g. '\3' => "^C").
135 * {{ ASCII DEPENDENT }}
136 */
137 public int
138carat_char(c)
139 int c;
140{
141 return ((c == '\177') ? '?' : (c | 0100));
142}
143
144
145static char obuf[1024];
146static char *ob = obuf;
147
148/*
149 * Flush buffered output.
150 */
151 public void
152flush()
153{
154 register int n;
155
156 n = ob - obuf;
157 if (n == 0)
158 return;
159 if (write(1, obuf, n) != n)
160 screen_trashed = 1;
161 ob = obuf;
162}
163
bfe13c81
KB
164/*
165 * Output a character.
166 */
167 public void
168putchr(c)
169 int c;
170{
171 if (ob >= &obuf[sizeof(obuf)])
172 flush();
173 *ob++ = c;
174}
175
176/*
177 * Output a string.
178 */
179 public void
180putstr(s)
181 register char *s;
182{
183 while (*s != '\0')
184 putchr(*s++);
185}
186
187/*
188 * Output a message in the lower left corner of the screen
189 * and wait for carriage return.
190 */
191
192static char return_to_continue[] = " (press RETURN)";
193
194 public void
195error(s)
196 char *s;
197{
198 register int c;
199 static char buf[2];
200
201 errmsgs++;
202 if (!any_display)
203 {
204 /*
205 * Nothing has been displayed yet.
206 * Output this message on error output (file
207 * descriptor 2) and don't wait for a keystroke
208 * to continue.
209 *
210 * This has the desirable effect of producing all
211 * error messages on error output if standard output
212 * is directed to a file. It also does the same if
213 * we never produce any real output; for example, if
214 * the input file(s) cannot be opened. If we do
215 * eventually produce output, code in edit() makes
216 * sure these messages can be seen before they are
217 * overwritten or scrolled away.
218 */
219 write(2, s, strlen(s));
220 write(2, "\n", 1);
221 return;
222 }
223
224 lower_left();
225 clear_eol();
226 so_enter();
227 putstr(s);
228 putstr(return_to_continue);
229 so_exit();
230
bfe13c81
KB
231 c = getchr();
232 if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
233 {
234 buf[0] = c;
235 first_cmd = buf;
236 }
bfe13c81
KB
237 lower_left();
238
239 if (strlen(s) + sizeof(return_to_continue) +
240 so_width + se_width + 1 > sc_width)
241 /*
242 * Printing the message has probably scrolled the screen.
243 * {{ Unless the terminal doesn't have auto margins,
244 * in which case we just hammered on the right margin. }}
245 */
246 repaint();
247
248 flush();
249}
250
251static char intr_to_abort[] = "... (interrupt to abort)";
252
253 public void
254ierror(s)
255 char *s;
256{
257
258 lower_left();
259 clear_eol();
260 so_enter();
261 putstr(s);
262 putstr(intr_to_abort);
263 so_exit();
264 flush();
265}