Annotation of src/usr.bin/less/position.c, Revision 1.1.1.1
1.1 etheisen 1: /*
2: * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice in the documentation and/or other materials provided with
12: * the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
15: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
18: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
20: * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
21: * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27:
28: /*
29: * Routines dealing with the "position" table.
30: * This is a table which tells the position (in the input file) of the
31: * first char on each currently displayed line.
32: *
33: * {{ The position table is scrolled by moving all the entries.
34: * Would be better to have a circular table
35: * and just change a couple of pointers. }}
36: */
37:
38: #include "less.h"
39: #include "position.h"
40:
41: static POSITION *table = NULL; /* The position table */
42: static int table_size;
43:
44: extern int sc_width, sc_height;
45:
46: /*
47: * Return the starting file position of a line displayed on the screen.
48: * The line may be specified as a line number relative to the top
49: * of the screen, but is usually one of these special cases:
50: * the top (first) line on the screen
51: * the second line on the screen
52: * the bottom line on the screen
53: * the line after the bottom line on the screen
54: */
55: public POSITION
56: position(where)
57: int where;
58: {
59: switch (where)
60: {
61: case BOTTOM:
62: where = sc_height - 2;
63: break;
64: case BOTTOM_PLUS_ONE:
65: where = sc_height - 1;
66: break;
67: case MIDDLE:
68: where = (sc_height - 1) / 2;
69: }
70: return (table[where]);
71: }
72:
73: /*
74: * Add a new file position to the bottom of the position table.
75: */
76: public void
77: add_forw_pos(pos)
78: POSITION pos;
79: {
80: register int i;
81:
82: /*
83: * Scroll the position table up.
84: */
85: for (i = 1; i < sc_height; i++)
86: table[i-1] = table[i];
87: table[sc_height - 1] = pos;
88: }
89:
90: /*
91: * Add a new file position to the top of the position table.
92: */
93: public void
94: add_back_pos(pos)
95: POSITION pos;
96: {
97: register int i;
98:
99: /*
100: * Scroll the position table down.
101: */
102: for (i = sc_height - 1; i > 0; i--)
103: table[i] = table[i-1];
104: table[0] = pos;
105: }
106:
107: /*
108: * Initialize the position table, done whenever we clear the screen.
109: */
110: public void
111: pos_clear()
112: {
113: register int i;
114:
115: for (i = 0; i < sc_height; i++)
116: table[i] = NULL_POSITION;
117: }
118:
119: /*
120: * Allocate or reallocate the position table.
121: */
122: public void
123: pos_init()
124: {
125: struct scrpos scrpos;
126:
127: if (sc_height <= table_size)
128: return;
129: /*
130: * If we already have a table, remember the first line in it
131: * before we free it, so we can copy that line to the new table.
132: */
133: if (table != NULL)
134: {
135: get_scrpos(&scrpos);
136: free((char*)table);
137: } else
138: scrpos.pos = NULL_POSITION;
139: table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
140: table_size = sc_height;
141: pos_clear();
142: if (scrpos.pos != NULL_POSITION)
143: table[scrpos.ln-1] = scrpos.pos;
144: }
145:
146: /*
147: * See if the byte at a specified position is currently on the screen.
148: * Check the position table to see if the position falls within its range.
149: * Return the position table entry if found, -1 if not.
150: */
151: public int
152: onscreen(pos)
153: POSITION pos;
154: {
155: register int i;
156:
157: if (pos < table[0])
158: return (-1);
159: for (i = 1; i < sc_height; i++)
160: if (pos < table[i])
161: return (i-1);
162: return (-1);
163: }
164:
165: /*
166: * See if the entire screen is empty.
167: */
168: public int
169: empty_screen()
170: {
171: return (empty_lines(0, sc_height-1));
172: }
173:
174: public int
175: empty_lines(s, e)
176: int s;
177: int e;
178: {
179: register int i;
180:
181: for (i = s; i <= e; i++)
182: if (table[i] != NULL_POSITION)
183: return (0);
184: return (1);
185: }
186:
187: /*
188: * Get the current screen position.
189: * The screen position consists of both a file position and
190: * a screen line number where the file position is placed on the screen.
191: * Normally the screen line number is 0, but if we are positioned
192: * such that the top few lines are empty, we may have to set
193: * the screen line to a number > 0.
194: */
195: public void
196: get_scrpos(scrpos)
197: struct scrpos *scrpos;
198: {
199: register int i;
200:
201: /*
202: * Find the first line on the screen which has something on it,
203: * and return the screen line number and the file position.
204: */
205: for (i = 0; i < sc_height; i++)
206: if (table[i] != NULL_POSITION)
207: {
208: scrpos->ln = i+1;
209: scrpos->pos = table[i];
210: return;
211: }
212: /*
213: * The screen is empty.
214: */
215: scrpos->pos = NULL_POSITION;
216: }
217:
218: /*
219: * Adjust a screen line number to be a simple positive integer
220: * in the range { 0 .. sc_height-2 }.
221: * (The bottom line, sc_height-1, is reserved for prompts, etc.)
222: * The given "sline" may be in the range { 1 .. sc_height-1 }
223: * to refer to lines relative to the top of the screen (starting from 1),
224: * or it may be in { -1 .. -(sc_height-1) } to refer to lines
225: * relative to the bottom of the screen.
226: */
227: public int
228: adjsline(sline)
229: int sline;
230: {
231: /*
232: * Negative screen line number means
233: * relative to the bottom of the screen.
234: */
235: if (sline < 0)
236: sline += sc_height;
237: /*
238: * Can't be less than 1 or greater than sc_height-1.
239: */
240: if (sline <= 0)
241: sline = 1;
242: if (sline >= sc_height)
243: sline = sc_height - 1;
244: /*
245: * Return zero-based line number, not one-based.
246: */
247: return (sline-1);
248: }