]> git.tdb.fi Git - builder.git/blob - source/analyzer.cpp
Reorder class members
[builder.git] / source / analyzer.cpp
1 /* $Id$
2
3 This file is part of builder
4 Copyright © 2006-2009  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <iomanip>
9 #include <iostream>
10 #include <sstream>
11 #include <msp/fs/utils.h>
12 #include "analyzer.h"
13 #include "builder.h"
14 #include "install.h"
15 #include "objectfile.h"
16 #include "package.h"
17 #include "target.h"
18
19 using namespace std;
20 using namespace Msp;
21
22 Analyzer::Analyzer(Builder &b):
23         builder(b),
24         mode(DEPS),
25         max_depth(0),
26         full_paths(false)
27 { }
28
29 void Analyzer::analyze()
30 {
31         TableRow row;
32         row.push_back("Name");
33         row.push_back("Package");
34         row.push_back("Type");
35         row.push_back("Rebuild");
36         table.push_back(row);
37         
38         build_depend_table(*builder.get_target("cmdline"), 0);
39
40         print_table();
41 }
42
43 void Analyzer::build_depend_table(Target &tgt, unsigned depth)
44 {
45         if(mode!=REBUILD && mode!=ALLDEPS)
46         {
47                 // Skip trivial targets
48                 if(dynamic_cast<ObjectFile *>(&tgt))
49                         return build_depend_table(*tgt.get_depends().front(), depth);
50                 else if(dynamic_cast<Install *>(&tgt))
51                         return build_depend_table(*tgt.get_depends().front(), depth);
52         }
53         else if(mode==REBUILD && !tgt.get_rebuild())
54                 /* All targets that depend on to-be-built targets will be rebuilt
55                 themselves, so we cn stop here. */
56                 return;
57         
58         TableRow row;
59
60         string fn;
61         if(full_paths)
62                 fn=tgt.get_name();
63         else
64                 fn=FS::basename(tgt.get_name());
65         row.push_back(string(depth*2, ' ')+fn);
66
67         const Package *pkg=tgt.get_package();
68         if(pkg)
69                 row.push_back(pkg->get_name());
70         else
71                 row.push_back("");
72         
73         row.push_back(tgt.get_type());
74         
75         if(tgt.get_rebuild())
76         {
77                 if(tgt.get_rebuild_reason().empty())
78                         row.push_back("Yes (no reason)");
79                 else
80                         row.push_back(tgt.get_rebuild_reason());
81         }
82
83         table.push_back(row);
84
85         if(!max_depth || depth<max_depth-1)
86         {
87                 const TargetList &depends=tgt.get_depends();
88                 //XXX If we want to sort the targets, we need to take the value of full_paths into account
89                 //depends.sort(target_order);
90                 for(TargetList::const_iterator i=depends.begin(); i!=depends.end(); ++i)
91                         build_depend_table(**i, depth+1);
92         }
93 }
94
95 void Analyzer::print_table() const
96 {
97         vector<unsigned> col_width;
98
99         // Determine column widths
100         for(Table::const_iterator i=table.begin(); i!=table.end(); ++i)
101         {
102                 if(col_width.size()<i->size())
103                         col_width.resize(i->size(), 0);
104                 for(unsigned j=0; j<i->size(); ++j)
105                         col_width[j]=max(col_width[j], (*i)[j].size());
106         }
107
108         for(Table::const_iterator i=table.begin(); i!=table.end(); ++i)
109         {
110                 ostringstream ss;
111                 ss<<left;
112                 for(unsigned j=0; j<i->size(); ++j)
113                 {
114                         if(j>0)
115                                 ss<<"  ";
116                         ss<<setw(col_width[j])<<(*i)[j];
117                 }
118                 cout<<ss.str()<<'\n';
119         }
120 }
121
122 bool Analyzer::target_order(Target *t1, Target *t2)
123 { return t1->get_name()<t2->get_name(); }