aboutsummaryrefslogtreecommitdiff
path: root/unix/boot/mkpkg/fncache.c
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /unix/boot/mkpkg/fncache.c
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'unix/boot/mkpkg/fncache.c')
-rw-r--r--unix/boot/mkpkg/fncache.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/unix/boot/mkpkg/fncache.c b/unix/boot/mkpkg/fncache.c
new file mode 100644
index 00000000..2053f2fe
--- /dev/null
+++ b/unix/boot/mkpkg/fncache.c
@@ -0,0 +1,228 @@
+/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+//#include "../bootProto.h"
+
+
+/*
+ * FNCACHE -- Maintain a cache of system logical filenames (e.g., <config.h>)
+ * and their associated virtual filenames (e.g., "host$hlib/config.h").
+ * This can greatly reduce the amount of time required to resolve references
+ * to system include files in dependency file lists.
+ *
+ * External entry points:
+ *
+ * nc = m_sysfile (lname, fname, maxch) # return file name
+ * m_fninit (debug) # initialize cache
+ */
+
+#define MAX_FILES 20 /* size of the cache */
+#define SZ_LNAME 32 /* size of logical name */
+#define SZ_FNAME 32 /* size of virtual file name */
+#define EOS '\0'
+
+struct _sysfile { /* cache list element structure */
+ struct _sysfile *uplnk;
+ struct _sysfile *dnlnk;
+ int nrefs; /* number of references */
+ int chksum; /* speeds searches */
+ char lname[SZ_LNAME+1]; /* logical name */
+ char fname[SZ_FNAME+1]; /* file name */
+};
+
+struct _sysfile fncache[MAX_FILES]; /* the cache */
+struct _sysfile *fn_head; /* doubly linked list */
+struct _sysfile *fn_tail;
+int fn_hits, fn_misses;
+
+struct _sysfile *fn_unlink();
+struct _sysfile *fn_tohead();
+struct _sysfile *fn_totail();
+
+
+extern int os_sysfile (char *sysfile, char *fname, int maxch);
+
+int m_sysfile (char *lname, char *fname, int maxch);
+void m_fninit (int debug);
+int fn_chksum (char *s);
+int fn_strncpy (char *out, char *in, int maxch);
+
+
+
+/* M_SYSFILE -- Search for the named system file and return the virtual file
+ * name in the output string if the system file is found. This is functionally
+ * equivalent to os_sysfile().
+ */
+int
+m_sysfile (
+ char *lname, /* logical name of system file */
+ char *fname, /* receives virtual file name */
+ int maxch
+)
+{
+ register struct _sysfile *fn;
+ register int chksum;
+ int fnlen;
+
+ /* Look in the cache first. For a small cache a linear search is
+ * plenty fast enough.
+ */
+ chksum = fn_chksum (lname);
+ for (fn=fn_head; fn != NULL; fn=fn->dnlnk)
+ if (fn->chksum == chksum && strcmp (lname, fn->lname) == 0) {
+ fn_tohead (fn_unlink (fn));
+ fn->nrefs++;
+ fn_hits++;
+ return (fn_strncpy (fname, fn->fname, maxch));
+ }
+
+ /* Cache miss. Don't put in cache it name is too long.
+ */
+ fn_misses++;
+ fnlen = os_sysfile (lname, fname, maxch);
+ if (fnlen > SZ_FNAME || strlen(lname) > SZ_LNAME)
+ return (fnlen);
+
+ /* Put fname in the cache. Reuse slot at tail of list.
+ */
+ fn = fn_tohead (fn_unlink (fn_tail));
+ strcpy (fn->lname, lname);
+ strcpy (fn->fname, fname);
+ fn->chksum = fn_chksum (lname);
+ fn->nrefs = 1;
+
+ return (fnlen);
+}
+
+
+/* M_FNINIT -- Initialize (clear) the sysfile cache.
+ */
+void
+m_fninit (int debug)
+{
+ register struct _sysfile *fn;
+ register int i;
+ int total;
+
+ if (debug) {
+ char lname[SZ_FNAME+1];
+
+ total = fn_hits + fn_misses;
+ printf ("file name cache: %d hits, %d misses, %d%% of %d\n",
+ fn_hits, fn_misses, (total ? fn_hits * 100 / total : 0), total);
+
+ for (fn=fn_head; fn != NULL; fn=fn->dnlnk)
+ if (fn->lname[0]) {
+ sprintf (lname, "<%s>", fn->lname);
+ printf ("%3d (%05d) %-20s => %s\n",
+ fn->nrefs, fn->chksum, lname, fn->fname);
+ }
+
+ fn_hits = 0;
+ fn_misses = 0;
+
+ fflush (stdout);
+ }
+
+ fn = fn_head = fn_tail = &fncache[0];
+ fn->uplnk = NULL;
+ fn->dnlnk = NULL;
+ fn->nrefs = 0;
+ fn->chksum = -1;
+ fn->lname[0] = EOS;
+
+ for (i=1; i < MAX_FILES; i++) {
+ fn = fn_tohead (&fncache[i]);
+ fn->lname[0] = EOS;
+ fn->chksum = -1;
+ fn->nrefs = 0;
+ }
+}
+
+
+/* FN_TOHEAD -- Link a sysfile struct at the head of the list.
+ */
+struct _sysfile *
+fn_tohead (register struct _sysfile *fn)
+{
+ if (fn != fn_head) {
+ fn->uplnk = NULL;
+ fn->dnlnk = fn_head;
+ fn_head->uplnk = fn;
+ fn_head = fn;
+ }
+
+ return (fn);
+}
+
+
+/* FN_TOTAIL -- Link a sysfile struct at the tail of the list.
+ */
+struct _sysfile *
+fn_totail (register struct _sysfile *fn)
+{
+ if (fn != fn_tail) {
+ fn->uplnk = fn_tail;
+ fn->dnlnk = NULL;
+ fn_tail->dnlnk = fn;
+ fn_tail = fn;
+ }
+
+ return (fn);
+}
+
+
+/* FN_UNLINK -- Unlink an sysfile struct.
+ */
+struct _sysfile *
+fn_unlink (register struct _sysfile *fn)
+{
+ if (fn == fn_head)
+ fn_head = fn->dnlnk;
+ if (fn == fn_tail)
+ fn_tail = fn->uplnk;
+
+ if (fn->uplnk)
+ fn->uplnk->dnlnk = fn->dnlnk;
+ if (fn->dnlnk)
+ fn->dnlnk->uplnk = fn->uplnk;
+
+ return (fn);
+}
+
+
+/* FN_CHKSUM -- Compute the checksum of a character string.
+ */
+int
+fn_chksum (char *s)
+{
+ register int sum=0;
+
+ while (*s)
+ sum += *s++;
+
+ return (sum);
+}
+
+
+/* FN_STRNCPY -- Copy up to maxch characters from a string and return the
+ * number of characters copied as the function value.
+ */
+int
+fn_strncpy (
+ char *out,
+ char *in,
+ int maxch
+)
+{
+ register char *ip, *op;
+ register int n;
+
+ for (ip=in, op=out, n=maxch; --n >= 0 && (*op++ = *ip++); )
+ ;
+ return (op-1 - out);
+}