]> git.tdb.fi Git - builder.git/blob - source/sourcefile.cpp
Move file-to-target mapping to a separate class
[builder.git] / source / sourcefile.cpp
1 #include <msp/core/maputils.h>
2 #include <msp/fs/utils.h>
3 #include <msp/io/print.h>
4 #include <msp/strings/regex.h>
5 #include "builder.h"
6 #include "component.h"
7 #include "sourcefile.h"
8 #include "sourcepackage.h"
9
10 using namespace std;
11 using namespace Msp;
12
13 SourceFile::SourceFile(Builder &b, const FS::Path &p):
14         FileTarget(b, 0, p),
15         comp(0)
16 { }
17
18 SourceFile::SourceFile(Builder &b, const Component &c, const FS::Path &p):
19         FileTarget(b, &c.get_package(), p),
20         comp(&c)
21 { }
22
23 void SourceFile::find_depends()
24 {
25         if(!comp)
26         {
27                 deps_ready = true;
28                 return;
29         }
30
31         const SourcePackage &spkg = comp->get_package();
32         string relname = FS::relative(path, spkg.get_source()).str();
33         DependencyCache &deps_cache = spkg.get_deps_cache();
34         bool deps_found = false;
35         if(mtime<deps_cache.get_mtime())
36         {
37                 try
38                 {
39                         includes = deps_cache.get_deps(relname);
40                         deps_found = true;
41                 }
42                 catch(const key_error &)
43                 { }
44         }
45
46         if(!deps_found)
47         {
48                 try
49                 {
50                         IO::BufferedFile in(path.str());
51
52                         if(builder.get_verbose()>=4)
53                                 IO::print("Reading includes from %s\n", path.str());
54
55                         Regex r_include("^[ \t]*#include[ \t]+([\"<].*)[\">]");
56
57                         string line;
58                         while(in.getline(line))
59                                 if(RegMatch match = r_include.match(line))
60                                         includes.push_back(match[1].str);
61
62                         deps_cache.set_deps(relname, includes);
63                 }
64                 catch(const IO::file_not_found &)
65                 {
66                         if(builder.get_verbose()>=4)
67                                 IO::print("Failed to read includes from %s\n", path.str());
68                         deps_ready = true;
69                         return;
70                 }
71         }
72
73         const StringList &incpath = comp->get_build_info().incpath;
74
75         FS::Path dir = FS::dirname(path);
76         for(list<string>::iterator i=includes.begin(); i!=includes.end(); ++i)
77         {
78                 Target *hdr = builder.get_vfs().find_header(*i, dir, incpath);
79                 if(hdr)
80                         add_depend(hdr);
81         }
82
83         deps_ready = true;
84 }