[BACK]Return to position.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

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: }