home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / util / makedepend / include.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-05  |  5.5 KB  |  266 lines

  1. /*
  2.  * $XConsortium: include.c,v 1.11 91/04/05 17:33:48 rws Exp $
  3.  */
  4. #include "def.h"
  5.  
  6. extern struct    inclist    inclist[ MAXFILES ],
  7.             *inclistp;
  8. extern char    *includedirs[ ];
  9. extern char    *notdotdot[ ];
  10. extern boolean show_where_not;
  11.  
  12. struct inclist *inc_path(file, include, dot)
  13.     register char    *file,
  14.             *include;
  15.     boolean    dot;
  16. {
  17.     static char    path[ BUFSIZ ];
  18.     register char        **pp, *p;
  19.     register struct inclist    *ip;
  20.     struct stat    st;
  21.     boolean    found = FALSE;
  22.  
  23.     /*
  24.      * Check all previously found include files for a path that
  25.      * has already been expanded.
  26.      */
  27.     for (ip = inclist; ip->i_file; ip++)
  28.         if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
  29.         {
  30.         found = TRUE;
  31.         break;
  32.         }
  33.  
  34.     /*
  35.      * If the path was surrounded by "", then check the absolute
  36.      * path provided.
  37.      */
  38.     if (!found && dot) {
  39.         if (stat(include, &st) == 0) {
  40.             ip = newinclude(include, include);
  41.             found = TRUE;
  42.         }
  43.         else if (show_where_not)
  44.             warning1("\tnot in %s\n", include);
  45.     }
  46.  
  47.     /*
  48.      * See if this include file is in the directory of the
  49.      * file being compiled.
  50.      */
  51.     if (!found) {
  52.         for (p=file+strlen(file); p>file; p--)
  53.             if (*p == '/')
  54.                 break;
  55.         if (p == file)
  56.             strcpy(path, include);
  57.         else {
  58.             strncpy(path, file, (p-file) + 1);
  59.             path[ (p-file) + 1 ] = '\0';
  60.             strcpy(path + (p-file) + 1, include);
  61.         }
  62.         remove_dotdot(path);
  63.         if (stat(path, &st) == 0) {
  64.             ip = newinclude(path, include);
  65.             found = TRUE;
  66.         }
  67.         else if (show_where_not)
  68.             warning1("\tnot in %s\n", path);
  69.     }
  70.  
  71.     /*
  72.      * Check the include directories specified. (standard include dir
  73.      * should be at the end.)
  74.      */
  75.     if (!found)
  76.         for (pp = includedirs; *pp; pp++) {
  77.             sprintf(path, "%s/%s", *pp, include);
  78.             remove_dotdot(path);
  79.             if (stat(path, &st) == 0) {
  80.                 ip = newinclude(path, include);
  81.                 found = TRUE;
  82.                 break;
  83.             }
  84.             else if (show_where_not)
  85.                 warning1("\tnot in %s\n", path);
  86.         }
  87.  
  88.     if (!found)
  89.         ip = NULL;
  90.     return(ip);
  91. }
  92.  
  93. /*
  94.  * Ocaisionally, pathnames are created that look like ../x/../y
  95.  * Any of the 'x/..' sequences within the name can be eliminated.
  96.  * (but only if 'x' is not a symbolic link!!)
  97.  */
  98. remove_dotdot(path)
  99.     char    *path;
  100. {
  101.     register char    *end, *from, *to, **cp;
  102.     char        *components[ MAXFILES ],
  103.             newpath[ BUFSIZ ];
  104.     boolean        component_copied;
  105.  
  106.     /*
  107.      * slice path up into components.
  108.      */
  109.     to = newpath;
  110.     if (*path == '/')
  111.         *to++ = '/';
  112.     *to = '\0';
  113.     cp = components;
  114.     for (from=end=path; *end; end++)
  115.         if (*end == '/') {
  116.             while (*end == '/')
  117.                 *end++ = '\0';
  118.             if (*from)
  119.                 *cp++ = from;
  120.             from = end;
  121.         }
  122.     *cp++ = from;
  123.     *cp = NULL;
  124.  
  125.     /*
  126.      * Now copy the path, removing all 'x/..' components.
  127.      */
  128.     cp = components;
  129.     component_copied = FALSE;
  130.     while(*cp) {
  131.         if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
  132.             if (issymbolic(newpath, *cp))
  133.                 goto dont_remove;
  134.             cp++;
  135.         } else {
  136.         dont_remove:
  137.             if (component_copied)
  138.                 *to++ = '/';
  139.             component_copied = TRUE;
  140.             for (from = *cp; *from; )
  141.                 *to++ = *from++;
  142.             *to = '\0';
  143.         }
  144.         cp++;
  145.     }
  146.     *to++ = '\0';
  147.  
  148.     /*
  149.      * copy the reconstituted path back to our pointer.
  150.      */
  151.     strcpy(path, newpath);
  152. }
  153.  
  154. isdot(p)
  155.     register char    *p;
  156. {
  157.     if(p && *p++ == '.' && *p++ == '\0')
  158.         return(TRUE);
  159.     return(FALSE);
  160. }
  161.  
  162. isdotdot(p)
  163.     register char    *p;
  164. {
  165.     if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
  166.         return(TRUE);
  167.     return(FALSE);
  168. }
  169.  
  170. issymbolic(dir, component)
  171.     register char    *dir, *component;
  172. {
  173. #ifdef S_IFLNK
  174.     struct stat    st;
  175.     char    buf[ BUFSIZ ], **pp;
  176.  
  177.     sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
  178.     for (pp=notdotdot; *pp; pp++)
  179.         if (strcmp(*pp, buf) == 0)
  180.             return (TRUE);
  181.     if (lstat(buf, &st) == 0
  182.     && (st.st_mode & S_IFMT) == S_IFLNK) {
  183.         *pp++ = copy(buf);
  184.         if (pp >= ¬dotdot[ MAXDIRS ])
  185.             fatal("out of .. dirs, increase MAXDIRS\n");
  186.         return(TRUE);
  187.     }
  188. #endif
  189.     return(FALSE);
  190. }
  191.  
  192. /*
  193.  * Add an include file to the list of those included by 'file'.
  194.  */
  195. struct inclist *newinclude(newfile, incstring)
  196.     register char    *newfile, *incstring;
  197. {
  198.     register struct inclist    *ip;
  199.  
  200.     /*
  201.      * First, put this file on the global list of include files.
  202.      */
  203.     ip = inclistp++;
  204.     if (inclistp == inclist + MAXFILES - 1)
  205.         fatal("out of space: increase MAXFILES\n");
  206.     ip->i_file = copy(newfile);
  207.     ip->i_included_sym = FALSE;
  208.     if (incstring == NULL)
  209.         ip->i_incstring = ip->i_file;
  210.     else
  211.         ip->i_incstring = copy(incstring);
  212.  
  213.     return(ip);
  214. }
  215.  
  216. included_by(ip, newfile)
  217.     register struct inclist    *ip, *newfile;
  218. {
  219.     register i;
  220.  
  221.     if (ip == NULL)
  222.         return;
  223.     /*
  224.      * Put this include file (newfile) on the list of files included
  225.      * by 'file'.  If 'file' is NULL, then it is not an include
  226.      * file itself (i.e. was probably mentioned on the command line).
  227.      * If it is already on the list, don't stick it on again.
  228.      */
  229.     if (ip->i_list == NULL)
  230.         ip->i_list = (struct inclist **)
  231.             malloc(sizeof(struct inclist *) * ++ip->i_listlen);
  232.     else {
  233.         for (i=0; i<ip->i_listlen; i++)
  234.             if (ip->i_list[ i ] == newfile) {
  235.                 i = strlen(newfile->i_file);
  236.                 if (!ip->i_included_sym &&
  237.                 !(i > 2 &&
  238.                   newfile->i_file[i-1] == 'c' &&
  239.                   newfile->i_file[i-2] == '.'))
  240.                 {
  241.                 /* only bitch if ip has */
  242.                 /* no #include SYMBOL lines  */
  243.                 /* and is not a .c file */
  244.                 warning("%s includes %s more than once!\n",
  245.                     ip->i_file, newfile->i_file);
  246.                 warning1("Already have\n");
  247.                 for (i=0; i<ip->i_listlen; i++)
  248.                     warning1("\t%s\n", ip->i_list[i]->i_file);
  249.                 }
  250.                 return;
  251.             }
  252.         ip->i_list = (struct inclist **) realloc(ip->i_list,
  253.             sizeof(struct inclist *) * ++ip->i_listlen);
  254.     }
  255.     ip->i_list[ ip->i_listlen-1 ] = newfile;
  256. }
  257.  
  258. inc_clean ()
  259. {
  260.     register struct inclist *ip;
  261.  
  262.     for (ip = inclist; ip < inclistp; ip++) {
  263.         ip->i_marked = FALSE;
  264.     }
  265. }
  266.