xref: /original-bsd/usr.bin/more/position.c (revision 2301fdfb)
1 /*
2  * Copyright (c) 1988 Mark Nudleman
3  * Copyright (c) 1988 Regents of the University of California.
4  * All rights reserved.
5  *
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
11  * by Mark Nudleman and the University of California, Berkeley.  The
12  * name of Mark Nudleman or the
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
21 static char sccsid[] = "@(#)position.c	5.4 (Berkeley) 12/13/88";
22 #endif /* not lint */
23 
24 /*
25  * Routines dealing with the "position" table.
26  * This is a table which tells the position (in the input file) of the
27  * first char on each currently displayed line.
28  *
29  * {{ The position table is scrolled by moving all the entries.
30  *    Would be better to have a circular table
31  *    and just change a couple of pointers. }}
32  */
33 
34 #include <sys/types.h>
35 #include <less.h>
36 
37 #define	NPOS	100		/* {{ sc_height must be less than NPOS }} */
38 static off_t table[NPOS];	/* The position table */
39 
40 extern int sc_height;
41 
42 /*
43  * Return the starting file position of a line displayed on the screen.
44  * The line may be specified as a line number relative to the top
45  * of the screen, but is usually one of these special cases:
46  *	the top (first) line on the screen
47  *	the second line on the screen
48  *	the bottom line on the screen
49  *	the line after the bottom line on the screen
50  */
51 off_t
52 position(where)
53 	int where;
54 {
55 	switch (where)
56 	{
57 	case BOTTOM:
58 		where = sc_height - 2;
59 		break;
60 	case BOTTOM_PLUS_ONE:
61 		where = sc_height - 1;
62 		break;
63 	case MIDDLE:
64 		where = sc_height / 2;
65 	}
66 	return (table[where]);
67 }
68 
69 /*
70  * Add a new file position to the bottom of the position table.
71  */
72 add_forw_pos(pos)
73 	off_t pos;
74 {
75 	register int i;
76 
77 	/*
78 	 * Scroll the position table up.
79 	 */
80 	for (i = 1;  i < sc_height;  i++)
81 		table[i-1] = table[i];
82 	table[sc_height - 1] = pos;
83 }
84 
85 /*
86  * Add a new file position to the top of the position table.
87  */
88 add_back_pos(pos)
89 	off_t pos;
90 {
91 	register int i;
92 
93 	/*
94 	 * Scroll the position table down.
95 	 */
96 	for (i = sc_height - 1;  i > 0;  i--)
97 		table[i] = table[i-1];
98 	table[0] = pos;
99 }
100 
101 copytable()
102 {
103 	register int a, b;
104 
105 	for (a = 0; a < sc_height && table[a] == NULL_POSITION; a++);
106 	for (b = 0; a < sc_height; a++, b++) {
107 		table[b] = table[a];
108 		table[a] = NULL_POSITION;
109 	}
110 }
111 
112 /*
113  * Initialize the position table, done whenever we clear the screen.
114  */
115 pos_clear()
116 {
117 	register int i;
118 
119 	for (i = 0;  i < sc_height;  i++)
120 		table[i] = NULL_POSITION;
121 }
122 
123 /*
124  * See if the byte at a specified position is currently on the screen.
125  * Check the position table to see if the position falls within its range.
126  * Return the position table entry if found, -1 if not.
127  */
128 onscreen(pos)
129 	off_t pos;
130 {
131 	register int i;
132 
133 	if (pos < table[0])
134 		return (-1);
135 	for (i = 1;  i < sc_height;  i++)
136 		if (pos < table[i])
137 			return (i-1);
138 	return (-1);
139 }
140