1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-29 18:32:36 +00:00
OpenMW/apps/opencs/model/tools/scriptcheck.cpp
Atahualpa 9d61d76e92 Adds the option to ignore "Base" records when running the verifier. (fixes #4466)
Adds a boolean setting to the user preferences. This setting is locally saved to all OpenMW-CS check stages. When a verification is done, the setting is updated on setup for each check stage. If set to true, the boolean value is then used to skip the verification process for every base record - minus some special cases where, e.g., counters are to be set first.

Related issue:
- Fixes #4466: Editor: Add option to ignore base records when running verifier (https://gitlab.com/OpenMW/openmw/issues/4466)

Tests:
The changes were successfully tested in OpenMW-CS by creating faulty "Base" and "Modified" records for every record type (if possible) and, then, running the verifier with and without the option respectively.
2018-06-20 00:20:03 +02:00

138 lines
3.9 KiB
C++

#include "scriptcheck.hpp"
#include <components/compiler/tokenloc.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/fileparser.hpp>
#include <components/compiler/exception.hpp>
#include <components/compiler/extensions0.hpp>
#include "../doc/document.hpp"
#include "../world/data.hpp"
#include "../prefs/state.hpp"
CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity (Type type)
{
switch (type)
{
case WarningMessage: return CSMDoc::Message::Severity_Warning;
case ErrorMessage: return CSMDoc::Message::Severity_Error;
}
return CSMDoc::Message::Severity_SeriousError;
}
void CSMTools::ScriptCheckStage::report (const std::string& message, const Compiler::TokenLoc& loc,
Type type)
{
std::ostringstream stream;
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
stream
<< "script " << mFile
<< ", line " << loc.mLine << ", column " << loc.mColumn
<< " (" << loc.mLiteral << "): " << message;
std::ostringstream hintStream;
hintStream << "l:" << loc.mLine << " " << loc.mColumn;
mMessages->add (id, stream.str(), hintStream.str(), getSeverity (type));
}
void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
{
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
std::ostringstream stream;
stream << "script " << mFile << ": " << message;
mMessages->add (id, stream.str(), "", getSeverity (type));
}
CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
: mDocument (document), mContext (document.getData()), mMessages (0), mWarningMode (Mode_Ignore)
{
/// \todo add an option to configure warning mode
setWarningsMode (0);
Compiler::registerExtensions (mExtensions);
mContext.setExtensions (&mExtensions);
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
}
int CSMTools::ScriptCheckStage::setup()
{
std::string warnings = CSMPrefs::get()["Scripts"]["warnings"].toString();
if (warnings=="Ignore")
mWarningMode = Mode_Ignore;
else if (warnings=="Normal")
mWarningMode = Mode_Normal;
else if (warnings=="Strict")
mWarningMode = Mode_Strict;
mContext.clear();
mMessages = 0;
mId.clear();
Compiler::ErrorHandler::reset();
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
return mDocument.getData().getScripts().getSize();
}
void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
{
const CSMWorld::Record<ESM::Script> &record = mDocument.getData().getScripts().getRecord(stage);
mId = mDocument.getData().getScripts().getId (stage);
if (mDocument.isBlacklisted (
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, mId)))
return;
// Skip "Base" records (setting!) and "Deleted" records
if ((mIgnoreBaseRecords && record.isBaseOnly()) || record.isDeleted())
return;
mMessages = &messages;
switch (mWarningMode)
{
case Mode_Ignore: setWarningsMode (0); break;
case Mode_Normal: setWarningsMode (1); break;
case Mode_Strict: setWarningsMode (2); break;
}
try
{
mFile = record.get().mId;
std::istringstream input (record.get().mScriptText);
Compiler::Scanner scanner (*this, input, mContext.getExtensions());
Compiler::FileParser parser (*this, mContext);
scanner.scan (parser);
}
catch (const Compiler::SourceException&)
{
// error has already been reported via error handler
}
catch (const std::exception& error)
{
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
std::ostringstream stream;
stream << "script " << mFile << ": " << error.what();
messages.add (id, stream.str(), "", CSMDoc::Message::Severity_SeriousError);
}
mMessages = 0;
}