File indexing completed on 2024-05-05 08:44:17
0001 /* 0002 * This file is part of KDevelop Krazy2 Plugin. 0003 * 0004 * Copyright 2012 Daniel Calviño Sánchez <danxuliu@gmail.com> 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU General Public License 0008 * as published by the Free Software Foundation; either version 2 0009 * of the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 */ 0019 0020 #ifndef ANALYSISPROGRESSPARSER_H 0021 #define ANALYSISPROGRESSPARSER_H 0022 0023 #include <QHash> 0024 0025 #include <interfaces/istatus.h> 0026 0027 /** 0028 * Shows progress information about krazy2 execution. 0029 * krazy2 shows a line with the progress of each test. Each test progress is 0030 * shown using dots after the test information. A new dot is printed for each 0031 * group of 10 files checked (even if tests are skipped on those files), but 0032 * there is no (easy) way to know how many files will be checked before krazy2 0033 * starts. However, the same files are checked for all the tests of the same 0034 * filetype. When the test ends, "done" is printed. 0035 * 0036 * Example for "foo" file type and "bar" checker program on 100 files: 0037 * =>foo/bar test in-progress..........done 0038 * 0039 * The progress is updated proportionally to how many checker programs are going 0040 * to be run and how many checker programs have been already run. Also, after 0041 * the first checker program for a filetype is run, the progress will be updated 0042 * also taking into account each checker program individual progress. The 0043 * progress will never reach the 100% before krazy2 finishes; that is, the 0044 * progress shown when the last checker is run is 99%, even if mathematically it 0045 * should be 100%. 0046 * 0047 * Also, the status message will specify which checker is being run. 0048 * 0049 * If, for any reason, there are more checkers parsed than the number set, each 0050 * time a new checker name is parsed the number of checkers is increased by one. 0051 * If the number of dots that will be outputted for that checker is known 0052 * (because its file type is already known), this will cause the progress to go 0053 * back from 99% (from the last checker run) to a smaller value which will 0054 * increase with each dot up to 99% when that unexpected checker is done. 0055 * 0056 * Note that, before starting the analysis itself, krazy2 performs a run over 0057 * all the files to be analyzed to filter out those that will not be checked 0058 * (because the file can not be accessed, or because the file type is not 0059 * supported). When a file is filtered out, krazy2 prints a message explaining 0060 * why. Those messages are parsed and discarded by the AnalysisProgressParser. 0061 * 0062 * The AnalysisProgressParser can be used to parse the progress of several 0063 * krazy2 executions in one single batch. That is, if two executions are parsed 0064 * one after the other, and the first execution runs seven checkers and the 0065 * second executions runs three checkers, the progress reported at the end of 0066 * the first execution will be 70%, and the progress reported at the end of the 0067 * second execution will be 99%. start() must be called before the first krazy2 0068 * execution, and end() must be called after the last krazy2 execution, like 0069 * done with a single execution. The only difference with several executions is 0070 * that, whenever the analyzed files change between executions, 0071 * resetNumberOfFilesForEachFileType() must be called, as the number of files 0072 * analyzed by the checkers of each file type may have changed. 0073 */ 0074 class AnalysisProgressParser: public QObject, public KDevelop::IStatus { 0075 Q_OBJECT 0076 Q_INTERFACES(KDevelop::IStatus) 0077 public: 0078 0079 /** 0080 * Creates a new AnalysisProgressParser. 0081 * 0082 * @param parent The parent QObject. 0083 */ 0084 explicit AnalysisProgressParser(QObject* parent = nullptr); 0085 0086 //<KDevelop::IStatus> 0087 0088 /** 0089 * The name of this status update. 0090 * 0091 * @return "Running krazy2" 0092 */ 0093 QString statusName() const override; 0094 0095 Q_SIGNALS: 0096 0097 void clearMessage(KDevelop::IStatus* status) override; 0098 void showMessage(KDevelop::IStatus* status, const QString & message, int timeout = 0) override; 0099 void showErrorMessage(const QString & message, int timeout = 0) override; 0100 void hideProgress(KDevelop::IStatus* status) override; 0101 void showProgress(KDevelop::IStatus* status, int minimum, int maximum, int value) override; 0102 0103 //</KDevelop::IStatus> 0104 0105 public: 0106 0107 /** 0108 * Sets the number of checkers that will be run. 0109 * 0110 * @param numberOfCheckers The number of checkers that will be run. 0111 */ 0112 void setNumberOfCheckers(int numberOfCheckers); 0113 0114 /** 0115 * Resets the number of files assumed for each file type. 0116 * If this AnalysisProgressParser is used to parse the progress of several 0117 * krazy2 executions in a single batch, this method must be called whenever 0118 * the analyzed files change between executions. 0119 */ 0120 void resetNumberOfFilesForEachFileType(); 0121 0122 public Q_SLOTS: 0123 0124 /** 0125 * Reports that krazy2 has been started. 0126 * No message will be given. 0127 */ 0128 void start(); 0129 0130 /** 0131 * Parses the next progress data outputted by krazy2 process. 0132 * 0133 * @param data The next progress data to parse. 0134 */ 0135 void parse(const QByteArray& data); 0136 0137 /** 0138 * Reports that krazy2 has finished, no matter why. 0139 * Shows a 100% progress before hidding it. 0140 */ 0141 void finish(); 0142 0143 private: 0144 0145 /** 0146 * Buffered data from previous outputs not parsed yet. 0147 */ 0148 QString m_buffer; 0149 0150 /** 0151 * The number of checkers that will be run. 0152 */ 0153 int m_numberOfCheckers; 0154 0155 /** 0156 * The number of checkers that have been already run. 0157 */ 0158 int m_numberOfCheckersRun; 0159 0160 /** 0161 * Maps a file type with the number of dots outputted when checking them. 0162 */ 0163 QHash<QString, int> m_fileTypeToNumberOfDots; 0164 0165 /** 0166 * The file type of the checker being run, 0167 */ 0168 QString m_currentFileType; 0169 0170 /** 0171 * The number of dots already outputted by the checker being run. 0172 */ 0173 int m_currentNumberOfDots; 0174 0175 /** 0176 * Discards the "Cannot access file" and "Unsupported file type" messages. 0177 */ 0178 void discardFilteredOutFileMessages(); 0179 0180 /** 0181 * Discards a single "Cannot access file" message. 0182 */ 0183 bool discardCannotAccessFileMessage(); 0184 0185 /** 0186 * Discards a single "Unsupported file type" message. 0187 */ 0188 bool discardUnsupportedFileTypeMessage(); 0189 0190 /** 0191 * Parses the "=>fileType" chunk. 0192 * 0193 * @return True if the data in the buffer matched, false otherwise. 0194 */ 0195 bool parseFileType(); 0196 0197 /** 0198 * Parses the "/checkerName test in-progress" chunk. 0199 * A message is shown with the file type and name of the checker being run. 0200 * 0201 * @return True if the data in the buffer matched, false otherwise. 0202 */ 0203 bool parseCheckerName(); 0204 0205 /** 0206 * Parses the dots. 0207 * If it is known how many dots will be outputted for the current file type, 0208 * the progress is updated with the progress of the current checker program. 0209 * It is proportional to how many dots are going to be outputted and how 0210 * many dots have been already outputted. 0211 * 0212 * @return True if the data in the buffer matched, false otherwise. 0213 */ 0214 bool parseDots(); 0215 0216 /** 0217 * Parses the "done\n" chunk. 0218 * The progress is updated proportionally to how many checker programs are 0219 * going to be run and how many checker programs have been already run, 0220 * although it is limited to 99% at most, never 100%. 0221 * 0222 * @return True if the data in the buffer matched, false otherwise. 0223 */ 0224 bool parseDone(); 0225 0226 }; 0227 0228 #endif