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