#include "def.h"
extern struct inclist inclist[ MAXFILES ],
*inclistp;
extern char *includedirs[ ];
extern char *notdotdot[ ];
extern boolean show_where_not;
extern boolean warn_multiple;
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;
for (ip = inclist; ip->i_file; ip++)
if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
{
found = TRUE;
break;
}
if (!found && (dot || *include == '/')) {
if (stat(include, &st) == 0) {
ip = newinclude(include, include);
found = TRUE;
}
else if (show_where_not)
warning1("\tnot in %s\n", include);
}
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)
warning1("\tnot in %s\n", path);
}
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)
warning1("\tnot in %s\n", path);
}
if (!found)
ip = NULL;
return(ip);
}
remove_dotdot(path)
char *path;
{
register char *end, *from, *to, **cp;
char *components[ MAXFILES ],
newpath[ BUFSIZ ];
boolean component_copied;
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;
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';
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;
{
#ifdef S_IFLNK
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 >= ¬dotdot[ MAXDIRS ])
fatalerr("out of .. dirs, increase MAXDIRS\n");
return(TRUE);
}
#endif
return(FALSE);
}
struct inclist *newinclude(newfile, incstring)
register char *newfile, *incstring;
{
register struct inclist *ip;
ip = inclistp++;
if (inclistp == inclist + MAXFILES - 1)
fatalerr("out of space: increase MAXFILES\n");
ip->i_file = copy(newfile);
ip->i_included_sym = FALSE;
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;
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) {
i = strlen(newfile->i_file);
if (!ip->i_included_sym &&
!(i > 2 &&
newfile->i_file[i-1] == 'c' &&
newfile->i_file[i-2] == '.'))
{
if (warn_multiple)
{
warning("%s includes %s more than once!\n",
ip->i_file, newfile->i_file);
warning1("Already have\n");
for (i=0; i<ip->i_listlen; i++)
warning1("\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;
}
}