]> granicus.if.org Git - icinga2/blob - lib/config/configcompiler.hpp
Merge pull request #6510 from Icinga/feature/windows-build-scripts
[icinga2] / lib / config / configcompiler.hpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #ifndef CONFIGCOMPILER_H
21 #define CONFIGCOMPILER_H
22
23 #include "config/i2-config.hpp"
24 #include "config/expression.hpp"
25 #include "base/debuginfo.hpp"
26 #include "base/registry.hpp"
27 #include "base/initialize.hpp"
28 #include "base/singleton.hpp"
29 #include <future>
30 #include <iostream>
31 #include <stack>
32
33 typedef union YYSTYPE YYSTYPE;
34 typedef void *yyscan_t;
35
36 namespace icinga
37 {
38
39 struct CompilerDebugInfo
40 {
41         const char *Path;
42
43         int FirstLine;
44         int FirstColumn;
45
46         int LastLine;
47         int LastColumn;
48
49         operator DebugInfo() const
50         {
51                 DebugInfo di;
52                 di.Path = Path;
53                 di.FirstLine = FirstLine;
54                 di.FirstColumn = FirstColumn;
55                 di.LastLine = LastLine;
56                 di.LastColumn = LastColumn;
57                 return di;
58         }
59 };
60
61 struct EItemInfo
62 {
63         bool SideEffect;
64         CompilerDebugInfo DebugInfo;
65 };
66
67 enum FlowControlType
68 {
69         FlowControlReturn = 1,
70         FlowControlContinue = 2,
71         FlowControlBreak = 4
72 };
73
74 struct ZoneFragment
75 {
76         String Tag;
77         String Path;
78 };
79
80 /**
81  * The configuration compiler can be used to compile a configuration file
82  * into a number of configuration items.
83  *
84  * @ingroup config
85  */
86 class ConfigCompiler
87 {
88 public:
89         explicit ConfigCompiler(String path, std::istream *input,
90                 String zone = String(), String package = String());
91         virtual ~ConfigCompiler();
92
93         std::unique_ptr<Expression> Compile();
94
95         static std::unique_ptr<Expression>CompileStream(const String& path, std::istream *stream,
96                 const String& zone = String(), const String& package = String());
97         static std::unique_ptr<Expression>CompileFile(const String& path, const String& zone = String(),
98                 const String& package = String());
99         static std::unique_ptr<Expression>CompileText(const String& path, const String& text,
100                 const String& zone = String(), const String& package = String());
101
102         static void AddIncludeSearchDir(const String& dir);
103
104         const char *GetPath() const;
105
106         void SetZone(const String& zone);
107         String GetZone() const;
108
109         void SetPackage(const String& package);
110         String GetPackage() const;
111
112         void AddImport(const std::shared_ptr<Expression>& import);
113         std::vector<std::shared_ptr<Expression> > GetImports() const;
114
115         static void CollectIncludes(std::vector<std::unique_ptr<Expression> >& expressions,
116                 const String& file, const String& zone, const String& package);
117
118         static std::unique_ptr<Expression> HandleInclude(const String& relativeBase, const String& path, bool search,
119                 const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
120         static std::unique_ptr<Expression> HandleIncludeRecursive(const String& relativeBase, const String& path,
121                 const String& pattern, const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
122         static std::unique_ptr<Expression> HandleIncludeZones(const String& relativeBase, const String& tag,
123                 const String& path, const String& pattern, const String& package, const DebugInfo& debuginfo = DebugInfo());
124
125         size_t ReadInput(char *buffer, size_t max_bytes);
126         void *GetScanner() const;
127
128         static std::vector<ZoneFragment> GetZoneDirs(const String& zone);
129         static void RegisterZoneDir(const String& tag, const String& ppath, const String& zoneName);
130
131         static bool HasZoneConfigAuthority(const String& zoneName);
132
133 private:
134         std::promise<std::shared_ptr<Expression> > m_Promise;
135
136         String m_Path;
137         std::istream *m_Input;
138         String m_Zone;
139         String m_Package;
140         std::vector<std::shared_ptr<Expression> > m_Imports;
141
142         void *m_Scanner;
143
144         static std::vector<String> m_IncludeSearchDirs;
145         static boost::mutex m_ZoneDirsMutex;
146         static std::map<String, std::vector<ZoneFragment> > m_ZoneDirs;
147
148         void InitializeScanner();
149         void DestroyScanner();
150
151         static void HandleIncludeZone(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, std::vector<std::unique_ptr<Expression> >& expressions);
152
153         static bool IsAbsolutePath(const String& path);
154
155 public:
156         bool m_Eof;
157         int m_OpenBraces;
158
159         std::ostringstream m_LexBuffer;
160         CompilerDebugInfo m_LocationBegin;
161
162         std::stack<bool> m_IgnoreNewlines;
163         std::stack<bool> m_Apply;
164         std::stack<bool> m_ObjectAssign;
165         std::stack<bool> m_SeenAssign;
166         std::stack<bool> m_SeenIgnore;
167         std::stack<Expression *> m_Assign;
168         std::stack<Expression *> m_Ignore;
169         std::stack<String> m_FKVar;
170         std::stack<String> m_FVVar;
171         std::stack<Expression *> m_FTerm;
172         std::stack<int> m_FlowControlInfo;
173 };
174
175 }
176
177 #endif /* CONFIGCOMPILER_H */