summaryrefslogtreecommitdiffstats
path: root/lib/config/configcompiler.hpp
blob: fe00bedfc66227a347e14a31c49ed195cac9db03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* 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 <future>
#include <iostream>
#include <stack>

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<Expression> Compile();

	static std::unique_ptr<Expression>CompileStream(const String& path, std::istream *stream,
		const String& zone = String(), const String& package = String());
	static std::unique_ptr<Expression>CompileFile(const String& path, const String& zone = String(),
		const String& package = String());
	static std::unique_ptr<Expression>CompileText(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<Expression::Ptr> GetImports() const;

	static void CollectIncludes(std::vector<std::unique_ptr<Expression> >& expressions,
		const String& file, const String& zone, const String& package);

	static std::unique_ptr<Expression> HandleInclude(const String& relativeBase, const String& path, bool search,
		const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
	static std::unique_ptr<Expression> HandleIncludeRecursive(const String& relativeBase, const String& path,
		const String& pattern, const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
	static std::unique_ptr<Expression> 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<ZoneFragment> 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<Expression::Ptr> m_Promise;

	String m_Path;
	std::istream *m_Input;
	String m_Zone;
	String m_Package;
	std::vector<Expression::Ptr> m_Imports;

	void *m_Scanner;

	static std::vector<String> m_IncludeSearchDirs;
	static std::mutex m_ZoneDirsMutex;
	static std::map<String, std::vector<ZoneFragment> > 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<std::unique_ptr<Expression> >& expressions);

	static bool IsAbsolutePath(const String& path);

public:
	bool m_Eof;
	int m_OpenBraces;

	String m_LexBuffer;
	CompilerDebugInfo m_LocationBegin;

	std::stack<bool> m_IgnoreNewlines;
	std::stack<bool> m_Apply;
	std::stack<bool> m_ObjectAssign;
	std::stack<bool> m_SeenAssign;
	std::stack<bool> m_SeenIgnore;
	std::stack<Expression *> m_Assign;
	std::stack<Expression *> m_Ignore;
	std::stack<String> m_FKVar;
	std::stack<String> m_FVVar;
	std::stack<Expression *> m_FTerm;
	std::stack<int> m_FlowControlInfo;
};

}

#endif /* CONFIGCOMPILER_H */