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

Annotation of src/usr.bin/less/forwback.c, Revision 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:  * Primitives for displaying the file on the screen,
        !            30:  * scrolling either forward or backward.
        !            31:  */
        !            32:
        !            33: #include "less.h"
        !            34: #include "position.h"
        !            35:
        !            36: public int hit_eof;    /* Keeps track of how many times we hit end of file */
        !            37: public int screen_trashed;
        !            38: public int squished;
        !            39:
        !            40: extern int sigs;
        !            41: extern int top_scroll;
        !            42: extern int quiet;
        !            43: extern int sc_width, sc_height;
        !            44: extern int quit_at_eof;
        !            45: extern int plusoption;
        !            46: extern int forw_scroll;
        !            47: extern int back_scroll;
        !            48: extern int need_clr;
        !            49: extern int ignore_eoi;
        !            50: #if TAGS
        !            51: extern char *tagoption;
        !            52: #endif
        !            53:
        !            54: /*
        !            55:  * Sound the bell to indicate user is trying to move past end of file.
        !            56:  */
        !            57:        static void
        !            58: eof_bell()
        !            59: {
        !            60:        if (quiet == NOT_QUIET)
        !            61:                bell();
        !            62:        else
        !            63:                vbell();
        !            64: }
        !            65:
        !            66: /*
        !            67:  * Check to see if the end of file is currently "displayed".
        !            68:  */
        !            69:        static void
        !            70: eof_check()
        !            71: {
        !            72:        POSITION pos;
        !            73:
        !            74:        if (ignore_eoi)
        !            75:                return;
        !            76:        if (ABORT_SIGS())
        !            77:                return;
        !            78:        /*
        !            79:         * If the bottom line is empty, we are at EOF.
        !            80:         * If the bottom line ends at the file length,
        !            81:         * we must be just at EOF.
        !            82:         */
        !            83:        pos = position(BOTTOM_PLUS_ONE);
        !            84:        if (pos == NULL_POSITION || pos == ch_length())
        !            85:                hit_eof++;
        !            86: }
        !            87:
        !            88: /*
        !            89:  * If the screen is "squished", repaint it.
        !            90:  * "Squished" means the first displayed line is not at the top
        !            91:  * of the screen; this can happen when we display a short file
        !            92:  * for the first time.
        !            93:  */
        !            94:        static void
        !            95: squish_check()
        !            96: {
        !            97:        if (!squished)
        !            98:                return;
        !            99:        squished = 0;
        !           100:        repaint();
        !           101: }
        !           102:
        !           103: /*
        !           104:  * Display n lines, scrolling forward,
        !           105:  * starting at position pos in the input file.
        !           106:  * "force" means display the n lines even if we hit end of file.
        !           107:  * "only_last" means display only the last screenful if n > screen size.
        !           108:  * "nblank" is the number of blank lines to draw before the first
        !           109:  *   real line.  If nblank > 0, the pos must be NULL_POSITION.
        !           110:  *   The first real line after the blanks will start at ch_zero().
        !           111:  */
        !           112:        public void
        !           113: forw(n, pos, force, only_last, nblank)
        !           114:        register int n;
        !           115:        POSITION pos;
        !           116:        int force;
        !           117:        int only_last;
        !           118:        int nblank;
        !           119: {
        !           120:        int eof = 0;
        !           121:        int nlines = 0;
        !           122:        int do_repaint;
        !           123:        static int first_time = 1;
        !           124:
        !           125:        squish_check();
        !           126:
        !           127:        /*
        !           128:         * do_repaint tells us not to display anything till the end,
        !           129:         * then just repaint the entire screen.
        !           130:         * We repaint if we are supposed to display only the last
        !           131:         * screenful and the request is for more than a screenful.
        !           132:         * Also if the request exceeds the forward scroll limit
        !           133:         * (but not if the request is for exactly a screenful, since
        !           134:         * repainting itself involves scrolling forward a screenful).
        !           135:         */
        !           136:        do_repaint = (only_last && n > sc_height-1) ||
        !           137:                (forw_scroll >= 0 && n > forw_scroll && n != sc_height-1);
        !           138:
        !           139:        if (!do_repaint)
        !           140:        {
        !           141:                if (top_scroll && n >= sc_height - 1 && pos != ch_length())
        !           142:                {
        !           143:                        /*
        !           144:                         * Start a new screen.
        !           145:                         * {{ This is not really desirable if we happen
        !           146:                         *    to hit eof in the middle of this screen,
        !           147:                         *    but we don't yet know if that will happen. }}
        !           148:                         */
        !           149:                        if (top_scroll == OPT_ONPLUS || first_time)
        !           150:                                clear();
        !           151:                        home();
        !           152:                        force = 1;
        !           153:                } else
        !           154:                {
        !           155:                        clear_bot();
        !           156:                }
        !           157:
        !           158:                if (pos != position(BOTTOM_PLUS_ONE) || empty_screen())
        !           159:                {
        !           160:                        /*
        !           161:                         * This is not contiguous with what is
        !           162:                         * currently displayed.  Clear the screen image
        !           163:                         * (position table) and start a new screen.
        !           164:                         */
        !           165:                        pos_clear();
        !           166:                        add_forw_pos(pos);
        !           167:                        force = 1;
        !           168:                        if (top_scroll)
        !           169:                        {
        !           170:                                if (top_scroll == OPT_ONPLUS)
        !           171:                                        clear();
        !           172:                                home();
        !           173:                        } else if (!first_time)
        !           174:                        {
        !           175:                                putstr("...skipping...\n");
        !           176:                        }
        !           177:                }
        !           178:        }
        !           179:
        !           180:        while (--n >= 0)
        !           181:        {
        !           182:                /*
        !           183:                 * Read the next line of input.
        !           184:                 */
        !           185:                if (nblank > 0)
        !           186:                {
        !           187:                        /*
        !           188:                         * Still drawing blanks; don't get a line
        !           189:                         * from the file yet.
        !           190:                         * If this is the last blank line, get ready to
        !           191:                         * read a line starting at ch_zero() next time.
        !           192:                         */
        !           193:                        if (--nblank == 0)
        !           194:                                pos = ch_zero();
        !           195:                } else
        !           196:                {
        !           197:                        /*
        !           198:                         * Get the next line from the file.
        !           199:                         */
        !           200:                        pos = forw_line(pos);
        !           201:                        if (pos == NULL_POSITION)
        !           202:                        {
        !           203:                                /*
        !           204:                                 * End of file: stop here unless the top line
        !           205:                                 * is still empty, or "force" is true.
        !           206:                                 */
        !           207:                                eof = 1;
        !           208:                                if (!force && position(TOP) != NULL_POSITION)
        !           209:                                        break;
        !           210:                        }
        !           211:                }
        !           212:                /*
        !           213:                 * Add the position of the next line to the position table.
        !           214:                 * Display the current line on the screen.
        !           215:                 */
        !           216:                add_forw_pos(pos);
        !           217:                nlines++;
        !           218:                if (do_repaint)
        !           219:                        continue;
        !           220:                /*
        !           221:                 * If this is the first screen displayed and
        !           222:                 * we hit an early EOF (i.e. before the requested
        !           223:                 * number of lines), we "squish" the display down
        !           224:                 * at the bottom of the screen.
        !           225:                 * But don't do this if a + option or a -t option
        !           226:                 * was given.  These options can cause us to
        !           227:                 * start the display after the beginning of the file,
        !           228:                 * and it is not appropriate to squish in that case.
        !           229:                 */
        !           230:                if (first_time && pos == NULL_POSITION && !top_scroll &&
        !           231: #if TAGS
        !           232:                    tagoption == NULL &&
        !           233: #endif
        !           234:                    !plusoption)
        !           235:                {
        !           236:                        squished = 1;
        !           237:                        continue;
        !           238:                }
        !           239:                if (top_scroll == 1)
        !           240:                        clear_eol();
        !           241:                put_line();
        !           242:        }
        !           243:
        !           244:        if (ignore_eoi)
        !           245:                hit_eof = 0;
        !           246:        else if (eof && !ABORT_SIGS())
        !           247:                hit_eof++;
        !           248:        else
        !           249:                eof_check();
        !           250:        if (nlines == 0)
        !           251:                eof_bell();
        !           252:        else if (do_repaint)
        !           253:                repaint();
        !           254:        first_time = 0;
        !           255:        (void) currline(BOTTOM);
        !           256: }
        !           257:
        !           258: /*
        !           259:  * Display n lines, scrolling backward.
        !           260:  */
        !           261:        public void
        !           262: back(n, pos, force, only_last)
        !           263:        register int n;
        !           264:        POSITION pos;
        !           265:        int force;
        !           266:        int only_last;
        !           267: {
        !           268:        int nlines = 0;
        !           269:        int do_repaint;
        !           270:
        !           271:        squish_check();
        !           272:        do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1));
        !           273:        hit_eof = 0;
        !           274:        while (--n >= 0)
        !           275:        {
        !           276:                /*
        !           277:                 * Get the previous line of input.
        !           278:                 */
        !           279:                pos = back_line(pos);
        !           280:                if (pos == NULL_POSITION)
        !           281:                {
        !           282:                        /*
        !           283:                         * Beginning of file: stop here unless "force" is true.
        !           284:                         */
        !           285:                        if (!force)
        !           286:                                break;
        !           287:                }
        !           288:                /*
        !           289:                 * Add the position of the previous line to the position table.
        !           290:                 * Display the line on the screen.
        !           291:                 */
        !           292:                add_back_pos(pos);
        !           293:                nlines++;
        !           294:                if (!do_repaint)
        !           295:                {
        !           296:                        home();
        !           297:                        add_line();
        !           298:                        put_line();
        !           299:                }
        !           300:        }
        !           301:
        !           302:        eof_check();
        !           303:        if (nlines == 0)
        !           304:                eof_bell();
        !           305:        else if (do_repaint)
        !           306:                repaint();
        !           307:        (void) currline(BOTTOM);
        !           308: }
        !           309:
        !           310: /*
        !           311:  * Display n more lines, forward.
        !           312:  * Start just after the line currently displayed at the bottom of the screen.
        !           313:  */
        !           314:        public void
        !           315: forward(n, force, only_last)
        !           316:        int n;
        !           317:        int force;
        !           318:        int only_last;
        !           319: {
        !           320:        POSITION pos;
        !           321:
        !           322:        if (quit_at_eof && hit_eof)
        !           323:        {
        !           324:                /*
        !           325:                 * If the -e flag is set and we're trying to go
        !           326:                 * forward from end-of-file, go on to the next file.
        !           327:                 */
        !           328:                if (edit_next(1))
        !           329:                        quit(QUIT_OK);
        !           330:                return;
        !           331:        }
        !           332:
        !           333:        pos = position(BOTTOM_PLUS_ONE);
        !           334:        if (pos == NULL_POSITION && (!force || empty_lines(2, sc_height-1)))
        !           335:        {
        !           336:                if (ignore_eoi)
        !           337:                {
        !           338:                        /*
        !           339:                         * ignore_eoi is to support A_F_FOREVER.
        !           340:                         * Back up until there is a line at the bottom
        !           341:                         * of the screen.
        !           342:                         */
        !           343:                        if (empty_screen())
        !           344:                                pos = ch_zero();
        !           345:                        else
        !           346:                        {
        !           347:                                do
        !           348:                                {
        !           349:                                        back(1, position(TOP), 1, 0);
        !           350:                                        pos = position(BOTTOM_PLUS_ONE);
        !           351:                                } while (pos == NULL_POSITION);
        !           352:                        }
        !           353:                } else
        !           354:                {
        !           355:                        eof_bell();
        !           356:                        hit_eof++;
        !           357:                        return;
        !           358:                }
        !           359:        }
        !           360:        forw(n, pos, force, only_last, 0);
        !           361: }
        !           362:
        !           363: /*
        !           364:  * Display n more lines, backward.
        !           365:  * Start just before the line currently displayed at the top of the screen.
        !           366:  */
        !           367:        public void
        !           368: backward(n, force, only_last)
        !           369:        int n;
        !           370:        int force;
        !           371:        int only_last;
        !           372: {
        !           373:        POSITION pos;
        !           374:
        !           375:        pos = position(TOP);
        !           376:        if (pos == NULL_POSITION && (!force || position(BOTTOM) == 0))
        !           377:        {
        !           378:                eof_bell();
        !           379:                return;
        !           380:        }
        !           381:        back(n, pos, force, only_last);
        !           382: }
        !           383:
        !           384: /*
        !           385:  * Get the backwards scroll limit.
        !           386:  * Must call this function instead of just using the value of
        !           387:  * back_scroll, because the default case depends on sc_height and
        !           388:  * top_scroll, as well as back_scroll.
        !           389:  */
        !           390:        public int
        !           391: get_back_scroll()
        !           392: {
        !           393:        if (back_scroll >= 0)
        !           394:                return (back_scroll);
        !           395:        if (top_scroll)
        !           396:                return (sc_height - 2);
        !           397:        return (10000); /* infinity */
        !           398: }