]> granicus.if.org Git - icinga2/blob - lib/config/configcompiler.hpp
Turn includes into AST expressions
[icinga2] / lib / config / configcompiler.hpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org)    *
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 <boost/function.hpp>
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(void) 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 struct ZoneFragment
68 {
69         String Tag;
70         String Path;
71 };
72
73 /**
74  * The configuration compiler can be used to compile a configuration file
75  * into a number of configuration items.
76  *
77  * @ingroup config
78  */
79 class I2_CONFIG_API ConfigCompiler
80 {
81 public:
82         explicit ConfigCompiler(const String& path, std::istream *input,
83             const String& zone = String(), const String& package = String());
84         virtual ~ConfigCompiler(void);
85
86         Expression *Compile(void);
87
88         static Expression *CompileStream(const String& path, std::istream *stream,
89             const String& zone = String(), const String& package = String());
90         static Expression *CompileFile(const String& path, const String& zone = String(),
91             const String& package = String());
92         static Expression *CompileText(const String& path, const String& text,
93             const String& zone = String(), const String& package = String());
94
95         static void AddIncludeSearchDir(const String& dir);
96
97         const char *GetPath(void) const;
98
99         void SetZone(const String& zone);
100         String GetZone(void) const;
101         
102         void SetPackage(const String& package);
103         String GetPackage(void) const;
104
105         static void CollectIncludes(std::vector<Expression *>& expressions,
106             const String& file, const String& zone, const String& package);
107
108         static Expression *HandleInclude(const String& relativeBase, const String& path, bool search,
109             const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
110         static Expression *HandleIncludeRecursive(const String& relativeBase, const String& path,
111             const String& pattern, const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
112         static Expression *HandleIncludeZones(const String& relativeBase, const String& tag,
113             const String& path, const String& pattern, const String& package, const DebugInfo& debuginfo = DebugInfo());
114
115         size_t ReadInput(char *buffer, size_t max_bytes);
116         void *GetScanner(void) const;
117
118         static std::vector<ZoneFragment> GetZoneDirs(const String& zone);
119         static void RegisterZoneDir(const String& tag, const String& ppath, const String& zoneName);
120
121         static const std::vector<String>& GetKeywords(void);
122
123 private:
124         boost::promise<boost::shared_ptr<Expression> > m_Promise;
125
126         String m_Path;
127         std::istream *m_Input;
128         String m_Zone;
129         String m_Package;
130
131         void *m_Scanner;
132
133         static std::vector<String> m_IncludeSearchDirs;
134         static boost::mutex m_ZoneDirsMutex;
135         static std::map<String, std::vector<ZoneFragment> > m_ZoneDirs;
136
137         void InitializeScanner(void);
138         void DestroyScanner(void);
139
140         static void HandleIncludeZone(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, std::vector<Expression *>& expressions);
141
142 public:
143         bool m_Eof;
144         int m_OpenBraces;
145
146         std::ostringstream m_LexBuffer;
147         CompilerDebugInfo m_LocationBegin;
148
149         std::stack<bool> m_IgnoreNewlines;
150         std::stack<bool> m_Apply;
151         std::stack<bool> m_ObjectAssign;
152         std::stack<bool> m_SeenAssign;
153         std::stack<bool> m_SeenIgnore;
154         std::stack<Expression *> m_Assign;
155         std::stack<Expression *> m_Ignore;
156         std::stack<String> m_FKVar;
157         std::stack<String> m_FVVar;
158         std::stack<Expression *> m_FTerm;
159 };
160
161 }
162
163 #endif /* CONFIGCOMPILER_H */