mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 04:58:21 +00:00

For backward compatibility when reading values, we first check the ZEEK-prefixed value, and if not set, then check the corresponding BRO-prefixed value.
389 lines
8.5 KiB
C++
389 lines
8.5 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#ifndef ZEEKYGEN_TARGET_H
|
|
#define ZEEKYGEN_TARGET_H
|
|
|
|
#include "Info.h"
|
|
#include "PackageInfo.h"
|
|
#include "ScriptInfo.h"
|
|
#include "IdentifierInfo.h"
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <cstdio>
|
|
|
|
namespace zeekygen {
|
|
|
|
/**
|
|
* Helper class to create files in arbitrary file paths and automatically
|
|
* close it on destruction.
|
|
*/
|
|
struct TargetFile {
|
|
/**
|
|
* Open a file.
|
|
* @param arg_name Path to a file to create. It's a fatal error if
|
|
* creating it fails. Creating it will also create any intermediate
|
|
* directories that don't already exist.
|
|
*
|
|
*/
|
|
explicit TargetFile(const std::string& arg_name);
|
|
|
|
/**
|
|
* Close the file.
|
|
*/
|
|
~TargetFile();
|
|
|
|
std::string name; /**< File name. */
|
|
FILE* f; /**< File stream. */
|
|
};
|
|
|
|
/**
|
|
* A Zeekygen target abstract base class. A target is generally any portion of
|
|
* documentation that Bro can build. It's identified by a type (e.g. script,
|
|
* identifier, package), a pattern (e.g. "example.zeek", "HTTP::Info"), and
|
|
* a path to an output file.
|
|
*/
|
|
class Target {
|
|
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param arg_name output file name of the target.
|
|
* @param arg_pattern pattern of info objects the target depends upon. Only
|
|
* exact string and simple prefix matching is currently allowed.
|
|
*/
|
|
Target(const std::string& arg_name, const std::string& arg_pattern);
|
|
|
|
/**
|
|
* Dtor.
|
|
*/
|
|
virtual ~Target()
|
|
{ }
|
|
|
|
/**
|
|
* Filter out any dependency information from a set of all known info.
|
|
* @param infos All known info objects.
|
|
*/
|
|
void FindDependencies(const std::vector<Info*>& infos)
|
|
{ DoFindDependencies(infos); }
|
|
|
|
/**
|
|
* Build the target by generating its output file. Implementations may
|
|
* not always write to the output file if they determine an existing
|
|
* version is already up-to-date.
|
|
*/
|
|
void Generate() const
|
|
{ DoGenerate(); }
|
|
|
|
/**
|
|
* Check if a particular info object matches the target pattern.
|
|
* Currently only exact string and simple prefix matching patterns are
|
|
* used. E.g. for prefix matching "HTTP::*" or "base/protocols/http*".
|
|
* @param info An info object for some thing that is documentable.
|
|
* @return true if it matches, else false.
|
|
*/
|
|
bool MatchesPattern(Info* info) const;
|
|
|
|
/**
|
|
* @return The output file name of the target.
|
|
*/
|
|
std::string Name() const
|
|
{ return name; }
|
|
|
|
/**
|
|
* @return The pattern string of the target.
|
|
*/
|
|
std::string Pattern() const
|
|
{ return pattern; }
|
|
|
|
private:
|
|
|
|
virtual void DoFindDependencies(const std::vector<Info*>& infos) = 0;
|
|
|
|
virtual void DoGenerate() const = 0;
|
|
|
|
std::string name;
|
|
std::string pattern;
|
|
std::string prefix;
|
|
};
|
|
|
|
template<class T>
|
|
static Target* create_target(const std::string& name,
|
|
const std::string& pattern)
|
|
{
|
|
return new T(name, pattern);
|
|
}
|
|
|
|
/**
|
|
* Factory for creating Target instances.
|
|
*/
|
|
class TargetFactory {
|
|
|
|
public:
|
|
|
|
/**
|
|
* Register a new target type.
|
|
* @param type_name The target type name as it will appear in Zeekygen
|
|
* config files.
|
|
*/
|
|
template<class T>
|
|
void Register(const std::string& type_name)
|
|
{
|
|
target_creators[type_name] = &create_target<T>;
|
|
}
|
|
|
|
/**
|
|
* Instantiate a target.
|
|
* @param type_name The target type name as it appears in Zeekygen config
|
|
* files.
|
|
* @param name The output file name of the target.
|
|
* @param pattern The dependency pattern of the target.
|
|
* @return A new target instance or a pointer if \a type_name is not
|
|
* registered.
|
|
*/
|
|
Target* Create(const std::string& type_name,
|
|
const std::string& name, const std::string& pattern)
|
|
{
|
|
target_creator_map::const_iterator it = target_creators.find(type_name);
|
|
|
|
if ( it == target_creators.end() )
|
|
return 0;
|
|
|
|
return it->second(name, pattern);
|
|
}
|
|
|
|
private:
|
|
|
|
typedef Target* (*TargetFactoryFn)(const std::string& name,
|
|
const std::string& pattern);
|
|
typedef std::map<std::string, TargetFactoryFn> target_creator_map;
|
|
target_creator_map target_creators;
|
|
};
|
|
|
|
/**
|
|
* Target to build analyzer documentation.
|
|
*/
|
|
class AnalyzerTarget : public Target {
|
|
public:
|
|
|
|
/**
|
|
* Writes out plugin index documentation for all analyzer plugins.
|
|
* @param f an open file stream to write docs into.
|
|
*/
|
|
void CreateAnalyzerDoc(FILE* f) const
|
|
{ return DoCreateAnalyzerDoc(f); }
|
|
|
|
protected:
|
|
|
|
typedef void (*doc_creator_fn)(FILE*);
|
|
|
|
AnalyzerTarget(const std::string& name, const std::string& pattern)
|
|
: Target(name, pattern)
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoFindDependencies(const std::vector<Info*>& infos) override;
|
|
|
|
void DoGenerate() const override;
|
|
|
|
virtual void DoCreateAnalyzerDoc(FILE* f) const = 0;
|
|
};
|
|
|
|
/**
|
|
* Target to build protocol analyzer documentation.
|
|
*/
|
|
class ProtoAnalyzerTarget : public AnalyzerTarget {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
ProtoAnalyzerTarget(const std::string& name, const std::string& pattern)
|
|
: AnalyzerTarget(name, pattern)
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoCreateAnalyzerDoc(FILE* f) const override;
|
|
};
|
|
|
|
/**
|
|
* Target to build file analyzer documentation.
|
|
*/
|
|
class FileAnalyzerTarget : public AnalyzerTarget {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
FileAnalyzerTarget(const std::string& name, const std::string& pattern)
|
|
: AnalyzerTarget(name, pattern)
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoCreateAnalyzerDoc(FILE* f) const override;
|
|
};
|
|
|
|
/**
|
|
* Target to build package documentation.
|
|
*/
|
|
class PackageTarget : public Target {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
PackageTarget(const std::string& name, const std::string& pattern)
|
|
: Target(name, pattern), pkg_deps(), script_deps(), pkg_manifest()
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoFindDependencies(const std::vector<Info*>& infos) override;
|
|
|
|
void DoGenerate() const override;
|
|
|
|
std::vector<PackageInfo*> pkg_deps;
|
|
std::vector<ScriptInfo*> script_deps;
|
|
typedef std::map<PackageInfo*,std::vector<ScriptInfo*> > manifest_t;
|
|
manifest_t pkg_manifest;
|
|
};
|
|
|
|
/**
|
|
* Target to build package index documentation.
|
|
*/
|
|
class PackageIndexTarget : public Target {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
PackageIndexTarget(const std::string& name, const std::string& pattern)
|
|
: Target(name, pattern), pkg_deps()
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoFindDependencies(const std::vector<Info*>& infos) override;
|
|
|
|
void DoGenerate() const override;
|
|
|
|
std::vector<PackageInfo*> pkg_deps;
|
|
};
|
|
|
|
/**
|
|
* Target to build script documentation.
|
|
*/
|
|
class ScriptTarget : public Target {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name or directory. If it's a directory,
|
|
* then one document for each script that matches the pattern is written to
|
|
* the directory in a directory structure which mirrors the script's path
|
|
* relative to a component in ZEEKPATH.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
ScriptTarget(const std::string& name, const std::string& pattern)
|
|
: Target(name, pattern), script_deps()
|
|
{ }
|
|
|
|
~ScriptTarget() override
|
|
{ for ( size_t i = 0; i < pkg_deps.size(); ++i ) delete pkg_deps[i]; }
|
|
|
|
protected:
|
|
|
|
std::vector<ScriptInfo*> script_deps;
|
|
|
|
private:
|
|
|
|
void DoFindDependencies(const std::vector<Info*>& infos) override;
|
|
|
|
void DoGenerate() const override;
|
|
|
|
bool IsDir() const
|
|
{ return Name()[Name().size() - 1] == '/'; }
|
|
|
|
std::vector<Target*> pkg_deps;
|
|
};
|
|
|
|
/**
|
|
* Target to build script summary documentation.
|
|
*/
|
|
class ScriptSummaryTarget : public ScriptTarget {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
ScriptSummaryTarget(const std::string& name, const std::string& pattern)
|
|
: ScriptTarget(name, pattern)
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoGenerate() const override /* override */;
|
|
};
|
|
|
|
/**
|
|
* Target to build script index documentation.
|
|
*/
|
|
class ScriptIndexTarget : public ScriptTarget {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
ScriptIndexTarget(const std::string& name, const std::string& pattern)
|
|
: ScriptTarget(name, pattern)
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoGenerate() const override /* override */;
|
|
};
|
|
|
|
/**
|
|
* Target to build identifier documentation.
|
|
*/
|
|
class IdentifierTarget : public Target {
|
|
public:
|
|
|
|
/**
|
|
* Ctor.
|
|
* @param name Output file name.
|
|
* @param pattern Dependency pattern.
|
|
*/
|
|
IdentifierTarget(const std::string& name, const std::string& pattern)
|
|
: Target(name, pattern), id_deps()
|
|
{ }
|
|
|
|
private:
|
|
|
|
void DoFindDependencies(const std::vector<Info*>& infos) override;
|
|
|
|
void DoGenerate() const override;
|
|
|
|
std::vector<IdentifierInfo*> id_deps;
|
|
};
|
|
|
|
} // namespace zeekygen
|
|
|
|
#endif
|