1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +01:00

Include code line in debug.

Includes the line of code that causes a syntax error. Few other minor fixes.
This commit is contained in:
Sandu Liviu Catalin 2019-06-16 02:12:51 +03:00
parent b1d214b196
commit d6a3937107
5 changed files with 119 additions and 22 deletions

View File

@ -6,6 +6,8 @@ StackSize=2048
ErrorHandling=true ErrorHandling=true
# Allow the plug-in to load even if no scripts were loaded # Allow the plug-in to load even if no scripts were loaded
EmptyInit=false EmptyInit=false
# Include code in debug information
Debugging=true
# Logging options # Logging options
[Log] [Log]

View File

@ -87,43 +87,51 @@ void ScriptSrc::Process()
FileHandle fp(mPath.c_str()); FileHandle fp(mPath.c_str());
// First 2 bytes of the file will tell if this is a compiled script // First 2 bytes of the file will tell if this is a compiled script
std::uint16_t tag; std::uint16_t tag;
// Read the first 2 bytes of the file and determine the file type
if (std::fread(&tag, 1, 2, fp) != 2 || tag == SQ_BYTECODE_STREAM_TAG)
{
return; // Probably an empty file or compiled script
}
// Go to the end of the file // Go to the end of the file
std::fseek(fp, 0, SEEK_END); std::fseek(fp, 0, SEEK_END);
// Calculate buffer size from beginning to current position // Calculate buffer size from beginning to current position
const LongI length = std::ftell(fp); const LongI length = std::ftell(fp);
// Go back to the beginning // Go back to the beginning
std::fseek(fp, 0, SEEK_SET); std::fseek(fp, 0, SEEK_SET);
// Read the first 2 bytes of the file and determine the file type
if ((length >= 2) && (std::fread(&tag, 1, 2, fp) != 2 || tag == SQ_BYTECODE_STREAM_TAG))
{
return; // Probably an empty file or compiled script
}
// Allocate enough space to hold the file data // Allocate enough space to hold the file data
mData.resize(length, 0); mData.resize(length, 0);
// Read the file contents into allocated data // Read the file contents into allocated data
std::fread(&mData[0], 1, length, fp); std::fread(&mData[0], 1, length, fp);
// Where the last line ended // Where the last line ended
unsigned line = 0; size_t line_start = 0, line_end = 0;
// Process the file data and locate new lines // Process the file data and locate new lines
for (String::const_iterator itr = mData.cbegin(); itr != mData.cend();) for (String::const_iterator itr = mData.cbegin(); itr != mData.cend();)
{ {
// Is this a Unix style line ending? // Is this a Unix style line ending?
if (*itr == '\n') if (*itr == '\n')
{ {
// Extract the line length
line_end = std::distance(mData.cbegin(), itr);
// Store the beginning of the line // Store the beginning of the line
mLine.push_back(line); mLine.emplace_back(line_start, line_end);
// Advance to the next line // Advance to the next line
line = std::distance(mData.cbegin(), ++itr); line_start = line_end+1;
// The line end character was not included
++itr;
} }
// Is this a Windows style line ending? // Is this a Windows style line ending?
else if (*itr == '\r') else if (*itr == '\r')
{ {
if (*(++itr) == '\n') if (*(++itr) == '\n')
{ {
// Extract the line length
line_end = std::distance(mData.cbegin(), itr)-1;
// Store the beginning of the line // Store the beginning of the line
mLine.push_back(line); mLine.emplace_back(line_start, line_end);
// Advance to the next line // Advance to the next line
line = std::distance(mData.cbegin(), ++itr); line_start = line_end+2;
// The line end character was not included
++itr;
} }
} }
else else
@ -132,9 +140,9 @@ void ScriptSrc::Process()
} }
} }
// Should we add the last line as well? // Should we add the last line as well?
if (line) if (mData.size() - line_start > 0)
{ {
mLine.push_back(line); mLine.emplace_back(line_start, mData.size());
} }
// Specify that this script contains line information // Specify that this script contains line information
mInfo = true; mInfo = true;

View File

@ -22,7 +22,7 @@ class ScriptSrc
public: public:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
typedef std::vector< Uint32 > Line; typedef std::vector< std::pair< Uint32, Uint32 > > Line;
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
Script mExec; // Reference to the script object. Script mExec; // Reference to the script object.

View File

@ -51,8 +51,6 @@ extern void TerminateTasks();
extern void TerminateRoutines(); extern void TerminateRoutines();
extern void TerminateCommands(); extern void TerminateCommands();
extern void TerminateSignals(); extern void TerminateSignals();
extern void MgInitialize();
extern void MgTerminate();
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
extern Buffer GetRealFilePath(CSStr path); extern Buffer GetRealFilePath(CSStr path);
@ -275,7 +273,7 @@ bool Core::Initialize()
// Configure error handling // Configure error handling
ErrorHandling::Enable(conf.GetBoolValue("Squirrel", "ErrorHandling", true)); ErrorHandling::Enable(conf.GetBoolValue("Squirrel", "ErrorHandling", true));
// See if debugging options should be enabled // See if debugging options should be enabled
m_Debugging = conf.GetBoolValue("Squirrel", "Debugging", false); m_Debugging = conf.GetBoolValue("Squirrel", "Debugging", m_Debugging);
// Prevent common null objects from using dead virtual machines // Prevent common null objects from using dead virtual machines
NullArray() = Array(); NullArray() = Array();
@ -374,9 +372,6 @@ bool Core::Initialize()
InitializeRoutines(); InitializeRoutines();
InitializeTasks(); InitializeTasks();
// Initialize the Mongoose library
//MgInitialize();
// Initialization successful // Initialization successful
return true; return true;
} }
@ -541,8 +536,6 @@ void Core::Terminate(bool shutdown)
// Tell modules to do their monkey business // Tell modules to do their monkey business
_Func->SendPluginCommand(SQMOD_RELEASED_CMD, ""); _Func->SendPluginCommand(SQMOD_RELEASED_CMD, "");
} }
// Terminate the Mongoose manager
//MgTerminate();
OutputMessage("Squirrel plug-in was successfully terminated"); OutputMessage("Squirrel plug-in was successfully terminated");
} }
@ -594,6 +587,38 @@ void Core::SetOption(CSStr name, CSStr value)
m_Options[name] = value; m_Options[name] = value;
} }
// ------------------------------------------------------------------------------------------------
Core::Scripts::iterator Core::FindScript(const CSStr src)
{
// Iterate over loaded scripts
for (Scripts::iterator itr = m_Scripts.begin(); itr != m_Scripts.end(); ++itr)
{
// Is this script the source we're looking for?
if (itr->mPath.compare(0, String::npos, src) == 0)
{
return itr;
}
}
// Not found!
return m_Scripts.end();
}
// ------------------------------------------------------------------------------------------------
Core::Scripts::iterator Core::FindPendingScript(const CSStr src)
{
// Iterate over loaded scripts
for (Scripts::iterator itr = m_PendingScripts.begin(); itr != m_PendingScripts.end(); ++itr)
{
// Is this script the source we're looking for?
if (itr->mPath.compare(0, String::npos, src) == 0)
{
return itr;
}
}
// Not found!
return m_PendingScripts.end();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Core::LoadScript(CSStr filepath, bool delay) bool Core::LoadScript(CSStr filepath, bool delay)
{ {
@ -852,7 +877,42 @@ SQInteger Core::RuntimeErrorHandler(HSQUIRRELVM vm)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Core::CompilerErrorHandler(HSQUIRRELVM /*vm*/, CSStr desc, CSStr src, SQInteger line, SQInteger column) void Core::CompilerErrorHandler(HSQUIRRELVM /*vm*/, CSStr desc, CSStr src, SQInteger line, SQInteger column)
{ {
LogFtl("Message: %s\n[\n=>Location: %s\n=>Line: %" PRINT_INT_FMT "\n=>Column: %" PRINT_INT_FMT "\n]", desc, src, line, column); // Should we include code in output? (we count lines from 0, squirrel counts from 1)
if ((line <= 0) || !Core::Get().IsDebugging() || !Core::Get().CompilerErrorHandlerEx(desc, src, --line, column)) {
LogFtl("Message: %s\n[\n=>Location: %s\n=>Line: %" PRINT_INT_FMT "\n=>Column: %" PRINT_INT_FMT "\n]", desc, src, line, column);
}
}
// ------------------------------------------------------------------------------------------------
bool Core::CompilerErrorHandlerEx(CSStr desc, CSStr src, SQInteger line, SQInteger column)
{
// Find the script we're looking for
Scripts::iterator script = FindScript(src);
// Found anything?
if (script == m_Scripts.end())
{
return false; // No such script!
}
// Have debug information?
else if (!(script->mInfo))
{
return false; // Nothing to show!
}
// Is this line outside the range that we have?
else if (script->mLine.size() < line)
{
return false; // No such line!
}
// Grab the line we're looking for
ScriptSrc::Line::iterator itr = script->mLine.begin() + line;
// Grab the code from that line
String code = script->mData.substr(itr->first, itr->second - itr->first);
// Trim whitespace from the beginning of the code code
code.erase(0, code.find_first_not_of(" \t\n\r\f\v"));
// Display the error message with the code included
LogFtl("Message: %s\n[\n=>Location: %s\n=>Line: %" PRINT_SZ_FMT "\n=>Column: %" PRINT_INT_FMT "\n=>Code: %s\n]", desc, src, ++line, column, code.c_str());
// We displayed the information
return true;
} }
} // Namespace:: SqMod } // Namespace:: SqMod

View File

@ -831,6 +831,32 @@ public:
*/ */
void SetOption(CSStr name, CSStr value); void SetOption(CSStr name, CSStr value);
/* --------------------------------------------------------------------------------------------
* Retrieve the script source associated with a certain path in the scripts list.
*/
Scripts::iterator FindScript(const CSStr src);
/* --------------------------------------------------------------------------------------------
* Retrieve the script source associated with a certain path in the pending scripts list.
*/
Scripts::iterator FindPendingScript(const CSStr src);
/* --------------------------------------------------------------------------------------------
* Retrieve the scripts list. Should not be modified directly! Information purposes only.
*/
Scripts & GetScripts()
{
return m_Scripts;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the pending scripts list. Should not be modified directly! Information purposes only.
*/
Scripts & GetPendingScripts()
{
return m_PendingScripts;
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the virtual machine. * Retrieve the virtual machine.
*/ */
@ -958,6 +984,7 @@ protected:
static SQInteger RuntimeErrorHandler(HSQUIRRELVM vm); static SQInteger RuntimeErrorHandler(HSQUIRRELVM vm);
static void CompilerErrorHandler(HSQUIRRELVM vm, CSStr desc, CSStr src, static void CompilerErrorHandler(HSQUIRRELVM vm, CSStr desc, CSStr src,
SQInteger line, SQInteger column); SQInteger line, SQInteger column);
bool CompilerErrorHandlerEx(CSStr desc, CSStr src, SQInteger line, SQInteger column);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Entity scanners. * Entity scanners.