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