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

Annotation of src/usr.bin/less/ifile.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:  * An IFILE represents an input file.
        !            30:  *
        !            31:  * It is actually a pointer to an ifile structure,
        !            32:  * but is opaque outside this module.
        !            33:  * Ifile structures are kept in a linked list in the order they
        !            34:  * appear on the command line.
        !            35:  * Any new file which does not already appear in the list is
        !            36:  * inserted after the current file.
        !            37:  */
        !            38:
        !            39: #include "less.h"
        !            40:
        !            41: extern IFILE   curr_ifile;
        !            42:
        !            43: struct ifile {
        !            44:        struct ifile *h_next;           /* Links for command line list */
        !            45:        struct ifile *h_prev;
        !            46:        char *h_filename;               /* Name of the file */
        !            47:        void *h_filestate;              /* File state (used in ch.c) */
        !            48:        int h_index;                    /* Index within command line list */
        !            49:        int h_opened;                   /* Only need one bit */
        !            50:        struct scrpos h_scrpos;         /* Saved position within the file */
        !            51: };
        !            52:
        !            53: /*
        !            54:  * Convert an IFILE (external representation)
        !            55:  * to a struct file (internal representation), and vice versa.
        !            56:  */
        !            57: #define int_ifile(h)   ((struct ifile *)(h))
        !            58: #define ext_ifile(h)   ((IFILE)(h))
        !            59:
        !            60: /*
        !            61:  * Anchor for linked list.
        !            62:  */
        !            63: static struct ifile anchor = { &anchor, &anchor, 0 };
        !            64: static int ifiles = 0;
        !            65:
        !            66:        static void
        !            67: incr_index(p, incr)
        !            68:        register struct ifile *p;
        !            69:        int incr;
        !            70: {
        !            71:        for (;  p != &anchor;  p = p->h_next)
        !            72:                p->h_index += incr;
        !            73: }
        !            74:
        !            75:        static void
        !            76: link_ifile(p, prev)
        !            77:        struct ifile *p;
        !            78:        struct ifile *prev;
        !            79: {
        !            80:        /*
        !            81:         * Link into list.
        !            82:         */
        !            83:        if (prev == NULL)
        !            84:                prev = &anchor;
        !            85:        p->h_next = prev->h_next;
        !            86:        p->h_prev = prev;
        !            87:        prev->h_next->h_prev = p;
        !            88:        prev->h_next = p;
        !            89:        /*
        !            90:         * Calculate index for the new one,
        !            91:         * and adjust the indexes for subsequent ifiles in the list.
        !            92:         */
        !            93:        p->h_index = prev->h_index + 1;
        !            94:        incr_index(p->h_next, 1);
        !            95:        ifiles++;
        !            96: }
        !            97:
        !            98:        static void
        !            99: unlink_ifile(p)
        !           100:        struct ifile *p;
        !           101: {
        !           102:        p->h_next->h_prev = p->h_prev;
        !           103:        p->h_prev->h_next = p->h_next;
        !           104:        incr_index(p->h_next, -1);
        !           105:        ifiles--;
        !           106: }
        !           107:
        !           108: /*
        !           109:  * Allocate a new ifile structure and stick a filename in it.
        !           110:  * It should go after "prev" in the list
        !           111:  * (or at the beginning of the list if "prev" is NULL).
        !           112:  * Return a pointer to the new ifile structure.
        !           113:  */
        !           114:        static struct ifile *
        !           115: new_ifile(filename, prev)
        !           116:        char *filename;
        !           117:        struct ifile *prev;
        !           118: {
        !           119:        register struct ifile *p;
        !           120:
        !           121:        /*
        !           122:         * Allocate and initialize structure.
        !           123:         */
        !           124:        p = (struct ifile *) ecalloc(1, sizeof(struct ifile));
        !           125:        p->h_filename = save(filename);
        !           126:        p->h_scrpos.pos = NULL_POSITION;
        !           127:        p->h_opened = 0;
        !           128:        link_ifile(p, prev);
        !           129:        return (p);
        !           130: }
        !           131:
        !           132: /*
        !           133:  * Delete an existing ifile structure.
        !           134:  */
        !           135:        public void
        !           136: del_ifile(h)
        !           137:        IFILE h;
        !           138: {
        !           139:        register struct ifile *p;
        !           140:
        !           141:        if (h == NULL_IFILE)
        !           142:                return;
        !           143:        /*
        !           144:         * If the ifile we're deleting is the currently open ifile,
        !           145:         * move off it.
        !           146:         */
        !           147:        if (h == curr_ifile)
        !           148:                curr_ifile = getoff_ifile(curr_ifile);
        !           149:        p = int_ifile(h);
        !           150:        unlink_ifile(p);
        !           151:        free(p->h_filename);
        !           152:        free(p);
        !           153: }
        !           154:
        !           155: /*
        !           156:  * Get the ifile after a given one in the list.
        !           157:  */
        !           158:        public IFILE
        !           159: next_ifile(h)
        !           160:        IFILE h;
        !           161: {
        !           162:        register struct ifile *p;
        !           163:
        !           164:        p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
        !           165:        if (p->h_next == &anchor)
        !           166:                return (NULL_IFILE);
        !           167:        return (ext_ifile(p->h_next));
        !           168: }
        !           169:
        !           170: /*
        !           171:  * Get the ifile before a given one in the list.
        !           172:  */
        !           173:        public IFILE
        !           174: prev_ifile(h)
        !           175:        IFILE h;
        !           176: {
        !           177:        register struct ifile *p;
        !           178:
        !           179:        p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
        !           180:        if (p->h_prev == &anchor)
        !           181:                return (NULL_IFILE);
        !           182:        return (ext_ifile(p->h_prev));
        !           183: }
        !           184:
        !           185: /*
        !           186:  * Return a different ifile from the given one.
        !           187:  */
        !           188:        public IFILE
        !           189: getoff_ifile(ifile)
        !           190:        IFILE ifile;
        !           191: {
        !           192:        IFILE newifile;
        !           193:
        !           194:        if ((newifile = prev_ifile(ifile)) != NULL_IFILE)
        !           195:                return (newifile);
        !           196:        if ((newifile = next_ifile(ifile)) != NULL_IFILE)
        !           197:                return (newifile);
        !           198:        return (NULL_IFILE);
        !           199: }
        !           200:
        !           201: /*
        !           202:  * Return the number of ifiles.
        !           203:  */
        !           204:        public int
        !           205: nifile()
        !           206: {
        !           207:        return (ifiles);
        !           208: }
        !           209:
        !           210: /*
        !           211:  * Find an ifile structure, given a filename.
        !           212:  */
        !           213:        static struct ifile *
        !           214: find_ifile(filename)
        !           215:        char *filename;
        !           216: {
        !           217:        register struct ifile *p;
        !           218:
        !           219:        for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
        !           220:                if (strcmp(filename, p->h_filename) == 0)
        !           221:                        return (p);
        !           222:        return (NULL);
        !           223: }
        !           224:
        !           225: /*
        !           226:  * Get the ifile associated with a filename.
        !           227:  * If the filename has not been seen before,
        !           228:  * insert the new ifile after "prev" in the list.
        !           229:  */
        !           230:        public IFILE
        !           231: get_ifile(filename, prev)
        !           232:        char *filename;
        !           233:        IFILE prev;
        !           234: {
        !           235:        register struct ifile *p;
        !           236:
        !           237:        if ((p = find_ifile(filename)) == NULL)
        !           238:                p = new_ifile(filename, int_ifile(prev));
        !           239:        return (ext_ifile(p));
        !           240: }
        !           241:
        !           242: /*
        !           243:  * Get the filename associated with a ifile.
        !           244:  */
        !           245:        public char *
        !           246: get_filename(ifile)
        !           247:        IFILE ifile;
        !           248: {
        !           249:        if (ifile == NULL)
        !           250:                return (NULL);
        !           251:        return (int_ifile(ifile)->h_filename);
        !           252: }
        !           253:
        !           254: /*
        !           255:  * Get the index of the file associated with a ifile.
        !           256:  */
        !           257:        public int
        !           258: get_index(ifile)
        !           259:        IFILE ifile;
        !           260: {
        !           261:        return (int_ifile(ifile)->h_index);
        !           262: }
        !           263:
        !           264: /*
        !           265:  * Save the file position to be associated with a given file.
        !           266:  */
        !           267:        public void
        !           268: store_pos(ifile, scrpos)
        !           269:        IFILE ifile;
        !           270:        struct scrpos *scrpos;
        !           271: {
        !           272:        int_ifile(ifile)->h_scrpos = *scrpos;
        !           273: }
        !           274:
        !           275: /*
        !           276:  * Recall the file position associated with a file.
        !           277:  * If no position has been associated with the file, return NULL_POSITION.
        !           278:  */
        !           279:        public void
        !           280: get_pos(ifile, scrpos)
        !           281:        IFILE ifile;
        !           282:        struct scrpos *scrpos;
        !           283: {
        !           284:        *scrpos = int_ifile(ifile)->h_scrpos;
        !           285: }
        !           286:
        !           287: /*
        !           288:  * Mark the ifile as "opened".
        !           289:  */
        !           290:        public void
        !           291: set_open(ifile)
        !           292:        IFILE ifile;
        !           293: {
        !           294:        int_ifile(ifile)->h_opened = 1;
        !           295: }
        !           296:
        !           297: /*
        !           298:  * Return whether the ifile has been opened previously.
        !           299:  */
        !           300:        public int
        !           301: opened(ifile)
        !           302:        IFILE ifile;
        !           303: {
        !           304:        return (int_ifile(ifile)->h_opened);
        !           305: }
        !           306:
        !           307:        public void *
        !           308: get_filestate(ifile)
        !           309:        IFILE ifile;
        !           310: {
        !           311:        return (int_ifile(ifile)->h_filestate);
        !           312: }
        !           313:
        !           314:        public void
        !           315: set_filestate(ifile, filestate)
        !           316:        IFILE ifile;
        !           317:        void *filestate;
        !           318: {
        !           319:        int_ifile(ifile)->h_filestate = filestate;
        !           320: }
        !           321:
        !           322: #if 0
        !           323:        public void
        !           324: if_dump()
        !           325: {
        !           326:        register struct ifile *p;
        !           327:
        !           328:        for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
        !           329:        {
        !           330:                printf("%x: %d. <%s> pos %d,%x\n",
        !           331:                        p, p->h_index, p->h_filename,
        !           332:                        p->h_scrpos.ln, p->h_scrpos.pos);
        !           333:                ch_dump(p->h_filestate);
        !           334:        }
        !           335: }
        !           336: #endif