void ScanFile(FileInfo fi) { string path = CanonicalPath(fi); Data.SourceFile sf = null; if (_project.Files.ContainsKey(path) && _project.LastScan > fi.LastWriteTime) { sf = _project.Files[path]; } else { Parser.Result res = Parser.ParseFile(fi, Errors); sf = new Data.SourceFile(); sf.Lines = res.Lines; sf.LocalIncludes = res.LocalIncludes; sf.SystemIncludes = res.SystemIncludes; _project.Files[path] = sf; } sf.Touched = true; sf.AbsoluteIncludes.Clear(); string local_dir = Path.GetDirectoryName(path); foreach (string s in sf.LocalIncludes) { try { FileInfo inc = new FileInfo(Path.Combine(local_dir, s)); string abs = CanonicalPath(inc); if (!inc.Exists) { if (!sf.SystemIncludes.Contains(s)) { sf.SystemIncludes.Add(s); } continue; } sf.AbsoluteIncludes.Add(abs); Enqueue(inc, abs); } catch (Exception e) { Errors.Add(String.Format("Exception: \"{0}\" for #include \"{1}\"", e.Message, s)); } } foreach (string s in sf.SystemIncludes) { try { if (_system_includes.ContainsKey(s)) { string abs = _system_includes[s]; sf.AbsoluteIncludes.Add(abs); } else { FileInfo found = null; foreach (string dir in _project.IncludeDirectories) { found = new FileInfo(Path.Combine(dir, s)); if (found.Exists) { break; } found = null; } if (found != null) { string abs = CanonicalPath(found); sf.AbsoluteIncludes.Add(abs); _system_includes[s] = abs; Enqueue(found, abs); } else { NotFound.Add(s); } } } catch (Exception e) { Errors.Add(String.Format("Exception: \"{0}\" for #include <{1}>", e.Message, s)); } } }
void ScanFile(FileInfo fi) { string path = CanonicalPath(fi); Data.SourceFile sf = null; if (_project.Files.ContainsKey(path) && _project.LastScan > fi.LastWriteTime && !_scanning_pch) { sf = _project.Files[path]; } else { Parser.Result res = Parser.ParseFile(fi, Errors); sf = new Data.SourceFile(); sf.Lines = res.Lines; sf.LocalIncludes = res.LocalIncludes; sf.SystemIncludes = res.SystemIncludes; sf.Precompiled = _scanning_pch; _project.Files[path] = sf; } sf.Touched = true; sf.AbsoluteIncludes.Clear(); string local_dir = Path.GetDirectoryName(path); foreach (string s in sf.LocalIncludes) { try { FileInfo inc = new FileInfo(Path.Combine(local_dir, s)); string abs = CanonicalPath(inc); // found a header that's part of PCH during regular scan: ignore it if (!_scanning_pch && _project.Files.ContainsKey(abs) && _project.Files[abs].Precompiled) { _project.Files[abs].Touched = true; continue; } if (!inc.Exists) { if (!sf.SystemIncludes.Contains(s)) { sf.SystemIncludes.Add(s); } continue; } sf.AbsoluteIncludes.Add(abs); Enqueue(inc, abs); } catch (Exception e) { Errors.Add(String.Format("Exception: \"{0}\" for #include \"{1}\"", e.Message, s)); } } foreach (string s in sf.SystemIncludes) { try { if (_system_includes.ContainsKey(s)) { string abs = _system_includes[s]; // found a header that's part of PCH during regular scan: ignore it if (!_scanning_pch && _project.Files.ContainsKey(abs) && _project.Files[abs].Precompiled) { _project.Files[abs].Touched = true; continue; } sf.AbsoluteIncludes.Add(abs); } else { FileInfo found = null; foreach (string dir in _project.IncludeDirectories) { found = new FileInfo(Path.Combine(dir, s)); if (found.Exists) { break; } found = null; } if (found != null) { string abs = CanonicalPath(found); // found a header that's part of PCH during regular scan: ignore it if (!_scanning_pch && _project.Files.ContainsKey(abs) && _project.Files[abs].Precompiled) { _project.Files[abs].Touched = true; continue; } sf.AbsoluteIncludes.Add(abs); _system_includes[s] = abs; Enqueue(found, abs); } else { if (NotFound.Add(s)) { NotFoundOrigins.Add(s, path); } } } } catch (Exception e) { Errors.Add(String.Format("Exception: \"{0}\" for #include <{1}>", e.Message, s)); } } // Only treat each include as done once. Since we completely ignore preprocessor, for patterns like // this we'd end up having same file in includes list multiple times. Let's assume that all includes use // pragma once or include guards and are only actually parsed just once. // #if FOO // #include <bar> // #else // #include <bar> // #endif sf.AbsoluteIncludes = sf.AbsoluteIncludes.Distinct().ToList(); }