File:  [Research Unix] / researchv9 / X11 / src / X.V11R1 / util / makedepend / include.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:22:00 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

/*
 * $Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/util/makedepend/include.c,v 1.1.1.1 2018/04/24 17:22:00 root Exp $
 *
 * $Log: include.c,v $
 * Revision 1.1.1.1  2018/04/24 17:22:00  root
 * researchv9-SUN3(old)
 *
 * Revision 1.3  87/08/14  18:14:41  toddb
 * Add the routine inc_clean().  This will "un-mark" all nodes after traversal,
 * so that during traversal, no node is printed more than once.
 * 
 * Revision 1.2  87/08/06  17:40:34  toddb
 * Bug in removing .. (removedotdot).
 * 
 * Revision 1.1  87/08/06  17:34:55  toddb
 * Initial revision
 * 
 * Revision 1.1  87/04/08  16:40:43  rich
 * Initial revision
 * 
 * Revision 1.1  86/04/15  08:34:26  toddb
 * Initial revision
 * 
 */
#include "def.h"

extern struct	inclist	inclist[ MAXFILES ],
			*inclistp;
extern char	*includedirs[ ];
extern char	*notdotdot[ ];
extern boolean show_where_not;

struct inclist *inc_path(file, include, dot)
	register char	*file,
			*include;
	boolean	dot;
{
	static char	path[ BUFSIZ ];
	register char		**pp, *p;
	register struct inclist	*ip;
	struct stat	st;
	boolean	found = FALSE;

	/*
	 * Check all previously found include files for a path that
	 * has already been expanded.
	 */
	for (ip = inclist; ip->i_file; ip++)
		if (strcmp(ip->i_incstring, include) == 0) {
			found = TRUE;
			break;
		}

	/*
	 * If the path was surrounded by "", then check the absolute
	 * path provided.
	 */
	if (!found && dot) {
		if (stat(include, &st) == 0) {
			ip = newinclude(include, include);
			found = TRUE;
		}
		else if (show_where_not)
			log("\tnot in %s\n", include);
	}

	/*
	 * See if this include file is in the directory of the
	 * file being compiled.
	 */
	if (!found) {
		for (p=file+strlen(file); p>file; p--)
			if (*p == '/')
				break;
		if (p == file)
			strcpy(path, include);
		else {
			strncpy(path, file, (p-file) + 1);
			path[ (p-file) + 1 ] = '\0';
			strcpy(path + (p-file) + 1, include);
		}
		remove_dotdot(path);
		if (stat(path, &st) == 0) {
			ip = newinclude(path, include);
			found = TRUE;
		}
		else if (show_where_not)
			log("\tnot in %s\n", path);
	}

	/*
	 * Check the include directories specified. (standard include dir
	 * should be at the end.)
	 */
	if (!found)
		for (pp = includedirs; *pp; pp++) {
			sprintf(path, "%s/%s", *pp, include);
			remove_dotdot(path);
			if (stat(path, &st) == 0) {
				ip = newinclude(path, include);
				found = TRUE;
				break;
			}
			else if (show_where_not)
				log("\tnot in %s\n", path);
		}

	if (!found) {
		/*
		 * If we've announced where it's not include it anyway so
		 * it gets on the dependency list.
		 */
		if (show_where_not)
			ip = newinclude(include, include);
		else
			ip = NULL;
	}
	return(ip);
}

/*
 * Ocaisionally, pathnames are created that look like ../x/../y
 * Any of the 'x/..' sequences within the name can be eliminated.
 * (but only if 'x' is not a symbolic link!!)
 */
remove_dotdot(path)
	char	*path;
{
	register char	*end, *from, *to, **cp;
	char		*components[ MAXFILES ],
			newpath[ BUFSIZ ];
	boolean		component_copied;

	/*
	 * slice path up into components.
	 */
	to = newpath;
	if (*path == '/')
		*to++ = '/';
	*to = '\0';
	cp = components;
	for (from=end=path; *end; end++)
		if (*end == '/') {
			while (*end == '/')
				*end++ = '\0';
			if (*from)
				*cp++ = from;
			from = end;
		}
	*cp++ = from;
	*cp = NULL;

	/*
	 * Now copy the path, removing all 'x/..' components.
	 */
	cp = components;
	component_copied = FALSE;
	while(*cp) {
		if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
			if (issymbolic(newpath, *cp))
				goto dont_remove;
			cp++;
		} else {
		dont_remove:
			if (component_copied)
				*to++ = '/';
			component_copied = TRUE;
			for (from = *cp; *from; )
				*to++ = *from++;
			*to = '\0';
		}
		cp++;
	}
	*to++ = '\0';

	/*
	 * copy the reconstituted path back to our pointer.
	 */
	strcpy(path, newpath);
}

isdot(p)
	register char	*p;
{
	if(p && *p++ == '.' && *p++ == '\0')
		return(TRUE);
	return(FALSE);
}

isdotdot(p)
	register char	*p;
{
	if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
		return(TRUE);
	return(FALSE);
}

issymbolic(dir, component)
	register char	*dir, *component;
{
	struct stat	st;
	char	buf[ BUFSIZ ], **pp;

	sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
	for (pp=notdotdot; *pp; pp++)
		if (strcmp(*pp, buf) == 0)
			return (TRUE);
	if (lstat(buf, &st) == 0
	&& (st.st_mode & S_IFMT) == S_IFLNK) {
		*pp++ = copy(buf);
		if (pp >= &notdotdot[ MAXDIRS ])
			log_fatal("out of .. dirs, increase MAXDIRS\n");
		return(TRUE);
	}
	return(FALSE);
}

/*
 * Add an include file to the list of those included by 'file'.
 */
struct inclist *newinclude(newfile, incstring)
	register char	*newfile, *incstring;
{
	register struct inclist	*ip;

	/*
	 * First, put this file on the global list of include files.
	 */
	ip = inclistp++;
	if (inclistp == inclist + MAXFILES - 1)
		log_fatal("out of space: increase MAXFILES\n");
	ip->i_file = copy(newfile);
	if (incstring == NULL)
		ip->i_incstring = ip->i_file;
	else
		ip->i_incstring = copy(incstring);

	return(ip);
}

included_by(ip, newfile)
	register struct inclist	*ip, *newfile;
{
	register i;

	if (ip == NULL)
		return;
	/*
	 * Put this include file (newfile) on the list of files included
	 * by 'file'.  If 'file' is NULL, then it is not an include
	 * file itself (i.e. was probably mentioned on the command line).
	 * If it is already on the list, don't stick it on again.
	 */
	if (ip->i_list == NULL)
		ip->i_list = (struct inclist **)
			malloc(sizeof(struct inclist *) * ++ip->i_listlen);
	else {
		for (i=0; i<ip->i_listlen; i++)
			if (ip->i_list[ i ] == newfile) {
				log("%s includes %s more than once!\n",
					ip->i_file, newfile->i_file);
				log("Already have\n");
				for (i=0; i<ip->i_listlen; i++)
					log("\t%s\n", ip->i_list[i]->i_file);
				return;
			}
		ip->i_list = (struct inclist **) realloc(ip->i_list,
			sizeof(struct inclist *) * ++ip->i_listlen);
	}
	ip->i_list[ ip->i_listlen-1 ] = newfile;
}

inc_clean ()
{
	register struct inclist *ip;

	for (ip = inclist; ip < inclistp; ip++) {
		ip->i_marked = FALSE;
	}
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.