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

1.3     ! niklas      1: /*     $OpenBSD$       */
        !             2:
1.1       etheisen    3: /*
                      4:  * Copyright (c) 1984,1985,1989,1994,1995  Mark Nudelman
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice in the documentation and/or other materials provided with
                     14:  *    the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
                     17:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     19:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
                     20:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     21:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
                     22:  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
                     23:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     24:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
                     25:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
                     26:  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29:
                     30: /*
                     31:  * Routines dealing with the "position" table.
                     32:  * This is a table which tells the position (in the input file) of the
                     33:  * first char on each currently displayed line.
                     34:  *
                     35:  * {{ The position table is scrolled by moving all the entries.
                     36:  *    Would be better to have a circular table
                     37:  *    and just change a couple of pointers. }}
                     38:  */
                     39:
                     40: #include "less.h"
                     41: #include "position.h"
                     42:
                     43: static POSITION *table = NULL; /* The position table */
                     44: static int table_size;
                     45:
                     46: extern int sc_width, sc_height;
                     47:
                     48: /*
                     49:  * Return the starting file position of a line displayed on the screen.
                     50:  * The line may be specified as a line number relative to the top
                     51:  * of the screen, but is usually one of these special cases:
                     52:  *     the top (first) line on the screen
                     53:  *     the second line on the screen
                     54:  *     the bottom line on the screen
                     55:  *     the line after the bottom line on the screen
                     56:  */
                     57:        public POSITION
                     58: position(where)
                     59:        int where;
                     60: {
1.2       millert    61:        if (where >= table_size)
                     62:                where = BOTTOM;
                     63:
1.1       etheisen   64:        switch (where)
                     65:        {
                     66:        case BOTTOM:
                     67:                where = sc_height - 2;
                     68:                break;
                     69:        case BOTTOM_PLUS_ONE:
                     70:                where = sc_height - 1;
                     71:                break;
                     72:        case MIDDLE:
                     73:                where = (sc_height - 1) / 2;
                     74:        }
                     75:        return (table[where]);
                     76: }
                     77:
                     78: /*
                     79:  * Add a new file position to the bottom of the position table.
                     80:  */
                     81:        public void
                     82: add_forw_pos(pos)
                     83:        POSITION pos;
                     84: {
                     85:        register int i;
                     86:
                     87:        /*
                     88:         * Scroll the position table up.
                     89:         */
                     90:        for (i = 1;  i < sc_height;  i++)
                     91:                table[i-1] = table[i];
                     92:        table[sc_height - 1] = pos;
                     93: }
                     94:
                     95: /*
                     96:  * Add a new file position to the top of the position table.
                     97:  */
                     98:        public void
                     99: add_back_pos(pos)
                    100:        POSITION pos;
                    101: {
                    102:        register int i;
                    103:
                    104:        /*
                    105:         * Scroll the position table down.
                    106:         */
                    107:        for (i = sc_height - 1;  i > 0;  i--)
                    108:                table[i] = table[i-1];
                    109:        table[0] = pos;
                    110: }
                    111:
                    112: /*
                    113:  * Initialize the position table, done whenever we clear the screen.
                    114:  */
                    115:        public void
                    116: pos_clear()
                    117: {
                    118:        register int i;
                    119:
                    120:        for (i = 0;  i < sc_height;  i++)
                    121:                table[i] = NULL_POSITION;
                    122: }
                    123:
                    124: /*
                    125:  * Allocate or reallocate the position table.
                    126:  */
                    127:        public void
                    128: pos_init()
                    129: {
                    130:        struct scrpos scrpos;
                    131:
                    132:        if (sc_height <= table_size)
                    133:                return;
                    134:        /*
                    135:         * If we already have a table, remember the first line in it
                    136:         * before we free it, so we can copy that line to the new table.
                    137:         */
                    138:        if (table != NULL)
                    139:        {
                    140:                get_scrpos(&scrpos);
                    141:                free((char*)table);
                    142:        } else
                    143:                scrpos.pos = NULL_POSITION;
                    144:        table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
                    145:        table_size = sc_height;
                    146:        pos_clear();
                    147:        if (scrpos.pos != NULL_POSITION)
                    148:                table[scrpos.ln-1] = scrpos.pos;
                    149: }
                    150:
                    151: /*
                    152:  * See if the byte at a specified position is currently on the screen.
                    153:  * Check the position table to see if the position falls within its range.
                    154:  * Return the position table entry if found, -1 if not.
                    155:  */
                    156:        public int
                    157: onscreen(pos)
                    158:        POSITION pos;
                    159: {
                    160:        register int i;
                    161:
                    162:        if (pos < table[0])
                    163:                return (-1);
                    164:        for (i = 1;  i < sc_height;  i++)
                    165:                if (pos < table[i])
                    166:                        return (i-1);
                    167:        return (-1);
                    168: }
                    169:
                    170: /*
                    171:  * See if the entire screen is empty.
                    172:  */
                    173:        public int
                    174: empty_screen()
                    175: {
                    176:        return (empty_lines(0, sc_height-1));
                    177: }
                    178:
                    179:        public int
                    180: empty_lines(s, e)
                    181:        int s;
                    182:        int e;
                    183: {
                    184:        register int i;
                    185:
                    186:        for (i = s;  i <= e;  i++)
                    187:                if (table[i] != NULL_POSITION)
                    188:                        return (0);
                    189:        return (1);
                    190: }
                    191:
                    192: /*
                    193:  * Get the current screen position.
                    194:  * The screen position consists of both a file position and
                    195:  * a screen line number where the file position is placed on the screen.
                    196:  * Normally the screen line number is 0, but if we are positioned
                    197:  * such that the top few lines are empty, we may have to set
                    198:  * the screen line to a number > 0.
                    199:  */
                    200:        public void
                    201: get_scrpos(scrpos)
                    202:        struct scrpos *scrpos;
                    203: {
                    204:        register int i;
                    205:
                    206:        /*
                    207:         * Find the first line on the screen which has something on it,
                    208:         * and return the screen line number and the file position.
                    209:         */
                    210:        for (i = 0; i < sc_height;  i++)
                    211:                if (table[i] != NULL_POSITION)
                    212:                {
                    213:                        scrpos->ln = i+1;
                    214:                        scrpos->pos = table[i];
                    215:                        return;
                    216:                }
                    217:        /*
                    218:         * The screen is empty.
                    219:         */
                    220:        scrpos->pos = NULL_POSITION;
                    221: }
                    222:
                    223: /*
                    224:  * Adjust a screen line number to be a simple positive integer
                    225:  * in the range { 0 .. sc_height-2 }.
                    226:  * (The bottom line, sc_height-1, is reserved for prompts, etc.)
                    227:  * The given "sline" may be in the range { 1 .. sc_height-1 }
                    228:  * to refer to lines relative to the top of the screen (starting from 1),
                    229:  * or it may be in { -1 .. -(sc_height-1) } to refer to lines
                    230:  * relative to the bottom of the screen.
                    231:  */
                    232:        public int
                    233: adjsline(sline)
                    234:        int sline;
                    235: {
                    236:        /*
                    237:         * Negative screen line number means
                    238:         * relative to the bottom of the screen.
                    239:         */
                    240:        if (sline < 0)
                    241:                sline += sc_height;
                    242:        /*
                    243:         * Can't be less than 1 or greater than sc_height-1.
                    244:         */
                    245:        if (sline <= 0)
                    246:                sline = 1;
                    247:        if (sline >= sc_height)
                    248:                sline = sc_height - 1;
                    249:        /*
                    250:         * Return zero-based line number, not one-based.
                    251:         */
                    252:        return (sline-1);
                    253: }