/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ #ifndef CONFIGCOMPILER_H #define CONFIGCOMPILER_H #include "config/i2-config.hpp" #include "config/expression.hpp" #include "base/debuginfo.hpp" #include "base/registry.hpp" #include "base/initialize.hpp" #include "base/singleton.hpp" #include "base/string.hpp" #include #include #include typedef union YYSTYPE YYSTYPE; typedef void *yyscan_t; namespace icinga { struct CompilerDebugInfo { const char *Path; int FirstLine; int FirstColumn; int LastLine; int LastColumn; operator DebugInfo() const { DebugInfo di; di.Path = Path; di.FirstLine = FirstLine; di.FirstColumn = FirstColumn; di.LastLine = LastLine; di.LastColumn = LastColumn; return di; } }; struct EItemInfo { bool SideEffect; CompilerDebugInfo DebugInfo; }; enum FlowControlType { FlowControlReturn = 1, FlowControlContinue = 2, FlowControlBreak = 4 }; struct ZoneFragment { String Tag; String Path; }; /** * The configuration compiler can be used to compile a configuration file * into a number of configuration items. * * @ingroup config */ class ConfigCompiler { public: explicit ConfigCompiler(String path, std::istream *input, String zone = String(), String package = String()); virtual ~ConfigCompiler(); std::unique_ptr Compile(); static std::unique_ptrCompileStream(const String& path, std::istream *stream, const String& zone = String(), const String& package = String()); static std::unique_ptrCompileFile(const String& path, const String& zone = String(), const String& package = String()); static std::unique_ptrCompileText(const String& path, const String& text, const String& zone = String(), const String& package = String()); static void AddIncludeSearchDir(const String& dir); const char *GetPath() const; void SetZone(const String& zone); String GetZone() const; void SetPackage(const String& package); String GetPackage() const; void AddImport(const Expression::Ptr& import); std::vector GetImports() const; static void CollectIncludes(std::vector >& expressions, const String& file, const String& zone, const String& package); static std::unique_ptr HandleInclude(const String& relativeBase, const String& path, bool search, const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo()); static std::unique_ptr HandleIncludeRecursive(const String& relativeBase, const String& path, const String& pattern, const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo()); static std::unique_ptr HandleIncludeZones(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, const DebugInfo& debuginfo = DebugInfo()); size_t ReadInput(char *buffer, size_t max_bytes); void *GetScanner() const; static std::vector GetZoneDirs(const String& zone); static void RegisterZoneDir(const String& tag, const String& ppath, const String& zoneName); static bool HasZoneConfigAuthority(const String& zoneName); private: std::promise m_Promise; String m_Path; std::istream *m_Input; String m_Zone; String m_Package; std::vector m_Imports; void *m_Scanner; static std::vector m_IncludeSearchDirs; static std::mutex m_ZoneDirsMutex; static std::map > m_ZoneDirs; void InitializeScanner(); void DestroyScanner(); static void HandleIncludeZone(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, std::vector >& expressions); static bool IsAbsolutePath(const String& path); public: bool m_Eof; int m_OpenBraces; String m_LexBuffer; CompilerDebugInfo m_LocationBegin; std::stack m_IgnoreNewlines; std::stack m_Apply; std::stack m_ObjectAssign; std::stack m_SeenAssign; std::stack m_SeenIgnore; std::stack m_Assign; std::stack m_Ignore; std::stack m_FKVar; std::stack m_FVVar; std::stack m_FTerm; std::stack m_FlowControlInfo; }; } #endif /* CONFIGCOMPILER_H */