1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-20 19:57:12 +01:00

Implement utility to hold script contents for debugging purposes.

This commit is contained in:
Sandu Liviu Catalin 2016-06-17 03:15:02 +03:00
parent 399ef5a292
commit 2b6fdcd855
3 changed files with 237 additions and 0 deletions

View File

@ -445,6 +445,8 @@
<Unit filename="../source/Base/Color4.hpp" />
<Unit filename="../source/Base/Quaternion.cpp" />
<Unit filename="../source/Base/Quaternion.hpp" />
<Unit filename="../source/Base/ScriptSrc.cpp" />
<Unit filename="../source/Base/ScriptSrc.hpp" />
<Unit filename="../source/Base/Shared.cpp" />
<Unit filename="../source/Base/Shared.hpp" />
<Unit filename="../source/Base/Sphere.cpp" />

160
source/Base/ScriptSrc.cpp Normal file
View File

@ -0,0 +1,160 @@
// ------------------------------------------------------------------------------------------------
#include "Base/ScriptSrc.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <algorithm>
#include <stdexcept>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class to ensure the file handle is closed regardless of the situation.
*/
class FileHandle
{
public:
// --------------------------------------------------------------------------------------------
std::FILE * mFile; // Handle to the opened file.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
FileHandle(CSStr path)
: mFile(std::fopen(path, "rb"))
{
if (!mFile)
{
throw std::runtime_error(ToStrF("Unable to open script source (%s)", path));
}
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
FileHandle(const FileHandle & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
FileHandle(FileHandle && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~FileHandle()
{
if (mFile)
{
std::fclose(mFile);
}
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
FileHandle & operator = (const FileHandle & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
FileHandle & operator = (FileHandle && o) = delete;
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed file handle.
*/
operator std::FILE * ()
{
return mFile;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed file handle.
*/
operator std::FILE * () const
{
return mFile;
}
};
// ------------------------------------------------------------------------------------------------
void ScriptSrc::Process()
{
// Attempt to open the specified file
FileHandle fp(mPath.c_str());
// First 2 bytes of the file will tell if this is a compiled script
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
std::fseek(fp, 0, SEEK_END);
// Calculate buffer size from beginning to current position
const LongI length = std::ftell(fp);
// Go back to the beginning
std::fseek(fp, 0, SEEK_SET);
// Allocate enough space to hold the file data
mData.resize(length, 0);
// Read the file contents into allocated data
std::fread(&mData[0], 1, length, fp);
// Where the last line ended
unsigned line = 0;
// Process the file data and locate new lines
for (String::const_iterator itr = mData.cbegin(); itr != mData.cend();)
{
// Is this a Unix style line ending?
if (*itr == '\n')
{
// Store the beginning of the line
mLine.push_back(line);
// Advance to the next line
line = std::distance(mData.cbegin(), ++itr);
}
// Is this a Windows style line ending?
else if (*itr == '\r')
{
if (*(++itr) == '\n')
{
// Store the beginning of the line
mLine.push_back(line);
// Advance to the next line
line = std::distance(mData.cbegin(), ++itr);
}
}
else
{
++itr;
}
}
// Should we add the last line as well?
if (line)
{
mLine.push_back(line);
}
}
// ------------------------------------------------------------------------------------------------
ScriptSrc::ScriptSrc(HSQUIRRELVM vm, const String & path, bool info)
: mExec(vm)
, mPath(path)
, mData()
, mLine()
{
// Is the specified path empty?
if (mPath.empty())
{
throw std::runtime_error("Invalid or empty script path");
}
// Should we load the file contents for debugging purposes?
if (info)
{
Process();
}
}
} // Namespace:: SqMod

75
source/Base/ScriptSrc.hpp Normal file
View File

@ -0,0 +1,75 @@
#ifndef _BASE_SCRIPTSRC_HPP_
#define _BASE_SCRIPTSRC_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <vector>
#include <utility>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
class Core;
/* ------------------------------------------------------------------------------------------------
* Hold a information about loaded scripts as it's contents and executable code.
*/
class ScriptSrc
{
// --------------------------------------------------------------------------------------------
friend class Core;
public:
// --------------------------------------------------------------------------------------------
typedef std::vector< Uint32 > Line;
// --------------------------------------------------------------------------------------------
Script mExec; // Reference to the script object.
String mPath; // Path to the script file.
String mData; // The contents of the script file.
Line mLine; // List of lines of code in the data.
private:
/* --------------------------------------------------------------------------------------------
* Read file contents and calculate information about the lines of code.
*/
void Process();
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ScriptSrc(HSQUIRRELVM vm, const String & path, bool info = false);
public:
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
ScriptSrc(const ScriptSrc & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
ScriptSrc(ScriptSrc && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
ScriptSrc & operator = (const ScriptSrc & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
ScriptSrc & operator = (ScriptSrc && o) = default;
};
} // Namespace:: SqMod
#endif // _BASE_SCRIPTSRC_HPP_