| GCC Code Coverage Report | |||||||||||||||||||||
        
  | 
    |||||||||||||||||||||
| Line | Branch | Exec | Source | 
1  | 
    /*  | 
    ||
2  | 
    * Copyright (C) 1984-2012 Mark Nudelman  | 
    ||
3  | 
    * Modified for use with illumos by Garrett D'Amore.  | 
    ||
4  | 
    * Copyright 2014 Garrett D'Amore <garrett@damore.org>  | 
    ||
5  | 
    *  | 
    ||
6  | 
    * You may distribute under the terms of either the GNU General Public  | 
    ||
7  | 
    * License or the Less License, as specified in the README file.  | 
    ||
8  | 
    *  | 
    ||
9  | 
    * For more information, see the README file.  | 
    ||
10  | 
    */  | 
    ||
11  | 
    |||
12  | 
    /*  | 
    ||
13  | 
    * Primitives for displaying the file on the screen,  | 
    ||
14  | 
    * scrolling either forward or backward.  | 
    ||
15  | 
    */  | 
    ||
16  | 
    |||
17  | 
    #include "less.h"  | 
    ||
18  | 
    #include "position.h"  | 
    ||
19  | 
    |||
20  | 
    int screen_trashed;  | 
    ||
21  | 
    int squished;  | 
    ||
22  | 
    int no_back_scroll = 0;  | 
    ||
23  | 
    int forw_prompt;  | 
    ||
24  | 
    |||
25  | 
    extern volatile sig_atomic_t sigs;  | 
    ||
26  | 
    extern int top_scroll;  | 
    ||
27  | 
    extern int quiet;  | 
    ||
28  | 
    extern int sc_width, sc_height;  | 
    ||
29  | 
    extern int plusoption;  | 
    ||
30  | 
    extern int forw_scroll;  | 
    ||
31  | 
    extern int back_scroll;  | 
    ||
32  | 
    extern int ignore_eoi;  | 
    ||
33  | 
    extern int clear_bg;  | 
    ||
34  | 
    extern int final_attr;  | 
    ||
35  | 
    extern int oldbot;  | 
    ||
36  | 
    extern char *tagoption;  | 
    ||
37  | 
    |||
38  | 
    /*  | 
    ||
39  | 
    * Sound the bell to indicate user is trying to move past end of file.  | 
    ||
40  | 
    */  | 
    ||
41  | 
    static void  | 
    ||
42  | 
    eof_bell(void)  | 
    ||
43  | 
    { | 
    ||
44  | 
    ✓✗ | 60  | 
    if (quiet == NOT_QUIET)  | 
    
45  | 
    30  | 
    ring_bell();  | 
    |
46  | 
    else  | 
    ||
47  | 
    vbell();  | 
    ||
48  | 
    30  | 
    }  | 
    |
49  | 
    |||
50  | 
    /*  | 
    ||
51  | 
    * Check to see if the end of file is currently displayed.  | 
    ||
52  | 
    */  | 
    ||
53  | 
    int  | 
    ||
54  | 
    eof_displayed(void)  | 
    ||
55  | 
    { | 
    ||
56  | 
    off_t pos;  | 
    ||
57  | 
    |||
58  | 
    ✗✓ | 1932  | 
    if (ignore_eoi)  | 
    
59  | 
    return (0);  | 
    ||
60  | 
    |||
61  | 
    ✓✓ | 966  | 
    if (ch_length() == -1)  | 
    
62  | 
    /*  | 
    ||
63  | 
    * If the file length is not known,  | 
    ||
64  | 
    * we can't possibly be displaying EOF.  | 
    ||
65  | 
    */  | 
    ||
66  | 
    196  | 
    return (0);  | 
    |
67  | 
    |||
68  | 
    /*  | 
    ||
69  | 
    * If the bottom line is empty, we are at EOF.  | 
    ||
70  | 
    * If the bottom line ends at the file length,  | 
    ||
71  | 
    * we must be just at EOF.  | 
    ||
72  | 
    */  | 
    ||
73  | 
    770  | 
    pos = position(BOTTOM_PLUS_ONE);  | 
    |
74  | 
    ✓✓ | 2286  | 
    return (pos == -1 || pos == ch_length());  | 
    
75  | 
    966  | 
    }  | 
    |
76  | 
    |||
77  | 
    /*  | 
    ||
78  | 
    * Check to see if the entire file is currently displayed.  | 
    ||
79  | 
    */  | 
    ||
80  | 
    int  | 
    ||
81  | 
    entire_file_displayed(void)  | 
    ||
82  | 
    { | 
    ||
83  | 
    off_t pos;  | 
    ||
84  | 
    |||
85  | 
    /* Make sure last line of file is displayed. */  | 
    ||
86  | 
    if (!eof_displayed())  | 
    ||
87  | 
    return (0);  | 
    ||
88  | 
    |||
89  | 
    /* Make sure first line of file is displayed. */  | 
    ||
90  | 
    pos = position(0);  | 
    ||
91  | 
    return (pos == -1 || pos == 0);  | 
    ||
92  | 
    }  | 
    ||
93  | 
    |||
94  | 
    /*  | 
    ||
95  | 
    * If the screen is "squished", repaint it.  | 
    ||
96  | 
    * "Squished" means the first displayed line is not at the top  | 
    ||
97  | 
    * of the screen; this can happen when we display a short file  | 
    ||
98  | 
    * for the first time.  | 
    ||
99  | 
    */  | 
    ||
100  | 
    void  | 
    ||
101  | 
    squish_check(void)  | 
    ||
102  | 
    { | 
    ||
103  | 
    ✗✓ | 1970  | 
    if (!squished)  | 
    
104  | 
    return;  | 
    ||
105  | 
    squished = 0;  | 
    ||
106  | 
    repaint();  | 
    ||
107  | 
    985  | 
    }  | 
    |
108  | 
    |||
109  | 
    /*  | 
    ||
110  | 
    * Display n lines, scrolling forward,  | 
    ||
111  | 
    * starting at position pos in the input file.  | 
    ||
112  | 
    * "force" means display the n lines even if we hit end of file.  | 
    ||
113  | 
    * "only_last" means display only the last screenful if n > screen size.  | 
    ||
114  | 
    * "nblank" is the number of blank lines to draw before the first  | 
    ||
115  | 
    * real line. If nblank > 0, the pos must be -1.  | 
    ||
116  | 
    * The first real line after the blanks will start at ch_zero().  | 
    ||
117  | 
    */  | 
    ||
118  | 
    void  | 
    ||
119  | 
    forw(int n, off_t pos, int force, int only_last, int nblank)  | 
    ||
120  | 
    { | 
    ||
121  | 
    int nlines = 0;  | 
    ||
122  | 
    int do_repaint;  | 
    ||
123  | 
    static int first_time = 1;  | 
    ||
124  | 
    |||
125  | 
    1714  | 
    squish_check();  | 
    |
126  | 
    |||
127  | 
    /*  | 
    ||
128  | 
    * do_repaint tells us not to display anything till the end,  | 
    ||
129  | 
    * then just repaint the entire screen.  | 
    ||
130  | 
    * We repaint if we are supposed to display only the last  | 
    ||
131  | 
    * screenful and the request is for more than a screenful.  | 
    ||
132  | 
    * Also if the request exceeds the forward scroll limit  | 
    ||
133  | 
    * (but not if the request is for exactly a screenful, since  | 
    ||
134  | 
    * repainting itself involves scrolling forward a screenful).  | 
    ||
135  | 
    */  | 
    ||
136  | 
    ✓✓✓✗ | 
    2367  | 
    do_repaint = (only_last && n > sc_height-1) ||  | 
    
137  | 
    ✗✓✗✗ | 
    857  | 
    (forw_scroll >= 0 && n > forw_scroll && n != sc_height-1);  | 
    
138  | 
    |||
139  | 
    ✓✗ | 857  | 
    	if (!do_repaint) { | 
    
140  | 
    ✓✓✓✓ ✓✗  | 
    2405  | 
    		if (top_scroll && n >= sc_height - 1 && pos != ch_length()) { | 
    
141  | 
    /*  | 
    ||
142  | 
    * Start a new screen.  | 
    ||
143  | 
    			 * {{ This is not really desirable if we happen | 
    ||
144  | 
    * to hit eof in the middle of this screen,  | 
    ||
145  | 
    * but we don't yet know if that will happen. }}  | 
    ||
146  | 
    */  | 
    ||
147  | 
    745  | 
    pos_clear();  | 
    |
148  | 
    745  | 
    add_forw_pos(pos);  | 
    |
149  | 
    force = 1;  | 
    ||
150  | 
    745  | 
    do_clear();  | 
    |
151  | 
    745  | 
    home();  | 
    |
152  | 
    745  | 
    }  | 
    |
153  | 
    |||
154  | 
    ✓✓✓✓ | 
    1707  | 
    		if (pos != position(BOTTOM_PLUS_ONE) || empty_screen()) { | 
    
155  | 
    /*  | 
    ||
156  | 
    * This is not contiguous with what is  | 
    ||
157  | 
    * currently displayed. Clear the screen image  | 
    ||
158  | 
    * (position table) and start a new screen.  | 
    ||
159  | 
    */  | 
    ||
160  | 
    42  | 
    pos_clear();  | 
    |
161  | 
    42  | 
    add_forw_pos(pos);  | 
    |
162  | 
    force = 1;  | 
    ||
163  | 
    ✓✓ | 42  | 
    			if (top_scroll) { | 
    
164  | 
    35  | 
    do_clear();  | 
    |
165  | 
    35  | 
    home();  | 
    |
166  | 
    ✓✓ | 42  | 
    			} else if (!first_time) { | 
    
167  | 
    2  | 
    				putstr("...skipping...\n"); | 
    |
168  | 
    2  | 
    }  | 
    |
169  | 
    }  | 
    ||
170  | 
    }  | 
    ||
171  | 
    |||
172  | 
    ✓✓ | 50787  | 
    	while (--n >= 0) { | 
    
173  | 
    /*  | 
    ||
174  | 
    * Read the next line of input.  | 
    ||
175  | 
    */  | 
    ||
176  | 
    ✗✓ | 24969  | 
    		if (nblank > 0) { | 
    
177  | 
    /*  | 
    ||
178  | 
    * Still drawing blanks; don't get a line  | 
    ||
179  | 
    * from the file yet.  | 
    ||
180  | 
    * If this is the last blank line, get ready to  | 
    ||
181  | 
    * read a line starting at ch_zero() next time.  | 
    ||
182  | 
    */  | 
    ||
183  | 
    if (--nblank == 0)  | 
    ||
184  | 
    pos = ch_zero();  | 
    ||
185  | 
    		} else { | 
    ||
186  | 
    /*  | 
    ||
187  | 
    * Get the next line from the file.  | 
    ||
188  | 
    */  | 
    ||
189  | 
    24969  | 
    pos = forw_line(pos);  | 
    |
190  | 
    ✓✓ | 24969  | 
    			if (pos == -1) { | 
    
191  | 
    /*  | 
    ||
192  | 
    * End of file: stop here unless the top line  | 
    ||
193  | 
    * is still empty, or "force" is true.  | 
    ||
194  | 
    * Even if force is true, stop when the last  | 
    ||
195  | 
    * line in the file reaches the top of screen.  | 
    ||
196  | 
    */  | 
    ||
197  | 
    ✓✓✗✓ | 
    177  | 
    if (!force && position(TOP) != -1)  | 
    
198  | 
    break;  | 
    ||
199  | 
    ✗✓✗✗ | 
    169  | 
    if (!empty_lines(0, 0) &&  | 
    
200  | 
    !empty_lines(1, 1) &&  | 
    ||
201  | 
    empty_lines(2, sc_height-1))  | 
    ||
202  | 
    break;  | 
    ||
203  | 
    }  | 
    ||
204  | 
    }  | 
    ||
205  | 
    /*  | 
    ||
206  | 
    * Add the position of the next line to the position table.  | 
    ||
207  | 
    * Display the current line on the screen.  | 
    ||
208  | 
    */  | 
    ||
209  | 
    24965  | 
    add_forw_pos(pos);  | 
    |
210  | 
    24965  | 
    nlines++;  | 
    |
211  | 
    ✗✓ | 24965  | 
    if (do_repaint)  | 
    
212  | 
    continue;  | 
    ||
213  | 
    /*  | 
    ||
214  | 
    * If this is the first screen displayed and  | 
    ||
215  | 
    * we hit an early EOF (i.e. before the requested  | 
    ||
216  | 
    * number of lines), we "squish" the display down  | 
    ||
217  | 
    * at the bottom of the screen.  | 
    ||
218  | 
    * But don't do this if a + option or a -t option  | 
    ||
219  | 
    * was given. These options can cause us to  | 
    ||
220  | 
    * start the display after the beginning of the file,  | 
    ||
221  | 
    * and it is not appropriate to squish in that case.  | 
    ||
222  | 
    */  | 
    ||
223  | 
    ✗✓ | 74895  | 
    if (first_time && pos == -1 && !top_scroll &&  | 
    
224  | 
    49930  | 
    		    tagoption == NULL && !plusoption) { | 
    |
225  | 
    squished = 1;  | 
    ||
226  | 
    continue;  | 
    ||
227  | 
    }  | 
    ||
228  | 
    24965  | 
    put_line();  | 
    |
229  | 
    24965  | 
    forw_prompt = 1;  | 
    |
230  | 
    }  | 
    ||
231  | 
    |||
232  | 
    ✗✓ | 857  | 
    if (nlines == 0)  | 
    
233  | 
    eof_bell();  | 
    ||
234  | 
    ✗✓ | 857  | 
    else if (do_repaint)  | 
    
235  | 
    repaint();  | 
    ||
236  | 
    857  | 
    first_time = 0;  | 
    |
237  | 
    857  | 
    (void) currline(BOTTOM);  | 
    |
238  | 
    857  | 
    }  | 
    |
239  | 
    |||
240  | 
    /*  | 
    ||
241  | 
    * Display n lines, scrolling backward.  | 
    ||
242  | 
    */  | 
    ||
243  | 
    void  | 
    ||
244  | 
    back(int n, off_t pos, int force, int only_last)  | 
    ||
245  | 
    { | 
    ||
246  | 
    int nlines = 0;  | 
    ||
247  | 
    int do_repaint;  | 
    ||
248  | 
    |||
249  | 
    254  | 
    squish_check();  | 
    |
250  | 
    ✓✓✓✓ | 
    309  | 
    do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1));  | 
    
251  | 
    ✓✓ | 2677  | 
    	while (--n >= 0) { | 
    
252  | 
    /*  | 
    ||
253  | 
    * Get the previous line of input.  | 
    ||
254  | 
    */  | 
    ||
255  | 
    2449  | 
    pos = back_line(pos);  | 
    |
256  | 
    ✓✓ | 4898  | 
    		if (pos == -1) { | 
    
257  | 
    /*  | 
    ||
258  | 
    * Beginning of file: stop here unless "force" is true.  | 
    ||
259  | 
    */  | 
    ||
260  | 
    2449  | 
    if (!force)  | 
    |
261  | 
    break;  | 
    ||
262  | 
    }  | 
    ||
263  | 
    /*  | 
    ||
264  | 
    * Add the position of the previous line to the position table.  | 
    ||
265  | 
    * Display the line on the screen.  | 
    ||
266  | 
    */  | 
    ||
267  | 
    2423  | 
    add_back_pos(pos);  | 
    |
268  | 
    2423  | 
    nlines++;  | 
    |
269  | 
    ✓✓ | 2423  | 
    		if (!do_repaint) { | 
    
270  | 
    128  | 
    home();  | 
    |
271  | 
    128  | 
    add_line();  | 
    |
272  | 
    128  | 
    put_line();  | 
    |
273  | 
    128  | 
    }  | 
    |
274  | 
    }  | 
    ||
275  | 
    |||
276  | 
    ✓✓ | 127  | 
    if (nlines == 0)  | 
    
277  | 
    28  | 
    eof_bell();  | 
    |
278  | 
    ✓✓ | 99  | 
    else if (do_repaint)  | 
    
279  | 
    72  | 
    repaint();  | 
    |
280  | 
    ✓✗ | 27  | 
    else if (!oldbot)  | 
    
281  | 
    27  | 
    lower_left();  | 
    |
282  | 
    127  | 
    (void) currline(BOTTOM);  | 
    |
283  | 
    127  | 
    }  | 
    |
284  | 
    |||
285  | 
    /*  | 
    ||
286  | 
    * Display n more lines, forward.  | 
    ||
287  | 
    * Start just after the line currently displayed at the bottom of the screen.  | 
    ||
288  | 
    */  | 
    ||
289  | 
    void  | 
    ||
290  | 
    forward(int n, int force, int only_last)  | 
    ||
291  | 
    { | 
    ||
292  | 
    off_t pos;  | 
    ||
293  | 
    |||
294  | 
    ✓✓✓✓ ✓✗  | 
    1515  | 
    if (get_quit_at_eof() && eof_displayed() &&  | 
    
295  | 
    3  | 
    	    !(ch_getflags() & CH_HELPFILE)) { | 
    |
296  | 
    /*  | 
    ||
297  | 
    * If the -e flag is set and we're trying to go  | 
    ||
298  | 
    * forward from end-of-file, go on to the next file.  | 
    ||
299  | 
    */  | 
    ||
300  | 
    ✓✗ | 3  | 
    if (edit_next(1))  | 
    
301  | 
    3  | 
    quit(QUIT_OK);  | 
    |
302  | 
    return;  | 
    ||
303  | 
    }  | 
    ||
304  | 
    |||
305  | 
    728  | 
    pos = position(BOTTOM_PLUS_ONE);  | 
    |
306  | 
    ✓✓✗✓ ✗✗  | 
    730  | 
    	if (pos == -1 && (!force || empty_lines(2, sc_height-1))) { | 
    
307  | 
    ✗✓ | 2  | 
    		if (ignore_eoi) { | 
    
308  | 
    /*  | 
    ||
309  | 
    * ignore_eoi is to support A_F_FOREVER.  | 
    ||
310  | 
    * Back up until there is a line at the bottom  | 
    ||
311  | 
    * of the screen.  | 
    ||
312  | 
    */  | 
    ||
313  | 
    			if (empty_screen()) { | 
    ||
314  | 
    pos = ch_zero();  | 
    ||
315  | 
    			} else { | 
    ||
316  | 
    				do { | 
    ||
317  | 
    back(1, position(TOP), 1, 0);  | 
    ||
318  | 
    pos = position(BOTTOM_PLUS_ONE);  | 
    ||
319  | 
    } while (pos == -1);  | 
    ||
320  | 
    }  | 
    ||
321  | 
    		} else { | 
    ||
322  | 
    2  | 
    eof_bell();  | 
    |
323  | 
    2  | 
    return;  | 
    |
324  | 
    }  | 
    ||
325  | 
    }  | 
    ||
326  | 
    726  | 
    forw(n, pos, force, only_last, 0);  | 
    |
327  | 
    1454  | 
    }  | 
    |
328  | 
    |||
329  | 
    /*  | 
    ||
330  | 
    * Display n more lines, backward.  | 
    ||
331  | 
    * Start just before the line currently displayed at the top of the screen.  | 
    ||
332  | 
    */  | 
    ||
333  | 
    void  | 
    ||
334  | 
    backward(int n, int force, int only_last)  | 
    ||
335  | 
    { | 
    ||
336  | 
    off_t pos;  | 
    ||
337  | 
    |||
338  | 
    242  | 
    pos = position(TOP);  | 
    |
339  | 
    ✗✓✗✗ ✗✗  | 
    121  | 
    	if (pos == -1 && (!force || position(BOTTOM) == 0)) { | 
    
340  | 
    eof_bell();  | 
    ||
341  | 
    return;  | 
    ||
342  | 
    }  | 
    ||
343  | 
    121  | 
    back(n, pos, force, only_last);  | 
    |
344  | 
    242  | 
    }  | 
    |
345  | 
    |||
346  | 
    /*  | 
    ||
347  | 
    * Get the backwards scroll limit.  | 
    ||
348  | 
    * Must call this function instead of just using the value of  | 
    ||
349  | 
    * back_scroll, because the default case depends on sc_height and  | 
    ||
350  | 
    * top_scroll, as well as back_scroll.  | 
    ||
351  | 
    */  | 
    ||
352  | 
    int  | 
    ||
353  | 
    get_back_scroll(void)  | 
    ||
354  | 
    { | 
    ||
355  | 
    ✗✓ | 254  | 
    if (no_back_scroll)  | 
    
356  | 
    return (0);  | 
    ||
357  | 
    ✗✓ | 127  | 
    if (back_scroll >= 0)  | 
    
358  | 
    return (back_scroll);  | 
    ||
359  | 
    ✓✓ | 127  | 
    if (top_scroll)  | 
    
360  | 
    113  | 
    return (sc_height - 2);  | 
    |
361  | 
    14  | 
    return (10000); /* infinity */  | 
    |
362  | 
    127  | 
    }  | 
    
| Generated by: GCOVR (Version 3.3) |