xref: /original-bsd/usr.bin/more/position.c (revision 76f06662)
1273e1e22Sbostic /*
2273e1e22Sbostic  * Copyright (c) 1988 Mark Nudleman
3*76f06662Sbostic  * Copyright (c) 1988, 1993
4*76f06662Sbostic  *	The Regents of the University of California.  All rights reserved.
5273e1e22Sbostic  *
69918a12eSbostic  * %sccs.include.redist.c%
7273e1e22Sbostic  */
8273e1e22Sbostic 
9273e1e22Sbostic #ifndef lint
10*76f06662Sbostic static char sccsid[] = "@(#)position.c	8.1 (Berkeley) 06/06/93";
11273e1e22Sbostic #endif /* not lint */
12273e1e22Sbostic 
13273e1e22Sbostic /*
14273e1e22Sbostic  * Routines dealing with the "position" table.
15273e1e22Sbostic  * This is a table which tells the position (in the input file) of the
16273e1e22Sbostic  * first char on each currently displayed line.
17273e1e22Sbostic  *
18273e1e22Sbostic  * {{ The position table is scrolled by moving all the entries.
19273e1e22Sbostic  *    Would be better to have a circular table
20273e1e22Sbostic  *    and just change a couple of pointers. }}
21273e1e22Sbostic  */
22273e1e22Sbostic 
23427e68f0Sbostic #include <sys/types.h>
24427e68f0Sbostic #include <less.h>
25273e1e22Sbostic 
263ba132e0Sdonn static off_t *table;		/* The position table */
273ba132e0Sdonn static int tablesize;
28273e1e22Sbostic 
29427e68f0Sbostic extern int sc_height;
30273e1e22Sbostic 
31273e1e22Sbostic /*
32273e1e22Sbostic  * Return the starting file position of a line displayed on the screen.
33273e1e22Sbostic  * The line may be specified as a line number relative to the top
34273e1e22Sbostic  * of the screen, but is usually one of these special cases:
35273e1e22Sbostic  *	the top (first) line on the screen
36273e1e22Sbostic  *	the second line on the screen
37273e1e22Sbostic  *	the bottom line on the screen
38273e1e22Sbostic  *	the line after the bottom line on the screen
39273e1e22Sbostic  */
40427e68f0Sbostic off_t
position(where)41273e1e22Sbostic position(where)
42273e1e22Sbostic 	int where;
43273e1e22Sbostic {
44273e1e22Sbostic 	switch (where)
45273e1e22Sbostic 	{
46273e1e22Sbostic 	case BOTTOM:
47273e1e22Sbostic 		where = sc_height - 2;
48273e1e22Sbostic 		break;
49273e1e22Sbostic 	case BOTTOM_PLUS_ONE:
50273e1e22Sbostic 		where = sc_height - 1;
51273e1e22Sbostic 		break;
52273e1e22Sbostic 	case MIDDLE:
53273e1e22Sbostic 		where = sc_height / 2;
54273e1e22Sbostic 	}
55273e1e22Sbostic 	return (table[where]);
56273e1e22Sbostic }
57273e1e22Sbostic 
58273e1e22Sbostic /*
59273e1e22Sbostic  * Add a new file position to the bottom of the position table.
60273e1e22Sbostic  */
add_forw_pos(pos)61273e1e22Sbostic add_forw_pos(pos)
62427e68f0Sbostic 	off_t pos;
63273e1e22Sbostic {
64273e1e22Sbostic 	register int i;
65273e1e22Sbostic 
66273e1e22Sbostic 	/*
67273e1e22Sbostic 	 * Scroll the position table up.
68273e1e22Sbostic 	 */
69273e1e22Sbostic 	for (i = 1;  i < sc_height;  i++)
70273e1e22Sbostic 		table[i-1] = table[i];
71273e1e22Sbostic 	table[sc_height - 1] = pos;
72273e1e22Sbostic }
73273e1e22Sbostic 
74273e1e22Sbostic /*
75273e1e22Sbostic  * Add a new file position to the top of the position table.
76273e1e22Sbostic  */
add_back_pos(pos)77273e1e22Sbostic add_back_pos(pos)
78427e68f0Sbostic 	off_t pos;
79273e1e22Sbostic {
80273e1e22Sbostic 	register int i;
81273e1e22Sbostic 
82273e1e22Sbostic 	/*
83273e1e22Sbostic 	 * Scroll the position table down.
84273e1e22Sbostic 	 */
85273e1e22Sbostic 	for (i = sc_height - 1;  i > 0;  i--)
86273e1e22Sbostic 		table[i] = table[i-1];
87273e1e22Sbostic 	table[0] = pos;
88273e1e22Sbostic }
89273e1e22Sbostic 
copytable()903f4685f3Sbostic copytable()
913f4685f3Sbostic {
923f4685f3Sbostic 	register int a, b;
933f4685f3Sbostic 
943f4685f3Sbostic 	for (a = 0; a < sc_height && table[a] == NULL_POSITION; a++);
953f4685f3Sbostic 	for (b = 0; a < sc_height; a++, b++) {
963f4685f3Sbostic 		table[b] = table[a];
973f4685f3Sbostic 		table[a] = NULL_POSITION;
983f4685f3Sbostic 	}
993f4685f3Sbostic }
1003f4685f3Sbostic 
101273e1e22Sbostic /*
102273e1e22Sbostic  * Initialize the position table, done whenever we clear the screen.
103273e1e22Sbostic  */
pos_clear()104273e1e22Sbostic pos_clear()
105273e1e22Sbostic {
106273e1e22Sbostic 	register int i;
1073ba132e0Sdonn 	extern char *malloc(), *realloc();
1083ba132e0Sdonn 
1093ba132e0Sdonn 	if (table == 0) {
1103ba132e0Sdonn 		tablesize = sc_height > 25 ? sc_height : 25;
111c1af0a2fSdonn 		table = (off_t *)malloc(tablesize * sizeof *table);
1123ba132e0Sdonn 	} else if (sc_height >= tablesize) {
1133ba132e0Sdonn 		tablesize = sc_height;
114c1af0a2fSdonn 		table = (off_t *)realloc(table, tablesize * sizeof *table);
1153ba132e0Sdonn 	}
116273e1e22Sbostic 
117273e1e22Sbostic 	for (i = 0;  i < sc_height;  i++)
118273e1e22Sbostic 		table[i] = NULL_POSITION;
119273e1e22Sbostic }
120273e1e22Sbostic 
121273e1e22Sbostic /*
122273e1e22Sbostic  * See if the byte at a specified position is currently on the screen.
123273e1e22Sbostic  * Check the position table to see if the position falls within its range.
124273e1e22Sbostic  * Return the position table entry if found, -1 if not.
125273e1e22Sbostic  */
onscreen(pos)126273e1e22Sbostic onscreen(pos)
127427e68f0Sbostic 	off_t pos;
128273e1e22Sbostic {
129273e1e22Sbostic 	register int i;
130273e1e22Sbostic 
131273e1e22Sbostic 	if (pos < table[0])
132273e1e22Sbostic 		return (-1);
133273e1e22Sbostic 	for (i = 1;  i < sc_height;  i++)
134273e1e22Sbostic 		if (pos < table[i])
135273e1e22Sbostic 			return (i-1);
136273e1e22Sbostic 	return (-1);
137273e1e22Sbostic }
138