From eee16e1177310154ae049626f9a92a99e8f7a753 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 7 Jun 2013 13:19:36 -0500 Subject: [PATCH 1/2] const adjustments --- src/analyzer/Component.cc | 2 +- src/analyzer/Component.h | 2 +- src/plugin/Component.cc | 2 +- src/plugin/Component.h | 2 +- src/plugin/Plugin.cc | 18 +++++++++--------- src/plugin/Plugin.h | 18 +++++++++--------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/analyzer/Component.cc b/src/analyzer/Component.cc index 5844da848f..f7da1d530c 100644 --- a/src/analyzer/Component.cc +++ b/src/analyzer/Component.cc @@ -58,7 +58,7 @@ analyzer::Tag Component::Tag() const return tag; } -void Component::Describe(ODesc* d) +void Component::Describe(ODesc* d) const { plugin::Component::Describe(d); d->Add(name); diff --git a/src/analyzer/Component.h b/src/analyzer/Component.h index b766c2fe82..0bc081c3e1 100644 --- a/src/analyzer/Component.h +++ b/src/analyzer/Component.h @@ -120,7 +120,7 @@ public: * Generates a human-readable description of the component's main * parameters. This goes into the output of \c "bro -NN". */ - virtual void Describe(ODesc* d); + virtual void Describe(ODesc* d) const; Component& operator=(const Component& other); diff --git a/src/plugin/Component.cc b/src/plugin/Component.cc index 7d2e69eb86..c6f0e02174 100644 --- a/src/plugin/Component.cc +++ b/src/plugin/Component.cc @@ -21,7 +21,7 @@ component::Type Component::Type() const return type; } -void Component::Describe(ODesc* d) +void Component::Describe(ODesc* d) const { d->Add(" "); d->Add("["); diff --git a/src/plugin/Component.h b/src/plugin/Component.h index fbeb70ebed..dadf054a3c 100644 --- a/src/plugin/Component.h +++ b/src/plugin/Component.h @@ -57,7 +57,7 @@ public: * * @param d The description object to use. */ - virtual void Describe(ODesc* d); + virtual void Describe(ODesc* d) const; private: component::Type type; diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 352aff6aed..084c49f51e 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -59,7 +59,7 @@ Plugin::~Plugin() delete [] description; } -const char* Plugin::Name() +const char* Plugin::Name() const { return name; } @@ -69,7 +69,7 @@ void Plugin::SetName(const char* arg_name) name = copy_string(arg_name); } -const char* Plugin::Description() +const char* Plugin::Description() const { return description; } @@ -79,7 +79,7 @@ void Plugin::SetDescription(const char* arg_description) description = copy_string(arg_description); } -int Plugin::Version() +int Plugin::Version() const { return dynamic ? version : 0; } @@ -89,12 +89,12 @@ void Plugin::SetVersion(int arg_version) version = arg_version; } -int Plugin::APIVersion() +int Plugin::APIVersion() const { return api_version; } -bool Plugin::DynamicPlugin() +bool Plugin::DynamicPlugin() const { return dynamic; } @@ -127,7 +127,7 @@ void Plugin::InitPostScript() } } -Plugin::bif_item_list Plugin::BifItems() +Plugin::bif_item_list Plugin::BifItems() const { bif_item_list l1 = bif_items; bif_item_list l2 = CustomBifItems(); @@ -138,7 +138,7 @@ Plugin::bif_item_list Plugin::BifItems() return l1; } -Plugin::bif_item_list Plugin::CustomBifItems() +Plugin::bif_item_list Plugin::CustomBifItems() const { return bif_item_list(); } @@ -151,7 +151,7 @@ void Plugin::Done() components.clear(); } -Plugin::component_list Plugin::Components() +Plugin::component_list Plugin::Components() const { return components; } @@ -166,7 +166,7 @@ void Plugin::AddBifInitFunction(bif_init_func c) bif_inits.push_back(c); } -void Plugin::Describe(ODesc* d) +void Plugin::Describe(ODesc* d) const { d->Add("Plugin: "); d->Add(name); diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 6c6d89a4d1..4abd260550 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -102,24 +102,24 @@ public: /** * Returns the name of the plugin. */ - const char* Name(); + const char* Name() const; /** * Returns a short textual description of the plugin, if provided. */ - const char* Description(); + const char* Description() const; /** * Returns the version of the plugin. Version are only meaningful for * dynamically compiled plugins; for statically compiled ones, this * will always return 0. */ - int Version(); + int Version() const; /** * Returns true if this is a dynamically linked in plugin. */ - bool DynamicPlugin(); + bool DynamicPlugin() const; /** * Returns the internal API version that this plugin relies on. Only @@ -128,18 +128,18 @@ public: * dynamically loaded plugins may cause a mismatch if they were * compiled for a different Bro version. */ - int APIVersion(); + int APIVersion() const; /** * Returns a list of all components the plugin provides. */ - component_list Components(); + component_list Components() const; /** * Returns a list of all BiF items that the plugin provides. This * must be called only after InitBif() has been executed. */ - bif_item_list BifItems(); + bif_item_list BifItems() const; /** * First-stage initialization of the plugin called early during Bro's @@ -171,7 +171,7 @@ public: * is disabled, the rendering will include a list of all components * and BiF items. */ - void Describe(ODesc* d); + void Describe(ODesc* d) const; protected: typedef std::list > bif_init_func_result; @@ -225,7 +225,7 @@ protected: * for informational purpuses only and will show up in the result of * BifItems() as well as in the Describe() output. */ - virtual bif_item_list CustomBifItems() ; + virtual bif_item_list CustomBifItems() const; /** * Internal function adding an entry point for registering From e56a17102ef8288b32095a1dfa5ef72437160975 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 7 Jun 2013 13:21:18 -0500 Subject: [PATCH 2/2] Teach broxygen to generate protocol analyzer plugin reference. --- doc/ext/bro.py | 9 +- doc/index.rst | 2 +- doc/scripts/CMakeLists.txt | 31 ++- doc/scripts/bifs.rst | 5 - scripts/base/frameworks/analyzer/main.bro | 4 +- src/BroDoc.cc | 310 ++++++++++++++++------ src/BroDoc.h | 230 ++++++++-------- src/BroDocObj.cc | 3 + src/BroDocObj.h | 6 + src/Type.cc | 10 + src/Type.h | 2 + src/main.cc | 2 + 12 files changed, 397 insertions(+), 217 deletions(-) delete mode 100644 doc/scripts/bifs.rst diff --git a/doc/ext/bro.py b/doc/ext/bro.py index 9bdd86bd9a..6ef11c37f6 100644 --- a/doc/ext/bro.py +++ b/doc/ext/bro.py @@ -82,7 +82,8 @@ class BroGeneric(ObjectDescription): objects = self.env.domaindata['bro']['objects'] key = (self.objtype, name) - if key in objects: + if ( key in objects and self.objtype != "id" and + self.objtype != "type" ): self.env.warn(self.env.docname, 'duplicate description of %s %s, ' % (self.objtype, name) + @@ -150,6 +151,12 @@ class BroEnum(BroGeneric): #self.indexnode['entries'].append(('single', indextext, # targetname, targetname)) m = sig.split() + + if len(m) < 2: + self.env.warn(self.env.docname, + "bro:enum directive missing argument(s)") + return + if m[1] == "Notice::Type": if 'notices' not in self.env.domaindata['bro']: self.env.domaindata['bro']['notices'] = [] diff --git a/doc/index.rst b/doc/index.rst index 29b29541b4..7704081cab 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -45,7 +45,7 @@ Script Reference scripts/packages scripts/index scripts/builtins - scripts/bifs + scripts/proto-analyzers Other Bro Components -------------------- diff --git a/doc/scripts/CMakeLists.txt b/doc/scripts/CMakeLists.txt index 64c3de92eb..ddb09bb29c 100644 --- a/doc/scripts/CMakeLists.txt +++ b/doc/scripts/CMakeLists.txt @@ -15,11 +15,11 @@ endif () # # srcDir: the directory which contains broInput # broInput: the file name of a bro policy script, any path prefix of this -# argument will be used to derive what path under policy/ the generated +# argument will be used to derive what path under scripts/ the generated # documentation will be placed. # group: optional name of group that the script documentation will belong to. -# If this is not given, .bif files automatically get their own group or -# the group is automatically by any path portion of the broInput argument. +# If this is not given, the group is automatically set to any path portion +# of the broInput argument. # # In addition to adding the makefile target, several CMake variables are set: # @@ -64,8 +64,6 @@ macro(REST_TARGET srcDir broInput) if (NOT "${ARGN}" STREQUAL "") set(group ${ARGN}) - elseif (${broInput} MATCHES "\\.bif\\.bro$") - set(group bifs) elseif (relDstDir) set(group ${relDstDir}/index) # add package index to master package list if not already in it @@ -126,6 +124,29 @@ endmacro(REST_TARGET) # Schedule Bro scripts for which to generate documentation. include(DocSourcesList.cmake) +# This reST target is independent of a particular Bro script... +add_custom_command(OUTPUT proto-analyzers.rst + # delete any leftover state from previous bro runs + COMMAND "${CMAKE_COMMAND}" + ARGS -E remove_directory .state + # generate the reST documentation using bro + COMMAND BROPATH=${BROPATH}:${srcDir} BROMAGIC=${CMAKE_SOURCE_DIR}/magic ${CMAKE_BINARY_DIR}/src/bro + ARGS -b -Z base/init-bare.bro || (rm -rf .state *.log *.rst && exit 1) + # move generated doc into a new directory tree that + # defines the final structure of documents + COMMAND "${CMAKE_COMMAND}" + ARGS -E make_directory ${dstDir} + COMMAND "${CMAKE_COMMAND}" + ARGS -E copy proto-analyzers.rst ${dstDir} + # clean up the build directory + COMMAND rm + ARGS -rf .state *.log *.rst + DEPENDS bro + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "[Bro] Generating reST docs for proto-analyzers.rst" +) +list(APPEND ALL_REST_OUTPUTS proto-analyzers.rst) + # create temporary list of all docs to include in the master policy/index file file(WRITE ${MASTER_POLICY_INDEX} "${MASTER_POLICY_INDEX_TEXT}") diff --git a/doc/scripts/bifs.rst b/doc/scripts/bifs.rst deleted file mode 100644 index eaae0e13b8..0000000000 --- a/doc/scripts/bifs.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. This is a stub doc to which broxygen appends during the build process - -Built-In Functions (BIFs) -========================= - diff --git a/scripts/base/frameworks/analyzer/main.bro b/scripts/base/frameworks/analyzer/main.bro index e2dcf151c7..c7bfd1ce34 100644 --- a/scripts/base/frameworks/analyzer/main.bro +++ b/scripts/base/frameworks/analyzer/main.bro @@ -9,9 +9,7 @@ ##! :bro:enum:`Analyzer::ANALYZER_HTTP`. These tags are defined internally by ##! the analyzers themselves, and documented in their analyzer-specific ##! description along with the events that they generate. -##! -##! .. todo: ``The ANALYZER_*`` are in fact not yet documented, we need to -##! add that to Broxygen. + module Analyzer; export { diff --git a/src/BroDoc.cc b/src/BroDoc.cc index 984bdc90a4..c04cd92eca 100644 --- a/src/BroDoc.cc +++ b/src/BroDoc.cc @@ -8,6 +8,9 @@ #include "BroDoc.h" #include "BroDocObj.h" #include "util.h" +#include "plugin/Manager.h" +#include "analyzer/Manager.h" +#include "analyzer/Component.h" BroDoc::BroDoc(const std::string& rel, const std::string& abs) { @@ -164,84 +167,77 @@ void BroDoc::SetPacketFilter(const std::string& s) packet_filter.clear(); } -void BroDoc::AddPortAnalysis(const std::string& analyzer, - const std::string& ports) - { - std::string reST_string = analyzer + "::\n" + ports + "\n\n"; - port_analysis.push_back(reST_string); - } - void BroDoc::WriteDocFile() const { - WriteToDoc(".. Automatically generated. Do not edit.\n\n"); + WriteToDoc(reST_file, ".. Automatically generated. Do not edit.\n\n"); - WriteToDoc(":tocdepth: 3\n\n"); + WriteToDoc(reST_file, ":tocdepth: 3\n\n"); - WriteSectionHeading(doc_title.c_str(), '='); + WriteSectionHeading(reST_file, doc_title.c_str(), '='); - WriteStringList(".. bro:namespace:: %s\n", modules); + WriteStringList(reST_file, ".. bro:namespace:: %s\n", modules); - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); - // WriteSectionHeading("Overview", '-'); - WriteStringList("%s\n", summary); + // WriteSectionHeading(reST_file, "Overview", '-'); + WriteStringList(reST_file, "%s\n", summary); - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); if ( ! modules.empty() ) { - WriteToDoc(":Namespace%s: ", (modules.size() > 1 ? "s" : "")); - // WriteStringList(":bro:namespace:`%s`", modules); - WriteStringList("``%s``, ", "``%s``", modules); - WriteToDoc("\n"); + WriteToDoc(reST_file, ":Namespace%s: ", (modules.size() > 1 ? "s" : "")); + // WriteStringList(reST_file, ":bro:namespace:`%s`", modules); + WriteStringList(reST_file, "``%s``, ", "``%s``", modules); + WriteToDoc(reST_file, "\n"); } if ( ! imports.empty() ) { - WriteToDoc(":Imports: "); + WriteToDoc(reST_file, ":Imports: "); std::list::const_iterator it; for ( it = imports.begin(); it != imports.end(); ++it ) { if ( it != imports.begin() ) - WriteToDoc(", "); + WriteToDoc(reST_file, ", "); string pretty(*it); size_t pos = pretty.find("/index"); if ( pos != std::string::npos && pos + 6 == pretty.size() ) pretty = pretty.substr(0, pos); - WriteToDoc(":doc:`%s `", pretty.c_str(), it->c_str()); + WriteToDoc(reST_file, ":doc:`%s `", pretty.c_str(), it->c_str()); } - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); } - WriteToDoc(":Source File: :download:`%s`\n", + WriteToDoc(reST_file, ":Source File: :download:`%s`\n", downloadable_filename.c_str()); - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); WriteInterface("Summary", '~', '#', true, true); if ( ! notices.empty() ) - WriteBroDocObjList(notices, "Notices", '#'); + WriteBroDocObjList(reST_file, notices, "Notices", '#'); if ( port_analysis.size() || packet_filter.size() ) - WriteSectionHeading("Configuration Changes", '#'); + WriteSectionHeading(reST_file, "Configuration Changes", '#'); if ( ! port_analysis.empty() ) { - WriteSectionHeading("Port Analysis", '^'); - WriteToDoc("Loading this script makes the following changes to " + WriteSectionHeading(reST_file, "Port Analysis", '^'); + WriteToDoc(reST_file, "Loading this script makes the following changes to " ":bro:see:`dpd_config`.\n\n"); - WriteStringList("%s, ", "%s", port_analysis); + WriteStringList(reST_file, "%s, ", "%s", port_analysis); } if ( ! packet_filter.empty() ) { - WriteSectionHeading("Packet Filter", '^'); - WriteToDoc("Loading this script makes the following changes to " + WriteSectionHeading(reST_file, "Packet Filter", '^'); + WriteToDoc(reST_file, "Loading this script makes the following changes to " ":bro:see:`capture_filters`.\n\n"); - WriteToDoc("Filters added::\n\n"); - WriteToDoc("%s\n", packet_filter.c_str()); + WriteToDoc(reST_file, "Filters added::\n\n"); + WriteToDoc(reST_file, "%s\n", packet_filter.c_str()); } WriteInterface("Detailed Interface", '~', '#', true, false); @@ -267,23 +263,23 @@ void BroDoc::WriteDocFile() const void BroDoc::WriteInterface(const char* heading, char underline, char sub, bool isPublic, bool isShort) const { - WriteSectionHeading(heading, underline); - WriteBroDocObjList(options, isPublic, "Options", sub, isShort); - WriteBroDocObjList(constants, isPublic, "Constants", sub, isShort); - WriteBroDocObjList(state_vars, isPublic, "State Variables", sub, isShort); - WriteBroDocObjList(types, isPublic, "Types", sub, isShort); - WriteBroDocObjList(events, isPublic, "Events", sub, isShort); - WriteBroDocObjList(hooks, isPublic, "Hooks", sub, isShort); - WriteBroDocObjList(functions, isPublic, "Functions", sub, isShort); - WriteBroDocObjList(redefs, isPublic, "Redefinitions", sub, isShort); + WriteSectionHeading(reST_file, heading, underline); + WriteBroDocObjList(reST_file, options, isPublic, "Options", sub, isShort); + WriteBroDocObjList(reST_file, constants, isPublic, "Constants", sub, isShort); + WriteBroDocObjList(reST_file, state_vars, isPublic, "State Variables", sub, isShort); + WriteBroDocObjList(reST_file, types, isPublic, "Types", sub, isShort); + WriteBroDocObjList(reST_file, events, isPublic, "Events", sub, isShort); + WriteBroDocObjList(reST_file, hooks, isPublic, "Hooks", sub, isShort); + WriteBroDocObjList(reST_file, functions, isPublic, "Functions", sub, isShort); + WriteBroDocObjList(reST_file, redefs, isPublic, "Redefinitions", sub, isShort); } -void BroDoc::WriteStringList(const char* format, const char* last_format, - const std::list& l) const +void BroDoc::WriteStringList(FILE* f, const char* format, const char* last_format, + const std::list& l) { if ( l.empty() ) { - WriteToDoc("\n"); + WriteToDoc(f, "\n"); return; } @@ -292,12 +288,12 @@ void BroDoc::WriteStringList(const char* format, const char* last_format, last--; for ( it = l.begin(); it != last; ++it ) - WriteToDoc(format, it->c_str()); + WriteToDoc(f, format, it->c_str()); - WriteToDoc(last_format, last->c_str()); + WriteToDoc(f, last_format, last->c_str()); } -void BroDoc::WriteBroDocObjTable(const BroDocObjList& l) const +void BroDoc::WriteBroDocObjTable(FILE* f, const BroDocObjList& l) { int max_id_col = 0; int max_com_col = 0; @@ -317,38 +313,38 @@ void BroDoc::WriteBroDocObjTable(const BroDocObjList& l) const } // Start table. - WriteRepeatedChar('=', max_id_col); - WriteToDoc(" "); + WriteRepeatedChar(f, '=', max_id_col); + WriteToDoc(f, " "); if ( max_com_col == 0 ) - WriteToDoc("="); + WriteToDoc(f, "="); else - WriteRepeatedChar('=', max_com_col); + WriteRepeatedChar(f, '=', max_com_col); - WriteToDoc("\n"); + WriteToDoc(f, "\n"); for ( it = l.begin(); it != l.end(); ++it ) { if ( it != l.begin() ) - WriteToDoc("\n\n"); - (*it)->WriteReSTCompact(reST_file, max_id_col); + WriteToDoc(f, "\n\n"); + (*it)->WriteReSTCompact(f, max_id_col); } // End table. - WriteToDoc("\n"); - WriteRepeatedChar('=', max_id_col); - WriteToDoc(" "); + WriteToDoc(f, "\n"); + WriteRepeatedChar(f, '=', max_id_col); + WriteToDoc(f, " "); if ( max_com_col == 0 ) - WriteToDoc("="); + WriteToDoc(f, "="); else - WriteRepeatedChar('=', max_com_col); + WriteRepeatedChar(f, '=', max_com_col); - WriteToDoc("\n\n"); + WriteToDoc(f, "\n\n"); } -void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, - const char* heading, char underline, bool isShort) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, bool wantPublic, + const char* heading, char underline, bool isShort) { if ( l.empty() ) return; @@ -366,7 +362,7 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, if ( it == l.end() ) return; - WriteSectionHeading(heading, underline); + WriteSectionHeading(f, heading, underline); BroDocObjList filtered_list; @@ -377,13 +373,13 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, } if ( isShort ) - WriteBroDocObjTable(filtered_list); + WriteBroDocObjTable(f, filtered_list); else - WriteBroDocObjList(filtered_list); + WriteBroDocObjList(f, filtered_list); } -void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic, - const char* heading, char underline, bool isShort) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, bool wantPublic, + const char* heading, char underline, bool isShort) { BroDocObjMap::const_iterator it; BroDocObjList l; @@ -391,24 +387,24 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic, for ( it = m.begin(); it != m.end(); ++it ) l.push_back(it->second); - WriteBroDocObjList(l, wantPublic, heading, underline, isShort); + WriteBroDocObjList(f, l, wantPublic, heading, underline, isShort); } -void BroDoc::WriteBroDocObjList(const BroDocObjList& l, const char* heading, - char underline) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, const char* heading, + char underline) { - WriteSectionHeading(heading, underline); - WriteBroDocObjList(l); + WriteSectionHeading(f, heading, underline); + WriteBroDocObjList(f, l); } -void BroDoc::WriteBroDocObjList(const BroDocObjList& l) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l) { for ( BroDocObjList::const_iterator it = l.begin(); it != l.end(); ++it ) - (*it)->WriteReST(reST_file); + (*it)->WriteReST(f); } -void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, const char* heading, - char underline) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, const char* heading, + char underline) { BroDocObjMap::const_iterator it; BroDocObjList l; @@ -416,28 +412,28 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, const char* heading, for ( it = m.begin(); it != m.end(); ++it ) l.push_back(it->second); - WriteBroDocObjList(l, heading, underline); + WriteBroDocObjList(f, l, heading, underline); } -void BroDoc::WriteToDoc(const char* format, ...) const +void BroDoc::WriteToDoc(FILE* f, const char* format, ...) { va_list argp; va_start(argp, format); - vfprintf(reST_file, format, argp); + vfprintf(f, format, argp); va_end(argp); } -void BroDoc::WriteSectionHeading(const char* heading, char underline) const +void BroDoc::WriteSectionHeading(FILE* f, const char* heading, char underline) { - WriteToDoc("%s\n", heading); - WriteRepeatedChar(underline, strlen(heading)); - WriteToDoc("\n"); + WriteToDoc(f, "%s\n", heading); + WriteRepeatedChar(f, underline, strlen(heading)); + WriteToDoc(f, "\n"); } -void BroDoc::WriteRepeatedChar(char c, size_t n) const +void BroDoc::WriteRepeatedChar(FILE* f, char c, size_t n) { for ( size_t i = 0; i < n; ++i ) - WriteToDoc("%c", c); + WriteToDoc(f, "%c", c); } void BroDoc::FreeBroDocObjPtrList(BroDocObjList& l) @@ -459,3 +455,143 @@ void BroDoc::AddFunction(BroDocObj* o) else functions[o->Name()]->Combine(o); } + +static void WritePluginSectionHeading(FILE* f, const plugin::Plugin* p) + { + string name = p->Name(); + + fprintf(f, "%s\n", name.c_str()); + for ( size_t i = 0; i < name.size(); ++i ) + fprintf(f, "-"); + fprintf(f, "\n\n"); + + fprintf(f, "%s\n\n", p->Description()); + } + +static void WriteAnalyzerComponent(FILE* f, const analyzer::Component* c) + { + EnumType* atag = analyzer_mgr->GetTagEnumType(); + string tag = fmt("ANALYZER_%s", c->CanonicalName()); + + if ( atag->Lookup("Analyzer", tag.c_str()) < 0 ) + reporter->InternalError("missing analyzer tag for %s", tag.c_str()); + + fprintf(f, ":bro:enum:`Analyzer::%s`\n\n", tag.c_str()); + } + +static void WritePluginComponents(FILE* f, const plugin::Plugin* p) + { + plugin::Plugin::component_list components = p->Components(); + plugin::Plugin::component_list::const_iterator it; + + fprintf(f, "Components\n"); + fprintf(f, "++++++++++\n\n"); + + for ( it = components.begin(); it != components.end(); ++it ) + { + switch ( (*it)->Type() ) { + case plugin::component::ANALYZER: + WriteAnalyzerComponent(f, + dynamic_cast(*it)); + break; + case plugin::component::READER: + reporter->InternalError("docs for READER component unimplemented"); + case plugin::component::WRITER: + reporter->InternalError("docs for WRITER component unimplemented"); + default: + reporter->InternalError("docs for unknown component unimplemented"); + } + } + } + +static void WritePluginBifItems(FILE* f, const plugin::Plugin* p, + plugin::BifItem::Type t, const string& heading) + { + plugin::Plugin::bif_item_list bifitems = p->BifItems(); + plugin::Plugin::bif_item_list::iterator it = bifitems.begin(); + + while ( it != bifitems.end() ) + { + if ( it->GetType() != t ) + it = bifitems.erase(it); + else + ++it; + } + + if ( bifitems.empty() ) + return; + + fprintf(f, "%s\n", heading.c_str()); + for ( size_t i = 0; i < heading.size(); ++i ) + fprintf(f, "+"); + fprintf(f, "\n\n"); + + for ( it = bifitems.begin(); it != bifitems.end(); ++it ) + { + BroDocObj* o = doc_ids[it->GetID()]; + + if ( o ) + o->WriteReST(f); + else + reporter->Warning("No docs for ID: %s\n", it->GetID()); + } + } + +static void WriteAnalyzerTagDefn(FILE* f, EnumType* e) + { + e = new CommentedEnumType(e); + e->SetTypeID(copy_string("Analyzer::Tag")); + + ID* dummy_id = new ID(copy_string("Analyzer::Tag"), SCOPE_GLOBAL, true); + dummy_id->SetType(e); + dummy_id->MakeType(); + + list* r = new list(); + r->push_back("Unique identifiers for protocol analyzers."); + + BroDocObj bdo(dummy_id, r, true); + + bdo.WriteReST(f); + } + +static bool IsAnalyzerPlugin(const plugin::Plugin* p) + { + plugin::Plugin::component_list components = p->Components(); + plugin::Plugin::component_list::const_iterator it; + + for ( it = components.begin(); it != components.end(); ++it ) + if ( (*it)->Type() != plugin::component::ANALYZER ) + return false; + + return true; + } + +void CreateProtoAnalyzerDoc(const char* filename) + { + FILE* f = fopen(filename, "w"); + + fprintf(f, "Protocol Analyzer Reference\n"); + fprintf(f, "===========================\n\n"); + + WriteAnalyzerTagDefn(f, analyzer_mgr->GetTagEnumType()); + + plugin::Manager::plugin_list plugins = plugin_mgr->Plugins(); + plugin::Manager::plugin_list::const_iterator it; + + for ( it = plugins.begin(); it != plugins.end(); ++it ) + { + if ( ! IsAnalyzerPlugin(*it) ) + continue; + + WritePluginSectionHeading(f, *it); + WritePluginComponents(f, *it); + WritePluginBifItems(f, *it, plugin::BifItem::CONSTANT, + "Options/Constants"); + WritePluginBifItems(f, *it, plugin::BifItem::GLOBAL, "Globals"); + WritePluginBifItems(f, *it, plugin::BifItem::TYPE, "Types"); + WritePluginBifItems(f, *it, plugin::BifItem::EVENT, "Events"); + WritePluginBifItems(f, *it, plugin::BifItem::FUNCTION, "Functions"); + } + + fclose(f); + } diff --git a/src/BroDoc.h b/src/BroDoc.h index 79f02b7110..9f92f821f8 100644 --- a/src/BroDoc.h +++ b/src/BroDoc.h @@ -81,15 +81,6 @@ public: */ void SetPacketFilter(const std::string& s); - /** - * Schedules documentation of a given set of ports being associated - * with a particular analyzer as a result of the current script - * being loaded -- the way the "dpd_config" table is changed. - * @param analyzer An analyzer that changed the "dpd_config" table. - * @param ports The set of ports assigned to the analyzer in table. - */ - void AddPortAnalysis(const std::string& analyzer, const std::string& ports); - /** * Schedules documentation of a script option. An option is * defined as any variable in the script that is declared 'const' @@ -242,7 +233,115 @@ public: return reST_filename.c_str(); } -protected: + typedef std::list BroDocObjList; + typedef std::map BroDocObjMap; + + /** + * Writes out a table of BroDocObj's to the reST document + * @param f The file to write to. + * @param l A list of BroDocObj pointers + */ + static void WriteBroDocObjTable(FILE* f, const BroDocObjList& l); + + /** + * Writes out given number of characters to reST document + * @param f The file to write to. + * @param c the character to write + * @param n the number of characters to write + */ + static void WriteRepeatedChar(FILE* f, char c, size_t n); + + /** + * A wrapper to fprintf() that always uses the reST document + * for the FILE* argument. + * @param f The file to write to. + * @param format A printf style format string. + */ + static void WriteToDoc(FILE* f, const char* format, ...); + + /** + * Writes out a list of strings to the reST document. + * If the list is empty, prints a newline character. + * @param f The file to write to. + * @param format A printf style format string for elements of the list + * except for the last one in the list + * @param last_format A printf style format string to use for the last + * element of the list + * @param l A reference to a list of strings + */ + static void WriteStringList(FILE* f, const char* format, const char* last_format, + const std::list& l); + + /** + * @see WriteStringList(FILE* f, const char*, const char*, + * const std::list&>) + */ + static void WriteStringList(FILE* f, const char* format, + const std::list& l){ + WriteStringList(f, format, format, l); + } + + /** + * Writes out a list of BroDocObj objects to the reST document + * @param f The file to write to. + * @param l A list of BroDocObj pointers + * @param wantPublic If true, filter out objects that are not declared + * in the global scope. If false, filter out those that are in + * the global scope. + * @param heading The title of the section to create in the reST doc. + * @param underline The character to use to underline the reST + * section heading. + * @param isShort Whether to write the full documentation or a "short" + * version (a single sentence) + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjList& l, bool wantPublic, + const char* heading, char underline, + bool isShort); + + /** + * Wraps the BroDocObjMap into a BroDocObjList and the writes that list + * to the reST document + * @see WriteBroDocObjList(FILE* f, const BroDocObjList&, bool, const char*, char, + bool) + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjMap& m, bool wantPublic, + const char* heading, char underline, + bool isShort); + + /** + * Writes out a list of BroDocObj objects to the reST document + * @param l A list of BroDocObj pointers + * @param heading The title of the section to create in the reST doc. + * @param underline The character to use to underline the reST + * section heading. + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjList& l, const char* heading, + char underline); + + /** + * Writes out a list of BroDocObj objects to the reST document + * @param l A list of BroDocObj pointers + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjList& l); + + /** + * Wraps the BroDocObjMap into a BroDocObjList and the writes that list + * to the reST document + * @see WriteBroDocObjList(FILE* f, const BroDocObjList&, const char*, char) + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjMap& m, const char* heading, + char underline); + + /** + * Writes out a reST section heading + * @param f The file to write to. + * @param heading The title of the heading to create + * @param underline The character to use to underline the section title + * within the reST document + */ + static void WriteSectionHeading(FILE* f, const char* heading, char underline); + +private: FILE* reST_file; std::string reST_filename; std::string source_filename; // points to the basename of source file @@ -255,9 +354,6 @@ protected: std::list imports; std::list port_analysis; - typedef std::list BroDocObjList; - typedef std::map BroDocObjMap; - BroDocObjList options; BroDocObjList constants; BroDocObjList state_vars; @@ -272,107 +368,6 @@ protected: BroDocObjList all; - /** - * Writes out a list of strings to the reST document. - * If the list is empty, prints a newline character. - * @param format A printf style format string for elements of the list - * except for the last one in the list - * @param last_format A printf style format string to use for the last - * element of the list - * @param l A reference to a list of strings - */ - void WriteStringList(const char* format, const char* last_format, - const std::list& l) const; - - /** - * @see WriteStringList(const char*, const char*, - * const std::list&>) - */ - void WriteStringList(const char* format, - const std::list& l) const - { - WriteStringList(format, format, l); - } - - - /** - * Writes out a table of BroDocObj's to the reST document - * @param l A list of BroDocObj pointers - */ - void WriteBroDocObjTable(const BroDocObjList& l) const; - - /** - * Writes out a list of BroDocObj objects to the reST document - * @param l A list of BroDocObj pointers - * @param wantPublic If true, filter out objects that are not declared - * in the global scope. If false, filter out those that are in - * the global scope. - * @param heading The title of the section to create in the reST doc. - * @param underline The character to use to underline the reST - * section heading. - * @param isShort Whether to write the full documentation or a "short" - * version (a single sentence) - */ - void WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, - const char* heading, char underline, - bool isShort) const; - - /** - * Wraps the BroDocObjMap into a BroDocObjList and the writes that list - * to the reST document - * @see WriteBroDocObjList(const BroDocObjList&, bool, const char*, char, - bool) - */ - void WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic, - const char* heading, char underline, - bool isShort) const; - - /** - * Writes out a list of BroDocObj objects to the reST document - * @param l A list of BroDocObj pointers - * @param heading The title of the section to create in the reST doc. - * @param underline The character to use to underline the reST - * section heading. - */ - void WriteBroDocObjList(const BroDocObjList& l, const char* heading, - char underline) const; - - /** - * Writes out a list of BroDocObj objects to the reST document - * @param l A list of BroDocObj pointers - */ - void WriteBroDocObjList(const BroDocObjList& l) const; - - /** - * Wraps the BroDocObjMap into a BroDocObjList and the writes that list - * to the reST document - * @see WriteBroDocObjList(const BroDocObjList&, const char*, char) - */ - void WriteBroDocObjList(const BroDocObjMap& m, const char* heading, - char underline) const; - - /** - * A wrapper to fprintf() that always uses the reST document - * for the FILE* argument. - * @param format A printf style format string. - */ - void WriteToDoc(const char* format, ...) const; - - /** - * Writes out a reST section heading - * @param heading The title of the heading to create - * @param underline The character to use to underline the section title - * within the reST document - */ - void WriteSectionHeading(const char* heading, char underline) const; - - /** - * Writes out given number of characters to reST document - * @param c the character to write - * @param n the number of characters to write - */ - void WriteRepeatedChar(char c, size_t n) const; - /** * Writes out the reST for either the script's public or private interface * @param heading The title of the interfaces section heading @@ -387,7 +382,6 @@ protected: */ void WriteInterface(const char* heading, char underline, char subunderline, bool isPublic, bool isShort) const; -private: /** * Frees memory allocated to BroDocObj's objects in a given list. @@ -413,4 +407,10 @@ private: }; }; +/** + * Writes out plugin index documentation for all analyzer plugins. + * @param filename the name of the file to write. + */ +void CreateProtoAnalyzerDoc(const char* filename); + #endif diff --git a/src/BroDocObj.cc b/src/BroDocObj.cc index 12753ea15d..4316b3113a 100644 --- a/src/BroDocObj.cc +++ b/src/BroDocObj.cc @@ -4,6 +4,8 @@ #include "ID.h" #include "BroDocObj.h" +map doc_ids = map(); + BroDocObj* BroDocObj::last = 0; BroDocObj::BroDocObj(const ID* id, std::list*& reST, @@ -16,6 +18,7 @@ BroDocObj::BroDocObj(const ID* id, std::list*& reST, is_fake_id = is_fake; use_role = 0; FormulateShortDesc(); + doc_ids[id->Name()] = this; } BroDocObj::~BroDocObj() diff --git a/src/BroDocObj.h b/src/BroDocObj.h index cb512f8cda..ab42dc3c94 100644 --- a/src/BroDocObj.h +++ b/src/BroDocObj.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "ID.h" @@ -134,4 +135,9 @@ protected: private: }; +/** + * Map identifiers to their broxygen documentation objects. + */ +extern map doc_ids; + #endif diff --git a/src/Type.cc b/src/Type.cc index 6461bf2560..917c6f46b3 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1334,6 +1334,16 @@ EnumType::EnumType(const string& arg_name) counter = 0; } +EnumType::EnumType(EnumType* e) +: BroType(TYPE_ENUM) + { + name = e->name; + counter = e->counter; + + for ( NameMap::iterator it = e->names.begin(); it != e->names.end(); ++it ) + names[copy_string(it->first)] = it->second; + } + EnumType::~EnumType() { for ( NameMap::iterator iter = names.begin(); iter != names.end(); ++iter ) diff --git a/src/Type.h b/src/Type.h index bad51776d9..b10e249745 100644 --- a/src/Type.h +++ b/src/Type.h @@ -523,6 +523,7 @@ protected: class EnumType : public BroType { public: EnumType(const string& arg_name); + EnumType(EnumType* e); ~EnumType(); // The value of this name is next internal counter value, starting @@ -567,6 +568,7 @@ protected: class CommentedEnumType: public EnumType { public: CommentedEnumType(const string& arg_name) : EnumType(arg_name) {} + CommentedEnumType(EnumType* e) : EnumType(e) {} ~CommentedEnumType(); void DescribeReST(ODesc* d) const; diff --git a/src/main.cc b/src/main.cc index 491f8a732d..77a3468805 100644 --- a/src/main.cc +++ b/src/main.cc @@ -868,6 +868,8 @@ int main(int argc, char** argv) if ( generate_documentation ) { + CreateProtoAnalyzerDoc("proto-analyzers.rst"); + std::list::iterator it; for ( it = docs_generated.begin(); it != docs_generated.end(); ++it )