mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
convert line endings from CRLF (Windows) to LF (Linux/Unix)
Mixed line endings cause problems when exporting patches with git-format-patch and then trying to "git am" a patch with mixed and non-matching line endings. In such a situation git will fail to apply the patch. This commit runs the dos2unix tools on the remaining files with CRLF (\r\n) line endings to convert them to line-feeds (\n) only. Files that are Windows specific like *.vcxproj and *.props files were not converted. Closes: #3073
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,318 +1,318 @@
|
||||
/*
|
||||
* ERMInterpreter.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ERMParser.h"
|
||||
#include "ERMScriptModule.h"
|
||||
|
||||
class ERMInterpreter;
|
||||
|
||||
namespace VERMInterpreter
|
||||
{
|
||||
using namespace ERM;
|
||||
|
||||
//different exceptions that can be thrown during interpreting
|
||||
class EInterpreterProblem : public std::exception
|
||||
{
|
||||
std::string problem;
|
||||
public:
|
||||
const char * what() const throw() override
|
||||
{
|
||||
return problem.c_str();
|
||||
}
|
||||
~EInterpreterProblem() throw()
|
||||
{}
|
||||
EInterpreterProblem(const std::string & problemDesc) : problem(problemDesc)
|
||||
{}
|
||||
};
|
||||
|
||||
struct ESymbolNotFound : public EInterpreterProblem
|
||||
{
|
||||
ESymbolNotFound(const std::string & sym) :
|
||||
EInterpreterProblem(std::string("Symbol \"") + sym + std::string("\" not found!"))
|
||||
{}
|
||||
};
|
||||
|
||||
struct EInvalidTrigger : public EInterpreterProblem
|
||||
{
|
||||
EInvalidTrigger(const std::string & sym) :
|
||||
EInterpreterProblem(std::string("Trigger \"") + sym + std::string("\" is invalid!"))
|
||||
{}
|
||||
};
|
||||
|
||||
struct EUsageOfUndefinedMacro : public EInterpreterProblem
|
||||
{
|
||||
EUsageOfUndefinedMacro(const std::string & macro) :
|
||||
EInterpreterProblem(std::string("Macro ") + macro + " is undefined")
|
||||
{}
|
||||
};
|
||||
|
||||
struct EIexpProblem : public EInterpreterProblem
|
||||
{
|
||||
EIexpProblem(const std::string & desc) :
|
||||
EInterpreterProblem(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
struct ELineProblem : public EInterpreterProblem
|
||||
{
|
||||
ELineProblem(const std::string & desc) :
|
||||
EInterpreterProblem(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
struct EExecutionError : public EInterpreterProblem
|
||||
{
|
||||
EExecutionError(const std::string & desc) :
|
||||
EInterpreterProblem(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
//internal interpreter error related to execution
|
||||
struct EInterpreterError : public EExecutionError
|
||||
{
|
||||
EInterpreterError(const std::string & desc) :
|
||||
EExecutionError(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
//wrong script
|
||||
struct EScriptExecError : public EExecutionError
|
||||
{
|
||||
EScriptExecError(const std::string & desc) :
|
||||
EExecutionError(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
//wrong script
|
||||
struct EVermScriptExecError : public EScriptExecError
|
||||
{
|
||||
EVermScriptExecError(const std::string & desc) :
|
||||
EScriptExecError(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
// All numeric variables are integer variables and have a range of -2147483647...+2147483647
|
||||
// c stores game active day number //indirect variable
|
||||
// d current value //not an actual variable but a modifier
|
||||
// e1..e100 Function floating point variables //local
|
||||
// e-1..e-100 Trigger local floating point variables //local
|
||||
// 'f'..'t' Standard variables ('quick variables') //global
|
||||
// v1..v1000 Standard variables //global
|
||||
// w1..w100 Hero variables
|
||||
// w101..w200 Hero variables
|
||||
// x1..x16 Function parameters //local
|
||||
// y1..y100 Function local variables //local
|
||||
// y-1..y-100 Trigger-based local integer variables //local
|
||||
// z1..z1000 String variables //global
|
||||
// z-1..z-10 Function local string variables //local
|
||||
|
||||
|
||||
struct TriggerType
|
||||
{
|
||||
//the same order of trigger types in this enum and in validTriggers array is obligatory!
|
||||
enum ETrigType
|
||||
{
|
||||
AE, BA, BF, BG, BR, CM, CO, FU, GE, GM, HE, HL, HM, IP, LE, MF, MG, MM, MR, MW, OB, PI, SN, TH, TM
|
||||
};
|
||||
|
||||
ETrigType type;
|
||||
|
||||
static ETrigType convertTrigger(const std::string & trig)
|
||||
{
|
||||
static const std::string validTriggers[] =
|
||||
{
|
||||
"AE", "BA", "BF", "BG", "BR", "CM", "CO", "FU",
|
||||
"GE", "GM", "HE", "HL", "HM", "IP", "LE", "MF", "MG", "MM", "MR", "MW", "OB", "PI", "SN",
|
||||
"TH", "TM"
|
||||
};
|
||||
|
||||
for(int i=0; i<std::size(validTriggers); ++i)
|
||||
{
|
||||
if(validTriggers[i] == trig)
|
||||
return static_cast<ETrigType>(i);
|
||||
}
|
||||
throw EInvalidTrigger(trig);
|
||||
}
|
||||
|
||||
bool operator<(const TriggerType & t2) const
|
||||
{
|
||||
return type < t2.type;
|
||||
}
|
||||
|
||||
TriggerType(const std::string & sym)
|
||||
{
|
||||
type = convertTrigger(sym);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct LinePointer
|
||||
{
|
||||
int lineNum;
|
||||
int realLineNum;
|
||||
int fileLength;
|
||||
|
||||
LinePointer()
|
||||
: fileLength(-1)
|
||||
{}
|
||||
|
||||
LinePointer(int _fileLength, int line, int _realLineNum)
|
||||
: fileLength(_fileLength),
|
||||
lineNum(line),
|
||||
realLineNum(_realLineNum)
|
||||
{}
|
||||
|
||||
bool operator<(const LinePointer & rhs) const
|
||||
{
|
||||
return lineNum < rhs.lineNum;
|
||||
}
|
||||
|
||||
bool operator!=(const LinePointer & rhs) const
|
||||
{
|
||||
return lineNum != rhs.lineNum;
|
||||
}
|
||||
LinePointer & operator++()
|
||||
{
|
||||
++lineNum;
|
||||
return *this;
|
||||
}
|
||||
bool isValid() const
|
||||
{
|
||||
return fileLength > 0 && lineNum < fileLength;
|
||||
}
|
||||
};
|
||||
|
||||
struct Trigger
|
||||
{
|
||||
LinePointer line;
|
||||
Trigger()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//verm goodies
|
||||
struct VSymbol
|
||||
{
|
||||
std::string text;
|
||||
VSymbol(const std::string & txt) : text(txt)
|
||||
{}
|
||||
};
|
||||
|
||||
struct VNode;
|
||||
struct VOptionList;
|
||||
|
||||
struct VNIL
|
||||
{};
|
||||
|
||||
|
||||
typedef std::variant<char, double, int, std::string> TLiteral;
|
||||
|
||||
typedef std::variant<VNIL, boost::recursive_wrapper<VNode>, VSymbol, TLiteral, ERM::Tcommand> VOption; //options in v-expression, VNIl should be the default
|
||||
|
||||
template<typename T, typename SecType>
|
||||
T& getAs(SecType & opt)
|
||||
{
|
||||
if(opt.type() == typeid(T))
|
||||
return std::get<T>(opt);
|
||||
else
|
||||
throw EVermScriptExecError("Wrong type!");
|
||||
}
|
||||
|
||||
template<typename T, typename SecType>
|
||||
bool isA(const SecType & opt)
|
||||
{
|
||||
if(opt.type() == typeid(T))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
struct VermTreeIterator
|
||||
{
|
||||
private:
|
||||
friend struct VOptionList;
|
||||
VOptionList * parent;
|
||||
enum Estate {NORM, CAR} state;
|
||||
int basePos; //car/cdr offset
|
||||
public:
|
||||
VermTreeIterator(VOptionList & _parent) : parent(&_parent), state(NORM), basePos(0)
|
||||
{}
|
||||
VermTreeIterator() : parent(nullptr), state(NORM)
|
||||
{}
|
||||
|
||||
VermTreeIterator & operator=(const VOption & opt);
|
||||
VermTreeIterator & operator=(const std::vector<VOption> & opt);
|
||||
VermTreeIterator & operator=(const VOptionList & opt);
|
||||
VOption & getAsItem();
|
||||
VOptionList getAsList();
|
||||
size_t size() const;
|
||||
|
||||
VermTreeIterator& operator=(const VermTreeIterator & rhs)
|
||||
{
|
||||
if(this == &rhs)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
parent = rhs.parent;
|
||||
state = rhs.state;
|
||||
basePos = rhs.basePos;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct VOptionList : public std::vector<VOption>
|
||||
{
|
||||
private:
|
||||
friend struct VermTreeIterator;
|
||||
public:
|
||||
VermTreeIterator car();
|
||||
VermTreeIterator cdr();
|
||||
};
|
||||
|
||||
struct VNode
|
||||
{
|
||||
private:
|
||||
void processModifierList(const std::vector<TVModifier> & modifierList, bool asSymbol);
|
||||
public:
|
||||
VOptionList children;
|
||||
VNode( const ERM::TVExp & exp);
|
||||
VNode( const VOptionList & cdren );
|
||||
VNode( const ERM::TSymbol & sym ); //only in case sym has modifiers!
|
||||
VNode( const VOption & first, const VOptionList & rest); //merges given arguments into [a, rest];
|
||||
void setVnode( const VOption & first, const VOptionList & rest);
|
||||
};
|
||||
}
|
||||
|
||||
class ERMInterpreter
|
||||
{
|
||||
/*not so*/ public:
|
||||
|
||||
std::map<VERMInterpreter::LinePointer, ERM::TLine> scripts;
|
||||
|
||||
typedef std::map<VERMInterpreter::TriggerType, std::vector<VERMInterpreter::Trigger> > TtriggerListType;
|
||||
TtriggerListType triggers;
|
||||
TtriggerListType postTriggers;
|
||||
std::vector<VERMInterpreter::LinePointer> instructions;
|
||||
|
||||
static bool isCMDATrigger(const ERM::Tcommand & cmd);
|
||||
static bool isATrigger(const ERM::TLine & line);
|
||||
static ERM::EVOtions getExpType(const ERM::TVOption & opt);
|
||||
ERM::TLine & retrieveLine(const VERMInterpreter::LinePointer & linePtr);
|
||||
static ERM::TTriggerBase & retrieveTrigger(ERM::TLine & line);
|
||||
public:
|
||||
vstd::CLoggerBase * logger;
|
||||
|
||||
ERMInterpreter(vstd::CLoggerBase * logger_);
|
||||
virtual ~ERMInterpreter();
|
||||
|
||||
std::string loadScript(const std::string & name, const std::string & source);
|
||||
};
|
||||
/*
|
||||
* ERMInterpreter.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ERMParser.h"
|
||||
#include "ERMScriptModule.h"
|
||||
|
||||
class ERMInterpreter;
|
||||
|
||||
namespace VERMInterpreter
|
||||
{
|
||||
using namespace ERM;
|
||||
|
||||
//different exceptions that can be thrown during interpreting
|
||||
class EInterpreterProblem : public std::exception
|
||||
{
|
||||
std::string problem;
|
||||
public:
|
||||
const char * what() const throw() override
|
||||
{
|
||||
return problem.c_str();
|
||||
}
|
||||
~EInterpreterProblem() throw()
|
||||
{}
|
||||
EInterpreterProblem(const std::string & problemDesc) : problem(problemDesc)
|
||||
{}
|
||||
};
|
||||
|
||||
struct ESymbolNotFound : public EInterpreterProblem
|
||||
{
|
||||
ESymbolNotFound(const std::string & sym) :
|
||||
EInterpreterProblem(std::string("Symbol \"") + sym + std::string("\" not found!"))
|
||||
{}
|
||||
};
|
||||
|
||||
struct EInvalidTrigger : public EInterpreterProblem
|
||||
{
|
||||
EInvalidTrigger(const std::string & sym) :
|
||||
EInterpreterProblem(std::string("Trigger \"") + sym + std::string("\" is invalid!"))
|
||||
{}
|
||||
};
|
||||
|
||||
struct EUsageOfUndefinedMacro : public EInterpreterProblem
|
||||
{
|
||||
EUsageOfUndefinedMacro(const std::string & macro) :
|
||||
EInterpreterProblem(std::string("Macro ") + macro + " is undefined")
|
||||
{}
|
||||
};
|
||||
|
||||
struct EIexpProblem : public EInterpreterProblem
|
||||
{
|
||||
EIexpProblem(const std::string & desc) :
|
||||
EInterpreterProblem(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
struct ELineProblem : public EInterpreterProblem
|
||||
{
|
||||
ELineProblem(const std::string & desc) :
|
||||
EInterpreterProblem(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
struct EExecutionError : public EInterpreterProblem
|
||||
{
|
||||
EExecutionError(const std::string & desc) :
|
||||
EInterpreterProblem(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
//internal interpreter error related to execution
|
||||
struct EInterpreterError : public EExecutionError
|
||||
{
|
||||
EInterpreterError(const std::string & desc) :
|
||||
EExecutionError(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
//wrong script
|
||||
struct EScriptExecError : public EExecutionError
|
||||
{
|
||||
EScriptExecError(const std::string & desc) :
|
||||
EExecutionError(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
//wrong script
|
||||
struct EVermScriptExecError : public EScriptExecError
|
||||
{
|
||||
EVermScriptExecError(const std::string & desc) :
|
||||
EScriptExecError(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
// All numeric variables are integer variables and have a range of -2147483647...+2147483647
|
||||
// c stores game active day number //indirect variable
|
||||
// d current value //not an actual variable but a modifier
|
||||
// e1..e100 Function floating point variables //local
|
||||
// e-1..e-100 Trigger local floating point variables //local
|
||||
// 'f'..'t' Standard variables ('quick variables') //global
|
||||
// v1..v1000 Standard variables //global
|
||||
// w1..w100 Hero variables
|
||||
// w101..w200 Hero variables
|
||||
// x1..x16 Function parameters //local
|
||||
// y1..y100 Function local variables //local
|
||||
// y-1..y-100 Trigger-based local integer variables //local
|
||||
// z1..z1000 String variables //global
|
||||
// z-1..z-10 Function local string variables //local
|
||||
|
||||
|
||||
struct TriggerType
|
||||
{
|
||||
//the same order of trigger types in this enum and in validTriggers array is obligatory!
|
||||
enum ETrigType
|
||||
{
|
||||
AE, BA, BF, BG, BR, CM, CO, FU, GE, GM, HE, HL, HM, IP, LE, MF, MG, MM, MR, MW, OB, PI, SN, TH, TM
|
||||
};
|
||||
|
||||
ETrigType type;
|
||||
|
||||
static ETrigType convertTrigger(const std::string & trig)
|
||||
{
|
||||
static const std::string validTriggers[] =
|
||||
{
|
||||
"AE", "BA", "BF", "BG", "BR", "CM", "CO", "FU",
|
||||
"GE", "GM", "HE", "HL", "HM", "IP", "LE", "MF", "MG", "MM", "MR", "MW", "OB", "PI", "SN",
|
||||
"TH", "TM"
|
||||
};
|
||||
|
||||
for(int i=0; i<std::size(validTriggers); ++i)
|
||||
{
|
||||
if(validTriggers[i] == trig)
|
||||
return static_cast<ETrigType>(i);
|
||||
}
|
||||
throw EInvalidTrigger(trig);
|
||||
}
|
||||
|
||||
bool operator<(const TriggerType & t2) const
|
||||
{
|
||||
return type < t2.type;
|
||||
}
|
||||
|
||||
TriggerType(const std::string & sym)
|
||||
{
|
||||
type = convertTrigger(sym);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct LinePointer
|
||||
{
|
||||
int lineNum;
|
||||
int realLineNum;
|
||||
int fileLength;
|
||||
|
||||
LinePointer()
|
||||
: fileLength(-1)
|
||||
{}
|
||||
|
||||
LinePointer(int _fileLength, int line, int _realLineNum)
|
||||
: fileLength(_fileLength),
|
||||
lineNum(line),
|
||||
realLineNum(_realLineNum)
|
||||
{}
|
||||
|
||||
bool operator<(const LinePointer & rhs) const
|
||||
{
|
||||
return lineNum < rhs.lineNum;
|
||||
}
|
||||
|
||||
bool operator!=(const LinePointer & rhs) const
|
||||
{
|
||||
return lineNum != rhs.lineNum;
|
||||
}
|
||||
LinePointer & operator++()
|
||||
{
|
||||
++lineNum;
|
||||
return *this;
|
||||
}
|
||||
bool isValid() const
|
||||
{
|
||||
return fileLength > 0 && lineNum < fileLength;
|
||||
}
|
||||
};
|
||||
|
||||
struct Trigger
|
||||
{
|
||||
LinePointer line;
|
||||
Trigger()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//verm goodies
|
||||
struct VSymbol
|
||||
{
|
||||
std::string text;
|
||||
VSymbol(const std::string & txt) : text(txt)
|
||||
{}
|
||||
};
|
||||
|
||||
struct VNode;
|
||||
struct VOptionList;
|
||||
|
||||
struct VNIL
|
||||
{};
|
||||
|
||||
|
||||
typedef std::variant<char, double, int, std::string> TLiteral;
|
||||
|
||||
typedef std::variant<VNIL, boost::recursive_wrapper<VNode>, VSymbol, TLiteral, ERM::Tcommand> VOption; //options in v-expression, VNIl should be the default
|
||||
|
||||
template<typename T, typename SecType>
|
||||
T& getAs(SecType & opt)
|
||||
{
|
||||
if(opt.type() == typeid(T))
|
||||
return std::get<T>(opt);
|
||||
else
|
||||
throw EVermScriptExecError("Wrong type!");
|
||||
}
|
||||
|
||||
template<typename T, typename SecType>
|
||||
bool isA(const SecType & opt)
|
||||
{
|
||||
if(opt.type() == typeid(T))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
struct VermTreeIterator
|
||||
{
|
||||
private:
|
||||
friend struct VOptionList;
|
||||
VOptionList * parent;
|
||||
enum Estate {NORM, CAR} state;
|
||||
int basePos; //car/cdr offset
|
||||
public:
|
||||
VermTreeIterator(VOptionList & _parent) : parent(&_parent), state(NORM), basePos(0)
|
||||
{}
|
||||
VermTreeIterator() : parent(nullptr), state(NORM)
|
||||
{}
|
||||
|
||||
VermTreeIterator & operator=(const VOption & opt);
|
||||
VermTreeIterator & operator=(const std::vector<VOption> & opt);
|
||||
VermTreeIterator & operator=(const VOptionList & opt);
|
||||
VOption & getAsItem();
|
||||
VOptionList getAsList();
|
||||
size_t size() const;
|
||||
|
||||
VermTreeIterator& operator=(const VermTreeIterator & rhs)
|
||||
{
|
||||
if(this == &rhs)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
parent = rhs.parent;
|
||||
state = rhs.state;
|
||||
basePos = rhs.basePos;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct VOptionList : public std::vector<VOption>
|
||||
{
|
||||
private:
|
||||
friend struct VermTreeIterator;
|
||||
public:
|
||||
VermTreeIterator car();
|
||||
VermTreeIterator cdr();
|
||||
};
|
||||
|
||||
struct VNode
|
||||
{
|
||||
private:
|
||||
void processModifierList(const std::vector<TVModifier> & modifierList, bool asSymbol);
|
||||
public:
|
||||
VOptionList children;
|
||||
VNode( const ERM::TVExp & exp);
|
||||
VNode( const VOptionList & cdren );
|
||||
VNode( const ERM::TSymbol & sym ); //only in case sym has modifiers!
|
||||
VNode( const VOption & first, const VOptionList & rest); //merges given arguments into [a, rest];
|
||||
void setVnode( const VOption & first, const VOptionList & rest);
|
||||
};
|
||||
}
|
||||
|
||||
class ERMInterpreter
|
||||
{
|
||||
/*not so*/ public:
|
||||
|
||||
std::map<VERMInterpreter::LinePointer, ERM::TLine> scripts;
|
||||
|
||||
typedef std::map<VERMInterpreter::TriggerType, std::vector<VERMInterpreter::Trigger> > TtriggerListType;
|
||||
TtriggerListType triggers;
|
||||
TtriggerListType postTriggers;
|
||||
std::vector<VERMInterpreter::LinePointer> instructions;
|
||||
|
||||
static bool isCMDATrigger(const ERM::Tcommand & cmd);
|
||||
static bool isATrigger(const ERM::TLine & line);
|
||||
static ERM::EVOtions getExpType(const ERM::TVOption & opt);
|
||||
ERM::TLine & retrieveLine(const VERMInterpreter::LinePointer & linePtr);
|
||||
static ERM::TTriggerBase & retrieveTrigger(ERM::TLine & line);
|
||||
public:
|
||||
vstd::CLoggerBase * logger;
|
||||
|
||||
ERMInterpreter(vstd::CLoggerBase * logger_);
|
||||
virtual ~ERMInterpreter();
|
||||
|
||||
std::string loadScript(const std::string & name, const std::string & source);
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,278 +1,278 @@
|
||||
/*
|
||||
* ERMParser.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/variant/recursive_wrapper.hpp>
|
||||
|
||||
namespace spirit = boost::spirit;
|
||||
|
||||
class CERMPreprocessor
|
||||
{
|
||||
std::string fname;
|
||||
std::stringstream sourceStream;
|
||||
int lineNo;
|
||||
|
||||
|
||||
void getline(std::string &ret);
|
||||
|
||||
public:
|
||||
enum class Version : ui8
|
||||
{
|
||||
INVALID,
|
||||
ERM,
|
||||
VERM
|
||||
};
|
||||
Version version;
|
||||
|
||||
CERMPreprocessor(const std::string & source);
|
||||
std::string retrieveCommandLine();
|
||||
int getCurLineNo() const
|
||||
{
|
||||
return lineNo;
|
||||
}
|
||||
|
||||
const std::string& getCurFileName() const
|
||||
{
|
||||
return fname;
|
||||
}
|
||||
};
|
||||
|
||||
//various classes that represent ERM/VERM AST
|
||||
namespace ERM
|
||||
{
|
||||
using ValType = int; //todo: set to int64_t
|
||||
using IType = int; //todo: set to int32_t
|
||||
|
||||
struct TStringConstant
|
||||
{
|
||||
std::string str;
|
||||
};
|
||||
struct TMacroUsage
|
||||
{
|
||||
std::string macro;
|
||||
};
|
||||
|
||||
// //macro with '?', for write only
|
||||
// struct TQMacroUsage
|
||||
// {
|
||||
// std::string qmacro;
|
||||
// };
|
||||
|
||||
//definition of a macro
|
||||
struct TMacroDef
|
||||
{
|
||||
std::string macro;
|
||||
};
|
||||
typedef std::string TCmdName;
|
||||
|
||||
struct TVarExpNotMacro
|
||||
{
|
||||
typedef std::optional<int> Tval;
|
||||
std::optional<char> questionMark;
|
||||
std::string varsym;
|
||||
Tval val;
|
||||
};
|
||||
|
||||
typedef std::variant<TVarExpNotMacro, TMacroUsage> TVarExp;
|
||||
|
||||
//write-only variable expression
|
||||
struct TVarpExp
|
||||
{
|
||||
TVarExp var;
|
||||
};
|
||||
|
||||
//i-expression (identifier expression) - an integral constant, variable symbol or array symbol
|
||||
typedef std::variant<TVarExp, int> TIexp;
|
||||
|
||||
struct TArithmeticOp
|
||||
{
|
||||
TIexp lhs, rhs;
|
||||
char opcode;
|
||||
};
|
||||
|
||||
struct TVRLogic
|
||||
{
|
||||
char opcode;
|
||||
TIexp var;
|
||||
};
|
||||
|
||||
struct TVRArithmetic
|
||||
{
|
||||
char opcode;
|
||||
TIexp rhs;
|
||||
};
|
||||
|
||||
struct TSemiCompare
|
||||
{
|
||||
std::string compSign;
|
||||
TIexp rhs;
|
||||
};
|
||||
|
||||
struct TCurriedString
|
||||
{
|
||||
TIexp iexp;
|
||||
TStringConstant string;
|
||||
};
|
||||
|
||||
struct TVarConcatString
|
||||
{
|
||||
TVarExp var;
|
||||
TStringConstant string;
|
||||
};
|
||||
|
||||
typedef std::variant<TVarConcatString, TStringConstant, TCurriedString, TSemiCompare, TMacroDef, TIexp, TVarpExp> TBodyOptionItem;
|
||||
|
||||
typedef std::vector<TBodyOptionItem> TNormalBodyOptionList;
|
||||
|
||||
struct TNormalBodyOption
|
||||
{
|
||||
char optionCode;
|
||||
std::optional<TNormalBodyOptionList> params;
|
||||
};
|
||||
typedef std::variant<TVRLogic, TVRArithmetic, TNormalBodyOption> TBodyOption;
|
||||
|
||||
// typedef std::variant<TIexp, TArithmeticOp > TIdentifierInternal;
|
||||
typedef std::vector< TIexp > Tidentifier;
|
||||
|
||||
struct TComparison
|
||||
{
|
||||
std::string compSign;
|
||||
TIexp lhs, rhs;
|
||||
};
|
||||
|
||||
struct Tcondition;
|
||||
typedef std::optional<boost::recursive_wrapper<Tcondition>> TconditionNode;
|
||||
|
||||
struct Tcondition
|
||||
{
|
||||
typedef std::variant<
|
||||
TComparison,
|
||||
int>
|
||||
Tcond; //comparison or condition flag
|
||||
char ctype;
|
||||
Tcond cond;
|
||||
TconditionNode rhs;
|
||||
};
|
||||
|
||||
struct TTriggerBase
|
||||
{
|
||||
bool pre; //if false it's !$ post-trigger, elsewise it's !# (pre)trigger
|
||||
TCmdName name;
|
||||
std::optional<Tidentifier> identifier;
|
||||
std::optional<Tcondition> condition;
|
||||
};
|
||||
|
||||
struct Ttrigger : TTriggerBase
|
||||
{
|
||||
Ttrigger()
|
||||
{
|
||||
pre = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct TPostTrigger : TTriggerBase
|
||||
{
|
||||
TPostTrigger()
|
||||
{
|
||||
pre = false;
|
||||
}
|
||||
};
|
||||
|
||||
//a dirty workaround for preprocessor magic that prevents the use types with comma in it in BOOST_FUSION_ADAPT_STRUCT
|
||||
//see http://comments.gmane.org/gmane.comp.lib.boost.user/62501 for some info
|
||||
//
|
||||
//moreover, I encountered a quite serious bug in boost: http://boost.2283326.n4.nabble.com/container-hpp-111-error-C2039-value-type-is-not-a-member-of-td3352328.html
|
||||
//not sure how serious it is...
|
||||
|
||||
//typedef std::variant<char, TStringConstant, TMacroUsage, TMacroDef> bodyItem;
|
||||
typedef std::vector<TBodyOption> Tbody;
|
||||
|
||||
struct Tinstruction
|
||||
{
|
||||
TCmdName name;
|
||||
std::optional<Tidentifier> identifier;
|
||||
std::optional<Tcondition> condition;
|
||||
Tbody body;
|
||||
};
|
||||
|
||||
struct Treceiver
|
||||
{
|
||||
TCmdName name;
|
||||
std::optional<Tidentifier> identifier;
|
||||
std::optional<Tcondition> condition;
|
||||
std::optional<Tbody> body;
|
||||
};
|
||||
|
||||
struct Tcommand
|
||||
{
|
||||
typedef std::variant<
|
||||
Ttrigger,
|
||||
Tinstruction,
|
||||
Treceiver,
|
||||
TPostTrigger
|
||||
>
|
||||
Tcmd;
|
||||
Tcmd cmd;
|
||||
//std::string comment;
|
||||
};
|
||||
|
||||
//vector expression
|
||||
|
||||
|
||||
typedef std::variant<Tcommand, std::string, boost::spirit::unused_type> TERMline;
|
||||
|
||||
typedef std::string TVModifier; //'`', ',', ',@', '#''
|
||||
|
||||
struct TSymbol
|
||||
{
|
||||
std::vector<TVModifier> symModifier;
|
||||
std::string sym;
|
||||
};
|
||||
|
||||
//for #'symbol expression
|
||||
|
||||
enum EVOtions{VEXP, SYMBOL, CHAR, DOUBLE, INT, TCMD, STRINGC};
|
||||
struct TVExp;
|
||||
typedef std::variant<boost::recursive_wrapper<TVExp>, TSymbol, char, double, int, Tcommand, TStringConstant > TVOption; //options in v-expression
|
||||
//v-expression
|
||||
struct TVExp
|
||||
{
|
||||
std::vector<TVModifier> modifier;
|
||||
std::vector<TVOption> children;
|
||||
};
|
||||
|
||||
//script line
|
||||
typedef std::variant<TVExp, TERMline> TLine;
|
||||
|
||||
template <typename T> struct ERM_grammar;
|
||||
}
|
||||
|
||||
struct LineInfo
|
||||
{
|
||||
ERM::TLine tl;
|
||||
int realLineNum;
|
||||
};
|
||||
|
||||
class ERMParser
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<ERM::ERM_grammar<std::string::const_iterator>> ERMgrammar;
|
||||
|
||||
ERMParser();
|
||||
virtual ~ERMParser();
|
||||
|
||||
std::vector<LineInfo> parseFile(CERMPreprocessor & preproc);
|
||||
private:
|
||||
void repairEncoding(char * str, int len) const; //removes nonstandard ascii characters from string
|
||||
void repairEncoding(std::string & str) const; //removes nonstandard ascii characters from string
|
||||
ERM::TLine parseLine(const std::string & line, int realLineNo);
|
||||
ERM::TLine parseLine(const std::string & line);
|
||||
};
|
||||
/*
|
||||
* ERMParser.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/variant/recursive_wrapper.hpp>
|
||||
|
||||
namespace spirit = boost::spirit;
|
||||
|
||||
class CERMPreprocessor
|
||||
{
|
||||
std::string fname;
|
||||
std::stringstream sourceStream;
|
||||
int lineNo;
|
||||
|
||||
|
||||
void getline(std::string &ret);
|
||||
|
||||
public:
|
||||
enum class Version : ui8
|
||||
{
|
||||
INVALID,
|
||||
ERM,
|
||||
VERM
|
||||
};
|
||||
Version version;
|
||||
|
||||
CERMPreprocessor(const std::string & source);
|
||||
std::string retrieveCommandLine();
|
||||
int getCurLineNo() const
|
||||
{
|
||||
return lineNo;
|
||||
}
|
||||
|
||||
const std::string& getCurFileName() const
|
||||
{
|
||||
return fname;
|
||||
}
|
||||
};
|
||||
|
||||
//various classes that represent ERM/VERM AST
|
||||
namespace ERM
|
||||
{
|
||||
using ValType = int; //todo: set to int64_t
|
||||
using IType = int; //todo: set to int32_t
|
||||
|
||||
struct TStringConstant
|
||||
{
|
||||
std::string str;
|
||||
};
|
||||
struct TMacroUsage
|
||||
{
|
||||
std::string macro;
|
||||
};
|
||||
|
||||
// //macro with '?', for write only
|
||||
// struct TQMacroUsage
|
||||
// {
|
||||
// std::string qmacro;
|
||||
// };
|
||||
|
||||
//definition of a macro
|
||||
struct TMacroDef
|
||||
{
|
||||
std::string macro;
|
||||
};
|
||||
typedef std::string TCmdName;
|
||||
|
||||
struct TVarExpNotMacro
|
||||
{
|
||||
typedef std::optional<int> Tval;
|
||||
std::optional<char> questionMark;
|
||||
std::string varsym;
|
||||
Tval val;
|
||||
};
|
||||
|
||||
typedef std::variant<TVarExpNotMacro, TMacroUsage> TVarExp;
|
||||
|
||||
//write-only variable expression
|
||||
struct TVarpExp
|
||||
{
|
||||
TVarExp var;
|
||||
};
|
||||
|
||||
//i-expression (identifier expression) - an integral constant, variable symbol or array symbol
|
||||
typedef std::variant<TVarExp, int> TIexp;
|
||||
|
||||
struct TArithmeticOp
|
||||
{
|
||||
TIexp lhs, rhs;
|
||||
char opcode;
|
||||
};
|
||||
|
||||
struct TVRLogic
|
||||
{
|
||||
char opcode;
|
||||
TIexp var;
|
||||
};
|
||||
|
||||
struct TVRArithmetic
|
||||
{
|
||||
char opcode;
|
||||
TIexp rhs;
|
||||
};
|
||||
|
||||
struct TSemiCompare
|
||||
{
|
||||
std::string compSign;
|
||||
TIexp rhs;
|
||||
};
|
||||
|
||||
struct TCurriedString
|
||||
{
|
||||
TIexp iexp;
|
||||
TStringConstant string;
|
||||
};
|
||||
|
||||
struct TVarConcatString
|
||||
{
|
||||
TVarExp var;
|
||||
TStringConstant string;
|
||||
};
|
||||
|
||||
typedef std::variant<TVarConcatString, TStringConstant, TCurriedString, TSemiCompare, TMacroDef, TIexp, TVarpExp> TBodyOptionItem;
|
||||
|
||||
typedef std::vector<TBodyOptionItem> TNormalBodyOptionList;
|
||||
|
||||
struct TNormalBodyOption
|
||||
{
|
||||
char optionCode;
|
||||
std::optional<TNormalBodyOptionList> params;
|
||||
};
|
||||
typedef std::variant<TVRLogic, TVRArithmetic, TNormalBodyOption> TBodyOption;
|
||||
|
||||
// typedef std::variant<TIexp, TArithmeticOp > TIdentifierInternal;
|
||||
typedef std::vector< TIexp > Tidentifier;
|
||||
|
||||
struct TComparison
|
||||
{
|
||||
std::string compSign;
|
||||
TIexp lhs, rhs;
|
||||
};
|
||||
|
||||
struct Tcondition;
|
||||
typedef std::optional<boost::recursive_wrapper<Tcondition>> TconditionNode;
|
||||
|
||||
struct Tcondition
|
||||
{
|
||||
typedef std::variant<
|
||||
TComparison,
|
||||
int>
|
||||
Tcond; //comparison or condition flag
|
||||
char ctype;
|
||||
Tcond cond;
|
||||
TconditionNode rhs;
|
||||
};
|
||||
|
||||
struct TTriggerBase
|
||||
{
|
||||
bool pre; //if false it's !$ post-trigger, elsewise it's !# (pre)trigger
|
||||
TCmdName name;
|
||||
std::optional<Tidentifier> identifier;
|
||||
std::optional<Tcondition> condition;
|
||||
};
|
||||
|
||||
struct Ttrigger : TTriggerBase
|
||||
{
|
||||
Ttrigger()
|
||||
{
|
||||
pre = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct TPostTrigger : TTriggerBase
|
||||
{
|
||||
TPostTrigger()
|
||||
{
|
||||
pre = false;
|
||||
}
|
||||
};
|
||||
|
||||
//a dirty workaround for preprocessor magic that prevents the use types with comma in it in BOOST_FUSION_ADAPT_STRUCT
|
||||
//see http://comments.gmane.org/gmane.comp.lib.boost.user/62501 for some info
|
||||
//
|
||||
//moreover, I encountered a quite serious bug in boost: http://boost.2283326.n4.nabble.com/container-hpp-111-error-C2039-value-type-is-not-a-member-of-td3352328.html
|
||||
//not sure how serious it is...
|
||||
|
||||
//typedef std::variant<char, TStringConstant, TMacroUsage, TMacroDef> bodyItem;
|
||||
typedef std::vector<TBodyOption> Tbody;
|
||||
|
||||
struct Tinstruction
|
||||
{
|
||||
TCmdName name;
|
||||
std::optional<Tidentifier> identifier;
|
||||
std::optional<Tcondition> condition;
|
||||
Tbody body;
|
||||
};
|
||||
|
||||
struct Treceiver
|
||||
{
|
||||
TCmdName name;
|
||||
std::optional<Tidentifier> identifier;
|
||||
std::optional<Tcondition> condition;
|
||||
std::optional<Tbody> body;
|
||||
};
|
||||
|
||||
struct Tcommand
|
||||
{
|
||||
typedef std::variant<
|
||||
Ttrigger,
|
||||
Tinstruction,
|
||||
Treceiver,
|
||||
TPostTrigger
|
||||
>
|
||||
Tcmd;
|
||||
Tcmd cmd;
|
||||
//std::string comment;
|
||||
};
|
||||
|
||||
//vector expression
|
||||
|
||||
|
||||
typedef std::variant<Tcommand, std::string, boost::spirit::unused_type> TERMline;
|
||||
|
||||
typedef std::string TVModifier; //'`', ',', ',@', '#''
|
||||
|
||||
struct TSymbol
|
||||
{
|
||||
std::vector<TVModifier> symModifier;
|
||||
std::string sym;
|
||||
};
|
||||
|
||||
//for #'symbol expression
|
||||
|
||||
enum EVOtions{VEXP, SYMBOL, CHAR, DOUBLE, INT, TCMD, STRINGC};
|
||||
struct TVExp;
|
||||
typedef std::variant<boost::recursive_wrapper<TVExp>, TSymbol, char, double, int, Tcommand, TStringConstant > TVOption; //options in v-expression
|
||||
//v-expression
|
||||
struct TVExp
|
||||
{
|
||||
std::vector<TVModifier> modifier;
|
||||
std::vector<TVOption> children;
|
||||
};
|
||||
|
||||
//script line
|
||||
typedef std::variant<TVExp, TERMline> TLine;
|
||||
|
||||
template <typename T> struct ERM_grammar;
|
||||
}
|
||||
|
||||
struct LineInfo
|
||||
{
|
||||
ERM::TLine tl;
|
||||
int realLineNum;
|
||||
};
|
||||
|
||||
class ERMParser
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<ERM::ERM_grammar<std::string::const_iterator>> ERMgrammar;
|
||||
|
||||
ERMParser();
|
||||
virtual ~ERMParser();
|
||||
|
||||
std::vector<LineInfo> parseFile(CERMPreprocessor & preproc);
|
||||
private:
|
||||
void repairEncoding(char * str, int len) const; //removes nonstandard ascii characters from string
|
||||
void repairEncoding(std::string & str) const; //removes nonstandard ascii characters from string
|
||||
ERM::TLine parseLine(const std::string & line, int realLineNo);
|
||||
ERM::TLine parseLine(const std::string & line);
|
||||
};
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
/*
|
||||
* ERMScriptModule.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "ERMScriptModule.h"
|
||||
|
||||
#include "ERMInterpreter.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define strcpy_s(a, b, c) strncpy(a, c, b)
|
||||
#endif
|
||||
|
||||
const char *g_cszAiName = "(V)ERM interpreter";
|
||||
|
||||
extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
{
|
||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT void GetNewModule(std::shared_ptr<scripting::Module> &out)
|
||||
{
|
||||
out = std::make_shared<ERMScriptModule>();
|
||||
}
|
||||
|
||||
ERMScriptModule::ERMScriptModule()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string ERMScriptModule::compile(const std::string & name, const std::string & source, vstd::CLoggerBase * logger) const
|
||||
{
|
||||
std::shared_ptr<ERMInterpreter> interp = std::make_shared<ERMInterpreter>(logger);
|
||||
|
||||
try
|
||||
{
|
||||
return interp->loadScript(name, source);
|
||||
}
|
||||
catch(const std::exception & ex)
|
||||
{
|
||||
logger->error(ex.what());
|
||||
}
|
||||
catch(const std::string & ex)
|
||||
{
|
||||
logger->error(ex);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
logger->error("Sorry, caught unknown exception type. No more info available.");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::shared_ptr<scripting::ContextBase> ERMScriptModule::createContextFor(const scripting::Script * source, const Environment * env) const
|
||||
{
|
||||
throw std::runtime_error("ERM context creation is not possible");
|
||||
}
|
||||
|
||||
void ERMScriptModule::registerSpellEffect(spells::effects::Registry * registry, const scripting::Script * source) const
|
||||
{
|
||||
throw std::runtime_error("ERM spell effect registration is not possible");
|
||||
}
|
||||
/*
|
||||
* ERMScriptModule.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "ERMScriptModule.h"
|
||||
|
||||
#include "ERMInterpreter.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define strcpy_s(a, b, c) strncpy(a, c, b)
|
||||
#endif
|
||||
|
||||
const char *g_cszAiName = "(V)ERM interpreter";
|
||||
|
||||
extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
{
|
||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT void GetNewModule(std::shared_ptr<scripting::Module> &out)
|
||||
{
|
||||
out = std::make_shared<ERMScriptModule>();
|
||||
}
|
||||
|
||||
ERMScriptModule::ERMScriptModule()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string ERMScriptModule::compile(const std::string & name, const std::string & source, vstd::CLoggerBase * logger) const
|
||||
{
|
||||
std::shared_ptr<ERMInterpreter> interp = std::make_shared<ERMInterpreter>(logger);
|
||||
|
||||
try
|
||||
{
|
||||
return interp->loadScript(name, source);
|
||||
}
|
||||
catch(const std::exception & ex)
|
||||
{
|
||||
logger->error(ex.what());
|
||||
}
|
||||
catch(const std::string & ex)
|
||||
{
|
||||
logger->error(ex);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
logger->error("Sorry, caught unknown exception type. No more info available.");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::shared_ptr<scripting::ContextBase> ERMScriptModule::createContextFor(const scripting::Script * source, const Environment * env) const
|
||||
{
|
||||
throw std::runtime_error("ERM context creation is not possible");
|
||||
}
|
||||
|
||||
void ERMScriptModule::registerSpellEffect(spells::effects::Registry * registry, const scripting::Script * source) const
|
||||
{
|
||||
throw std::runtime_error("ERM spell effect registration is not possible");
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/*
|
||||
* ERMScriptModule.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../lib/CScriptingModule.h"
|
||||
|
||||
class ERMScriptModule : public scripting::Module
|
||||
{
|
||||
public:
|
||||
ERMScriptModule();
|
||||
|
||||
std::string compile(const std::string & name, const std::string & source, vstd::CLoggerBase * logger) const override;
|
||||
|
||||
std::shared_ptr<scripting::ContextBase> createContextFor(const scripting::Script * source, const Environment * env) const override;
|
||||
|
||||
void registerSpellEffect(spells::effects::Registry * registry, const scripting::Script * source) const override;
|
||||
};
|
||||
|
||||
/*
|
||||
* ERMScriptModule.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../lib/CScriptingModule.h"
|
||||
|
||||
class ERMScriptModule : public scripting::Module
|
||||
{
|
||||
public:
|
||||
ERMScriptModule();
|
||||
|
||||
std::string compile(const std::string & name, const std::string & source, vstd::CLoggerBase * logger) const override;
|
||||
|
||||
std::shared_ptr<scripting::ContextBase> createContextFor(const scripting::Script * source, const Environment * env) const override;
|
||||
|
||||
void registerSpellEffect(spells::effects::Registry * registry, const scripting::Script * source) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// Creates the precompiled header
|
||||
// Creates the precompiled header
|
||||
#include "StdInc.h"
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../Global.h"
|
||||
|
||||
// This header should be treated as a pre compiled header file(PCH) in the compiler building settings.
|
||||
|
||||
// Here you can add specific libraries and macros which are specific to this project.
|
||||
|
||||
VCMI_LIB_USING_NAMESPACE
|
||||
#pragma once
|
||||
|
||||
#include "../../Global.h"
|
||||
|
||||
// This header should be treated as a pre compiled header file(PCH) in the compiler building settings.
|
||||
|
||||
// Here you can add specific libraries and macros which are specific to this project.
|
||||
|
||||
VCMI_LIB_USING_NAMESPACE
|
||||
|
||||
Reference in New Issue
Block a user