|
Cppcheck
|
00001 /* 00002 * Cppcheck - A tool for static C/C++ code analysis 00003 * Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team. 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <QObject> 00020 #include <QString> 00021 #include <QXmlStreamReader> 00022 #include <QXmlStreamWriter> 00023 #include <QFile> 00024 #include <QDir> 00025 #include "projectfile.h" 00026 00027 static const char ProjectElementName[] = "project"; 00028 static const char ProjectVersionAttrib[] = "version"; 00029 static const char ProjectFileVersion[] = "1"; 00030 static const char IncludeDirElementName[] = "includedir"; 00031 static const char DirElementName[] = "dir"; 00032 static const char DirNameAttrib[] = "name"; 00033 static const char DefinesElementName[] = "defines"; 00034 static const char DefineName[] = "define"; 00035 static const char DefineNameAttrib[] = "name"; 00036 static const char PathsElementName[] = "paths"; 00037 static const char PathName[] = "dir"; 00038 static const char PathNameAttrib[] = "name"; 00039 static const char RootPathName[] = "root"; 00040 static const char RootPathNameAttrib[] = "name"; 00041 static const char IgnoreElementName[] = "ignore"; 00042 static const char IgnorePathName[] = "path"; 00043 static const char IgnorePathNameAttrib[] = "name"; 00044 static const char ExcludeElementName[] = "exclude"; 00045 static const char ExcludePathName[] = "path"; 00046 static const char ExcludePathNameAttrib[] = "name"; 00047 00048 ProjectFile::ProjectFile(QObject *parent) : 00049 QObject(parent) 00050 { 00051 } 00052 00053 ProjectFile::ProjectFile(const QString &filename, QObject *parent) : 00054 QObject(parent), 00055 mFilename(filename) 00056 { 00057 } 00058 00059 bool ProjectFile::Read(const QString &filename) 00060 { 00061 if (!filename.isEmpty()) 00062 mFilename = filename; 00063 00064 QFile file(mFilename); 00065 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) 00066 return false; 00067 00068 QXmlStreamReader xmlReader(&file); 00069 bool insideProject = false; 00070 bool projectTagFound = false; 00071 while (!xmlReader.atEnd()) { 00072 switch (xmlReader.readNext()) { 00073 case QXmlStreamReader::StartElement: 00074 if (xmlReader.name() == ProjectElementName) { 00075 insideProject = true; 00076 projectTagFound = true; 00077 } 00078 // Read root path from inside project element 00079 if (insideProject && xmlReader.name() == RootPathName) 00080 ReadRootPath(xmlReader); 00081 00082 // Find paths to check from inside project element 00083 if (insideProject && xmlReader.name() == PathsElementName) 00084 ReadCheckPaths(xmlReader); 00085 00086 // Find include directory from inside project element 00087 if (insideProject && xmlReader.name() == IncludeDirElementName) 00088 ReadIncludeDirs(xmlReader); 00089 00090 // Find preprocessor define from inside project element 00091 if (insideProject && xmlReader.name() == DefinesElementName) 00092 ReadDefines(xmlReader); 00093 00094 // Find exclude list from inside project element 00095 if (insideProject && xmlReader.name() == ExcludeElementName) 00096 ReadExcludes(xmlReader); 00097 00098 // Find ignore list from inside project element 00099 // These are read for compatibility 00100 if (insideProject && xmlReader.name() == IgnoreElementName) 00101 ReadExcludes(xmlReader); 00102 00103 break; 00104 00105 case QXmlStreamReader::EndElement: 00106 if (xmlReader.name() == ProjectElementName) 00107 insideProject = false; 00108 break; 00109 00110 // Not handled 00111 case QXmlStreamReader::NoToken: 00112 case QXmlStreamReader::Invalid: 00113 case QXmlStreamReader::StartDocument: 00114 case QXmlStreamReader::EndDocument: 00115 case QXmlStreamReader::Characters: 00116 case QXmlStreamReader::Comment: 00117 case QXmlStreamReader::DTD: 00118 case QXmlStreamReader::EntityReference: 00119 case QXmlStreamReader::ProcessingInstruction: 00120 break; 00121 } 00122 } 00123 00124 file.close(); 00125 if (projectTagFound) 00126 return true; 00127 else 00128 return false; 00129 } 00130 00131 QStringList ProjectFile::GetIncludeDirs() const 00132 { 00133 QStringList dirs; 00134 foreach(QString path, mIncludeDirs) { 00135 dirs << QDir::fromNativeSeparators(path); 00136 } 00137 return dirs; 00138 } 00139 00140 QStringList ProjectFile::GetDefines() const 00141 { 00142 return mDefines; 00143 } 00144 00145 QStringList ProjectFile::GetCheckPaths() const 00146 { 00147 QStringList paths; 00148 foreach(QString path, mPaths) { 00149 paths << QDir::fromNativeSeparators(path); 00150 } 00151 return paths; 00152 } 00153 00154 QStringList ProjectFile::GetExcludedPaths() const 00155 { 00156 QStringList paths; 00157 foreach(QString path, mExcludedPaths) { 00158 paths << QDir::fromNativeSeparators(path); 00159 } 00160 return paths; 00161 } 00162 00163 void ProjectFile::ReadRootPath(QXmlStreamReader &reader) 00164 { 00165 QXmlStreamAttributes attribs = reader.attributes(); 00166 QString name = attribs.value("", RootPathNameAttrib).toString(); 00167 if (!name.isEmpty()) 00168 mRootPath = name; 00169 } 00170 00171 void ProjectFile::ReadIncludeDirs(QXmlStreamReader &reader) 00172 { 00173 QXmlStreamReader::TokenType type; 00174 bool allRead = false; 00175 do { 00176 type = reader.readNext(); 00177 switch (type) { 00178 case QXmlStreamReader::StartElement: 00179 00180 // Read dir-elements 00181 if (reader.name().toString() == DirElementName) { 00182 QXmlStreamAttributes attribs = reader.attributes(); 00183 QString name = attribs.value("", DirNameAttrib).toString(); 00184 if (!name.isEmpty()) 00185 mIncludeDirs << name; 00186 } 00187 break; 00188 00189 case QXmlStreamReader::EndElement: 00190 if (reader.name().toString() == IncludeDirElementName) 00191 allRead = true; 00192 break; 00193 00194 // Not handled 00195 case QXmlStreamReader::NoToken: 00196 case QXmlStreamReader::Invalid: 00197 case QXmlStreamReader::StartDocument: 00198 case QXmlStreamReader::EndDocument: 00199 case QXmlStreamReader::Characters: 00200 case QXmlStreamReader::Comment: 00201 case QXmlStreamReader::DTD: 00202 case QXmlStreamReader::EntityReference: 00203 case QXmlStreamReader::ProcessingInstruction: 00204 break; 00205 } 00206 } while (!allRead); 00207 } 00208 00209 void ProjectFile::ReadDefines(QXmlStreamReader &reader) 00210 { 00211 QXmlStreamReader::TokenType type; 00212 bool allRead = false; 00213 do { 00214 type = reader.readNext(); 00215 switch (type) { 00216 case QXmlStreamReader::StartElement: 00217 // Read define-elements 00218 if (reader.name().toString() == DefineName) { 00219 QXmlStreamAttributes attribs = reader.attributes(); 00220 QString name = attribs.value("", DefineNameAttrib).toString(); 00221 if (!name.isEmpty()) 00222 mDefines << name; 00223 } 00224 break; 00225 00226 case QXmlStreamReader::EndElement: 00227 if (reader.name().toString() == DefinesElementName) 00228 allRead = true; 00229 break; 00230 00231 // Not handled 00232 case QXmlStreamReader::NoToken: 00233 case QXmlStreamReader::Invalid: 00234 case QXmlStreamReader::StartDocument: 00235 case QXmlStreamReader::EndDocument: 00236 case QXmlStreamReader::Characters: 00237 case QXmlStreamReader::Comment: 00238 case QXmlStreamReader::DTD: 00239 case QXmlStreamReader::EntityReference: 00240 case QXmlStreamReader::ProcessingInstruction: 00241 break; 00242 } 00243 } while (!allRead); 00244 } 00245 00246 void ProjectFile::ReadCheckPaths(QXmlStreamReader &reader) 00247 { 00248 QXmlStreamReader::TokenType type; 00249 bool allRead = false; 00250 do { 00251 type = reader.readNext(); 00252 switch (type) { 00253 case QXmlStreamReader::StartElement: 00254 00255 // Read dir-elements 00256 if (reader.name().toString() == PathName) { 00257 QXmlStreamAttributes attribs = reader.attributes(); 00258 QString name = attribs.value("", PathNameAttrib).toString(); 00259 if (!name.isEmpty()) 00260 mPaths << name; 00261 } 00262 break; 00263 00264 case QXmlStreamReader::EndElement: 00265 if (reader.name().toString() == PathsElementName) 00266 allRead = true; 00267 break; 00268 00269 // Not handled 00270 case QXmlStreamReader::NoToken: 00271 case QXmlStreamReader::Invalid: 00272 case QXmlStreamReader::StartDocument: 00273 case QXmlStreamReader::EndDocument: 00274 case QXmlStreamReader::Characters: 00275 case QXmlStreamReader::Comment: 00276 case QXmlStreamReader::DTD: 00277 case QXmlStreamReader::EntityReference: 00278 case QXmlStreamReader::ProcessingInstruction: 00279 break; 00280 } 00281 } while (!allRead); 00282 } 00283 00284 void ProjectFile::ReadExcludes(QXmlStreamReader &reader) 00285 { 00286 QXmlStreamReader::TokenType type; 00287 bool allRead = false; 00288 do { 00289 type = reader.readNext(); 00290 switch (type) { 00291 case QXmlStreamReader::StartElement: 00292 // Read exclude-elements 00293 if (reader.name().toString() == ExcludePathName) { 00294 QXmlStreamAttributes attribs = reader.attributes(); 00295 QString name = attribs.value("", ExcludePathNameAttrib).toString(); 00296 if (!name.isEmpty()) 00297 mExcludedPaths << name; 00298 } 00299 // Read ignore-elements - deprecated but support reading them 00300 else if (reader.name().toString() == IgnorePathName) { 00301 QXmlStreamAttributes attribs = reader.attributes(); 00302 QString name = attribs.value("", IgnorePathNameAttrib).toString(); 00303 if (!name.isEmpty()) 00304 mExcludedPaths << name; 00305 } 00306 break; 00307 00308 case QXmlStreamReader::EndElement: 00309 if (reader.name().toString() == IgnoreElementName) 00310 allRead = true; 00311 if (reader.name().toString() == ExcludeElementName) 00312 allRead = true; 00313 break; 00314 00315 // Not handled 00316 case QXmlStreamReader::NoToken: 00317 case QXmlStreamReader::Invalid: 00318 case QXmlStreamReader::StartDocument: 00319 case QXmlStreamReader::EndDocument: 00320 case QXmlStreamReader::Characters: 00321 case QXmlStreamReader::Comment: 00322 case QXmlStreamReader::DTD: 00323 case QXmlStreamReader::EntityReference: 00324 case QXmlStreamReader::ProcessingInstruction: 00325 break; 00326 } 00327 } while (!allRead); 00328 } 00329 00330 void ProjectFile::SetIncludes(const QStringList &includes) 00331 { 00332 mIncludeDirs = includes; 00333 } 00334 00335 void ProjectFile::SetDefines(const QStringList &defines) 00336 { 00337 mDefines = defines; 00338 } 00339 00340 void ProjectFile::SetCheckPaths(const QStringList &paths) 00341 { 00342 mPaths = paths; 00343 } 00344 00345 void ProjectFile::SetExcludedPaths(const QStringList &paths) 00346 { 00347 mExcludedPaths = paths; 00348 } 00349 00350 bool ProjectFile::Write(const QString &filename) 00351 { 00352 if (!filename.isEmpty()) 00353 mFilename = filename; 00354 00355 QFile file(mFilename); 00356 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) 00357 return false; 00358 00359 QXmlStreamWriter xmlWriter(&file); 00360 xmlWriter.setAutoFormatting(true); 00361 xmlWriter.writeStartDocument("1.0"); 00362 xmlWriter.writeStartElement(ProjectElementName); 00363 xmlWriter.writeAttribute(ProjectVersionAttrib, ProjectFileVersion); 00364 00365 if (!mRootPath.isEmpty()) { 00366 xmlWriter.writeStartElement(RootPathName); 00367 xmlWriter.writeAttribute(RootPathNameAttrib, mRootPath); 00368 xmlWriter.writeEndElement(); 00369 } 00370 00371 if (!mIncludeDirs.isEmpty()) { 00372 xmlWriter.writeStartElement(IncludeDirElementName); 00373 foreach(QString incdir, mIncludeDirs) { 00374 xmlWriter.writeStartElement(DirElementName); 00375 xmlWriter.writeAttribute(DirNameAttrib, incdir); 00376 xmlWriter.writeEndElement(); 00377 } 00378 xmlWriter.writeEndElement(); 00379 } 00380 00381 if (!mDefines.isEmpty()) { 00382 xmlWriter.writeStartElement(DefinesElementName); 00383 foreach(QString define, mDefines) { 00384 xmlWriter.writeStartElement(DefineName); 00385 xmlWriter.writeAttribute(DefineNameAttrib, define); 00386 xmlWriter.writeEndElement(); 00387 } 00388 xmlWriter.writeEndElement(); 00389 } 00390 00391 if (!mPaths.isEmpty()) { 00392 xmlWriter.writeStartElement(PathsElementName); 00393 foreach(QString path, mPaths) { 00394 xmlWriter.writeStartElement(PathName); 00395 xmlWriter.writeAttribute(PathNameAttrib, path); 00396 xmlWriter.writeEndElement(); 00397 } 00398 xmlWriter.writeEndElement(); 00399 } 00400 00401 if (!mExcludedPaths.isEmpty()) { 00402 xmlWriter.writeStartElement(ExcludeElementName); 00403 foreach(QString path, mExcludedPaths) { 00404 xmlWriter.writeStartElement(ExcludePathName); 00405 xmlWriter.writeAttribute(ExcludePathNameAttrib, path); 00406 xmlWriter.writeEndElement(); 00407 } 00408 xmlWriter.writeEndElement(); 00409 } 00410 00411 xmlWriter.writeEndDocument(); 00412 file.close(); 00413 return true; 00414 }
1.7.6.1