summaryrefslogtreecommitdiffstats
path: root/tools/mkclass/classcompiler.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mkclass/classcompiler.hpp')
-rw-r--r--tools/mkclass/classcompiler.hpp245
1 files changed, 245 insertions, 0 deletions
diff --git a/tools/mkclass/classcompiler.hpp b/tools/mkclass/classcompiler.hpp
new file mode 100644
index 0000000..0bd789d
--- /dev/null
+++ b/tools/mkclass/classcompiler.hpp
@@ -0,0 +1,245 @@
+/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
+
+#ifndef CLASSCOMPILER_H
+#define CLASSCOMPILER_H
+
+#include <string>
+#include <istream>
+#include <utility>
+#include <vector>
+#include <algorithm>
+#include <map>
+
+namespace icinga
+{
+
+struct ClassDebugInfo
+{
+ std::string path;
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+
+enum FieldAccessorType
+{
+ FTGet,
+ FTSet,
+ FTDefault,
+ FTTrack,
+ FTNavigate
+};
+
+struct FieldAccessor
+{
+ FieldAccessorType Type;
+ std::string Accessor;
+ bool Pure;
+
+ FieldAccessor(FieldAccessorType type, std::string accessor, bool pure)
+ : Type(type), Accessor(std::move(accessor)), Pure(pure)
+ { }
+};
+
+/* keep this in sync with lib/base/type.hpp */
+enum FieldAttribute
+{
+ FAEphemeral = 1,
+ FAConfig = 2,
+ FAState = 4,
+ FAEnum = 8,
+ FAGetProtected = 16,
+ FASetProtected = 32,
+ FANoStorage = 64,
+ FALoadDependency = 128,
+ FARequired = 256,
+ FANavigation = 512,
+ FANoUserModify = 1024,
+ FANoUserView = 2048,
+ FADeprecated = 4096,
+ FAGetVirtual = 8192,
+ FASetVirtual = 16384,
+ FAActivationPriority = 32768,
+ FASignalWithOldValue = 65536,
+};
+
+struct FieldType
+{
+ bool IsName{false};
+ std::string TypeName;
+ int ArrayRank{0};
+
+ inline std::string GetRealType() const
+ {
+ if (ArrayRank > 0)
+ return "Array::Ptr";
+
+ if (IsName)
+ return "String";
+
+ return TypeName;
+ }
+
+ inline std::string GetArgumentType() const
+ {
+ std::string realType = GetRealType();
+
+ if (realType == "bool" || realType == "double" || realType == "int")
+ return realType;
+ else
+ return "const " + realType + "&";
+ }
+};
+
+struct Field
+{
+ int Attributes{0};
+ FieldType Type;
+ std::string Name;
+ std::string AlternativeName;
+ std::string GetAccessor;
+ bool PureGetAccessor{false};
+ std::string SetAccessor;
+ bool PureSetAccessor{false};
+ std::string DefaultAccessor;
+ std::string TrackAccessor;
+ std::string NavigationName;
+ std::string NavigateAccessor;
+ bool PureNavigateAccessor{false};
+ int Priority{0};
+
+ inline std::string GetFriendlyName() const
+ {
+ if (!AlternativeName.empty())
+ return AlternativeName;
+
+ bool cap = true;
+ std::string name = Name;
+
+ for (char& ch : name) {
+ if (ch == '_') {
+ cap = true;
+ continue;
+ }
+
+ if (cap) {
+ ch = toupper(ch);
+ cap = false;
+ }
+ }
+
+ name.erase(
+ std::remove(name.begin(), name.end(), '_'),
+ name.end()
+ );
+
+ /* TODO: figure out name */
+ return name;
+ }
+};
+
+enum TypeAttribute
+{
+ TAAbstract = 1,
+ TAVarArgConstructor = 2
+};
+
+struct Klass
+{
+ std::string Name;
+ std::string Parent;
+ std::string TypeBase;
+ int Attributes;
+ std::vector<Field> Fields;
+ std::vector<std::string> LoadDependencies;
+ int ActivationPriority{0};
+};
+
+enum RuleAttribute
+{
+ RARequired = 1
+};
+
+struct Rule
+{
+ int Attributes;
+ bool IsName;
+ std::string Type;
+ std::string Pattern;
+
+ std::vector<Rule> Rules;
+};
+
+enum ValidatorType
+{
+ ValidatorField,
+ ValidatorArray,
+ ValidatorDictionary
+};
+
+struct Validator
+{
+ std::string Name;
+ std::vector<Rule> Rules;
+};
+
+class ClassCompiler
+{
+public:
+ ClassCompiler(std::string path, std::istream& input, std::ostream& oimpl, std::ostream& oheader);
+ ~ClassCompiler();
+
+ void Compile();
+
+ std::string GetPath() const;
+
+ void InitializeScanner();
+ void DestroyScanner();
+
+ void *GetScanner();
+
+ 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);
+ void HandleImplInclude(const std::string& path, const ClassDebugInfo& locp);
+ void HandleAngleImplInclude(const std::string& path, const ClassDebugInfo& locp);
+ void HandleClass(const Klass& klass, const ClassDebugInfo& locp);
+ void HandleValidator(const Validator& validator, const ClassDebugInfo& locp);
+ void HandleNamespaceBegin(const std::string& name, const ClassDebugInfo& locp);
+ void HandleNamespaceEnd(const ClassDebugInfo& locp);
+ void HandleCode(const std::string& code, const ClassDebugInfo& locp);
+ void HandleLibrary(const std::string& library, const ClassDebugInfo& locp);
+ void HandleMissingValidators();
+
+ 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,
+ const std::string& headerpath);
+ static void CompileStream(const std::string& path, std::istream& input,
+ std::ostream& oimpl, std::ostream& oheader);
+
+ static void OptimizeStructLayout(std::vector<Field>& fields);
+
+private:
+ std::string m_Path;
+ std::istream& m_Input;
+ std::ostream& m_Impl;
+ std::ostream& m_Header;
+ void *m_Scanner;
+
+ std::string m_Library;
+
+ std::map<std::pair<std::string, std::string>, Field> m_MissingValidators;
+
+ static unsigned long SDBM(const std::string& str, size_t len);
+ static std::string BaseName(const std::string& path);
+ static std::string FileNameToGuardName(const std::string& path);
+};
+
+}
+
+#endif /* CLASSCOMPILER_H */
+