home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 036 / less232.zip / IFILE.C < prev    next >
C/C++ Source or Header  |  1994-09-09  |  6KB  |  307 lines

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