home *** CD-ROM | disk | FTP | other *** search
- /* $Header: dlist.c,v 1.1 85/04/23 13:56:29 nicklin Exp $ */
-
- /*
- * Author: Peter J. Nicklin
- */
- #include <stdio.h>
- #include "Mkmf.h"
- #include "dlist.h"
- #include "hash.h"
- #include "null.h"
- #include "slist.h"
- #include "yesno.h"
-
- static HASHBLK *printtag = NULL; /* include files already printed */
- static int COLUMN; /* last column printed */
-
- /*
- * dlappend() adds a dependency chain block to the end of a list of
- * dependency chain blocks. Each dependency chain block consists of a pointer
- * to a source file name block contained in a singly-linked list, and a pointer
- * to the head of the dependent list of included files. Returns a pointer to
- * the dependency chain block, or a null pointer if out of memory.
- */
- DLBLK *
- dlappend(srctyp, srcblk, incblk, dlist)
- int srctyp; /* source file type */
- SLBLK *srcblk; /* pointer to the source file block */
- INCBLK *incblk; /* included file dependency chain */
- DLIST *dlist; /* pointer to list head block */
- {
- char *malloc(); /* memory allocator */
- DLBLK *dblk; /* pointer to dependency list block */
-
- if (dlist == NULL)
- return(NULL);
- if ((dblk = (DLBLK *) malloc(sizeof(DLBLK))) == NULL)
- {
- warn("out of memory");
- return(NULL);
- }
- dblk->d_src = srcblk;
- dblk->d_type = srctyp;
- dblk->d_incl = incblk;
- dblk->d_next = NULL;
- if (dlist->d_tail == NULL)
- {
- dlist->d_head = dlist->d_tail = dblk;
- }
- else {
- dlist->d_tail = dlist->d_tail->d_next = dblk;
- }
- return(dblk);
- }
-
-
-
- /*
- * dlinit() returns a pointer to the head block of a dependency list, or
- * null pointer if out of memory.
- */
- DLIST *
- dlinit()
- {
- char *malloc(); /* memory allocator */
- DLIST *dlist; /* pointer to list head block */
-
- if ((dlist = (DLIST *) malloc(sizeof(DLIST))) == NULL)
- {
- warn("out of memory");
- return(NULL);
- }
- dlist->d_head = dlist->d_tail = NULL;
- return(dlist);
- }
-
-
-
- /*
- * dlprint() appends the object-include file dependencies to the end of
- * a makefile. Transitive closure is checked by making suring that an
- * object-include file dependency is not generated if the source file is
- * included in another file.
- */
- void
- dlprint(dlist, ofp)
- DLIST *dlist; /* dependency list */
- FILE *ofp; /* output stream */
- {
- DLBLK *dblk; /* pointer to dependency list block */
- HASHBLK *lookupinclude(); /* look up include name in hash table */
- INCBLK *iblk; /* cur. include file hash table blk */
- void putinchain(); /* output nested subinclude filenames */
- void putobjd(); /* output object file name */
- void rmprinttag(); /* remove "already printed" tags */
-
- fprintf(ofp, "%s\n", DEPENDMARK);
- for (dblk=dlist->d_head; dblk != NULL; dblk=dblk->d_next)
- {
- if (lookupinclude(dblk->d_src->key, dblk->d_type) == NULL)
- {
- putobjd(dblk->d_src, ofp);
- for (iblk=dblk->d_incl; iblk != NULL; iblk=iblk->i_next)
- {
- putinchain(iblk->i_hblk, ofp);
- }
- fprintf(ofp, "\n");
- rmprinttag();
- }
- }
- }
-
-
-
- /*
- * putinchain() outputs a chain of nested include file names. It changes
- * the sign of each chain block h_val field as it traverses the chain to
- * detect looping.
- */
- static void
- putinchain(htb, ofp)
- HASHBLK *htb; /* hash table blk including chain */
- FILE *ofp; /* output stream */
- {
- INCBLK *iblk; /* cur. include file hash table blk */
- void putinclude(); /* output include file pathname */
- void putinchain(); /* output nested subinclude file names*/
-
- putinclude(htb, ofp);
- htb->h_val = -htb->h_val;
- for (iblk=htb->h_sub; iblk != NULL; iblk=iblk->i_next)
- {
- if (iblk->i_hblk->h_val < 0)
- {
- if (iblk->i_loop == NO)
- {
- warn2("recursive include nesting of \"%s\" in \"%s\"",
- iblk->i_hblk->h_def, htb->h_def);
- iblk->i_loop = YES;
- }
- continue;
- }
- putinchain(iblk->i_hblk, ofp);
- }
- htb->h_val = -htb->h_val;
- }
-
-
-
- #define MAXLINE 80
- #define TABSIZE 8
-
- /*
- * putinclude() writes an include file pathname to stream ofp if
- * if it has not already been written on the current dependency line.
- * and adds the hash block containing the file pathname to the
- * "already printed" printtag list. The last block on the list
- * points back onto itself rather than at NULL so that the non-NULL
- * tag will indicate that the filename has already been seen.
- */
- static void
- putinclude(htb, ofp)
- HASHBLK *htb; /* include file hash block */
- FILE *ofp; /* output stream */
- {
- if (htb->h_tag == NULL)
- {
- COLUMN += htb->h_val + 1;
- if (COLUMN >= (MAXLINE - 2))
- {
- fprintf(ofp, " \\\n\t%s", htb->h_def);
- COLUMN = htb->h_val + TABSIZE;
- }
- else {
- fprintf(ofp, " %s", htb->h_def);
- }
- /* add to "already printed" filenames */
- htb->h_tag = (printtag == NULL) ? htb :printtag;
- printtag = htb;
- }
- }
-
-
-
- /*
- * putobjd() writes an object file dependency name.
- */
- static void
- putobjd(srcblk, ofp)
- SLBLK *srcblk; /* source file name list block */
- FILE *ofp; /* output stream */
- {
- extern char OBJSFX[]; /* object file name suffix */
- int strlen(); /* string length */
- void putobj(); /* output object file name */
-
- COLUMN = strlen(srcblk->key) + strlen(OBJSFX) + 1;
- putobj(srcblk->key, ofp);
- fprintf(ofp, ":");
- }
-
-
-
- /*
- * rmprinttag() removes the chain of tags indicating that an include
- * file dependency has already been printed for the current source file.
- */
- static void
- rmprinttag()
- {
- register HASHBLK *curhtb; /* current hash table block */
- register HASHBLK *nxthtb; /* next hash table block */
-
- for (curhtb = printtag; curhtb != NULL; curhtb = nxthtb)
- {
- nxthtb = curhtb->h_tag;
- curhtb->h_tag = NULL;
- }
- printtag = NULL;
- }
-