Fetch the repository succeeded.
This action will force synchronization from Gitee 极速下载/Cppcheck, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2020 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cppchecklibrarydata.h"
#include <stdexcept>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U;
const unsigned int CppcheckLibraryData::Function::Arg::VARIADIC = ~1U;
CppcheckLibraryData::CppcheckLibraryData()
{
}
static std::string unhandledElement(const QXmlStreamReader &xmlReader)
{
throw std::runtime_error(QObject::tr("line %1: Unhandled element %2").arg(xmlReader.lineNumber()).arg(xmlReader.name().toString()).toStdString());
}
static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader)
{
CppcheckLibraryData::Container container;
container.id = xmlReader.attributes().value("id").toString();
container.inherits = xmlReader.attributes().value("inherits").toString();
container.startPattern = xmlReader.attributes().value("startPattern").toString();
container.endPattern = xmlReader.attributes().value("endPattern").toString();
container.opLessAllowed = xmlReader.attributes().value("opLessAllowed").toString();
container.itEndPattern = xmlReader.attributes().value("itEndPattern").toString();
QXmlStreamReader::TokenType type;
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
xmlReader.name().toString() != "container") {
if (type != QXmlStreamReader::StartElement)
continue;
const QString elementName = xmlReader.name().toString();
if (elementName == "type") {
container.type.templateParameter = xmlReader.attributes().value("templateParameter").toString();
container.type.string = xmlReader.attributes().value("string").toString();
} else if (elementName == "size" || elementName == "access" || elementName == "other") {
const QString indexOperator = xmlReader.attributes().value("indexOperator").toString();
if (elementName == "access" && indexOperator == "array-like")
container.access_arrayLike = true;
const QString templateParameter = xmlReader.attributes().value("templateParameter").toString();
if (elementName == "size" && !templateParameter.isEmpty())
container.size_templateParameter = templateParameter.toInt();
for (;;) {
type = xmlReader.readNext();
if (xmlReader.name().toString() == elementName)
break;
if (type != QXmlStreamReader::StartElement)
continue;
struct CppcheckLibraryData::Container::Function function;
function.name = xmlReader.attributes().value("name").toString();
function.action = xmlReader.attributes().value("action").toString();
function.yields = xmlReader.attributes().value("yields").toString();
if (elementName == "size")
container.sizeFunctions.append(function);
else if (elementName == "access")
container.accessFunctions.append(function);
else
container.otherFunctions.append(function);
}
} else {
unhandledElement(xmlReader);
}
}
return container;
}
static CppcheckLibraryData::Define loadDefine(const QXmlStreamReader &xmlReader)
{
CppcheckLibraryData::Define define;
define.name = xmlReader.attributes().value("name").toString();
define.value = xmlReader.attributes().value("value").toString();
return define;
}
static QString loadUndefine(const QXmlStreamReader &xmlReader)
{
return xmlReader.attributes().value("name").toString();
}
static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlReader)
{
CppcheckLibraryData::Function::Arg arg;
QString argnr = xmlReader.attributes().value("nr").toString();
if (argnr == "any")
arg.nr = CppcheckLibraryData::Function::Arg::ANY;
else if (argnr == "variadic")
arg.nr = CppcheckLibraryData::Function::Arg::VARIADIC;
else
arg.nr = argnr.toUInt();
arg.defaultValue = xmlReader.attributes().value("default").toString();
QXmlStreamReader::TokenType type;
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
xmlReader.name().toString() != "arg") {
if (type != QXmlStreamReader::StartElement)
continue;
const QString elementName = xmlReader.name().toString();
if (elementName == "not-bool")
arg.notbool = true;
else if (elementName == "not-null")
arg.notnull = true;
else if (elementName == "not-uninit")
arg.notuninit = true;
else if (elementName == "strz")
arg.strz = true;
else if (elementName == "formatstr")
arg.formatstr = true;
else if (elementName == "valid")
arg.valid = xmlReader.readElementText();
else if (elementName == "minsize") {
CppcheckLibraryData::Function::Arg::MinSize minsize;
minsize.type = xmlReader.attributes().value("type").toString();
minsize.arg = xmlReader.attributes().value("arg").toString();
minsize.arg2 = xmlReader.attributes().value("arg2").toString();
arg.minsizes.append(minsize);
} else if (elementName == "iterator") {
arg.iterator.container = xmlReader.attributes().value("container").toInt();
arg.iterator.type = xmlReader.attributes().value("type").toString();
} else {
unhandledElement(xmlReader);
}
}
return arg;
}
static CppcheckLibraryData::Function loadFunction(QXmlStreamReader &xmlReader, const QString &comments)
{
CppcheckLibraryData::Function function;
function.comments = comments;
function.name = xmlReader.attributes().value("name").toString();
QXmlStreamReader::TokenType type;
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
xmlReader.name().toString() != "function") {
if (type != QXmlStreamReader::StartElement)
continue;
const QString elementName = xmlReader.name().toString();
if (elementName == "noreturn")
function.noreturn = (xmlReader.readElementText() == "true") ? CppcheckLibraryData::Function::True : CppcheckLibraryData::Function::False;
else if (elementName == "pure")
function.gccPure = true;
else if (elementName == "const")
function.gccConst = true;
else if (elementName == "leak-ignore")
function.leakignore = true;
else if (elementName == "use-retval")
function.useretval = true;
else if (elementName == "returnValue") {
const QString container = xmlReader.attributes().value("container").toString();
function.returnValue.container = container.isNull() ? -1 : container.toInt();
function.returnValue.type = xmlReader.attributes().value("type").toString();
function.returnValue.value = xmlReader.readElementText();
} else if (elementName == "formatstr") {
function.formatstr.scan = xmlReader.attributes().value("scan").toString();
function.formatstr.secure = xmlReader.attributes().value("secure").toString();
} else if (elementName == "arg")
function.args.append(loadFunctionArg(xmlReader));
else if (elementName == "warn") {
function.warn.severity = xmlReader.attributes().value("severity").toString();
function.warn.cstd = xmlReader.attributes().value("cstd").toString();
function.warn.reason = xmlReader.attributes().value("reason").toString();
function.warn.alternatives = xmlReader.attributes().value("alternatives").toString();
function.warn.msg = xmlReader.readElementText();
} else {
unhandledElement(xmlReader);
}
}
return function;
}
static CppcheckLibraryData::MemoryResource loadMemoryResource(QXmlStreamReader &xmlReader)
{
CppcheckLibraryData::MemoryResource memoryresource;
memoryresource.type = xmlReader.name().toString();
QXmlStreamReader::TokenType type;
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
xmlReader.name().toString() != memoryresource.type) {
if (type != QXmlStreamReader::StartElement)
continue;
const QString elementName = xmlReader.name().toString();
if (elementName == "alloc") {
CppcheckLibraryData::MemoryResource::Alloc alloc;
alloc.init = (xmlReader.attributes().value("init").toString() == "true");
alloc.name = xmlReader.readElementText();
memoryresource.alloc.append(alloc);
} else if (elementName == "dealloc")
memoryresource.dealloc.append(xmlReader.readElementText());
else if (elementName == "use")
memoryresource.use.append(xmlReader.readElementText());
else
unhandledElement(xmlReader);
}
return memoryresource;
}
static CppcheckLibraryData::PodType loadPodType(const QXmlStreamReader &xmlReader)
{
CppcheckLibraryData::PodType podtype;
podtype.name = xmlReader.attributes().value("name").toString();
podtype.size = xmlReader.attributes().value("size").toString();
podtype.sign = xmlReader.attributes().value("sign").toString();
return podtype;
}
QString CppcheckLibraryData::open(QIODevice &file)
{
clear();
QString comments;
QXmlStreamReader xmlReader(&file);
while (!xmlReader.atEnd()) {
const QXmlStreamReader::TokenType t = xmlReader.readNext();
switch (t) {
case QXmlStreamReader::Comment:
if (!comments.isEmpty())
comments += "\n";
comments += xmlReader.text().toString();
break;
case QXmlStreamReader::StartElement:
try {
const QString elementName(xmlReader.name().toString());
if (elementName == "def")
;
else if (elementName == "container")
containers.append(loadContainer(xmlReader));
else if (elementName == "define")
defines.append(loadDefine(xmlReader));
else if (elementName == "undefine")
undefines.append(loadUndefine(xmlReader));
else if (elementName == "function")
functions.append(loadFunction(xmlReader, comments));
else if (elementName == "memory" || elementName == "resource")
memoryresource.append(loadMemoryResource(xmlReader));
else if (elementName == "podtype")
podtypes.append(loadPodType(xmlReader));
else
unhandledElement(xmlReader);
} catch (std::runtime_error &e) {
return e.what();
}
comments.clear();
break;
default:
break;
}
}
return QString();
}
static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString &name, int extra, const QList<struct CppcheckLibraryData::Container::Function> &functions)
{
if (functions.isEmpty() && extra < 0)
return;
xmlWriter.writeStartElement(name);
if (extra >= 0) {
if (name == "access")
xmlWriter.writeAttribute("indexOperator", "array-like");
else if (name == "size")
xmlWriter.writeAttribute("templateParameter", QString::number(extra));
}
foreach (const CppcheckLibraryData::Container::Function &function, functions) {
xmlWriter.writeStartElement("function");
xmlWriter.writeAttribute("name", function.name);
if (!function.action.isEmpty())
xmlWriter.writeAttribute("action", function.action);
if (!function.yields.isEmpty())
xmlWriter.writeAttribute("yields", function.yields);
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::Container &container)
{
xmlWriter.writeStartElement("container");
xmlWriter.writeAttribute("id", container.id);
if (!container.startPattern.isEmpty())
xmlWriter.writeAttribute("startPattern", container.startPattern);
if (!container.endPattern.isNull())
xmlWriter.writeAttribute("endPattern", container.endPattern);
if (!container.inherits.isEmpty())
xmlWriter.writeAttribute("inherits", container.inherits);
if (!container.opLessAllowed.isEmpty())
xmlWriter.writeAttribute("opLessAllowed", container.opLessAllowed);
if (!container.itEndPattern.isEmpty())
xmlWriter.writeAttribute("itEndPattern", container.itEndPattern);
if (!container.type.templateParameter.isEmpty() || !container.type.string.isEmpty()) {
xmlWriter.writeStartElement("type");
if (!container.type.templateParameter.isEmpty())
xmlWriter.writeAttribute("templateParameter", container.type.templateParameter);
if (!container.type.string.isEmpty())
xmlWriter.writeAttribute("string", container.type.string);
xmlWriter.writeEndElement();
}
writeContainerFunctions(xmlWriter, "size", container.size_templateParameter, container.sizeFunctions);
writeContainerFunctions(xmlWriter, "access", container.access_arrayLike?1:-1, container.accessFunctions);
writeContainerFunctions(xmlWriter, "other", -1, container.otherFunctions);
xmlWriter.writeEndElement();
}
static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::Function &function)
{
QString comments = function.comments;
while (comments.startsWith("\n"))
comments = comments.mid(1);
while (comments.endsWith("\n"))
comments.chop(1);
foreach (const QString &comment, comments.split('\n')) {
if (comment.length() >= 1)
xmlWriter.writeComment(comment);
}
xmlWriter.writeStartElement("function");
xmlWriter.writeAttribute("name", function.name);
if (function.useretval)
xmlWriter.writeEmptyElement("use-retval");
if (function.gccConst)
xmlWriter.writeEmptyElement("const");
if (function.gccPure)
xmlWriter.writeEmptyElement("pure");
if (!function.returnValue.empty()) {
xmlWriter.writeStartElement("returnValue");
if (!function.returnValue.type.isNull())
xmlWriter.writeAttribute("type", function.returnValue.type);
if (function.returnValue.container >= 0)
xmlWriter.writeAttribute("container", QString::number(function.returnValue.container));
if (!function.returnValue.value.isNull())
xmlWriter.writeCharacters(function.returnValue.value);
xmlWriter.writeEndElement();
}
if (function.noreturn != CppcheckLibraryData::Function::Unknown)
xmlWriter.writeTextElement("noreturn", (function.noreturn == CppcheckLibraryData::Function::True) ? "true" : "false");
if (function.leakignore)
xmlWriter.writeEmptyElement("leak-ignore");
// Argument info..
foreach (const CppcheckLibraryData::Function::Arg &arg, function.args) {
if (arg.formatstr) {
xmlWriter.writeStartElement("formatstr");
if (!function.formatstr.scan.isNull())
xmlWriter.writeAttribute("scan", function.formatstr.scan);
if (!function.formatstr.secure.isNull())
xmlWriter.writeAttribute("secure", function.formatstr.secure);
xmlWriter.writeEndElement();
}
xmlWriter.writeStartElement("arg");
if (arg.nr == CppcheckLibraryData::Function::Arg::ANY)
xmlWriter.writeAttribute("nr", "any");
else if (arg.nr == CppcheckLibraryData::Function::Arg::VARIADIC)
xmlWriter.writeAttribute("nr", "variadic");
else
xmlWriter.writeAttribute("nr", QString::number(arg.nr));
if (!arg.defaultValue.isNull())
xmlWriter.writeAttribute("default", arg.defaultValue);
if (arg.formatstr)
xmlWriter.writeEmptyElement("formatstr");
if (arg.notnull)
xmlWriter.writeEmptyElement("not-null");
if (arg.notuninit)
xmlWriter.writeEmptyElement("not-uninit");
if (arg.notbool)
xmlWriter.writeEmptyElement("not-bool");
if (arg.strz)
xmlWriter.writeEmptyElement("strz");
if (!arg.valid.isEmpty())
xmlWriter.writeTextElement("valid",arg.valid);
foreach (const CppcheckLibraryData::Function::Arg::MinSize &minsize, arg.minsizes) {
xmlWriter.writeStartElement("minsize");
xmlWriter.writeAttribute("type", minsize.type);
xmlWriter.writeAttribute("arg", minsize.arg);
if (!minsize.arg2.isEmpty())
xmlWriter.writeAttribute("arg2", minsize.arg2);
xmlWriter.writeEndElement();
}
if (arg.iterator.container >= 0 || !arg.iterator.type.isNull()) {
xmlWriter.writeStartElement("iterator");
if (arg.iterator.container >= 0)
xmlWriter.writeAttribute("container", QString::number(arg.iterator.container));
if (!arg.iterator.type.isNull())
xmlWriter.writeAttribute("type", arg.iterator.type);
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
if (!function.warn.isEmpty()) {
xmlWriter.writeStartElement("warn");
if (!function.warn.severity.isEmpty())
xmlWriter.writeAttribute("severity", function.warn.severity);
if (!function.warn.cstd.isEmpty())
xmlWriter.writeAttribute("cstd", function.warn.cstd);
if (!function.warn.alternatives.isEmpty())
xmlWriter.writeAttribute("alternatives", function.warn.alternatives);
if (!function.warn.reason.isEmpty())
xmlWriter.writeAttribute("reason", function.warn.reason);
if (!function.warn.msg.isEmpty())
xmlWriter.writeCharacters(function.warn.msg);
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
static void writeMemoryResource(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::MemoryResource &mr)
{
xmlWriter.writeStartElement(mr.type);
foreach (const CppcheckLibraryData::MemoryResource::Alloc &alloc, mr.alloc) {
xmlWriter.writeStartElement("alloc");
xmlWriter.writeAttribute("init", alloc.init ? "true" : "false");
xmlWriter.writeCharacters(alloc.name);
xmlWriter.writeEndElement();
}
foreach (const QString &dealloc, mr.dealloc) {
xmlWriter.writeTextElement("dealloc", dealloc);
}
foreach (const QString &use, mr.use) {
xmlWriter.writeTextElement("use", use);
}
xmlWriter.writeEndElement();
}
QString CppcheckLibraryData::toString() const
{
QString outputString;
QXmlStreamWriter xmlWriter(&outputString);
xmlWriter.setAutoFormatting(true);
xmlWriter.setAutoFormattingIndent(2);
xmlWriter.writeStartDocument("1.0");
xmlWriter.writeStartElement("def");
xmlWriter.writeAttribute("format","2");
foreach (const Define &define, defines) {
xmlWriter.writeStartElement("define");
xmlWriter.writeAttribute("name", define.name);
xmlWriter.writeAttribute("value", define.value);
xmlWriter.writeEndElement();
}
foreach (const QString &undef, undefines) {
xmlWriter.writeStartElement("undefine");
xmlWriter.writeAttribute("name", undef);
xmlWriter.writeEndElement();
}
foreach (const Function &function, functions) {
writeFunction(xmlWriter, function);
}
foreach (const MemoryResource &mr, memoryresource) {
writeMemoryResource(xmlWriter, mr);
}
foreach (const Container &container, containers) {
writeContainer(xmlWriter, container);
}
foreach (const PodType &podtype, podtypes) {
xmlWriter.writeStartElement("podtype");
xmlWriter.writeAttribute("name", podtype.name);
if (!podtype.sign.isEmpty())
xmlWriter.writeAttribute("sign", podtype.sign);
if (!podtype.size.isEmpty())
xmlWriter.writeAttribute("size", podtype.size);
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
return outputString;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。