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