+#include <msp/core/maputils.h>
+#include <msp/fs/utils.h>
+#include <msp/io/print.h>
+#include <msp/strings/regex.h>
+#include "builder.h"
+#include "component.h"
+#include "csourcefile.h"
+#include "sourcepackage.h"
+
+using namespace std;
+using namespace Msp;
+
+CSourceFile::CSourceFile(Builder &b, const FS::Path &p):
+ SourceFile(b, 0, p)
+{ }
+
+CSourceFile::CSourceFile(Builder &b, const Component &c, const FS::Path &p):
+ SourceFile(b, &c, p)
+{
+ string ext = FS::extpart(FS::basename(path));
+ if(ext==".h" || ext==".H" || ext==".hpp")
+ install_location = "include/"+comp->get_name();
+}
+
+void CSourceFile::find_depends()
+{
+ if(!comp)
+ {
+ deps_ready = true;
+ return;
+ }
+
+ const SourcePackage &spkg = comp->get_package();
+ string relname = FS::relative(path, spkg.get_source()).str();
+ DependencyCache &deps_cache = spkg.get_deps_cache();
+ bool deps_found = false;
+ if(mtime<deps_cache.get_mtime())
+ {
+ try
+ {
+ includes = deps_cache.get_deps(relname);
+ deps_found = true;
+ }
+ catch(const key_error &)
+ { }
+ }
+
+ if(!deps_found)
+ {
+ try
+ {
+ IO::BufferedFile in(path.str());
+
+ if(builder.get_verbose()>=4)
+ IO::print("Reading includes from %s\n", path.str());
+
+ Regex r_include("^[ \t]*#include[ \t]+([\"<].*)[\">]");
+
+ string line;
+ while(in.getline(line))
+ if(RegMatch match = r_include.match(line))
+ includes.push_back(match[1].str);
+
+ deps_cache.set_deps(relname, includes);
+ }
+ catch(const IO::file_not_found &)
+ {
+ if(builder.get_verbose()>=4)
+ IO::print("Failed to read includes from %s\n", path.str());
+ deps_ready = true;
+ return;
+ }
+ }
+
+ const StringList &incpath = comp->get_build_info().incpath;
+
+ FS::Path dir = FS::dirname(path);
+ for(list<string>::iterator i=includes.begin(); i!=includes.end(); ++i)
+ {
+ Target *hdr = builder.get_vfs().find_header(*i, dir, incpath);
+ if(hdr)
+ add_depend(hdr);
+ }
+
+ deps_ready = true;
+}