-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.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. *
- ******************************************************************************/
+/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
#include "config/configcompiler.hpp"
#include "config/configitem.hpp"
#include "base/exception.hpp"
#include <fstream>
-#ifdef _WIN32
-# include <shlwapi.h>
-#endif /* _WIN32 */
-
using namespace icinga;
std::vector<String> ConfigCompiler::m_IncludeSearchDirs;
* Constructor for the ConfigCompiler class.
*
* @param path The path of the configuration file (or another name that
- * identifies the source of the configuration text).
+ * identifies the source of the configuration text).
* @param input Input stream for the configuration file.
* @param zone The zone.
*/
-ConfigCompiler::ConfigCompiler(const String& path, std::istream *input,
- const String& zone, const String& package)
- : m_Path(path), m_Input(input), m_Zone(zone), m_Package(package),
- m_Eof(false), m_OpenBraces(0)
+ConfigCompiler::ConfigCompiler(String path, std::istream *input,
+ String zone, String package)
+ : m_Path(std::move(path)), m_Input(input), m_Zone(std::move(zone)),
+ m_Package(std::move(package)), m_Eof(false), m_OpenBraces(0)
{
InitializeScanner();
}
/**
* Destructor for the ConfigCompiler class.
*/
-ConfigCompiler::~ConfigCompiler(void)
+ConfigCompiler::~ConfigCompiler()
{
DestroyScanner();
}
*
* @returns The scanner object.
*/
-void *ConfigCompiler::GetScanner(void) const
+void *ConfigCompiler::GetScanner() const
{
return m_Scanner;
}
*
* @returns The path.
*/
-const char *ConfigCompiler::GetPath(void) const
+const char *ConfigCompiler::GetPath() const
{
return m_Path.CStr();
}
m_Zone = zone;
}
-String ConfigCompiler::GetZone(void) const
+String ConfigCompiler::GetZone() const
{
return m_Zone;
}
m_Package = package;
}
-String ConfigCompiler::GetPackage(void) const
+String ConfigCompiler::GetPackage() const
{
return m_Package;
}
-void ConfigCompiler::CollectIncludes(std::vector<Expression *>& expressions,
- const String& file, const String& zone, const String& package)
+void ConfigCompiler::CollectIncludes(std::vector<std::unique_ptr<Expression> >& expressions,
+ const String& file, const String& zone, const String& package)
{
try {
- Expression *expr = CompileFile(file, zone, package);
- expressions.push_back(expr);
+ expressions.emplace_back(CompileFile(file, zone, package));
} catch (const std::exception& ex) {
Log(LogWarning, "ConfigCompiler")
- << "Cannot compile file '"
- << file << "': " << DiagnosticInformation(ex);
+ << "Cannot compile file '"
+ << file << "': " << DiagnosticInformation(ex);
}
}
* @param search Whether to search global include dirs.
* @param debuginfo Debug information.
*/
-Expression *ConfigCompiler::HandleInclude(const String& relativeBase, const String& path,
- bool search, const String& zone, const String& package, const DebugInfo& debuginfo)
+std::unique_ptr<Expression> ConfigCompiler::HandleInclude(const String& relativeBase, const String& path,
+ bool search, const String& zone, const String& package, const DebugInfo& debuginfo)
{
String upath;
}
}
- std::vector<Expression *> expressions;
+ std::vector<std::unique_ptr<Expression> > expressions;
- if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zone, package), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
+ if (!Utility::Glob(includePath, std::bind(&ConfigCompiler::CollectIncludes, std::ref(expressions), _1, zone, package), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
std::ostringstream msgbuf;
msgbuf << "Include file '" + path + "' does not exist";
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debuginfo));
}
- DictExpression *expr = new DictExpression(expressions);
+ std::unique_ptr<DictExpression> expr{new DictExpression(std::move(expressions))};
expr->MakeInline();
- return expr;
+ return std::move(expr);
}
/**
* @param pattern The file pattern.
* @param debuginfo Debug information.
*/
-Expression *ConfigCompiler::HandleIncludeRecursive(const String& relativeBase, const String& path,
- const String& pattern, const String& zone, const String& package, const DebugInfo&)
+std::unique_ptr<Expression> ConfigCompiler::HandleIncludeRecursive(const String& relativeBase, const String& path,
+ const String& pattern, const String& zone, const String& package, const DebugInfo&)
{
String ppath;
else
ppath = relativeBase + "/" + path;
- std::vector<Expression *> expressions;
- Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zone, package), GlobFile);
+ std::vector<std::unique_ptr<Expression> > expressions;
+ Utility::GlobRecursive(ppath, pattern, std::bind(&ConfigCompiler::CollectIncludes, std::ref(expressions), _1, zone, package), GlobFile);
- DictExpression *dict = new DictExpression(expressions);
+ std::unique_ptr<DictExpression> dict{new DictExpression(std::move(expressions))};
dict->MakeInline();
- return dict;
+ return std::move(dict);
}
-void ConfigCompiler::HandleIncludeZone(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, std::vector<Expression *>& expressions)
+void ConfigCompiler::HandleIncludeZone(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, std::vector<std::unique_ptr<Expression> >& expressions)
{
String zoneName = Utility::BaseName(path);
RegisterZoneDir(tag, ppath, zoneName);
- Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zoneName, package), GlobFile);
+ Utility::GlobRecursive(ppath, pattern, std::bind(&ConfigCompiler::CollectIncludes, std::ref(expressions), _1, zoneName, package), GlobFile);
}
/**
* @param pattern The file pattern.
* @param debuginfo Debug information.
*/
-Expression *ConfigCompiler::HandleIncludeZones(const String& relativeBase, const String& tag,
- const String& path, const String& pattern, const String& package, const DebugInfo&)
+std::unique_ptr<Expression> ConfigCompiler::HandleIncludeZones(const String& relativeBase, const String& tag,
+ const String& path, const String& pattern, const String& package, const DebugInfo&)
{
String ppath;
String newRelativeBase = relativeBase;
newRelativeBase = ".";
}
- std::vector<Expression *> expressions;
- Utility::Glob(ppath + "/*", boost::bind(&ConfigCompiler::HandleIncludeZone, newRelativeBase, tag, _1, pattern, package, boost::ref(expressions)), GlobDirectory);
- return new DictExpression(expressions);
+ std::vector<std::unique_ptr<Expression> > expressions;
+ Utility::Glob(ppath + "/*", std::bind(&ConfigCompiler::HandleIncludeZone, newRelativeBase, tag, _1, pattern, package, std::ref(expressions)), GlobDirectory);
+ return std::unique_ptr<Expression>(new DictExpression(std::move(expressions)));
}
/**
* @param stream The input stream.
* @returns Configuration items.
*/
-Expression *ConfigCompiler::CompileStream(const String& path,
- std::istream *stream, const String& zone, const String& package)
+std::unique_ptr<Expression> ConfigCompiler::CompileStream(const String& path,
+ std::istream *stream, const String& zone, const String& package)
{
CONTEXT("Compiling configuration stream with name '" + path + "'");
try {
return ctx.Compile();
} catch (const ScriptError& ex) {
- return new ThrowExpression(MakeLiteral(ex.what()), ex.IsIncompleteExpression(), ex.GetDebugInfo());
+ return std::unique_ptr<Expression>(new ThrowExpression(MakeLiteral(ex.what()), ex.IsIncompleteExpression(), ex.GetDebugInfo()));
} catch (const std::exception& ex) {
- return new ThrowExpression(MakeLiteral(DiagnosticInformation(ex)), false);
+ return std::unique_ptr<Expression>(new ThrowExpression(MakeLiteral(DiagnosticInformation(ex)), false));
}
}
* @param path The path.
* @returns Configuration items.
*/
-Expression *ConfigCompiler::CompileFile(const String& path, const String& zone,
- const String& package)
+std::unique_ptr<Expression> ConfigCompiler::CompileFile(const String& path, const String& zone,
+ const String& package)
{
CONTEXT("Compiling configuration file '" + path + "'");
<< boost::errinfo_file_name(path));
Log(LogNotice, "ConfigCompiler")
- << "Compiling config file: " << path;
+ << "Compiling config file: " << path;
return CompileStream(path, &stream, zone, package);
}
* @param text The text.
* @returns Configuration items.
*/
-Expression *ConfigCompiler::CompileText(const String& path, const String& text,
- const String& zone, const String& package)
+std::unique_ptr<Expression> ConfigCompiler::CompileText(const String& path, const String& text,
+ const String& zone, const String& package)
{
std::stringstream stream(text);
return CompileStream(path, &stream, zone, package);
void ConfigCompiler::AddIncludeSearchDir(const String& dir)
{
Log(LogInformation, "ConfigCompiler")
- << "Adding include search dir: " << dir;
+ << "Adding include search dir: " << dir;
m_IncludeSearchDirs.push_back(dir);
}
if (!empty) {
std::vector<String> paths;
+ paths.reserve(zoneDirs.size());
+
for (const ZoneFragment& zf : zoneDirs) {
paths.push_back(zf.Path);
}
Log(LogNotice, "ConfigCompiler")
- << "Registered authoritative config directories for zone '" << zoneName << "': " << Utility::NaturalJoin(paths);
+ << "Registered authoritative config directories for zone '" << zoneName << "': " << Utility::NaturalJoin(paths);
}
return !empty;
#endif /* _WIN32 */
}
+void ConfigCompiler::AddImport(const std::shared_ptr<Expression>& import)
+{
+ m_Imports.push_back(import);
+}
+
+std::vector<std::shared_ptr<Expression> > ConfigCompiler::GetImports() const
+{
+ return m_Imports;
+}