]> andersk Git - moira.git/blobdiff - util/makedepend/include.c
sync'ing files for RCS->CVS migration
[moira.git] / util / makedepend / include.c
diff --git a/util/makedepend/include.c b/util/makedepend/include.c
new file mode 100644 (file)
index 0000000..e4f8f38
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * $XConsortium: include.c,v 1.6 88/09/22 13:52:38 jim Exp $
+ */
+#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) && !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)
+                       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);
+       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;
+       /*
+        * 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  */
+                               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;
+       }
+}
This page took 0.046756 seconds and 4 git commands to generate.