[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.2

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: {
1.2     ! millert    59:        if (where >= table_size)
        !            60:                where = BOTTOM;
        !            61:
1.1       etheisen   62:        switch (where)
                     63:        {
                     64:        case BOTTOM:
                     65:                where = sc_height - 2;
                     66:                break;
                     67:        case BOTTOM_PLUS_ONE:
                     68:                where = sc_height - 1;
                     69:                break;
                     70:        case MIDDLE:
                     71:                where = (sc_height - 1) / 2;
                     72:        }
                     73:        return (table[where]);
                     74: }
                     75:
                     76: /*
                     77:  * Add a new file position to the bottom of the position table.
                     78:  */
                     79:        public void
                     80: add_forw_pos(pos)
                     81:        POSITION pos;
                     82: {
                     83:        register int i;
                     84:
                     85:        /*
                     86:         * Scroll the position table up.
                     87:         */
                     88:        for (i = 1;  i < sc_height;  i++)
                     89:                table[i-1] = table[i];
                     90:        table[sc_height - 1] = pos;
                     91: }
                     92:
                     93: /*
                     94:  * Add a new file position to the top of the position table.
                     95:  */
                     96:        public void
                     97: add_back_pos(pos)
                     98:        POSITION pos;
                     99: {
                    100:        register int i;
                    101:
                    102:        /*
                    103:         * Scroll the position table down.
                    104:         */
                    105:        for (i = sc_height - 1;  i > 0;  i--)
                    106:                table[i] = table[i-1];
                    107:        table[0] = pos;
                    108: }
                    109:
                    110: /*
                    111:  * Initialize the position table, done whenever we clear the screen.
                    112:  */
                    113:        public void
                    114: pos_clear()
                    115: {
                    116:        register int i;
                    117:
                    118:        for (i = 0;  i < sc_height;  i++)
                    119:                table[i] = NULL_POSITION;
                    120: }
                    121:
                    122: /*
                    123:  * Allocate or reallocate the position table.
                    124:  */
                    125:        public void
                    126: pos_init()
                    127: {
                    128:        struct scrpos scrpos;
                    129:
                    130:        if (sc_height <= table_size)
                    131:                return;
                    132:        /*
                    133:         * If we already have a table, remember the first line in it
                    134:         * before we free it, so we can copy that line to the new table.
                    135:         */
                    136:        if (table != NULL)
                    137:        {
                    138:                get_scrpos(&scrpos);
                    139:                free((char*)table);
                    140:        } else
                    141:                scrpos.pos = NULL_POSITION;
                    142:        table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
                    143:        table_size = sc_height;
                    144:        pos_clear();
                    145:        if (scrpos.pos != NULL_POSITION)
                    146:                table[scrpos.ln-1] = scrpos.pos;
                    147: }
                    148:
                    149: /*
                    150:  * See if the byte at a specified position is currently on the screen.
                    151:  * Check the position table to see if the position falls within its range.
                    152:  * Return the position table entry if found, -1 if not.
                    153:  */
                    154:        public int
                    155: onscreen(pos)
                    156:        POSITION pos;
                    157: {
                    158:        register int i;
                    159:
                    160:        if (pos < table[0])
                    161:                return (-1);
                    162:        for (i = 1;  i < sc_height;  i++)
                    163:                if (pos < table[i])
                    164:                        return (i-1);
                    165:        return (-1);
                    166: }
                    167:
                    168: /*
                    169:  * See if the entire screen is empty.
                    170:  */
                    171:        public int
                    172: empty_screen()
                    173: {
                    174:        return (empty_lines(0, sc_height-1));
                    175: }
                    176:
                    177:        public int
                    178: empty_lines(s, e)
                    179:        int s;
                    180:        int e;
                    181: {
                    182:        register int i;
                    183:
                    184:        for (i = s;  i <= e;  i++)
                    185:                if (table[i] != NULL_POSITION)
                    186:                        return (0);
                    187:        return (1);
                    188: }
                    189:
                    190: /*
                    191:  * Get the current screen position.
                    192:  * The screen position consists of both a file position and
                    193:  * a screen line number where the file position is placed on the screen.
                    194:  * Normally the screen line number is 0, but if we are positioned
                    195:  * such that the top few lines are empty, we may have to set
                    196:  * the screen line to a number > 0.
                    197:  */
                    198:        public void
                    199: get_scrpos(scrpos)
                    200:        struct scrpos *scrpos;
                    201: {
                    202:        register int i;
                    203:
                    204:        /*
                    205:         * Find the first line on the screen which has something on it,
                    206:         * and return the screen line number and the file position.
                    207:         */
                    208:        for (i = 0; i < sc_height;  i++)
                    209:                if (table[i] != NULL_POSITION)
                    210:                {
                    211:                        scrpos->ln = i+1;
                    212:                        scrpos->pos = table[i];
                    213:                        return;
                    214:                }
                    215:        /*
                    216:         * The screen is empty.
                    217:         */
                    218:        scrpos->pos = NULL_POSITION;
                    219: }
                    220:
                    221: /*
                    222:  * Adjust a screen line number to be a simple positive integer
                    223:  * in the range { 0 .. sc_height-2 }.
                    224:  * (The bottom line, sc_height-1, is reserved for prompts, etc.)
                    225:  * The given "sline" may be in the range { 1 .. sc_height-1 }
                    226:  * to refer to lines relative to the top of the screen (starting from 1),
                    227:  * or it may be in { -1 .. -(sc_height-1) } to refer to lines
                    228:  * relative to the bottom of the screen.
                    229:  */
                    230:        public int
                    231: adjsline(sline)
                    232:        int sline;
                    233: {
                    234:        /*
                    235:         * Negative screen line number means
                    236:         * relative to the bottom of the screen.
                    237:         */
                    238:        if (sline < 0)
                    239:                sline += sc_height;
                    240:        /*
                    241:         * Can't be less than 1 or greater than sc_height-1.
                    242:         */
                    243:        if (sline <= 0)
                    244:                sline = 1;
                    245:        if (sline >= sc_height)
                    246:                sline = sc_height - 1;
                    247:        /*
                    248:         * Return zero-based line number, not one-based.
                    249:         */
                    250:        return (sline-1);
                    251: }