xref: /csrg-svn/usr.bin/more/position.c (revision 62131)
135209Sbostic /*
235209Sbostic  * Copyright (c) 1988 Mark Nudleman
3*62131Sbostic  * Copyright (c) 1988, 1993
4*62131Sbostic  *	The Regents of the University of California.  All rights reserved.
535209Sbostic  *
642742Sbostic  * %sccs.include.redist.c%
735209Sbostic  */
835209Sbostic 
935209Sbostic #ifndef lint
10*62131Sbostic static char sccsid[] = "@(#)position.c	8.1 (Berkeley) 06/06/93";
1135209Sbostic #endif /* not lint */
1235209Sbostic 
1335209Sbostic /*
1435209Sbostic  * Routines dealing with the "position" table.
1535209Sbostic  * This is a table which tells the position (in the input file) of the
1635209Sbostic  * first char on each currently displayed line.
1735209Sbostic  *
1835209Sbostic  * {{ The position table is scrolled by moving all the entries.
1935209Sbostic  *    Would be better to have a circular table
2035209Sbostic  *    and just change a couple of pointers. }}
2135209Sbostic  */
2235209Sbostic 
2336253Sbostic #include <sys/types.h>
2436253Sbostic #include <less.h>
2535209Sbostic 
2640235Sdonn static off_t *table;		/* The position table */
2740235Sdonn static int tablesize;
2835209Sbostic 
2936253Sbostic extern int sc_height;
3035209Sbostic 
3135209Sbostic /*
3235209Sbostic  * Return the starting file position of a line displayed on the screen.
3335209Sbostic  * The line may be specified as a line number relative to the top
3435209Sbostic  * of the screen, but is usually one of these special cases:
3535209Sbostic  *	the top (first) line on the screen
3635209Sbostic  *	the second line on the screen
3735209Sbostic  *	the bottom line on the screen
3835209Sbostic  *	the line after the bottom line on the screen
3935209Sbostic  */
4036253Sbostic off_t
position(where)4135209Sbostic position(where)
4235209Sbostic 	int where;
4335209Sbostic {
4435209Sbostic 	switch (where)
4535209Sbostic 	{
4635209Sbostic 	case BOTTOM:
4735209Sbostic 		where = sc_height - 2;
4835209Sbostic 		break;
4935209Sbostic 	case BOTTOM_PLUS_ONE:
5035209Sbostic 		where = sc_height - 1;
5135209Sbostic 		break;
5235209Sbostic 	case MIDDLE:
5335209Sbostic 		where = sc_height / 2;
5435209Sbostic 	}
5535209Sbostic 	return (table[where]);
5635209Sbostic }
5735209Sbostic 
5835209Sbostic /*
5935209Sbostic  * Add a new file position to the bottom of the position table.
6035209Sbostic  */
add_forw_pos(pos)6135209Sbostic add_forw_pos(pos)
6236253Sbostic 	off_t pos;
6335209Sbostic {
6435209Sbostic 	register int i;
6535209Sbostic 
6635209Sbostic 	/*
6735209Sbostic 	 * Scroll the position table up.
6835209Sbostic 	 */
6935209Sbostic 	for (i = 1;  i < sc_height;  i++)
7035209Sbostic 		table[i-1] = table[i];
7135209Sbostic 	table[sc_height - 1] = pos;
7235209Sbostic }
7335209Sbostic 
7435209Sbostic /*
7535209Sbostic  * Add a new file position to the top of the position table.
7635209Sbostic  */
add_back_pos(pos)7735209Sbostic add_back_pos(pos)
7836253Sbostic 	off_t pos;
7935209Sbostic {
8035209Sbostic 	register int i;
8135209Sbostic 
8235209Sbostic 	/*
8335209Sbostic 	 * Scroll the position table down.
8435209Sbostic 	 */
8535209Sbostic 	for (i = sc_height - 1;  i > 0;  i--)
8635209Sbostic 		table[i] = table[i-1];
8735209Sbostic 	table[0] = pos;
8835209Sbostic }
8935209Sbostic 
copytable()9036358Sbostic copytable()
9136358Sbostic {
9236358Sbostic 	register int a, b;
9336358Sbostic 
9436358Sbostic 	for (a = 0; a < sc_height && table[a] == NULL_POSITION; a++);
9536358Sbostic 	for (b = 0; a < sc_height; a++, b++) {
9636358Sbostic 		table[b] = table[a];
9736358Sbostic 		table[a] = NULL_POSITION;
9836358Sbostic 	}
9936358Sbostic }
10036358Sbostic 
10135209Sbostic /*
10235209Sbostic  * Initialize the position table, done whenever we clear the screen.
10335209Sbostic  */
pos_clear()10435209Sbostic pos_clear()
10535209Sbostic {
10635209Sbostic 	register int i;
10740235Sdonn 	extern char *malloc(), *realloc();
10835209Sbostic 
10940235Sdonn 	if (table == 0) {
11040235Sdonn 		tablesize = sc_height > 25 ? sc_height : 25;
11140238Sdonn 		table = (off_t *)malloc(tablesize * sizeof *table);
11240235Sdonn 	} else if (sc_height >= tablesize) {
11340235Sdonn 		tablesize = sc_height;
11440238Sdonn 		table = (off_t *)realloc(table, tablesize * sizeof *table);
11540235Sdonn 	}
11640235Sdonn 
11735209Sbostic 	for (i = 0;  i < sc_height;  i++)
11835209Sbostic 		table[i] = NULL_POSITION;
11935209Sbostic }
12035209Sbostic 
12135209Sbostic /*
12235209Sbostic  * See if the byte at a specified position is currently on the screen.
12335209Sbostic  * Check the position table to see if the position falls within its range.
12435209Sbostic  * Return the position table entry if found, -1 if not.
12535209Sbostic  */
onscreen(pos)12635209Sbostic onscreen(pos)
12736253Sbostic 	off_t pos;
12835209Sbostic {
12935209Sbostic 	register int i;
13035209Sbostic 
13135209Sbostic 	if (pos < table[0])
13235209Sbostic 		return (-1);
13335209Sbostic 	for (i = 1;  i < sc_height;  i++)
13435209Sbostic 		if (pos < table[i])
13535209Sbostic 			return (i-1);
13635209Sbostic 	return (-1);
13735209Sbostic }
138