Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/forks/pch_analyser/src/orxonox/Analyser.cc @ 7815

Last change on this file since 7815 was 7815, checked in by rgrieder, 13 years ago

Added code for the PCH Analyser (but impossible to use without a manual, which doesn't exist ).

File size: 8.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
24 *      Reto Grieder
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30/**
31@file
32@brief
33*/
34
35#include "Analyser.h"
36
37#include <fstream>
38#include <list>
39#include <map>
40#include <set>
41#include <QFileInfo>
42
43#include "core/PathConfig.h"
44
45namespace orxonox
46{
47    void lowercase(std::string* str)
48    {
49        for (size_t i = 0; i < str->size(); ++i)
50        {
51            (*str)[i] = (char)tolower((*str)[i]);
52        }
53    }
54
55    void parse()
56    {
57        std::string name = "tracker";
58        std::ifstream file;
59        file.open((PathConfig::getDataPathString() + name + "_includes_pch.txt").c_str());
60
61        std::map<std::string, std::set<std::string> > triggeredFiles;
62        std::map<std::string, std::pair<size_t, size_t> > totalTimesIncluded;
63        std::set<std::string> locallyIncluded;
64        std::vector<std::string> includeStack;
65        std::set<std::string> pchFiles;
66        bool inPCH = false;
67
68        while (file.good())
69        {
70            std::string line;
71            std::getline(file, line);
72            if (line.size() >= 8 && line.substr(2, 6) == "Note: ")
73            {
74                // Count white spaces
75                size_t indentation = 24;
76                while (line[indentation] == ' ')
77                    ++indentation;
78                size_t stackLevel = indentation - 24;
79                QFileInfo info(QString::fromStdString(line.substr(indentation)));
80                std::string filePath = info.canonicalFilePath().toStdString();
81                lowercase(&filePath);
82                if (inPCH)
83                {
84                    pchFiles.insert(filePath);
85                }
86                else
87                {
88                    if (pchFiles.find(filePath) == pchFiles.end())
89                    {
90                        while (stackLevel + 1 <= includeStack.size())
91                            includeStack.pop_back();
92
93                        triggeredFiles[filePath].insert(filePath);
94
95                        std::set<std::string>& set = triggeredFiles[filePath];
96                        for (std::set<std::string>::iterator it = set.begin();
97                            it != set.end(); ++it)
98                        {
99                            for (size_t i = 0; i < includeStack.size(); ++i)
100                                triggeredFiles[includeStack[i]].insert(*it);
101                        }
102
103                        includeStack.push_back(filePath);
104                        locallyIncluded.insert(filePath);
105                    }
106                }
107            }
108            else if (line.find("PrecompiledHeaders") != std::string::npos)
109            {
110                // Included in PCH file
111                inPCH = true;
112            }
113            else
114            {
115                // New file
116                inPCH = false;
117                for (std::set<std::string>::const_iterator it = locallyIncluded.begin();
118                    it != locallyIncluded.end(); ++it)
119                {
120                    std::map<std::string, std::pair<size_t, size_t> >::iterator mapIt = totalTimesIncluded.find(*it);
121                    if (mapIt != totalTimesIncluded.end())
122                        mapIt->second.first += 1;
123                    else
124                        totalTimesIncluded[*it].first = 1;
125                }
126
127                includeStack.clear();
128                locallyIncluded.clear();
129            }
130        }
131
132        // Get all file sizes
133        for (std::map<std::string, std::pair<size_t, size_t> >::iterator it = totalTimesIncluded.begin();
134            it != totalTimesIncluded.end(); ++it)
135        {
136            QFileInfo info(QString::fromStdString(it->first));
137            it->second.second = static_cast<size_t>(info.size());
138        }
139
140        struct IncludeFile
141        {
142            std::string filename;
143            size_t timesIncluded;
144            size_t fileSize;
145            size_t bytesIncluded;
146            size_t totalBytesIncluded;
147        };
148        std::list<IncludeFile> allFiles;
149
150        for (std::map<std::string, std::pair<size_t, size_t> >::const_iterator it = totalTimesIncluded.begin();
151            it != totalTimesIncluded.end(); ++it)
152        {
153            size_t totalFileSize = 0;
154            assert(triggeredFiles.find(it->first) != triggeredFiles.end());
155            std::set<std::string>& fileSet = triggeredFiles[it->first];
156            //if (it->first.find("scenemanager") != std::string::npos)
157            //    int a = 8;
158            for (std::set<std::string>::const_iterator setIt = fileSet.begin(); setIt != fileSet.end(); ++setIt)
159            {
160                totalFileSize += totalTimesIncluded[*setIt].second;
161            }
162
163            // Insert
164            IncludeFile file = { it->first, it->second.first, it->second.second, totalFileSize, totalFileSize * it->second.first };
165            if (allFiles.empty())
166            {
167                allFiles.insert(allFiles.end(), file);
168            }
169            else
170            {
171                bool inserted = false;
172                for (std::list<IncludeFile>::iterator listIt = allFiles.begin(); listIt != allFiles.end(); ++listIt)
173                {
174                    if (file.timesIncluded > listIt->timesIncluded || file.timesIncluded == listIt->timesIncluded && file.totalBytesIncluded >= listIt->totalBytesIncluded)
175                    {
176                        allFiles.insert(listIt, file);
177                        inserted = true;
178                        break;
179                    }
180                }
181                if (!inserted)
182                    allFiles.push_back(file);
183            }
184        }
185
186        // Clean list
187        //for (std::list<IncludeFile>::iterator listIt = allFiles.begin(); listIt != allFiles.end(); ++listIt)
188        //{
189        //    bool isCore = (listIt->filename.find("src/core/") != std::string::npos);
190        //    for (std::list<IncludeFile>::const_iterator listIt2 = allFiles.begin(); listIt2 != listIt; ++listIt2)
191        //    {
192        //        std::set<std::string>& fileSet = triggeredFiles[listIt2->filename];
193        //        std::set<std::string>::const_iterator setIt = fileSet.find(listIt->filename);
194        //        if (setIt != fileSet.end())// && listIt->timesIncluded < listIt2->timesIncluded)
195        //        {
196        //            if (isCore || listIt2->filename.find("src/core/") == std::string::npos)
197        //            {
198        //                // File already gets included by a 'worse' one --> remove
199        //                listIt = allFiles.erase(listIt);
200        //                --listIt;
201        //                break;
202        //            }
203        //        }
204        //    }
205        //}
206
207        // Write results
208        std::ofstream outFile;
209        outFile.open((PathConfig::getDataPathString() + name + "_results_pch.txt").c_str());
210        for (std::list<IncludeFile>::const_iterator listIt = allFiles.begin(); listIt != allFiles.end(); ++listIt)
211        {
212            outFile.width(10);
213            outFile << listIt->totalBytesIncluded;
214            outFile.width(10);
215            outFile << listIt->bytesIncluded;
216            outFile.width(5);
217            outFile << listIt->timesIncluded;
218            outFile << "  " << listIt->filename;
219            outFile << listIt->filename;
220            outFile << std::endl;
221        }
222    }
223}
Note: See TracBrowser for help on using the repository browser.