home *** CD-ROM | disk | FTP | other *** search
- #ifndef NO_IDENT
- static char *Id = "$Id: dirread.c,v 1.5 1995/06/04 23:11:58 tom Exp $";
- #endif
-
- /*
- * Title: dirread.c
- * Author: Thomas E. Dickey
- * Created: 31 Jan 1985
- * Last update:
- * 19 Feb 1995, prototyped
- * 15 Jun 1985, typed 'realloc', 'calloc'.
- * 05 Feb 1985, added 'dirread_path' entry.
- * 01 Feb 1985
- *
- * Function: This module updates the read-list for FLIST. Each time a
- * directory search is performed (i.e., by the initial invocation,
- * or by the READ command), FLIST calls this module to unite
- * the data with the read-list. We do pruning here, because we
- * want to make the full re-READ of the display list fast.
- * By eliminating redundant search-patterns, we can keep the
- * read-list from growing faster than the display list.
- *
- * We perform both directions of pruning:
- *
- * a) A pattern which is a proper subset of at least one
- * pattern already in the read-list is ignored.
- * b) A pattern which is a proper superset of one or more
- * patterns already in the read-list causes those patterns
- * to be replaced by the new pattern.
- */
-
- #include <string.h>
-
- #include <stdlib.h>
- #include <rms.h>
-
- #include "flist.h"
- #include "dirent.h"
- #include "dirfind.h"
- #include "dirread.h"
-
- import(readlist); import(readllen);
-
- /* <init>:
- * Initialize this module for a new directory-level:
- */
- void
- dirread_init (void)
- {
- readllen = 0;
- }
-
- /* <put>:
- * Put a new entry into the read-list:
- */
- void
- dirread_put (struct FAB *fab_)
- {
- struct NAM *nam_ = fab_->fab$l_nam; /* patch: should pass NAM */
- FILENT fz;
- register int j, k;
-
- dirent_chop (&fz, nullC, nam_);
-
- if (readllen)
- {
- /*
- * First, see if the new pattern is a subset of anything already
- * in the list:
- */
- for (j = 0; j < readllen; j++)
- {
- if (dirfind_tst (&fz, &readlist[j], FALSE)) return;
- }
- /*
- * If we get this far, then the new pattern is not a proper subset
- * of any already there. However, it may absorb others:
- */
- for (j = 0; j < readllen; j++)
- {
- if (dirfind_tst (&readlist[j], &fz, FALSE))
- {
- for (k = j; k < readllen; k++)
- readlist[k] = readlist[k+1]; /* compress list */
- readllen--;
- j--; /* ...and restart comparison */
- }
- }
- }
- j = (readllen + 2) * sizeof(FILENT);
- if (readllen)
- readlist = realloc (readlist, j);
- else
- readlist = calloc (1, j);
- readlist[readllen++] = fz;
- }
-
- /* <get>:
- * Return a string pointer to the inx'th item in the read-list. If no
- * more items remain, return null.
- */
- char *dirread_get (char *filespec, int inx)
- {
- return ((inx < readllen) ? dirent_glue (filespec, &readlist[inx]) : nullC);
- }
-
- /* <free>:
- * Release the structure on exit to a higher directory level:
- */
- void dirread_free (void)
- {
- cfree (readlist);
- }
-
- #ifdef DEBUG
- void dirread_show (void)
- {
- int j;
- char filespec[MAX_PATH];
-
- trace ("READ-LIST:\n");
- for (j = 0; j < readllen; j++)
- trace ("%d: '%s'\n", j, dirent_glue(filespec, &readlist[j]));
- }
- #endif
-
- /* <path>:
- * Given a (potential) index into the read-list, return a pointer to the
- * pathname portion. If the index lies beyond the end of the list, return
- * null. If the pathname is not unique (i.e., is a repeat of previous
- * entries in the list), skip to the next entry.
- *
- * To permit the skip, we pass the address of the index.
- */
- char *dirread_path (int *inx_)
- {
- FILENT *z;
- int j;
- char *c_;
-
- if (*inx_ >= readllen || *inx_ < 0)
- return (nullC);
- else
- {
- z = &readlist[*inx_];
- c_ = zPATHOF(z);
- for (j = 0; j < *inx_; j++)
- {
- z = &readlist[j];
- if (strcmp(c_, zPATHOF(z)) == 0)
- {
- *inx_ = *inx_ + 1;
- return (dirread_path(inx_));
- }
- }
- return (c_);
- }
- }
-