Broxygen doc-related test updates. Fix two regressions.

- Fix automatic function parameter documentation formatting for
  record fields that are functions.

- Document redefs in a fixed order.
This commit is contained in:
Jon Siwek 2013-11-22 14:18:24 -06:00
parent 7e0864468c
commit 98dcfc64a8
30 changed files with 714 additions and 846 deletions

View file

@ -1,20 +1,24 @@
##! This is an example script that demonstrates documentation features.
##! Comments of the form ``##!`` are for the script summary. The contents of
##! these comments are transferred directly into the auto-generated
##! This is an example script that demonstrates Broxygen-style
##! documentation. It generally will make most sense when viewing
##! the script's raw source code and comparing to the HTML-rendered
##! version.
##!
##! Comments in the from ``##!`` are meant to summarize the script's
##! purpose. They are transferred directly in to the generated
##! `reStructuredText <http://docutils.sourceforge.net/rst.html>`_
##! (reST) document's summary section.
##! (reST) document associated with the script.
##!
##! .. tip:: You can embed directives and roles within ``##``-stylized comments.
##!
##! There's also a custom role to reference any identifier node in
##! the Bro Sphinx domain that's good for "see alsos", e.g.
##!
##! See also: :bro:see:`Example::a_var`, :bro:see:`Example::ONE`,
##! :bro:see:`SSH::Info`
##! See also: :bro:see:`BroxygenExample::a_var`,
##! :bro:see:`BroxygenExample::ONE`, :bro:see:`SSH::Info`
##!
##! And a custom directive does the equivalent references:
##!
##! .. bro:see:: Example::a_var Example::ONE SSH::Info
##! .. bro:see:: BroxygenExample::a_var BroxygenExample::ONE SSH::Info
# Comments that use a single pound sign (#) are not significant to
# a script's auto-generated documentation, but ones that use a
@ -26,7 +30,7 @@
# variable declarations to associate with the last-declared identifier.
#
# Generally, the auto-doc comments (##) are associated with the
# next declaration/identifier found in the script, but the doc framework
# next declaration/identifier found in the script, but Broxygen
# will track/render identifiers regardless of whether they have any
# of these special comments associated with them.
#
@ -37,193 +41,154 @@
# in the "##"-stylized comments up until the first empty comment
# is taken as the summary text for a given identifier.
# @load directives are self-documenting
# @load directives are self-documenting, don't use any ``##`` style
# comments with them.
@load base/frameworks/notice
@load base/protocols/http
@load frameworks/software/vulnerable
# "module" statements are self-documenting
module Example;
# "module" statements are self-documenting, don't use any ``##`` style
# comments with them.
module BroxygenExample;
# redefinitions of "capture_filters" are self-documenting and
# go into the generated documentation's "Packet Filter" section
redef capture_filters += {
["ssl"] = "tcp port 443",
["nntps"] = "tcp port 562",
};
global example_ports = {
443/tcp, 562/tcp,
} &redef;
event bro_init()
{
Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, example_ports);
}
# redefinitions of "Notice::Type" are self-documenting, but
# more information can be supplied in two different ways
# Redefinitions of "Notice::Type" are self-documenting, but
# more information can be supplied in two different ways.
redef enum Notice::Type += {
## any number of this type of comment
## will document "Notice_One"
Notice_One,
Notice_Two, ##< any number of this type of comment
##< will document "Notice_Two"
Notice_Three,
Notice_Four,
## Any number of this type of comment
## will document "Broxygen_One".
Broxygen_One,
Broxygen_Two, ##< Any number of this type of comment
##< will document "BROXYGEN_TWO".
Broxygen_Three,
## Omitting comments is fine, and so is mixing ``##`` and ``##<``, but
Broxygen_Four, ##< it's probably best to use only one style consistently.
};
# Redef'ing the ID enumeration for logging streams is automatically tracked.
# Comments of the "##" form can be use to further document it, but it's
# better to do all documentation related to logging in the summary section
# as is shown above.
# All redefs are automatically tracked. Comments of the "##" form can be use
# to further document it, but in some cases, like here, they wouldn't be
# ading any interesting information that's not implicit.
redef enum Log::ID += { LOG };
# Anything declared in the export section will show up in the rendered
# documentation's "public interface" section
# Only identifiers declared in an export section will show up in generated docs.
export {
# these headings don't mean anything special to the
# doc framework right now, I'm just including them
# to make it more clear to the reader how the doc
# framework will actually categorize a script's identifiers
## Documentation for the "SimpleEnum" type goes here.
## It can span multiple lines.
type SimpleEnum: enum {
## Documentation for particular enum values is added like this.
## And can also span multiple lines.
ONE,
TWO, ##< Or this style is valid to document the preceding enum value.
THREE,
};
############## types ################
## Document the "SimpleEnum" redef here with any special info regarding
## the *redef* itself.
redef enum SimpleEnum += {
FOUR, ##< And some documentation for "FOUR".
## Also "FIVE".
FIVE
};
# Note that I'm just mixing the "##" and "##<"
# types of comments in the following declarations
# as a demonstration. Normally, it would be good style
# to pick one and be consistent.
## General documentation for a type "SimpleRecord" goes here.
## The way fields can be documented is similar to what's already seen
## for enums.
type SimpleRecord: record {
## Counts something.
field1: count;
field2: bool; ##< Toggles something.
};
## documentation for "SimpleEnum"
## goes here.
type SimpleEnum: enum {
## and more specific info for "ONE"
## can span multiple lines
ONE,
TWO, ##< or more info like this for "TWO"
##< can span multiple lines
THREE,
};
## Document the record extension *redef* itself here.
redef record SimpleRecord += {
## Document the extending field like this.
field_ext: string &optional; ##< Or here, like this.
};
## document the "SimpleEnum" redef here
redef enum SimpleEnum += {
FOUR, ##< and some documentation for "FOUR"
## also "FIVE" for good measure
FIVE
};
## General documentation for a type "ComplexRecord" goes here.
type ComplexRecord: record {
field1: count; ##< Counts something.
field2: bool; ##< Toggles something.
field3: SimpleRecord; ##< Broxygen automatically tracks types
##< and cross-references are automatically
##< inserted in to generated docs.
msg: string &default="blah"; ##< Attributes are self-documenting.
} &redef;
## general documentation for a type "SimpleRecord"
## goes here.
type SimpleRecord: record {
## counts something
field1: count;
field2: bool; ##< toggles something
};
## An example record to be used with a logging stream.
## Nothing special about it. If another script redefs this type
## to add fields, the generated documentation will show all original
## fields plus the extensions and the scripts which contributed to it
## (provided they are also @load'ed).
type Info: record {
ts: time &log;
uid: string &log;
status: count &log &optional;
};
## document the record extension redef here
redef record SimpleRecord += {
## document the extending field here
field_ext: string &optional; ##< (or here)
};
## Add documentation for "an_option" here.
## The type/attribute information is all generated automatically.
const an_option: set[addr, addr, string] &redef;
## general documentation for a type "ComplexRecord" goes here
type ComplexRecord: record {
field1: count; ##< counts something
field2: bool; ##< toggles something
field3: SimpleRecord;
msg: string &default="blah"; ##< attributes are self-documenting
} &redef;
## Default initialization will be generated automatically.
const option_with_init = 0.01 secs &redef; ##< More docs can be added here.
## An example record to be used with a logging stream.
type Info: record {
ts: time &log;
uid: string &log;
status: count &log &optional;
};
## Put some documentation for "a_var" here. Any global/non-const that
## isn't a function/event/hook is classified as a "state variable"
## in the generated docs.
global a_var: bool;
############## options ################
# right now, I'm just defining an option as
# any const with &redef (something that can
# change at parse time, but not at run time.
## Types are inferred, that information is self-documenting.
global var_without_explicit_type = "this works";
## add documentation for "an_option" here
const an_option: set[addr, addr, string] &redef;
# default initialization will be self-documenting
const option_with_init = 0.01 secs &redef; ##< More docs can be added here.
############## state variables ############
# right now, I'm defining this as any global
# that's not a function/event. doesn't matter
# if &redef attribute is present
## put some documentation for "a_var" here
global a_var: bool;
# attributes are self-documenting
global var_with_attr: count &persistent;
# it's fine if the type is inferred, that information is self-documenting
global var_without_explicit_type = "this works";
## The first.sentence for the summary text ends here. And this second
## sentence doesn't show in the short description.
global dummy: string;
############## functions/events ############
## The first sentence for a particular identifier's summary text ends here.
## And this second sentence doesn't show in the short description provided
## by the table of all identifiers declared by this script.
global summary_test: string;
## Summarize purpose of "a_function" here.
## Give more details about "a_function" here.
## Separating the documentation of the params/return values with
## empty comments is optional, but improves readability of script.
##
## tag: function arguments can be described
## like this
## msg: another param
## tag: Function arguments can be described
## like this.
##
## msg: Another param.
##
## Returns: describe the return type here
## Returns: Describe the return type here.
global a_function: function(tag: string, msg: string): string;
## Summarize "an_event" here.
## Give more details about "an_event" here.
## Example::an_event should not be confused as a parameter.
## name: describe the argument here
##
## BroxygenExample::a_function should not be confused as a parameter
## in the generated docs, but it also doesn't generate a cross-reference
## link. Use the see role instead: :bro:see:`BroxygenExample::a_function`.
##
## name: Describe the argument here.
global an_event: event(name: string);
## This is a declaration of an example event that can be used in
## logging streams and is raised once for each log entry.
global log_example: event(rec: Info);
}
function filter_func(rec: Info): bool
{
return T;
}
# this function is documented in the "private interface" section
# of generated documentation and any "##"-stylized comments would also
# be rendered there
# This function isn't exported, so it won't appear anywhere in the generated
# documentation. So using ``##``-style comments is pointless here.
function function_without_proto(tag: string): string
{
return "blah";
}
# this record type is documented in the "private interface" section
# of generated documentation and any "##"-stylized comments would also
# be rendered there
# Same thing goes for types -- it's not exported, so it's considered
# private to this script and comments are only interesting to a person
# who is already reading the raw source for the script (so don't use
# ``##`` comments here.
type PrivateRecord: record {
field1: bool;
field2: count;
};
# Event handlers are also an implementation detail of a script, so they
# don't show up anywhere in the generated documentation.
event bro_init()
{
Log::create_stream(Example::LOG, [$columns=Info, $ev=log_example]);
Log::add_filter(Example::LOG, [
$name="example-filter",
$path="example-filter",
$pred=filter_func,
$exclude=set("ts")
]);
}

View file

@ -9,6 +9,7 @@
#include "Serializer.h"
#include "Reporter.h"
#include "broxygen/Manager.h"
#include "broxygen/utils.h"
#include <string>
#include <list>
@ -1182,7 +1183,17 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const
if ( i > 0 )
d->NL();
d->Add(cmnts[i].c_str());
if ( IsFunc(td->type->Tag()) )
{
string s = cmnts[i];
if ( broxygen::prettify_params(s) )
d->NL();
d->Add(s.c_str());
}
else
d->Add(cmnts[i].c_str());
}
d->PopIndentNoNL();

View file

@ -9,6 +9,7 @@ set(broxygen_SRCS
Configuration.cc
Document.cc
Manager.cc
utils.cc
)
bif_target(broxygen.bif)

View file

@ -1,5 +1,6 @@
#include "Document.h"
#include "Manager.h"
#include "utils.h"
#include "util.h"
#include "Val.h"
@ -18,72 +19,6 @@ static bool is_public_api(const ID* id)
(id->Scope() == SCOPE_MODULE && id->IsExport());
}
static bool prettify_params(string& s)
{
size_t identifier_start_pos = 0;
bool in_identifier = false;
string identifier;
for ( size_t i = 0; i < s.size(); ++i )
{
char next = s[i];
if ( ! in_identifier )
{
// Pass by leading whitespace.
if ( isspace(next) )
continue;
// Only allow alphabetic and '_' as first char of identifier.
if ( isalpha(next) || next == '_' )
{
identifier_start_pos = i;
identifier += next;
in_identifier = true;
continue;
}
// Don't need to change anything.
return false;
}
// All other characters of identifier are alphanumeric or '_'.
if ( isalnum(next) || next == '_' )
{
identifier += next;
continue;
}
if ( next == ':' )
{
if ( i + 1 < s.size() && s[i + 1] == ':' )
{
// It's part of an identifier's namespace scoping.
identifier += next;
identifier += s[i + 1];
++i;
continue;
}
// Prettify function param/return value reST markup.
string subst;
if ( identifier == "Returns" )
subst = ":returns";
else
subst = ":param " + identifier;
s.replace(identifier_start_pos, identifier.size(), subst);
return true;
}
// Don't need to change anything.
return false;
}
return false;
}
static string make_heading(const string& heading, char underline)
{
return heading + "\n" + string(heading.size(), underline) + "\n";
@ -244,7 +179,7 @@ string IdentifierDocument::DoReStructuredText(bool roles_only) const
{
string s = comments[i];
if ( prettify_params(s) )
if ( broxygen::prettify_params(s) )
d.NL();
d.Add(s.c_str());
@ -523,15 +458,15 @@ static string make_summary(const string& heading, char underline, char border,
static string make_redef_summary(const string& heading, char underline,
char border, const string& from_script,
const set<IdentifierDocument*>& id_set)
const id_doc_set& id_set)
{
if ( id_set.empty() )
return "";
ReStructuredTextTable table(2);
for ( set<IdentifierDocument*>::const_iterator it = id_set.begin();
it != id_set.end(); ++it )
for ( id_doc_set::const_iterator it = id_set.begin(); it != id_set.end();
++it )
{
ID* id = (*it)->GetID();
ODesc d;
@ -568,14 +503,14 @@ static string make_details(const string& heading, char underline,
}
static string make_redef_details(const string& heading, char underline,
const set<IdentifierDocument*>& id_set)
const id_doc_set& id_set)
{
if ( id_set.empty() )
return "";
string rval = make_heading(heading, underline);
for ( set<IdentifierDocument*>::const_iterator it = id_set.begin();
for ( id_doc_set::const_iterator it = id_set.begin();
it != id_set.end(); ++it )
{
rval += (*it)->ReStructuredText(true);

View file

@ -145,6 +145,13 @@ private:
ScriptDocument* declaring_script;
};
struct IdDocComp {
bool operator() (IdentifierDocument* lhs, IdentifierDocument* rhs) const
{ return lhs->Name() < rhs->Name(); }
};
typedef std::set<IdentifierDocument*, IdDocComp> id_doc_set;
class ScriptDocument : public Document {
public:
@ -175,7 +182,6 @@ private:
typedef std::map<std::string, IdentifierDocument*> id_doc_map;
typedef std::list<IdentifierDocument*> id_doc_list;
typedef std::set<std::string> string_set;
typedef std::set<IdentifierDocument*> doc_set;
time_t DoGetModificationTime() const;
@ -200,7 +206,7 @@ private:
id_doc_list events;
id_doc_list hooks;
id_doc_list functions;
doc_set redefs;
id_doc_set redefs;
};

70
src/broxygen/utils.cc Normal file
View file

@ -0,0 +1,70 @@
#include "utils.h"
using namespace broxygen;
using namespace std;
bool broxygen::prettify_params(string& s)
{
size_t identifier_start_pos = 0;
bool in_identifier = false;
string identifier;
for ( size_t i = 0; i < s.size(); ++i )
{
char next = s[i];
if ( ! in_identifier )
{
// Pass by leading whitespace.
if ( isspace(next) )
continue;
// Only allow alphabetic and '_' as first char of identifier.
if ( isalpha(next) || next == '_' )
{
identifier_start_pos = i;
identifier += next;
in_identifier = true;
continue;
}
// Don't need to change anything.
return false;
}
// All other characters of identifier are alphanumeric or '_'.
if ( isalnum(next) || next == '_' )
{
identifier += next;
continue;
}
if ( next == ':' )
{
if ( i + 1 < s.size() && s[i + 1] == ':' )
{
// It's part of an identifier's namespace scoping.
identifier += next;
identifier += s[i + 1];
++i;
continue;
}
// Prettify function param/return value reST markup.
string subst;
if ( identifier == "Returns" )
subst = ":returns";
else
subst = ":param " + identifier;
s.replace(identifier_start_pos, identifier.size(), subst);
return true;
}
// Don't need to change anything.
return false;
}
return false;
}

12
src/broxygen/utils.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef BROXYGEN_UTILS_H
#define BROXYGEN_UTILS_H
#include <string>
namespace broxygen {
bool prettify_params(std::string& s);
} // namespace broxygen
#endif

View file

@ -1,116 +0,0 @@
.. Automatically generated. Do not edit.
:tocdepth: 3
autogen-reST-enums.bro
======================
:Source File: :download:`autogen-reST-enums.bro`
Summary
~~~~~~~
Options
#######
==================================================================== ======================================================================
:bro:id:`test_enum_option`: :bro:type:`TestEnum1` :bro:attr:`&redef` this should reference the TestEnum1 type and not a generic "enum" type
==================================================================== ======================================================================
Types
#####
======================================= ========================================
:bro:type:`TestEnum1`: :bro:type:`enum` There's tons of ways an enum can look...
:bro:type:`TestEnum2`: :bro:type:`enum` The final comma is optional
======================================= ========================================
Redefinitions
#############
======================================= =======================
:bro:type:`TestEnum1`: :bro:type:`enum` redefs should also work
:bro:type:`TestEnum1`: :bro:type:`enum` now with a comma
======================================= =======================
Detailed Interface
~~~~~~~~~~~~~~~~~~
Options
#######
.. bro:id:: test_enum_option
:Type: :bro:type:`TestEnum1`
:Attributes: :bro:attr:`&redef`
:Default: ``ONE``
this should reference the TestEnum1 type and not a generic "enum" type
Types
#####
.. bro:type:: TestEnum1
:Type: :bro:type:`enum`
.. bro:enum:: ONE TestEnum1
like this
.. bro:enum:: TWO TestEnum1
or like this
.. bro:enum:: THREE TestEnum1
multiple
comments
and even
more comments
There's tons of ways an enum can look...
.. bro:type:: TestEnum2
:Type: :bro:type:`enum`
.. bro:enum:: A TestEnum2
like this
.. bro:enum:: B TestEnum2
or like this
.. bro:enum:: C TestEnum2
multiple
comments
and even
more comments
The final comma is optional
Redefinitions
#############
:bro:type:`TestEnum1`
:Type: :bro:type:`enum`
.. bro:enum:: FOUR TestEnum1
adding another
value
redefs should also work
:bro:type:`TestEnum1`
:Type: :bro:type:`enum`
.. bro:enum:: FIVE TestEnum1
adding another
value
now with a comma

View file

@ -1,301 +0,0 @@
.. Automatically generated. Do not edit.
:tocdepth: 3
example.bro
===========
.. bro:namespace:: Example
This is an example script that demonstrates documentation features.
Comments of the form ``##!`` are for the script summary. The contents of
these comments are transferred directly into the auto-generated
`reStructuredText <http://docutils.sourceforge.net/rst.html>`_
(reST) document's summary section.
.. tip:: You can embed directives and roles within ``##``-stylized comments.
There's also a custom role to reference any identifier node in
the Bro Sphinx domain that's good for "see alsos", e.g.
See also: :bro:see:`Example::a_var`, :bro:see:`Example::ONE`,
:bro:see:`SSH::Info`
And a custom directive does the equivalent references:
.. bro:see:: Example::a_var Example::ONE SSH::Info
:Namespace: ``Example``
:Imports: :doc:`policy/frameworks/software/vulnerable </scripts/policy/frameworks/software/vulnerable>`
:Source File: :download:`example.bro`
Summary
~~~~~~~
Options
#######
============================================================================ ======================================
:bro:id:`Example::an_option`: :bro:type:`set` :bro:attr:`&redef` add documentation for "an_option" here
:bro:id:`Example::option_with_init`: :bro:type:`interval` :bro:attr:`&redef` More docs can be added here.
============================================================================ ======================================
State Variables
###############
=========================================================================== ==================================================
:bro:id:`Example::a_var`: :bro:type:`bool` put some documentation for "a_var" here
:bro:id:`Example::var_with_attr`: :bro:type:`count` :bro:attr:`&persistent`
:bro:id:`Example::var_without_explicit_type`: :bro:type:`string`
:bro:id:`Example::dummy`: :bro:type:`string` The first.sentence for the summary text ends here.
=========================================================================== ==================================================
Types
#####
====================================================== ==========================================================
:bro:type:`Example::SimpleEnum`: :bro:type:`enum` documentation for "SimpleEnum"
goes here.
:bro:type:`Example::SimpleRecord`: :bro:type:`record` general documentation for a type "SimpleRecord"
goes here.
:bro:type:`Example::ComplexRecord`: :bro:type:`record` general documentation for a type "ComplexRecord" goes here
:bro:type:`Example::Info`: :bro:type:`record` An example record to be used with a logging stream.
====================================================== ==========================================================
Events
######
================================================= =============================================================
:bro:id:`Example::an_event`: :bro:type:`event` Summarize "an_event" here.
:bro:id:`Example::log_example`: :bro:type:`event` This is a declaration of an example event that can be used in
logging streams and is raised once for each log entry.
================================================= =============================================================
Functions
#########
=================================================== =======================================
:bro:id:`Example::a_function`: :bro:type:`function` Summarize purpose of "a_function" here.
=================================================== =======================================
Redefinitions
#############
===================================================== ========================================
:bro:type:`Log::ID`: :bro:type:`enum`
:bro:type:`Example::SimpleEnum`: :bro:type:`enum` document the "SimpleEnum" redef here
:bro:type:`Example::SimpleRecord`: :bro:type:`record` document the record extension redef here
===================================================== ========================================
Notices
#######
:bro:type:`Notice::Type`
:Type: :bro:type:`enum`
.. bro:enum:: Example::Notice_One Notice::Type
any number of this type of comment
will document "Notice_One"
.. bro:enum:: Example::Notice_Two Notice::Type
any number of this type of comment
will document "Notice_Two"
.. bro:enum:: Example::Notice_Three Notice::Type
.. bro:enum:: Example::Notice_Four Notice::Type
Configuration Changes
#####################
Packet Filter
^^^^^^^^^^^^^
Loading this script makes the following changes to :bro:see:`capture_filters`.
Filters added::
[ssl] = tcp port 443,
[nntps] = tcp port 562
Detailed Interface
~~~~~~~~~~~~~~~~~~
Options
#######
.. bro:id:: Example::an_option
:Type: :bro:type:`set` [:bro:type:`addr`, :bro:type:`addr`, :bro:type:`string`]
:Attributes: :bro:attr:`&redef`
:Default: ``{}``
add documentation for "an_option" here
.. bro:id:: Example::option_with_init
:Type: :bro:type:`interval`
:Attributes: :bro:attr:`&redef`
:Default: ``10.0 msecs``
More docs can be added here.
State Variables
###############
.. bro:id:: Example::a_var
:Type: :bro:type:`bool`
put some documentation for "a_var" here
.. bro:id:: Example::var_with_attr
:Type: :bro:type:`count`
:Attributes: :bro:attr:`&persistent`
.. bro:id:: Example::var_without_explicit_type
:Type: :bro:type:`string`
:Default: ``"this works"``
.. bro:id:: Example::dummy
:Type: :bro:type:`string`
The first.sentence for the summary text ends here. And this second
sentence doesn't show in the short description.
Types
#####
.. bro:type:: Example::SimpleEnum
:Type: :bro:type:`enum`
.. bro:enum:: Example::ONE Example::SimpleEnum
and more specific info for "ONE"
can span multiple lines
.. bro:enum:: Example::TWO Example::SimpleEnum
or more info like this for "TWO"
can span multiple lines
.. bro:enum:: Example::THREE Example::SimpleEnum
documentation for "SimpleEnum"
goes here.
.. bro:type:: Example::SimpleRecord
:Type: :bro:type:`record`
field1: :bro:type:`count`
counts something
field2: :bro:type:`bool`
toggles something
general documentation for a type "SimpleRecord"
goes here.
.. bro:type:: Example::ComplexRecord
:Type: :bro:type:`record`
field1: :bro:type:`count`
counts something
field2: :bro:type:`bool`
toggles something
field3: :bro:type:`Example::SimpleRecord`
msg: :bro:type:`string` :bro:attr:`&default` = ``"blah"`` :bro:attr:`&optional`
attributes are self-documenting
general documentation for a type "ComplexRecord" goes here
.. bro:type:: Example::Info
:Type: :bro:type:`record`
ts: :bro:type:`time` :bro:attr:`&log`
uid: :bro:type:`string` :bro:attr:`&log`
status: :bro:type:`count` :bro:attr:`&log` :bro:attr:`&optional`
An example record to be used with a logging stream.
Events
######
.. bro:id:: Example::an_event
:Type: :bro:type:`event` (name: :bro:type:`string`)
Summarize "an_event" here.
Give more details about "an_event" here.
Example::an_event should not be confused as a parameter.
:param name: describe the argument here
.. bro:id:: Example::log_example
:Type: :bro:type:`event` (rec: :bro:type:`Example::Info`)
This is a declaration of an example event that can be used in
logging streams and is raised once for each log entry.
Functions
#########
.. bro:id:: Example::a_function
:Type: :bro:type:`function` (tag: :bro:type:`string`, msg: :bro:type:`string`) : :bro:type:`string`
Summarize purpose of "a_function" here.
Give more details about "a_function" here.
Separating the documentation of the params/return values with
empty comments is optional, but improves readability of script.
:param tag: function arguments can be described
like this
:param msg: another param
:returns: describe the return type here
Redefinitions
#############
:bro:type:`Log::ID`
:Type: :bro:type:`enum`
.. bro:enum:: Example::LOG Log::ID
:bro:type:`Example::SimpleEnum`
:Type: :bro:type:`enum`
.. bro:enum:: Example::FOUR Example::SimpleEnum
and some documentation for "FOUR"
.. bro:enum:: Example::FIVE Example::SimpleEnum
also "FIVE" for good measure
document the "SimpleEnum" redef here
:bro:type:`Example::SimpleRecord`
:Type: :bro:type:`record`
field_ext: :bro:type:`string` :bro:attr:`&optional`
document the extending field here
(or here)
document the record extension redef here

View file

@ -1,58 +0,0 @@
.. Automatically generated. Do not edit.
:tocdepth: 3
autogen-reST-func-params.bro
============================
:Source File: :download:`autogen-reST-func-params.bro`
Summary
~~~~~~~
Types
#####
======================================== =
:bro:type:`test_rec`: :bro:type:`record`
======================================== =
Functions
#########
========================================= ======================================
:bro:id:`test_func`: :bro:type:`function` This is a global function declaration.
========================================= ======================================
Detailed Interface
~~~~~~~~~~~~~~~~~~
Types
#####
.. bro:type:: test_rec
:Type: :bro:type:`record`
field_func: :bro:type:`function` (i: :bro:type:`int`, j: :bro:type:`int`) : :bro:type:`string`
This is a record field function.
:param i: First param.
:param j: Second param.
:returns: A string.
Functions
#########
.. bro:id:: test_func
:Type: :bro:type:`function` (i: :bro:type:`int`, j: :bro:type:`int`) : :bro:type:`string`
This is a global function declaration.
:param i: First param.
:param j: Second param.
:returns: A string.

View file

@ -1,53 +0,0 @@
.. Automatically generated. Do not edit.
:tocdepth: 3
autogen-reST-records.bro
========================
:Source File: :download:`autogen-reST-records.bro`
Summary
~~~~~~~
Types
#####
============================================ ============================================================
:bro:type:`SimpleRecord`: :bro:type:`record`
:bro:type:`TestRecord`: :bro:type:`record` Here's the ways records and record fields can be documented.
============================================ ============================================================
Detailed Interface
~~~~~~~~~~~~~~~~~~
Types
#####
.. bro:type:: SimpleRecord
:Type: :bro:type:`record`
field1: :bro:type:`bool`
field2: :bro:type:`count`
.. bro:type:: TestRecord
:Type: :bro:type:`record`
A: :bro:type:`count`
document ``A``
B: :bro:type:`bool`
document ``B``
C: :bro:type:`SimpleRecord`
and now ``C``
is a declared type
D: :bro:type:`set` [:bro:type:`count`, :bro:type:`bool`]
sets/tables should show the index types
Here's the ways records and record fields can be documented.

View file

@ -1,62 +0,0 @@
.. Automatically generated. Do not edit.
:tocdepth: 3
autogen-reST-type-aliases.bro
=============================
:Source File: :download:`autogen-reST-type-aliases.bro`
Summary
~~~~~~~
State Variables
###############
======================================= =======================================================
:bro:id:`a`: :bro:type:`TypeAlias` But this should reference a type of ``TypeAlias``.
:bro:id:`b`: :bro:type:`OtherTypeAlias` And this should reference a type of ``OtherTypeAlias``.
======================================= =======================================================
Types
#####
============================================ ==========================================================================
:bro:type:`TypeAlias`: :bro:type:`bool` This is just an alias for a builtin type ``bool``.
:bro:type:`OtherTypeAlias`: :bro:type:`bool` We decided that creating alias "chains" might not be so useful to document
so this type just creates a cross reference to ``bool``.
============================================ ==========================================================================
Detailed Interface
~~~~~~~~~~~~~~~~~~
State Variables
###############
.. bro:id:: a
:Type: :bro:type:`TypeAlias`
But this should reference a type of ``TypeAlias``.
.. bro:id:: b
:Type: :bro:type:`OtherTypeAlias`
And this should reference a type of ``OtherTypeAlias``.
Types
#####
.. bro:type:: TypeAlias
:Type: :bro:type:`bool`
This is just an alias for a builtin type ``bool``.
.. bro:type:: OtherTypeAlias
:Type: :bro:type:`bool`
We decided that creating alias "chains" might not be so useful to document
so this type just creates a cross reference to ``bool``.

View file

@ -0,0 +1 @@
WARNING: No Site::local_nets have been defined. It's usually a good idea to define your local networks.

View file

@ -0,0 +1,60 @@
.. bro:type:: TestEnum1
:Type: :bro:type:`enum`
.. bro:enum:: ONE TestEnum1
like this
.. bro:enum:: TWO TestEnum1
or like this
.. bro:enum:: THREE TestEnum1
multiple
comments
and even
more comments
.. bro:enum:: FOUR TestEnum1
adding another
value
.. bro:enum:: FIVE TestEnum1
adding another
value
There's tons of ways an enum can look...
.. bro:type:: TestEnum2
:Type: :bro:type:`enum`
.. bro:enum:: A TestEnum2
like this
.. bro:enum:: B TestEnum2
or like this
.. bro:enum:: C TestEnum2
multiple
comments
and even
more comments
The final comma is optional
.. bro:id:: TestEnumVal
:Type: :bro:type:`TestEnum1`
:Attributes: :bro:attr:`&redef`
:Default: ``ONE``
this should reference the TestEnum1 type and not a generic "enum" type

View file

@ -0,0 +1,249 @@
:tocdepth: 3
broxygen/example.bro
====================
.. bro:namespace:: BroxygenExample
This is an example script that demonstrates Broxygen-style
documentation. It generally will make most sense when viewing
the script's raw source code and comparing to the HTML-rendered
version.
Comments in the from ``##!`` are meant to summarize the script's
purpose. They are transferred directly in to the generated
`reStructuredText <http://docutils.sourceforge.net/rst.html>`_
(reST) document associated with the script.
.. tip:: You can embed directives and roles within ``##``-stylized comments.
There's also a custom role to reference any identifier node in
the Bro Sphinx domain that's good for "see alsos", e.g.
See also: :bro:see:`BroxygenExample::a_var`,
:bro:see:`BroxygenExample::ONE`, :bro:see:`SSH::Info`
And a custom directive does the equivalent references:
.. bro:see:: BroxygenExample::a_var BroxygenExample::ONE SSH::Info
:Namespace: BroxygenExample
:Imports: :doc:`base/frameworks/notice </scripts/base/frameworks/notice/index>`, :doc:`base/protocols/http </scripts/base/protocols/http/index>`, :doc:`policy/frameworks/software/vulnerable.bro </scripts/policy/frameworks/software/vulnerable.bro>`
:Source File: :download:`/scripts/broxygen/example.bro`
Summary
~~~~~~~
Options
#######
==================================================================================== =======================================================
:bro:id:`BroxygenExample::an_option`: :bro:type:`set` :bro:attr:`&redef` Add documentation for "an_option" here.
:bro:id:`BroxygenExample::option_with_init`: :bro:type:`interval` :bro:attr:`&redef` Default initialization will be generated automatically.
==================================================================================== =======================================================
State Variables
###############
======================================================================== ========================================================================
:bro:id:`BroxygenExample::a_var`: :bro:type:`bool` Put some documentation for "a_var" here.
:bro:id:`BroxygenExample::summary_test`: :bro:type:`string` The first sentence for a particular identifier's summary text ends here.
:bro:id:`BroxygenExample::var_without_explicit_type`: :bro:type:`string` Types are inferred, that information is self-documenting.
======================================================================== ========================================================================
Types
#####
================================================================================= ===========================================================
:bro:type:`BroxygenExample::ComplexRecord`: :bro:type:`record` :bro:attr:`&redef` General documentation for a type "ComplexRecord" goes here.
:bro:type:`BroxygenExample::Info`: :bro:type:`record` An example record to be used with a logging stream.
:bro:type:`BroxygenExample::SimpleEnum`: :bro:type:`enum` Documentation for the "SimpleEnum" type goes here.
:bro:type:`BroxygenExample::SimpleRecord`: :bro:type:`record` General documentation for a type "SimpleRecord" goes here.
================================================================================= ===========================================================
Redefinitions
#############
============================================================= ====================================================================
:bro:type:`BroxygenExample::SimpleEnum`: :bro:type:`enum` Document the "SimpleEnum" redef here with any special info regarding
the *redef* itself.
:bro:type:`BroxygenExample::SimpleRecord`: :bro:type:`record` Document the record extension *redef* itself here.
:bro:type:`Log::ID`: :bro:type:`enum`
:bro:type:`Notice::Type`: :bro:type:`enum`
============================================================= ====================================================================
Events
######
====================================================== ==========================
:bro:id:`BroxygenExample::an_event`: :bro:type:`event` Summarize "an_event" here.
====================================================== ==========================
Functions
#########
=========================================================== =======================================
:bro:id:`BroxygenExample::a_function`: :bro:type:`function` Summarize purpose of "a_function" here.
=========================================================== =======================================
Detailed Interface
~~~~~~~~~~~~~~~~~~
Options
#######
.. bro:id:: BroxygenExample::an_option
:Type: :bro:type:`set` [:bro:type:`addr`, :bro:type:`addr`, :bro:type:`string`]
:Attributes: :bro:attr:`&redef`
:Default: ``{}``
Add documentation for "an_option" here.
The type/attribute information is all generated automatically.
.. bro:id:: BroxygenExample::option_with_init
:Type: :bro:type:`interval`
:Attributes: :bro:attr:`&redef`
:Default: ``10.0 msecs``
Default initialization will be generated automatically.
More docs can be added here.
State Variables
###############
.. bro:id:: BroxygenExample::a_var
:Type: :bro:type:`bool`
Put some documentation for "a_var" here. Any global/non-const that
isn't a function/event/hook is classified as a "state variable"
in the generated docs.
.. bro:id:: BroxygenExample::summary_test
:Type: :bro:type:`string`
The first sentence for a particular identifier's summary text ends here.
And this second sentence doesn't show in the short description provided
by the table of all identifiers declared by this script.
.. bro:id:: BroxygenExample::var_without_explicit_type
:Type: :bro:type:`string`
:Default: ``"this works"``
Types are inferred, that information is self-documenting.
Types
#####
.. bro:type:: BroxygenExample::ComplexRecord
:Type: :bro:type:`record`
field1: :bro:type:`count`
Counts something.
field2: :bro:type:`bool`
Toggles something.
field3: :bro:type:`BroxygenExample::SimpleRecord`
Broxygen automatically tracks types
and cross-references are automatically
inserted in to generated docs.
msg: :bro:type:`string` :bro:attr:`&default` = ``"blah"`` :bro:attr:`&optional`
Attributes are self-documenting.
:Attributes: :bro:attr:`&redef`
General documentation for a type "ComplexRecord" goes here.
.. bro:type:: BroxygenExample::Info
:Type: :bro:type:`record`
ts: :bro:type:`time` :bro:attr:`&log`
uid: :bro:type:`string` :bro:attr:`&log`
status: :bro:type:`count` :bro:attr:`&log` :bro:attr:`&optional`
An example record to be used with a logging stream.
Nothing special about it. If another script redefs this type
to add fields, the generated documentation will show all original
fields plus the extensions and the scripts which contributed to it
(provided they are also @load'ed).
.. bro:type:: BroxygenExample::SimpleEnum
:Type: :bro:type:`enum`
.. bro:enum:: BroxygenExample::ONE BroxygenExample::SimpleEnum
Documentation for particular enum values is added like this.
And can also span multiple lines.
.. bro:enum:: BroxygenExample::TWO BroxygenExample::SimpleEnum
Or this style is valid to document the preceding enum value.
.. bro:enum:: BroxygenExample::THREE BroxygenExample::SimpleEnum
.. bro:enum:: BroxygenExample::FOUR BroxygenExample::SimpleEnum
And some documentation for "FOUR".
.. bro:enum:: BroxygenExample::FIVE BroxygenExample::SimpleEnum
Also "FIVE".
Documentation for the "SimpleEnum" type goes here.
It can span multiple lines.
.. bro:type:: BroxygenExample::SimpleRecord
:Type: :bro:type:`record`
field1: :bro:type:`count`
Counts something.
field2: :bro:type:`bool`
Toggles something.
field_ext: :bro:type:`string` :bro:attr:`&optional`
Document the extending field like this.
Or here, like this.
General documentation for a type "SimpleRecord" goes here.
The way fields can be documented is similar to what's already seen
for enums.
Events
######
.. bro:id:: BroxygenExample::an_event
:Type: :bro:type:`event` (name: :bro:type:`string`)
Summarize "an_event" here.
Give more details about "an_event" here.
BroxygenExample::a_function should not be confused as a parameter
in the generated docs, but it also doesn't generate a cross-reference
link. Use the see role instead: :bro:see:`BroxygenExample::a_function`.
:param name: Describe the argument here.
Functions
#########
.. bro:id:: BroxygenExample::a_function
:Type: :bro:type:`function` (tag: :bro:type:`string`, msg: :bro:type:`string`) : :bro:type:`string`
Summarize purpose of "a_function" here.
Give more details about "a_function" here.
Separating the documentation of the params/return values with
empty comments is optional, but improves readability of script.
:param tag: Function arguments can be described
like this.
:param msg: Another param.
:returns: Describe the return type here.

View file

@ -0,0 +1,30 @@
.. bro:id:: test_func_params_func
:Type: :bro:type:`function` (i: :bro:type:`int`, j: :bro:type:`int`) : :bro:type:`string`
This is a global function declaration.
:param i: First param.
:param j: Second param.
:returns: A string.
.. bro:type:: test_func_params_rec
:Type: :bro:type:`record`
field_func: :bro:type:`function` (i: :bro:type:`int`, j: :bro:type:`int`) : :bro:type:`string`
This is a record field function.
:param i: First param.
:param j: Second param.
:returns: A string.

View file

@ -0,0 +1,28 @@
.. bro:type:: TestRecord1
:Type: :bro:type:`record`
field1: :bro:type:`bool`
field2: :bro:type:`count`
.. bro:type:: TestRecord2
:Type: :bro:type:`record`
A: :bro:type:`count`
document ``A``
B: :bro:type:`bool`
document ``B``
C: :bro:type:`TestRecord1`
and now ``C``
is a declared type
D: :bro:type:`set` [:bro:type:`count`, :bro:type:`bool`]
sets/tables should show the index types
Here's the ways records and record fields can be documented.

View file

@ -0,0 +1,44 @@
.. bro:type:: BroxygenTest::TypeAlias
:Type: :bro:type:`bool`
This is just an alias for a builtin type ``bool``.
.. bro:type:: BroxygenTest::NotTypeAlias
:Type: :bro:type:`bool`
This type should get its own comments, not associated w/ TypeAlias.
.. bro:type:: BroxygenTest::OtherTypeAlias
:Type: :bro:type:`bool`
This cross references ``bool`` in the description of its type
instead of ``TypeAlias`` just because it seems more useful --
one doesn't have to click through the full type alias chain to
find out what the actual type is...
.. bro:id:: BroxygenTest::a
:Type: :bro:type:`BroxygenTest::TypeAlias`
But this should reference a type of ``TypeAlias``.
.. bro:id:: BroxygenTest::b
:Type: :bro:type:`BroxygenTest::OtherTypeAlias`
And this should reference a type of ``OtherTypeAlias``.
.. bro:type:: BroxygenTest::MyRecord
:Type: :bro:type:`record`
f1: :bro:type:`BroxygenTest::TypeAlias`
f2: :bro:type:`BroxygenTest::OtherTypeAlias`
f3: :bro:type:`bool`

View file

@ -1 +0,0 @@
@TEST-EXEC: cd $BUILD && make restdoc

View file

@ -1,2 +0,0 @@
@TEST-EXEC: bro --doc-scripts $DIST/doc/scripts/example.bro
@TEST-EXEC: btest-diff example.rst

View file

@ -1,15 +0,0 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
# @TEST-EXEC: btest-diff autogen-reST-type-aliases.rst
## This is just an alias for a builtin type ``bool``.
type TypeAlias: bool;
## We decided that creating alias "chains" might not be so useful to document
## so this type just creates a cross reference to ``bool``.
type OtherTypeAlias: TypeAlias;
## But this should reference a type of ``TypeAlias``.
global a: TypeAlias;
## And this should reference a type of ``OtherTypeAlias``.
global b: OtherTypeAlias;

View file

@ -0,0 +1,10 @@
# This test is mostly just checking that there's no errors that result
# from loading all scripts and generated docs for each.
# @TEST-EXEC: bro -X broxygen.config broxygen
# @TEST-EXEC: btest-diff .stdout
# @TEST-EXEC: btest-diff .stderr
@TEST-START-FILE broxygen.config
script scripts/ *
@TEST-END-FILE

View file

@ -1,6 +1,10 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
# @TEST-EXEC: bro -b -X broxygen.config %INPUT
# @TEST-EXEC: btest-diff autogen-reST-enums.rst
@TEST-START-FILE broxygen.config
identifier autogen-reST-enums.rst TestEnum*
@TEST-END-FILE
## There's tons of ways an enum can look...
type TestEnum1: enum {
## like this
@ -36,4 +40,4 @@ redef enum TestEnum1 += {
};
## this should reference the TestEnum1 type and not a generic "enum" type
const test_enum_option = ONE &redef;
const TestEnumVal = ONE &redef;

View file

@ -0,0 +1,8 @@
# @TEST-EXEC: bro -X broxygen.config %INPUT
# @TEST-EXEC: btest-diff example.rst
@TEST-START-FILE broxygen.config
script example.rst broxygen/example.bro
@TEST-END-FILE
@load broxygen/example.bro

View file

@ -1,15 +1,19 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
# @TEST-EXEC: bro -b -X broxygen.config %INPUT
# @TEST-EXEC: btest-diff autogen-reST-func-params.rst
@TEST-START-FILE broxygen.config
identifier autogen-reST-func-params.rst test_func_params*
@TEST-END-FILE
## This is a global function declaration.
##
## i: First param.
## j: Second param.
##
## Returns: A string.
global test_func: function(i: int, j: int): string;
global test_func_params_func: function(i: int, j: int): string;
type test_rec: record {
type test_func_params_rec: record {
## This is a record field function.
##
## i: First param.

View file

@ -1,21 +1,25 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
# @TEST-EXEC: bro -b -X broxygen.config %INPUT
# @TEST-EXEC: btest-diff autogen-reST-records.rst
@TEST-START-FILE broxygen.config
identifier autogen-reST-records.rst TestRecord*
@TEST-END-FILE
# undocumented record
type SimpleRecord: record {
type TestRecord1: record {
field1: bool;
field2: count;
};
## Here's the ways records and record fields can be documented.
type TestRecord: record {
type TestRecord2: record {
## document ``A``
A: count;
B: bool; ##< document ``B``
## and now ``C``
C: SimpleRecord; ##< is a declared type
C: TestRecord1; ##< is a declared type
## sets/tables should show the index types
D: set[count, bool];

View file

@ -0,0 +1,34 @@
# @TEST-EXEC: bro -b -X broxygen.config %INPUT
# @TEST-EXEC: btest-diff autogen-reST-type-aliases.rst
@TEST-START-FILE broxygen.config
identifier autogen-reST-type-aliases.rst BroxygenTest::*
@TEST-END-FILE
module BroxygenTest;
export {
## This is just an alias for a builtin type ``bool``.
type TypeAlias: bool;
## This type should get its own comments, not associated w/ TypeAlias.
type NotTypeAlias: bool;
## This cross references ``bool`` in the description of its type
## instead of ``TypeAlias`` just because it seems more useful --
## one doesn't have to click through the full type alias chain to
## find out what the actual type is...
type OtherTypeAlias: TypeAlias;
## But this should reference a type of ``TypeAlias``.
global a: TypeAlias;
## And this should reference a type of ``OtherTypeAlias``.
global b: OtherTypeAlias;
type MyRecord: record {
f1: TypeAlias;
f2: OtherTypeAlias;
f3: bool;
};
}

View file

@ -1,7 +1,7 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
# @TEST-EXEC: bro -b %INPUT
# When in doc mode, bro will clone declared types (see add_type() in Var.cc)
# in order to keep track of the identifier name associated with the new type.
# To support documentation of type aliases, Bro clones declared types
# (see add_type() in Var.cc) in order to keep track of type names and aliases.
# This test makes sure that the cloning is done in a way that's compatible
# with adding fields to a record type -- we want to be sure that cloning
# a type that contains record types will correctly see field additions to

View file

@ -1,4 +1,4 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
# @TEST-EXEC: bro -b %INPUT
type Tag: enum {
SOMETHING