]> git.tdb.fi Git - builder.git/blob - source/installmap.cpp
Replace basic for loops with range-based loops or algorithms
[builder.git] / source / installmap.cpp
1 #include <msp/core/algorithm.h>
2 #include <msp/fs/utils.h>
3 #include "component.h"
4 #include "filetarget.h"
5 #include "installmap.h"
6 #include "sourcepackage.h"
7 #include "templatefile.h"
8
9 using namespace std;
10 using namespace Msp;
11
12 void InstallMap::add_mapping(const FS::Path &src, const FS::Path &inst)
13 {
14         Entry e;
15         e.source = src;
16         e.install = inst;
17         entries.push_back(e);
18 }
19
20 FS::Path InstallMap::get_install_location(const FileTarget &target) const
21 {
22         const Component *comp = target.get_component();
23         unsigned overlay_depth = 0;
24         if(comp && !comp->get_overlays().empty())
25         {
26                 // Check if the target resides in an overlay directory
27                 string last_dir = FS::basename(FS::dirname(target.get_path()));
28                 if(any_equals(comp->get_overlays(), last_dir))
29                         overlay_depth = 1;
30         }
31
32         FS::Path source = target.get_path();
33         if(comp)
34         {
35                 /* Check if the target is a generated source file, residing in the
36                 temporary directory */
37                 const SourcePackage &pkg = comp->get_package();
38                 int temp_depth = FS::descendant_depth(source, pkg.get_temp_directory());
39                 if(temp_depth>0)
40                 {
41                         // If it is, use the generating template's directory instead
42                         for(Target *d: target.get_dependencies())
43                                 if(const TemplateFile *tmpl = dynamic_cast<const TemplateFile *>(d))
44                                 {
45                                         source = FS::dirname(tmpl->get_path())/FS::basename(source);
46                                         break;
47                                 }
48                 }
49         }
50
51         /* Look for a mapping entry matching both the target's original location
52         and default install location */
53         FS::Path install = target.get_install_location();
54         for(const Entry &e: entries)
55         {
56                 int source_depth = FS::descendant_depth(source, e.source);
57                 if(source_depth>=0)
58                 {
59                         FS::Path install_base = FS::common_ancestor(install, e.install);
60                         if(install_base.size()>1)
61                         {
62                                 install = e.install/source.subpath(e.source.size(), source_depth-1-overlay_depth);
63                                 break;
64                         }
65                 }
66         }
67
68         return install;
69 }
70
71
72 InstallMap::Loader::Loader(InstallMap &m, const FS::Path &s):
73         DataFile::ObjectLoader<InstallMap>(m),
74         source_base(s)
75 {
76         add("map", &Loader::map);
77 }
78
79 void InstallMap::Loader::map(const string &src, const string &inst)
80 {
81         obj.add_mapping(source_base/src, inst);
82 }