00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "def.h"
00031
00032 #ifdef __SUNPRO_C
00033 extern int lstat();
00034 #endif
00035
00036 extern struct inclist inclist[ MAXFILES ],
00037 *inclistp;
00038 extern char *includedirs[ ];
00039 extern char *notdotdot[ ];
00040 extern boolean show_where_not;
00041 extern boolean warn_multiple;
00042
00043
00044 boolean
00045 isdot(p)
00046 register char *p;
00047 {
00048 if (p && *p++ == '.' && *p++ == '\0')
00049 return(TRUE);
00050 return(FALSE);
00051 }
00052
00053 boolean
00054 isdotdot(p)
00055 register char *p;
00056 {
00057 if (p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
00058 return(TRUE);
00059 return(FALSE);
00060 }
00061
00062 boolean
00063 issymbolic(dir, component)
00064 register char *dir, *component;
00065 {
00066 #ifdef S_IFLNK
00067 struct stat st;
00068 char buf[ BUFSIZ ], **pp;
00069
00070 sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
00071 for (pp = notdotdot; *pp; pp++)
00072 if (strcmp(*pp, buf) == 0)
00073 return (TRUE);
00074 if (lstat(buf, &st) == 0
00075 && (st.st_mode & S_IFMT) == S_IFLNK) {
00076 *pp++ = copy(buf);
00077 if (pp >= ¬dotdot[ MAXDIRS ])
00078 fatalerr("out of .. dirs, increase MAXDIRS\n");
00079 return(TRUE);
00080 }
00081 #else
00082 if (dir && component) { }
00083 #endif
00084 return(FALSE);
00085 }
00086
00087
00088
00089
00090
00091
00092 void
00093 remove_dotdot(path)
00094 char *path;
00095 {
00096 register char *end, *from, *to, **cp;
00097 char *components[ MAXFILES ],
00098 newpath[ BUFSIZ ];
00099 boolean component_copied;
00100
00101
00102
00103
00104 to = newpath;
00105 if (*path == '/')
00106 *to++ = '/';
00107 *to = '\0';
00108 cp = components;
00109 for (from = end = path; *end; end++)
00110 if (*end == '/') {
00111 while (*end == '/')
00112 *end++ = '\0';
00113 if (*from)
00114 *cp++ = from;
00115 from = end;
00116 }
00117 *cp++ = from;
00118 *cp = NULL;
00119
00120
00121
00122
00123 cp = components;
00124 while (*cp) {
00125 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp + 1))
00126 && !issymbolic(newpath, *cp)) {
00127 char **fp = cp + 2;
00128 char **tp = cp;
00129
00130 do
00131 *tp++ = *fp;
00132 while (*fp++);
00133 if (cp != components)
00134 cp--;
00135 } else {
00136 cp++;
00137 }
00138 }
00139
00140
00141
00142 cp = components;
00143 component_copied = FALSE;
00144 while (*cp) {
00145 if (component_copied)
00146 *to++ = '/';
00147 component_copied = TRUE;
00148 for (from = *cp; *from;)
00149 *to++ = *from++;
00150 *to = '\0';
00151 cp++;
00152 }
00153 *to++ = '\0';
00154
00155
00156
00157
00158 strcpy(path, newpath);
00159 }
00160
00161
00162
00163
00164 struct inclist *newinclude(newfile, incstring)
00165 register char *newfile, *incstring;
00166 {
00167 register struct inclist *ip;
00168
00169
00170
00171
00172 ip = inclistp++;
00173 if (inclistp == inclist + MAXFILES - 1)
00174 fatalerr("out of space: increase MAXFILES\n");
00175 ip->i_file = copy(newfile);
00176
00177 if (incstring == NULL)
00178 ip->i_incstring = ip->i_file;
00179 else
00180 ip->i_incstring = copy(incstring);
00181
00182 return(ip);
00183 }
00184
00185 void
00186 included_by(ip, newfile)
00187 register struct inclist *ip, *newfile;
00188 {
00189 register int i;
00190
00191 if (ip == NULL)
00192 return;
00193
00194
00195
00196
00197
00198
00199 if (ip->i_list == NULL) {
00200 ip->i_list = (struct inclist **)
00201 malloc(sizeof(struct inclist *) * ++ip->i_listlen);
00202 ip->i_merged = (boolean *)
00203 malloc(sizeof(boolean) * ip->i_listlen);
00204 } else {
00205 for (i = 0; i < ip->i_listlen; i++)
00206 if (ip->i_list[ i ] == newfile) {
00207 i = strlen(newfile->i_file);
00208 if (!(ip->i_flags & INCLUDED_SYM) &&
00209 !(i > 2 &&
00210 newfile->i_file[i-1] == 'c' &&
00211 newfile->i_file[i-2] == '.')) {
00212
00213
00214
00215 if (warn_multiple) {
00216 warning("%s includes %s more than once!\n",
00217 ip->i_file, newfile->i_file);
00218 warning1("Already have\n");
00219 for (i = 0; i < ip->i_listlen; i++)
00220 warning1("\t%s\n", ip->i_list[i]->i_file);
00221 }
00222 }
00223 return;
00224 }
00225 ip->i_list = (struct inclist **) realloc(ip->i_list,
00226 sizeof(struct inclist *) * ++ip->i_listlen);
00227 ip->i_merged = (boolean *)
00228 realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen);
00229 }
00230 ip->i_list[ ip->i_listlen-1 ] = newfile;
00231 ip->i_merged[ ip->i_listlen-1 ] = FALSE;
00232 }
00233
00234 void
00235 inc_clean()
00236 {
00237 register struct inclist *ip;
00238
00239 for (ip = inclist; ip < inclistp; ip++) {
00240 ip->i_flags &= ~MARKED;
00241 ip->i_flags &= ~SEARCHED;
00242 undefine_all(ip);
00243 }
00244 }
00245
00246 struct inclist *inc_path(char *file, char *include, boolean dot) {
00247 static char path[ BUFSIZ ];
00248 register char **pp, *p;
00249 register struct inclist *ip;
00250 struct stat st;
00251 boolean found = FALSE;
00252
00253
00254
00255
00256
00257 for (ip = inclist; ip->i_file; ip++)
00258 if ((strcmp(ip->i_incstring, include) == 0) &&
00259 !(ip->i_flags & INCLUDED_SYM)) {
00260 found = TRUE;
00261 break;
00262 }
00263
00264
00265
00266
00267
00268 if (!found && (dot || *include == '/')) {
00269 #ifdef _WIN32
00270 if (stat(include, &st) == 0 && (st.st_mode & S_IFREG)) {
00271 #else
00272 if (stat(include, &st) == 0 && S_ISREG(st.st_mode)) {
00273 #endif
00274 ip = newinclude(include, include);
00275 found = TRUE;
00276 } else if (show_where_not)
00277 warning1("\tnot in %s\n", include);
00278 }
00279
00280
00281
00282
00283
00284 if (!found && dot) {
00285 for (p = file + strlen(file); p > file; p--)
00286 if (*p == '/')
00287 break;
00288 if (p == file) {
00289 strncpy(path, include, sizeof(path) - 1);
00290 path[sizeof(path)-1] = '\0';
00291 } else {
00292 strncpy(path, file, (p - file) + 1);
00293 path[(p-file) + 1] = '\0';
00294 strncpy(path + (p - file) + 1, include, sizeof(path) - (p - file + 1));
00295 }
00296 remove_dotdot(path);
00297 #ifdef _WIN32
00298 if (stat(path, &st) == 0 && (st.st_mode & S_IFREG)) {
00299 #else
00300 if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
00301 #endif
00302 ip = newinclude(path, include);
00303 found = TRUE;
00304 } else if (show_where_not)
00305 warning1("\tnot in %s\n", path);
00306 }
00307
00308
00309
00310
00311
00312 if (!found)
00313 for (pp = includedirs; *pp; pp++) {
00314 if (strlen(*pp) + strlen(include) + 2 > sizeof(path)) {
00315 warning1("\t%s/%s too long\n", *pp, include);
00316 continue;
00317 }
00318 sprintf(path, "%s/%s", *pp, include);
00319 remove_dotdot(path);
00320 #ifdef _WIN32
00321 if (stat(path, &st) == 0 && (st.st_mode & S_IFREG)) {
00322 #else
00323 if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
00324 #endif
00325 ip = newinclude(path, include);
00326 found = TRUE;
00327 break;
00328 } else if (show_where_not)
00329 warning1("\tnot in %s\n", path);
00330 }
00331
00332 if (!found)
00333 ip = NULL;
00334 return(ip);
00335 }