home *** CD-ROM | disk | FTP | other *** search
- /*
- //
- // Copyright (C) 1991 Texas Instruments Incorporated.
- //
- // Permission is granted to any individual or institution to use, copy, modify,
- // and distribute this software, provided that this complete copyright and
- // permission notice is maintained, intact, in all copies and supporting
- // documentation.
- //
- // Texas Instruments Incorporated provides this software "as is" without
- // express or implied warranty.
- //
- * $XConsortium: include.c,v 1.7 88/11/08 12:19:55 jim Exp $
- */
- #include "def.h"
-
- extern struct inclist inclist[ MAXFILES ],
- *inclistp;
- extern char *includedirs[ ];
- extern char *notdotdot[ ];
- extern boolean show_where_not;
- extern char path_sep;
-
- 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) && !ip->i_included_sym)
- {
- 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)
- do_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 == path_sep)
- 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)
- do_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++) {
- #ifdef VMS
- sprintf(path, "%s%s", *pp, include);
- #else
- #ifdef os2
- sprintf(path, "%s\\%s", *pp, include);
- #else
- sprintf(path, "%s/%s", *pp, include);
- #endif
- #endif
- remove_dotdot(path);
- if (stat(path, &st) == 0) {
- ip = newinclude(path, include);
- found = TRUE;
- break;
- }
- else if (show_where_not)
- do_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 == path_sep)
- *to++ = path_sep;
- *to = '\0';
- cp = components;
- for (from=end=path; *end; end++)
- if (*end == path_sep) {
- while (*end == path_sep)
- *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++ = path_sep;
- 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;
- {
- #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 ])
- log_fatal("out of .. dirs, increase MAXDIRS\n");
- return(TRUE);
- }
- #endif
- 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);
- ip->i_included_sym = FALSE;
- if (incstring == NULL)
- ip->i_incstring = ip->i_file;
- else
- ip->i_incstring = copy(incstring);
-
- return(ip);
- }
-
- void
- 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) {
- if (!ip->i_included_sym)
- {
- /* only bitch if ip has */
- /* no #include SYMBOL lines */
-
- /**
- ** The log messages for multiply included files seems inappropriate now that
- ** mkdepend generates dependencies for .[hcC] files instead of .o files. Thus
- ** I'm commenting this stuff out for now -- MBN
- **
- ** 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;
- }
- }
-