2019-02-25 14:48:22 +01:00
|
|
|
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
2013-10-26 09:41:45 +02:00
|
|
|
|
|
|
|
#ifndef CLASSCOMPILER_H
|
|
|
|
#define CLASSCOMPILER_H
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <istream>
|
2018-01-04 08:54:18 +01:00
|
|
|
#include <utility>
|
2013-10-26 09:41:45 +02:00
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
2014-11-30 23:32:13 +01:00
|
|
|
#include <map>
|
2013-10-26 09:41:45 +02:00
|
|
|
|
|
|
|
namespace icinga
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ClassDebugInfo
|
|
|
|
{
|
|
|
|
std::string path;
|
|
|
|
int first_line;
|
|
|
|
int first_column;
|
|
|
|
int last_line;
|
|
|
|
int last_column;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum FieldAccessorType
|
|
|
|
{
|
|
|
|
FTGet,
|
|
|
|
FTSet,
|
2015-08-25 13:53:43 +02:00
|
|
|
FTDefault,
|
2015-09-22 09:42:30 +02:00
|
|
|
FTTrack,
|
|
|
|
FTNavigate
|
2013-10-26 09:41:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FieldAccessor
|
|
|
|
{
|
|
|
|
FieldAccessorType Type;
|
|
|
|
std::string Accessor;
|
2015-02-09 08:50:17 +01:00
|
|
|
bool Pure;
|
2013-10-26 09:41:45 +02:00
|
|
|
|
2018-01-04 08:54:18 +01:00
|
|
|
FieldAccessor(FieldAccessorType type, std::string accessor, bool pure)
|
|
|
|
: Type(type), Accessor(std::move(accessor)), Pure(pure)
|
2013-10-26 09:41:45 +02:00
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
2015-03-11 16:06:58 +01:00
|
|
|
/* keep this in sync with lib/base/type.hpp */
|
2013-10-26 09:41:45 +02:00
|
|
|
enum FieldAttribute
|
|
|
|
{
|
2015-03-11 16:06:58 +01:00
|
|
|
FAEphemeral = 1,
|
|
|
|
FAConfig = 2,
|
|
|
|
FAState = 4,
|
|
|
|
FAEnum = 8,
|
|
|
|
FAGetProtected = 16,
|
|
|
|
FASetProtected = 32,
|
2015-10-20 08:20:35 +02:00
|
|
|
FANoStorage = 64,
|
|
|
|
FALoadDependency = 128,
|
|
|
|
FARequired = 256,
|
|
|
|
FANavigation = 512,
|
|
|
|
FANoUserModify = 1024,
|
2017-10-16 15:32:57 +02:00
|
|
|
FANoUserView = 2048,
|
2017-11-15 09:47:23 +01:00
|
|
|
FADeprecated = 4096,
|
|
|
|
FAGetVirtual = 8192,
|
2018-04-26 15:53:11 +02:00
|
|
|
FASetVirtual = 16384,
|
2021-10-08 16:43:09 +02:00
|
|
|
FAActivationPriority = 32768,
|
|
|
|
FASignalWithOldValue = 65536,
|
2014-11-30 23:32:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FieldType
|
|
|
|
{
|
2018-01-04 09:43:49 +01:00
|
|
|
bool IsName{false};
|
2014-11-30 23:32:13 +01:00
|
|
|
std::string TypeName;
|
2018-01-04 09:43:49 +01:00
|
|
|
int ArrayRank{0};
|
2014-11-30 23:32:13 +01:00
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
inline std::string GetRealType() const
|
2014-11-30 23:32:13 +01:00
|
|
|
{
|
2015-08-25 13:53:43 +02:00
|
|
|
if (ArrayRank > 0)
|
|
|
|
return "Array::Ptr";
|
|
|
|
|
2014-11-30 23:32:13 +01:00
|
|
|
if (IsName)
|
|
|
|
return "String";
|
2015-08-25 13:53:43 +02:00
|
|
|
|
|
|
|
return TypeName;
|
2014-11-30 23:32:13 +01:00
|
|
|
}
|
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
inline std::string GetArgumentType() const
|
2014-11-30 23:32:13 +01:00
|
|
|
{
|
|
|
|
std::string realType = GetRealType();
|
|
|
|
|
|
|
|
if (realType == "bool" || realType == "double" || realType == "int")
|
|
|
|
return realType;
|
|
|
|
else
|
|
|
|
return "const " + realType + "&";
|
|
|
|
}
|
2013-10-26 09:41:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Field
|
|
|
|
{
|
2018-01-04 09:43:49 +01:00
|
|
|
int Attributes{0};
|
2014-11-30 23:32:13 +01:00
|
|
|
FieldType Type;
|
2013-10-26 09:41:45 +02:00
|
|
|
std::string Name;
|
|
|
|
std::string AlternativeName;
|
|
|
|
std::string GetAccessor;
|
2018-01-04 09:43:49 +01:00
|
|
|
bool PureGetAccessor{false};
|
2013-10-26 09:41:45 +02:00
|
|
|
std::string SetAccessor;
|
2018-01-04 09:43:49 +01:00
|
|
|
bool PureSetAccessor{false};
|
2013-10-26 09:41:45 +02:00
|
|
|
std::string DefaultAccessor;
|
2015-08-25 13:53:43 +02:00
|
|
|
std::string TrackAccessor;
|
2015-09-22 09:42:30 +02:00
|
|
|
std::string NavigationName;
|
|
|
|
std::string NavigateAccessor;
|
2018-01-04 09:43:49 +01:00
|
|
|
bool PureNavigateAccessor{false};
|
2018-04-26 15:53:11 +02:00
|
|
|
int Priority{0};
|
2015-02-09 12:37:29 +01:00
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
inline std::string GetFriendlyName() const
|
2013-10-26 09:41:45 +02:00
|
|
|
{
|
|
|
|
if (!AlternativeName.empty())
|
|
|
|
return AlternativeName;
|
|
|
|
|
|
|
|
bool cap = true;
|
|
|
|
std::string name = Name;
|
|
|
|
|
2018-01-04 08:15:20 +01:00
|
|
|
for (char& ch : name) {
|
|
|
|
if (ch == '_') {
|
2013-10-26 09:41:45 +02:00
|
|
|
cap = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cap) {
|
2018-01-04 08:15:20 +01:00
|
|
|
ch = toupper(ch);
|
2013-10-26 09:41:45 +02:00
|
|
|
cap = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
name.erase(
|
|
|
|
std::remove(name.begin(), name.end(), '_'),
|
|
|
|
name.end()
|
|
|
|
);
|
|
|
|
|
|
|
|
/* TODO: figure out name */
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-12-18 10:18:57 +01:00
|
|
|
enum TypeAttribute
|
|
|
|
{
|
2016-03-29 12:45:22 +02:00
|
|
|
TAAbstract = 1,
|
|
|
|
TAVarArgConstructor = 2
|
2013-12-18 10:18:57 +01:00
|
|
|
};
|
|
|
|
|
2013-10-26 09:41:45 +02:00
|
|
|
struct Klass
|
|
|
|
{
|
|
|
|
std::string Name;
|
|
|
|
std::string Parent;
|
2014-04-05 22:17:20 +02:00
|
|
|
std::string TypeBase;
|
2013-12-18 10:18:57 +01:00
|
|
|
int Attributes;
|
2013-10-26 09:41:45 +02:00
|
|
|
std::vector<Field> Fields;
|
2015-02-25 12:43:03 +01:00
|
|
|
std::vector<std::string> LoadDependencies;
|
2018-04-26 15:53:11 +02:00
|
|
|
int ActivationPriority{0};
|
2013-10-26 09:41:45 +02:00
|
|
|
};
|
|
|
|
|
2014-11-30 23:32:13 +01:00
|
|
|
enum RuleAttribute
|
|
|
|
{
|
|
|
|
RARequired = 1
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Rule
|
|
|
|
{
|
|
|
|
int Attributes;
|
|
|
|
bool IsName;
|
|
|
|
std::string Type;
|
|
|
|
std::string Pattern;
|
|
|
|
|
|
|
|
std::vector<Rule> Rules;
|
|
|
|
};
|
|
|
|
|
2015-03-28 11:04:42 +01:00
|
|
|
enum ValidatorType
|
|
|
|
{
|
|
|
|
ValidatorField,
|
|
|
|
ValidatorArray,
|
|
|
|
ValidatorDictionary
|
|
|
|
};
|
|
|
|
|
2014-11-30 23:32:13 +01:00
|
|
|
struct Validator
|
|
|
|
{
|
|
|
|
std::string Name;
|
|
|
|
std::vector<Rule> Rules;
|
|
|
|
};
|
|
|
|
|
2013-10-26 09:41:45 +02:00
|
|
|
class ClassCompiler
|
|
|
|
{
|
|
|
|
public:
|
2018-01-04 08:54:18 +01:00
|
|
|
ClassCompiler(std::string path, std::istream& input, std::ostream& oimpl, std::ostream& oheader);
|
2018-01-04 04:25:35 +01:00
|
|
|
~ClassCompiler();
|
2013-10-26 09:41:45 +02:00
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
void Compile();
|
2013-10-26 09:41:45 +02:00
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
std::string GetPath() const;
|
2013-10-26 09:41:45 +02:00
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
void InitializeScanner();
|
|
|
|
void DestroyScanner();
|
2013-10-26 09:41:45 +02:00
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
void *GetScanner();
|
2013-10-26 09:41:45 +02:00
|
|
|
|
|
|
|
size_t ReadInput(char *buffer, size_t max_size);
|
|
|
|
|
|
|
|
void HandleInclude(const std::string& path, const ClassDebugInfo& locp);
|
|
|
|
void HandleAngleInclude(const std::string& path, const ClassDebugInfo& locp);
|
2015-08-25 13:53:43 +02:00
|
|
|
void HandleImplInclude(const std::string& path, const ClassDebugInfo& locp);
|
|
|
|
void HandleAngleImplInclude(const std::string& path, const ClassDebugInfo& locp);
|
2013-10-26 09:41:45 +02:00
|
|
|
void HandleClass(const Klass& klass, const ClassDebugInfo& locp);
|
2014-11-30 23:32:13 +01:00
|
|
|
void HandleValidator(const Validator& validator, const ClassDebugInfo& locp);
|
2013-10-26 09:41:45 +02:00
|
|
|
void HandleNamespaceBegin(const std::string& name, const ClassDebugInfo& locp);
|
|
|
|
void HandleNamespaceEnd(const ClassDebugInfo& locp);
|
|
|
|
void HandleCode(const std::string& code, const ClassDebugInfo& locp);
|
2015-08-04 14:47:44 +02:00
|
|
|
void HandleLibrary(const std::string& library, const ClassDebugInfo& locp);
|
2018-01-04 04:25:35 +01:00
|
|
|
void HandleMissingValidators();
|
2013-10-26 09:41:45 +02:00
|
|
|
|
2015-03-28 11:04:42 +01:00
|
|
|
void CodeGenValidator(const std::string& name, const std::string& klass, const std::vector<Rule>& rules, const std::string& field, const FieldType& fieldType, ValidatorType validatorType);
|
|
|
|
void CodeGenValidatorSubrules(const std::string& name, const std::string& klass, const std::vector<Rule>& rules);
|
|
|
|
|
|
|
|
static void CompileFile(const std::string& inputpath, const std::string& implpath,
|
2017-12-19 15:50:05 +01:00
|
|
|
const std::string& headerpath);
|
2015-03-28 11:04:42 +01:00
|
|
|
static void CompileStream(const std::string& path, std::istream& input,
|
2017-12-19 15:50:05 +01:00
|
|
|
std::ostream& oimpl, std::ostream& oheader);
|
2013-10-26 09:41:45 +02:00
|
|
|
|
2014-11-07 23:07:02 +01:00
|
|
|
static void OptimizeStructLayout(std::vector<Field>& fields);
|
|
|
|
|
2013-10-26 09:41:45 +02:00
|
|
|
private:
|
|
|
|
std::string m_Path;
|
2015-03-28 11:04:42 +01:00
|
|
|
std::istream& m_Input;
|
|
|
|
std::ostream& m_Impl;
|
|
|
|
std::ostream& m_Header;
|
2013-10-26 09:41:45 +02:00
|
|
|
void *m_Scanner;
|
2013-12-13 12:54:14 +01:00
|
|
|
|
2015-08-04 14:47:44 +02:00
|
|
|
std::string m_Library;
|
|
|
|
|
2014-11-30 23:32:13 +01:00
|
|
|
std::map<std::pair<std::string, std::string>, Field> m_MissingValidators;
|
|
|
|
|
2013-12-13 12:54:14 +01:00
|
|
|
static unsigned long SDBM(const std::string& str, size_t len);
|
2014-09-09 13:30:54 +02:00
|
|
|
static std::string BaseName(const std::string& path);
|
|
|
|
static std::string FileNameToGuardName(const std::string& path);
|
2013-10-26 09:41:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-11-03 10:41:30 +01:00
|
|
|
#endif /* CLASSCOMPILER_H */
|
|
|
|
|