File indexing completed on 2024-04-28 12:23:23
0001 /* This file is part of KDevelop 0002 Copyright 2011 Mathieu Lornac <mathieu.lornac@gmail.com> 0003 Copyright 2011 Damien Coppel <damien.coppel@gmail.com> 0004 Copyright 2011 Lionel Duc <lionel.data@gmail.com> 0005 Copyright 2011 Lucas Sarie <lucas.sarie@gmail.com> 0006 Copyright 2016 Anton Anikin <anton@anikin.xyz> 0007 0008 This program is free software; you can redistribute it and/or 0009 modify it under the terms of the GNU General Public 0010 License as published by the Free Software Foundation; either 0011 version 2 of the License, or (at your option) any later version. 0012 0013 This program is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 General Public License for more details. 0017 0018 You should have received a copy of the GNU General Public License 0019 along with this program; see the file COPYING. If not, write to 0020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0021 Boston, MA 02110-1301, USA. 0022 */ 0023 0024 #include "cachegrind_parser.h" 0025 0026 #include "debug.h" 0027 #include "cachegrind_model.h" 0028 0029 #include <QBuffer> 0030 #include <QUrl> 0031 0032 namespace Valgrind 0033 { 0034 0035 CachegrindFunction* cachegrindParseCachegrindItem(const QString& line, QStringList& eventsList) 0036 { 0037 auto item = new CachegrindFunction; 0038 0039 QStringList lineEventList = line.split(QChar(' '), QString::SkipEmptyParts); 0040 Q_ASSERT(lineEventList.size() >= eventsList.size()); 0041 0042 for (int i = 0; i < eventsList.size(); ++i) { 0043 item->eventValues += lineEventList.takeFirst().remove(QLatin1Char(',')).toInt(); 0044 } 0045 0046 QString fileCall = lineEventList.join(QChar(' ')); 0047 int colonPosition = fileCall.indexOf(QChar(':')); 0048 if (colonPosition >= 0) { 0049 // file name 0050 auto fileUrl = QUrl::fromLocalFile(fileCall.mid(0, colonPosition)).adjusted(QUrl::NormalizePathSegments); 0051 item->fileNames += fileUrl.toLocalFile(); 0052 0053 // call name 0054 item->functionName = fileCall.mid(colonPosition + 1); 0055 } 0056 0057 return item; 0058 } 0059 0060 enum CachegrindParserState 0061 { 0062 ParseRoot, 0063 ParseProgramTotalHeader, 0064 ParseProgramTotal, 0065 ParseProgramHeader, 0066 ParseProgram 0067 }; 0068 0069 void cachegrindParse(QByteArray& baData, CachegrindFunctionsModel* model) 0070 { 0071 Q_ASSERT(model); 0072 0073 CachegrindParserState parserState = ParseRoot; 0074 QStringList eventsList; 0075 QString eventsString; 0076 QString line; 0077 0078 QBuffer data(&baData); 0079 data.open(QIODevice::ReadOnly); 0080 0081 while (!data.atEnd()) 0082 { 0083 // remove useless characters 0084 line = data.readLine().simplified(); 0085 0086 if (parserState == ParseRoot) { 0087 if (line.startsWith(QLatin1String("Events shown:"))) { 0088 // 13 is 'Events shown:' length 0089 eventsString = line.mid(13).simplified(); 0090 eventsList = eventsString.split(QChar(' '), QString::SkipEmptyParts); 0091 parserState = ParseProgramTotalHeader; 0092 } 0093 } 0094 0095 else if (parserState == ParseProgramTotalHeader) { 0096 if (line == eventsString) { 0097 parserState = ParseProgramTotal; 0098 } 0099 } 0100 0101 else if (parserState == ParseProgramHeader) { 0102 if (line.startsWith(eventsString)) { 0103 parserState = ParseProgram; 0104 } 0105 } 0106 0107 else if (!line.isEmpty() && line.at(0).isDigit()) { 0108 bool isTotal = (parserState == ParseProgramTotal); 0109 model->addItem(cachegrindParseCachegrindItem(line, eventsList), isTotal); 0110 if (isTotal) { 0111 parserState = ParseProgramHeader; 0112 } 0113 } 0114 } 0115 0116 model->setEventsList(eventsList); 0117 } 0118 0119 }