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

1.1       etheisen    1: /*
1.6     ! shadchin    2:  * Copyright (C) 1984-2011  Mark Nudelman
1.1       etheisen    3:  *
1.5       millert     4:  * You may distribute under the terms of either the GNU General Public
                      5:  * License or the Less License, as specified in the README file.
1.1       etheisen    6:  *
1.5       millert     7:  * For more information about less, or for information on how to
                      8:  * contact the author, see the README file.
1.1       etheisen    9:  */
                     10:
                     11:
                     12: /*
                     13:  * Routines dealing with the "position" table.
                     14:  * This is a table which tells the position (in the input file) of the
                     15:  * first char on each currently displayed line.
                     16:  *
                     17:  * {{ The position table is scrolled by moving all the entries.
                     18:  *    Would be better to have a circular table
                     19:  *    and just change a couple of pointers. }}
                     20:  */
                     21:
                     22: #include "less.h"
                     23: #include "position.h"
                     24:
                     25: static POSITION *table = NULL; /* The position table */
                     26: static int table_size;
                     27:
                     28: extern int sc_width, sc_height;
                     29:
                     30: /*
                     31:  * Return the starting file position of a line displayed on the screen.
                     32:  * The line may be specified as a line number relative to the top
                     33:  * of the screen, but is usually one of these special cases:
                     34:  *     the top (first) line on the screen
                     35:  *     the second line on the screen
                     36:  *     the bottom line on the screen
                     37:  *     the line after the bottom line on the screen
                     38:  */
                     39:        public POSITION
                     40: position(where)
                     41:        int where;
                     42: {
                     43:        switch (where)
                     44:        {
                     45:        case BOTTOM:
                     46:                where = sc_height - 2;
                     47:                break;
                     48:        case BOTTOM_PLUS_ONE:
                     49:                where = sc_height - 1;
                     50:                break;
                     51:        case MIDDLE:
                     52:                where = (sc_height - 1) / 2;
                     53:        }
                     54:        return (table[where]);
                     55: }
                     56:
                     57: /*
                     58:  * Add a new file position to the bottom of the position table.
                     59:  */
                     60:        public void
                     61: add_forw_pos(pos)
                     62:        POSITION pos;
                     63: {
1.5       millert    64:        register int i;
1.1       etheisen   65:
                     66:        /*
                     67:         * Scroll the position table up.
                     68:         */
                     69:        for (i = 1;  i < sc_height;  i++)
                     70:                table[i-1] = table[i];
                     71:        table[sc_height - 1] = pos;
                     72: }
                     73:
                     74: /*
                     75:  * Add a new file position to the top of the position table.
                     76:  */
                     77:        public void
                     78: add_back_pos(pos)
                     79:        POSITION pos;
                     80: {
1.5       millert    81:        register int i;
1.1       etheisen   82:
                     83:        /*
                     84:         * Scroll the position table down.
                     85:         */
                     86:        for (i = sc_height - 1;  i > 0;  i--)
                     87:                table[i] = table[i-1];
                     88:        table[0] = pos;
                     89: }
                     90:
                     91: /*
                     92:  * Initialize the position table, done whenever we clear the screen.
                     93:  */
                     94:        public void
                     95: pos_clear()
                     96: {
1.5       millert    97:        register int i;
1.1       etheisen   98:
                     99:        for (i = 0;  i < sc_height;  i++)
                    100:                table[i] = NULL_POSITION;
                    101: }
                    102:
                    103: /*
                    104:  * Allocate or reallocate the position table.
                    105:  */
                    106:        public void
                    107: pos_init()
                    108: {
                    109:        struct scrpos scrpos;
                    110:
                    111:        if (sc_height <= table_size)
                    112:                return;
                    113:        /*
                    114:         * If we already have a table, remember the first line in it
                    115:         * before we free it, so we can copy that line to the new table.
                    116:         */
                    117:        if (table != NULL)
                    118:        {
                    119:                get_scrpos(&scrpos);
                    120:                free((char*)table);
                    121:        } else
                    122:                scrpos.pos = NULL_POSITION;
                    123:        table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
                    124:        table_size = sc_height;
                    125:        pos_clear();
                    126:        if (scrpos.pos != NULL_POSITION)
                    127:                table[scrpos.ln-1] = scrpos.pos;
                    128: }
                    129:
                    130: /*
                    131:  * See if the byte at a specified position is currently on the screen.
                    132:  * Check the position table to see if the position falls within its range.
                    133:  * Return the position table entry if found, -1 if not.
                    134:  */
                    135:        public int
                    136: onscreen(pos)
                    137:        POSITION pos;
                    138: {
1.5       millert   139:        register int i;
1.1       etheisen  140:
                    141:        if (pos < table[0])
                    142:                return (-1);
                    143:        for (i = 1;  i < sc_height;  i++)
                    144:                if (pos < table[i])
                    145:                        return (i-1);
                    146:        return (-1);
                    147: }
                    148:
                    149: /*
                    150:  * See if the entire screen is empty.
                    151:  */
                    152:        public int
                    153: empty_screen()
                    154: {
                    155:        return (empty_lines(0, sc_height-1));
                    156: }
                    157:
                    158:        public int
                    159: empty_lines(s, e)
                    160:        int s;
                    161:        int e;
                    162: {
1.5       millert   163:        register int i;
1.1       etheisen  164:
                    165:        for (i = s;  i <= e;  i++)
                    166:                if (table[i] != NULL_POSITION)
                    167:                        return (0);
                    168:        return (1);
                    169: }
                    170:
                    171: /*
                    172:  * Get the current screen position.
                    173:  * The screen position consists of both a file position and
                    174:  * a screen line number where the file position is placed on the screen.
                    175:  * Normally the screen line number is 0, but if we are positioned
                    176:  * such that the top few lines are empty, we may have to set
                    177:  * the screen line to a number > 0.
                    178:  */
                    179:        public void
                    180: get_scrpos(scrpos)
                    181:        struct scrpos *scrpos;
                    182: {
1.5       millert   183:        register int i;
1.1       etheisen  184:
                    185:        /*
                    186:         * Find the first line on the screen which has something on it,
                    187:         * and return the screen line number and the file position.
                    188:         */
                    189:        for (i = 0; i < sc_height;  i++)
                    190:                if (table[i] != NULL_POSITION)
                    191:                {
                    192:                        scrpos->ln = i+1;
                    193:                        scrpos->pos = table[i];
                    194:                        return;
                    195:                }
                    196:        /*
                    197:         * The screen is empty.
                    198:         */
                    199:        scrpos->pos = NULL_POSITION;
                    200: }
                    201:
                    202: /*
                    203:  * Adjust a screen line number to be a simple positive integer
                    204:  * in the range { 0 .. sc_height-2 }.
                    205:  * (The bottom line, sc_height-1, is reserved for prompts, etc.)
                    206:  * The given "sline" may be in the range { 1 .. sc_height-1 }
                    207:  * to refer to lines relative to the top of the screen (starting from 1),
                    208:  * or it may be in { -1 .. -(sc_height-1) } to refer to lines
                    209:  * relative to the bottom of the screen.
                    210:  */
                    211:        public int
                    212: adjsline(sline)
                    213:        int sline;
                    214: {
                    215:        /*
                    216:         * Negative screen line number means
                    217:         * relative to the bottom of the screen.
                    218:         */
                    219:        if (sline < 0)
                    220:                sline += sc_height;
                    221:        /*
                    222:         * Can't be less than 1 or greater than sc_height-1.
                    223:         */
                    224:        if (sline <= 0)
                    225:                sline = 1;
                    226:        if (sline >= sc_height)
                    227:                sline = sc_height - 1;
                    228:        /*
                    229:         * Return zero-based line number, not one-based.
                    230:         */
                    231:        return (sline-1);
                    232: }