/****************************************************************************** * Icinga 2 * * Copyright (C) 2012-2018 Icinga Development Team (https://icinga.com/) * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software Foundation * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ #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 #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 std::shared_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 boost::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; std::ostringstream 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 */