mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Broxygen can now read a config file specifying particular targets.
Though nothing currently gets built as most dependency/outdated checks and doc-generation methods are still skeleton code.
This commit is contained in:
parent
1fabbd441c
commit
bdd359d58c
9 changed files with 325 additions and 24 deletions
|
@ -6,8 +6,9 @@ include_directories(BEFORE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(broxygen_SRCS
|
set(broxygen_SRCS
|
||||||
Manager.cc
|
Configuration.cc
|
||||||
Document.cc
|
Document.cc
|
||||||
|
Manager.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
bif_target(broxygen.bif)
|
bif_target(broxygen.bif)
|
||||||
|
|
123
src/broxygen/Configuration.cc
Normal file
123
src/broxygen/Configuration.cc
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
#include "Configuration.h"
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "Reporter.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
using namespace broxygen;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
typedef map<string, Target::factory_fn> target_factory_map;
|
||||||
|
|
||||||
|
static target_factory_map create_target_factory_map()
|
||||||
|
{
|
||||||
|
target_factory_map rval;
|
||||||
|
rval["package_index"] = &PackageTarget::Instantiate;
|
||||||
|
rval["package"] = &PackageTarget::Instantiate;
|
||||||
|
rval["proto_analyzer"] = &ProtoAnalyzerTarget::Instantiate;
|
||||||
|
rval["file_analyzer"] = &FileAnalyzerTarget::Instantiate;
|
||||||
|
rval["script_summary"] = &ScriptTarget::Instantiate;
|
||||||
|
rval["script_index"] = &ScriptTarget::Instantiate;
|
||||||
|
rval["script"] = &ScriptTarget::Instantiate;
|
||||||
|
rval["identifier"] = &IdentifierTarget::Instantiate;
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static target_factory_map target_instantiators = create_target_factory_map();
|
||||||
|
|
||||||
|
bool Target::MatchesPattern(Document* doc) const
|
||||||
|
{
|
||||||
|
// TODO: prefix matching or full regex?
|
||||||
|
|
||||||
|
if ( doc->Name() == pattern )
|
||||||
|
{
|
||||||
|
DBG_LOG(DBG_BROXYGEN, "Doc '%s'' matched pattern for target '%s'",
|
||||||
|
doc->Name().c_str(), name.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void filter_matching_docs(const std::vector<Document*>& filter_from, Target* t)
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < filter_from.size(); ++i )
|
||||||
|
{
|
||||||
|
T* d = dynamic_cast<T*>(filter_from[i]);
|
||||||
|
|
||||||
|
if ( ! d )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( t->MatchesPattern(d) )
|
||||||
|
t->AddDependency(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdentifierTarget::DoFindDependencies(const std::vector<Document*>& docs)
|
||||||
|
{
|
||||||
|
filter_matching_docs<IdentifierDocument>(docs, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::Config(const string& file, const string& delim)
|
||||||
|
{
|
||||||
|
if ( file.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ifstream f(file.c_str());
|
||||||
|
|
||||||
|
if ( ! f.is_open() )
|
||||||
|
reporter->InternalError("failed to open Broxygen config file %s: %s",
|
||||||
|
file.c_str(), strerror(errno));
|
||||||
|
|
||||||
|
string line;
|
||||||
|
|
||||||
|
while ( getline(f, line) )
|
||||||
|
{
|
||||||
|
vector<string> tokens;
|
||||||
|
tokenize_string(line, delim, &tokens);
|
||||||
|
tokens.erase(remove(tokens.begin(), tokens.end(), ""), tokens.end());
|
||||||
|
|
||||||
|
if ( tokens.size() != 3 )
|
||||||
|
reporter->InternalError("malformed Broxygen target: %s",
|
||||||
|
line.c_str());
|
||||||
|
|
||||||
|
target_factory_map::const_iterator it =
|
||||||
|
target_instantiators.find(tokens[0]);
|
||||||
|
|
||||||
|
if ( it == target_instantiators.end() )
|
||||||
|
reporter->InternalError("unkown Broxygen target type: %s",
|
||||||
|
tokens[0].c_str());
|
||||||
|
|
||||||
|
targets.push_back(it->second(tokens[1], tokens[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( f.bad() )
|
||||||
|
reporter->InternalError("error reading Broxygen config file %s: %s",
|
||||||
|
file.c_str(), strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::~Config()
|
||||||
|
{
|
||||||
|
for ( target_list::const_iterator it = targets.begin();
|
||||||
|
it != targets.end(); ++it )
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::FindDependencies(const vector<Document*>& docs)
|
||||||
|
{
|
||||||
|
for ( target_list::const_iterator it = targets.begin();
|
||||||
|
it != targets.end(); ++it )
|
||||||
|
(*it)->FindDependencies(docs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::GenerateDocs() const
|
||||||
|
{
|
||||||
|
for ( target_list::const_iterator it = targets.begin();
|
||||||
|
it != targets.end(); ++it )
|
||||||
|
(*it)->Generate();
|
||||||
|
}
|
169
src/broxygen/Configuration.h
Normal file
169
src/broxygen/Configuration.h
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
#ifndef BROXYGEN_CONFIGURATION_H
|
||||||
|
#define BROXYGEN_CONFIGURATION_H
|
||||||
|
|
||||||
|
#include "Document.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace broxygen {
|
||||||
|
|
||||||
|
// TODO: documentation...
|
||||||
|
|
||||||
|
class Target {
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Target* (*factory_fn)(const std::string&, const std::string&);
|
||||||
|
|
||||||
|
virtual ~Target() { }
|
||||||
|
|
||||||
|
void FindDependencies(const std::vector<Document*>& docs)
|
||||||
|
{ DoFindDependencies(docs); }
|
||||||
|
|
||||||
|
void Generate() const
|
||||||
|
{ DoGenerate(); }
|
||||||
|
|
||||||
|
bool MatchesPattern(Document* doc) const;
|
||||||
|
|
||||||
|
void AddDependency(Document* doc)
|
||||||
|
{ dependencies.push_back(doc); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Target(const std::string& arg_name, const std::string& arg_pattern)
|
||||||
|
: name(arg_name), pattern(arg_pattern)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::string pattern;
|
||||||
|
std::list<Document*> dependencies;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual void DoFindDependencies(const std::vector<Document*>& docs) = 0;
|
||||||
|
|
||||||
|
virtual void DoGenerate() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProtoAnalyzerTarget : public Target {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Target* Instantiate(const std::string& name,
|
||||||
|
const std::string& pattern)
|
||||||
|
{ return new ProtoAnalyzerTarget(name, pattern); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ProtoAnalyzerTarget(const std::string& name, const std::string& pattern)
|
||||||
|
: Target(name, pattern)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void DoFindDependencies(const std::vector<Document*>& docs)
|
||||||
|
{ /* TODO */ }
|
||||||
|
|
||||||
|
void DoGenerate() const
|
||||||
|
{ /* TODO */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileAnalyzerTarget : public Target {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Target* Instantiate(const std::string& name,
|
||||||
|
const std::string& pattern)
|
||||||
|
{ return new FileAnalyzerTarget(name, pattern); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FileAnalyzerTarget(const std::string& name, const std::string& pattern)
|
||||||
|
: Target(name, pattern)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void DoFindDependencies(const std::vector<Document*>& docs)
|
||||||
|
{ /* TODO */ }
|
||||||
|
|
||||||
|
void DoGenerate() const
|
||||||
|
{ /* TODO */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackageTarget : public Target {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Target* Instantiate(const std::string& name,
|
||||||
|
const std::string& pattern)
|
||||||
|
{ return new PackageTarget(name, pattern); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
PackageTarget(const std::string& name, const std::string& pattern)
|
||||||
|
: Target(name, pattern)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void DoFindDependencies(const std::vector<Document*>& docs)
|
||||||
|
{ /* TODO */ }
|
||||||
|
|
||||||
|
void DoGenerate() const
|
||||||
|
{ /* TODO */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScriptTarget : public Target {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Target* Instantiate(const std::string& name,
|
||||||
|
const std::string& pattern)
|
||||||
|
{ return new ScriptTarget(name, pattern); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ScriptTarget(const std::string& name, const std::string& pattern)
|
||||||
|
: Target(name, pattern)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void DoFindDependencies(const std::vector<Document*>& docs)
|
||||||
|
{ /* TODO */ }
|
||||||
|
|
||||||
|
void DoGenerate() const
|
||||||
|
{ /* TODO */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
class IdentifierTarget : public Target {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Target* Instantiate(const std::string& name,
|
||||||
|
const std::string& pattern)
|
||||||
|
{ return new IdentifierTarget(name, pattern); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
IdentifierTarget(const std::string& name, const std::string& pattern)
|
||||||
|
: Target(name, pattern)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void DoFindDependencies(const std::vector<Document*>& docs);
|
||||||
|
|
||||||
|
void DoGenerate() const
|
||||||
|
{ /* TODO */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Config {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Config(const std::string& file, const std::string& delim = "\t");
|
||||||
|
|
||||||
|
~Config();
|
||||||
|
|
||||||
|
void FindDependencies(const std::vector<Document*>& docs);
|
||||||
|
|
||||||
|
void GenerateDocs() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef std::list<Target*> target_list;
|
||||||
|
|
||||||
|
target_list targets;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace broxygen
|
||||||
|
|
||||||
|
#endif
|
|
@ -48,11 +48,11 @@ IdentifierDocument::~IdentifierDocument()
|
||||||
{
|
{
|
||||||
Unref(id);
|
Unref(id);
|
||||||
|
|
||||||
for ( RedefList::const_iterator it = redefs.begin(); it != redefs.end();
|
for ( redef_list::const_iterator it = redefs.begin(); it != redefs.end();
|
||||||
++it )
|
++it )
|
||||||
delete *it;
|
delete *it;
|
||||||
|
|
||||||
for ( RecordFieldMap::const_iterator it = fields.begin();
|
for ( record_field_map::const_iterator it = fields.begin();
|
||||||
it != fields.end(); ++it )
|
it != fields.end(); ++it )
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ string IdentifierDocument::GetComments() const
|
||||||
|
|
||||||
string IdentifierDocument::GetFieldComments(const string& field) const
|
string IdentifierDocument::GetFieldComments(const string& field) const
|
||||||
{
|
{
|
||||||
RecordFieldMap::const_iterator it = fields.find(field);
|
record_field_map::const_iterator it = fields.find(field);
|
||||||
|
|
||||||
if ( it == fields.end() )
|
if ( it == fields.end() )
|
||||||
return string();
|
return string();
|
||||||
|
|
|
@ -116,14 +116,14 @@ private:
|
||||||
std::vector<std::string> comments;
|
std::vector<std::string> comments;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<Redefinition*> RedefList;
|
typedef std::list<Redefinition*> redef_list;
|
||||||
typedef std::map<std::string, RecordField*> RecordFieldMap;
|
typedef std::map<std::string, RecordField*> record_field_map;
|
||||||
|
|
||||||
std::vector<std::string> comments;
|
std::vector<std::string> comments;
|
||||||
ID* id;
|
ID* id;
|
||||||
string initial_val_desc;
|
string initial_val_desc;
|
||||||
RedefList redefs;
|
redef_list redefs;
|
||||||
RecordFieldMap fields;
|
record_field_map fields;
|
||||||
RecordField* last_field_seen;
|
RecordField* last_field_seen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -83,13 +83,13 @@ static string PrettifyParams(const string& s)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::Manager(const string& config)
|
Manager::Manager(const string& arg_config)
|
||||||
: disabled(), comment_buffer(), comment_buffer_map(), packages(), scripts(),
|
: disabled(), comment_buffer(), comment_buffer_map(), packages(), scripts(),
|
||||||
identifiers(), all_docs(), last_identifier_seen(), incomplete_type()
|
identifiers(), all_docs(), last_identifier_seen(), incomplete_type(),
|
||||||
|
config(arg_config)
|
||||||
{
|
{
|
||||||
if ( getenv("BRO_DISABLE_BROXYGEN") )
|
if ( getenv("BRO_DISABLE_BROXYGEN") )
|
||||||
disabled = true;
|
disabled = true;
|
||||||
// TODO config file stuff
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::~Manager()
|
Manager::~Manager()
|
||||||
|
@ -109,16 +109,16 @@ void Manager::InitPostScript()
|
||||||
{
|
{
|
||||||
if ( disabled )
|
if ( disabled )
|
||||||
return;
|
return;
|
||||||
// TODO: dependency resolution stuff?
|
|
||||||
|
config.FindDependencies(all_docs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::GenerateDocs() const
|
void Manager::GenerateDocs() const
|
||||||
{
|
{
|
||||||
if ( disabled )
|
if ( disabled )
|
||||||
return;
|
return;
|
||||||
// TODO
|
|
||||||
|
|
||||||
// may be a no-op if no config file
|
config.GenerateDocs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::File(const string& path)
|
void Manager::File(const string& path)
|
||||||
|
@ -214,7 +214,8 @@ IdentifierDocument* Manager::CreateIdentifierDoc(ID* id, ScriptDocument* script)
|
||||||
rval->AddComments(comment_buffer);
|
rval->AddComments(comment_buffer);
|
||||||
comment_buffer.clear();
|
comment_buffer.clear();
|
||||||
|
|
||||||
CommentBufferMap::const_iterator it = comment_buffer_map.find(id->Name());
|
comment_buffer_map_t::const_iterator it =
|
||||||
|
comment_buffer_map.find(id->Name());
|
||||||
|
|
||||||
if ( it != comment_buffer_map.end() )
|
if ( it != comment_buffer_map.end() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef BROXYGEN_MANAGER_H
|
#ifndef BROXYGEN_MANAGER_H
|
||||||
#define BROXYGEN_MANAGER_H
|
#define BROXYGEN_MANAGER_H
|
||||||
|
|
||||||
|
#include "Configuration.h"
|
||||||
#include "Document.h"
|
#include "Document.h"
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
|
@ -16,15 +17,15 @@ namespace broxygen {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct DocumentMap {
|
struct DocumentMap {
|
||||||
typedef std::map<std::string, T*> MapType;
|
typedef std::map<std::string, T*> map_type;
|
||||||
|
|
||||||
T* GetDocument(const std::string& name) const
|
T* GetDocument(const std::string& name) const
|
||||||
{
|
{
|
||||||
typename MapType::const_iterator it = map.find(name);
|
typename map_type::const_iterator it = map.find(name);
|
||||||
return it == map.end() ? 0 : it->second;
|
return it == map.end() ? 0 : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapType map;
|
map_type map;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Manager {
|
class Manager {
|
||||||
|
@ -75,20 +76,21 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef std::vector<std::string> CommentBuffer;
|
typedef std::vector<std::string> comment_buffer_t;
|
||||||
typedef std::map<std::string, CommentBuffer> CommentBufferMap;
|
typedef std::map<std::string, comment_buffer_t> comment_buffer_map_t;
|
||||||
|
|
||||||
IdentifierDocument* CreateIdentifierDoc(ID* id, ScriptDocument* script);
|
IdentifierDocument* CreateIdentifierDoc(ID* id, ScriptDocument* script);
|
||||||
|
|
||||||
bool disabled;
|
bool disabled;
|
||||||
CommentBuffer comment_buffer; // For whatever next identifier that comes in.
|
comment_buffer_t comment_buffer; // For whatever next identifier that comes in.
|
||||||
CommentBufferMap comment_buffer_map; // For a particular identifier.
|
comment_buffer_map_t comment_buffer_map; // For a particular identifier.
|
||||||
DocumentMap<PackageDocument> packages;
|
DocumentMap<PackageDocument> packages;
|
||||||
DocumentMap<ScriptDocument> scripts;
|
DocumentMap<ScriptDocument> scripts;
|
||||||
DocumentMap<IdentifierDocument> identifiers;
|
DocumentMap<IdentifierDocument> identifiers;
|
||||||
std::vector<Document*> all_docs;
|
std::vector<Document*> all_docs;
|
||||||
IdentifierDocument* last_identifier_seen;
|
IdentifierDocument* last_identifier_seen;
|
||||||
IdentifierDocument* incomplete_type;
|
IdentifierDocument* incomplete_type;
|
||||||
|
Config config;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace broxygen
|
} // namespace broxygen
|
||||||
|
|
|
@ -996,8 +996,8 @@ string flatten_script_name(const string& name, const string& prefix)
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vector<string>* tokenize_string(string input, const string& delim,
|
vector<string>* tokenize_string(string input, const string& delim,
|
||||||
vector<string>* rval)
|
vector<string>* rval)
|
||||||
{
|
{
|
||||||
if ( ! rval )
|
if ( ! rval )
|
||||||
rval = new vector<string>();
|
rval = new vector<string>();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -105,6 +106,10 @@ std::string extract_ip_and_len(const std::string& i, int* len);
|
||||||
std::string get_unescaped_string(const std::string& str);
|
std::string get_unescaped_string(const std::string& str);
|
||||||
std::string get_escaped_string(const std::string& str, bool escape_all);
|
std::string get_escaped_string(const std::string& str, bool escape_all);
|
||||||
|
|
||||||
|
std::vector<std::string>* tokenize_string(std::string input,
|
||||||
|
const std::string& delim,
|
||||||
|
std::vector<std::string>* rval = 0);
|
||||||
|
|
||||||
extern char* copy_string(const char* s);
|
extern char* copy_string(const char* s);
|
||||||
extern int streq(const char* s1, const char* s2);
|
extern int streq(const char* s1, const char* s2);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue