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

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