Major reformatting of auto-generated reST documentation.

Introduces reST directives and roles in a "bro" domain that Sphinx
will be taught to recognize.
This commit is contained in:
Jon Siwek 2011-03-22 16:05:59 -05:00
parent 384fa03c26
commit bbe7c98ab3
11 changed files with 132 additions and 45 deletions

View file

@ -51,12 +51,17 @@ void Attr::Describe(ODesc* d) const
void Attr::DescribeReST(ODesc* d) const void Attr::DescribeReST(ODesc* d) const
{ {
d->Add(".. bro:attr:: "); d->Add(":bro:attr:`");
AddTag(d); AddTag(d);
d->Add("`");
if ( expr ) if ( expr )
{ {
d->SP();
d->Add("="); d->Add("=");
d->SP();
d->Add("``");
expr->Describe(d); expr->Describe(d);
d-> Add("``");
} }
} }
@ -176,7 +181,8 @@ void Attributes::DescribeReST(ODesc* d) const
{ {
loop_over_list(*attrs, i) loop_over_list(*attrs, i)
{ {
d->NL(); if ( i > 0 )
d->Add(" ");
(*attrs)[i]->DescribeReST(d); (*attrs)[i]->DescribeReST(d);
} }
} }

View file

@ -99,14 +99,18 @@ void BroDoc::WriteDocFile() const
WriteToDoc(":Author(s): "); WriteToDoc(":Author(s): ");
WriteStringList("%s, ", "%s\n", authors); WriteStringList("%s, ", "%s\n", authors);
WriteToDoc(":Namespaces: ");
WriteStringList("`%s`, ", "`%s`\n", modules);
WriteToDoc(":Imports: "); WriteToDoc(":Imports: ");
WriteStringList(":doc:`%s`, ", ":doc:`%s`\n", imports); WriteStringList(":doc:`%s`, ", ":doc:`%s`\n", imports);
WriteToDoc("\n"); WriteToDoc("\n");
if ( ! modules.empty() )
{
WriteSectionHeading("Namespaces", '-');
WriteStringList(".. bro:namespace:: %s\n", modules);
WriteToDoc("\n");
}
if ( ! notices.empty() ) if ( ! notices.empty() )
WriteBroDocObjList(notices, "Notices", '-'); WriteBroDocObjList(notices, "Notices", '-');

View file

@ -11,6 +11,7 @@ BroDocObj::BroDocObj(const ID* id, std::list<std::string>*& reST,
reST_doc_strings = reST; reST_doc_strings = reST;
reST = 0; reST = 0;
is_fake_id = is_fake; is_fake_id = is_fake;
use_role = 0;
} }
BroDocObj::~BroDocObj() BroDocObj::~BroDocObj()
@ -21,11 +22,12 @@ BroDocObj::~BroDocObj()
void BroDocObj::WriteReST(FILE* file) const void BroDocObj::WriteReST(FILE* file) const
{ {
int indent_spaces = 3;
ODesc desc; ODesc desc;
desc.SetIndentSpaces(4); desc.SetIndentSpaces(indent_spaces);
desc.SetQuotes(1); desc.SetQuotes(1);
broID->DescribeReST(&desc); broID->DescribeReST(&desc, use_role);
fprintf(file, "%s\n", desc.Description()); fprintf(file, "%s", desc.Description());
if ( HasDocumentation() ) if ( HasDocumentation() )
{ {
@ -33,7 +35,11 @@ void BroDocObj::WriteReST(FILE* file) const
std::list<std::string>::const_iterator it; std::list<std::string>::const_iterator it;
for ( it = reST_doc_strings->begin(); for ( it = reST_doc_strings->begin();
it != reST_doc_strings->end(); ++it) it != reST_doc_strings->end(); ++it)
fprintf(file, " %s\n", it->c_str()); {
for ( int i = 0; i < indent_spaces; ++i )
fprintf(file, " ");
fprintf(file, "%s\n", it->c_str());
}
} }
fprintf(file, "\n"); fprintf(file, "\n");

View file

@ -50,10 +50,25 @@ public:
bool HasDocumentation() const { return reST_doc_strings && bool HasDocumentation() const { return reST_doc_strings &&
reST_doc_strings->size() > 0; } reST_doc_strings->size() > 0; }
/**
* @return whether this object will use reST role (T) or directive (F)
* notation for the wrapped identifier. Roles are usually used
* for cross-referencing.
*/
bool UseRole() const { return use_role; }
/**
* @param b whether this object will use reST role (T) or directive (F)
* notation for the wrapped identifier. Roles are usually used
* for cross-referencing.
*/
void SetRole(bool b) { use_role = b; }
protected: protected:
std::list<std::string>* reST_doc_strings; std::list<std::string>* reST_doc_strings;
const ID* broID; const ID* broID;
bool is_fake_id; /**< Whether the ID* is a dummy just for doc purposes */ bool is_fake_id; /**< Whether the ID* is a dummy just for doc purposes */
bool use_role; /**< Whether to use a reST role or directive for the ID */
private: private:
}; };

View file

@ -68,6 +68,12 @@ void ODesc::PopIndent()
NL(); NL();
} }
void ODesc::PopIndentNoNL()
{
if ( --indent_level < 0 )
internal_error("ODesc::PopIndent underflow");
}
void ODesc::Add(const char* s, int do_indent) void ODesc::Add(const char* s, int do_indent)
{ {
unsigned int n = strlen(s); unsigned int n = strlen(s);

View file

@ -51,6 +51,7 @@ public:
void PushIndent(); void PushIndent();
void PopIndent(); void PopIndent();
void PopIndentNoNL();
int GetIndentLevel() const { return indent_level; } int GetIndentLevel() const { return indent_level; }
int IndentSpaces() const { return indent_with_spaces; } int IndentSpaces() const { return indent_with_spaces; }

View file

@ -607,39 +607,57 @@ void ID::DescribeExtended(ODesc* d) const
} }
} }
void ID::DescribeReST(ODesc* d) const void ID::DescribeReST(ODesc* d, bool is_role) const
{ {
if ( is_role )
{
if ( is_type )
d->Add(":bro:type:`");
else
d->Add(":bro:id:`");
d->Add(name);
d->Add("`");
}
else
{
if ( is_type )
d->Add(".. bro:type:: ");
else
d->Add(".. bro:id:: "); d->Add(".. bro:id:: ");
d->Add(name); d->Add(name);
}
d->PushIndent(); d->PushIndent();
d->NL();
if ( type ) if ( type )
{ {
d->Add(".. bro:type:: "); d->Add(":Type: ");
if ( ! is_type && type->GetTypeID() ) if ( ! is_type && type->GetTypeID() )
{ {
d->Add("`"); d->Add(":bro:type:`");
d->Add(type->GetTypeID()); d->Add(type->GetTypeID());
d->Add("`"); d->Add("`");
} }
else else
type->DescribeReST(d); type->DescribeReST(d);
d->NL();
} }
if ( attrs ) if ( attrs )
{ {
d->Add(":Attributes: ");
attrs->DescribeReST(d); attrs->DescribeReST(d);
d->NL();
} }
if ( val && type && if ( val && type &&
type->InternalType() != TYPE_INTERNAL_OTHER && type->InternalType() != TYPE_INTERNAL_OTHER &&
type->InternalType() != TYPE_INTERNAL_VOID ) type->InternalType() != TYPE_INTERNAL_VOID )
{ {
d->NL(); d->Add(":Init: ");
d->Add(".. bro:val:: ");
val->DescribeReST(d); val->DescribeReST(d);
d->NL();
} }
} }
#ifdef DEBUG #ifdef DEBUG

View file

@ -85,7 +85,7 @@ public:
// Adds type and value to description. // Adds type and value to description.
void DescribeExtended(ODesc* d) const; void DescribeExtended(ODesc* d) const;
// Produces a description that's reST-ready // Produces a description that's reST-ready
void DescribeReST(ODesc* d) const; void DescribeReST(ODesc* d, bool is_role=false) const;
bool Serialize(SerialInfo* info) const; bool Serialize(SerialInfo* info) const;
static ID* Unserialize(UnserialInfo* info); static ID* Unserialize(UnserialInfo* info);

View file

@ -149,7 +149,9 @@ void BroType::Describe(ODesc* d) const
void BroType::DescribeReST(ODesc* d) const void BroType::DescribeReST(ODesc* d) const
{ {
Describe(d); d->Add(":bro:type:`");
d->Add(type_name(Tag()));
d->Add("`");
} }
void BroType::SetError() void BroType::SetError()
@ -439,20 +441,22 @@ void IndexType::Describe(ODesc* d) const
void IndexType::DescribeReST(ODesc* d) const void IndexType::DescribeReST(ODesc* d) const
{ {
d->Add(":bro:type:`");
if ( IsSet() ) if ( IsSet() )
d->Add("set"); d->Add("set");
else else
d->Add(type_name(Tag())); d->Add(type_name(Tag()));
d->Add("` ");
d->Add("["); d->Add("[");
loop_over_list(*IndexTypes(), i) loop_over_list(*IndexTypes(), i)
{ {
if ( i > 0 ) if ( i > 0 )
d->Add(","); d->Add(", ");
const BroType* t = (*IndexTypes())[i]; const BroType* t = (*IndexTypes())[i];
if ( t->GetTypeID() ) if ( t->GetTypeID() )
{ {
d->Add("`"); d->Add(":bro:type:`");
d->Add(t->GetTypeID()); d->Add(t->GetTypeID());
d->Add("`"); d->Add("`");
} }
@ -466,7 +470,7 @@ void IndexType::DescribeReST(ODesc* d) const
d->Add(" of "); d->Add(" of ");
if ( yield_type->GetTypeID() ) if ( yield_type->GetTypeID() )
{ {
d->Add("`"); d->Add(":bro:type:`");
d->Add(yield_type->GetTypeID()); d->Add(yield_type->GetTypeID());
d->Add("`"); d->Add("`");
} }
@ -711,8 +715,10 @@ void FuncType::Describe(ODesc* d) const
void FuncType::DescribeReST(ODesc* d) const void FuncType::DescribeReST(ODesc* d) const
{ {
d->Add(":bro:type:`");
d->Add(is_event ? "event" : "function"); d->Add(is_event ? "event" : "function");
d->Add("("); d->Add("`");
d->Add(" (");
args->DescribeFieldsReST(d, true); args->DescribeFieldsReST(d, true);
d->Add(")"); d->Add(")");
if ( yield ) if ( yield )
@ -720,7 +726,7 @@ void FuncType::DescribeReST(ODesc* d) const
d->AddSP(" :"); d->AddSP(" :");
if ( yield->GetTypeID() ) if ( yield->GetTypeID() )
{ {
d->Add("`"); d->Add(":bro:type:`");
d->Add(yield->GetTypeID()); d->Add(yield->GetTypeID());
d->Add("`"); d->Add("`");
} }
@ -997,7 +1003,8 @@ void RecordType::Describe(ODesc* d) const
void RecordType::DescribeReST(ODesc* d) const void RecordType::DescribeReST(ODesc* d) const
{ {
d->Add("record"); d->Add(":bro:type:`record`");
d->NL();
DescribeFieldsReST(d, false); DescribeFieldsReST(d, false);
} }
@ -1048,36 +1055,46 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const
for ( int i = 0; i < num_fields; ++i ) for ( int i = 0; i < num_fields; ++i )
{ {
const TypeDecl* td = FieldDecl(i); const TypeDecl* td = FieldDecl(i);
if ( ! func_args )
d->Add(":bro:field: "); if ( i > 0 )
if ( func_args )
d->Add(", ");
else
{
d->NL();
d->NL();
}
d->Add(td->id); d->Add(td->id);
d->Add(": "); d->Add(": ");
d->Add(":bro:type: ");
if ( td->type->GetTypeID() ) if ( td->type->GetTypeID() )
{ {
d->Add("`"); d->Add(":bro:type:`");
d->Add(td->type->GetTypeID()); d->Add(td->type->GetTypeID());
d->Add("`"); d->Add("`");
} }
else else
td->type->DescribeReST(d); td->type->DescribeReST(d);
if ( td->attrs )
{
d->SP();
td->attrs->DescribeReST(d);
}
if ( ! func_args ) if ( ! func_args )
{
if ( td->comment ) if ( td->comment )
{ {
d->PushIndent(); d->PushIndent();
d->Add(".. bro:comment:: ");
d->Add(td->comment); d->Add(td->comment);
d->PopIndent(); d->PopIndentNoNL();
}
}
} }
if ( i + 1 != num_fields ) if ( ! func_args )
if ( func_args ) d->PopIndentNoNL();
d->Add(", ");
else
d->NL();
}
} }
IMPLEMENT_SERIAL(RecordType, SER_RECORD_TYPE) IMPLEMENT_SERIAL(RecordType, SER_RECORD_TYPE)
@ -1362,25 +1379,35 @@ void CommentedEnumType::DescribeReST(ODesc* d) const
for ( NameMap::const_iterator it = names.begin(); it != names.end(); ++it ) for ( NameMap::const_iterator it = names.begin(); it != names.end(); ++it )
rev[it->second] = it->first; rev[it->second] = it->first;
d->Add(":bro:type:`");
d->Add(type_name(Tag())); d->Add(type_name(Tag()));
d->Add("`");
d->PushIndent(); d->PushIndent();
d->NL();
for ( RevNameMap::const_iterator it = rev.begin(); it != rev.end(); ) for ( RevNameMap::const_iterator it = rev.begin(); it != rev.end(); ++it )
{ {
if ( it != rev.begin() )
{
d->NL();
d->NL();
}
d->Add(".. bro:enum:: "); d->Add(".. bro:enum:: ");
d->Add(it->second); d->AddSP(it->second);
d->Add(GetTypeID());
CommentMap::const_iterator cmnt_it = comments.find(it->second); CommentMap::const_iterator cmnt_it = comments.find(it->second);
if ( cmnt_it != comments.end() ) if ( cmnt_it != comments.end() )
{ {
d->PushIndent(); d->PushIndent();
d->Add(".. bro:comment:: ");
d->Add(cmnt_it->second);
d->PopIndent();
}
if ( ++it != rev.end() )
d->NL(); d->NL();
d->Add(cmnt_it->second);
d->PopIndentNoNL();
} }
} }
d->PopIndentNoNL();
}
IMPLEMENT_SERIAL(EnumType, SER_ENUM_TYPE); IMPLEMENT_SERIAL(EnumType, SER_ENUM_TYPE);

View file

@ -576,7 +576,9 @@ void Val::Describe(ODesc* d) const
void Val::DescribeReST(ODesc* d) const void Val::DescribeReST(ODesc* d) const
{ {
d->Add("``");
ValDescribeReST(d); ValDescribeReST(d);
d->Add("``");
} }
void Val::ValDescribe(ODesc* d) const void Val::ValDescribe(ODesc* d) const

View file

@ -153,12 +153,13 @@ static void add_enum_comment (const char* comment)
cur_enum_type_doc->AddComment(current_module, cur_enum_elem_id, comment); cur_enum_type_doc->AddComment(current_module, cur_enum_elem_id, comment);
} }
static ID* create_dummy_id (const char* name, const BroType* type) static ID* create_dummy_id (const char* name, BroType* type)
{ {
// normally, install_ID() figures out the right IDScope // normally, install_ID() figures out the right IDScope
// but it doesn't matter for the dummy ID so use SCOPE_GLOBAL // but it doesn't matter for the dummy ID so use SCOPE_GLOBAL
ID* fake_id = new ID(copy_string(name), SCOPE_GLOBAL, is_export); ID* fake_id = new ID(copy_string(name), SCOPE_GLOBAL, is_export);
fake_id->SetType(cur_enum_type_doc); fake_id->SetType(cur_enum_type_doc);
type->SetTypeID(copy_string(name));
fake_id->MakeType(); fake_id->MakeType();
return fake_id; return fake_id;
} }
@ -995,6 +996,7 @@ decl:
ID* fake_id = create_dummy_id($3->Name(), cur_enum_type_doc); ID* fake_id = create_dummy_id($3->Name(), cur_enum_type_doc);
cur_enum_type_doc = 0; cur_enum_type_doc = 0;
BroDocObj* o = new BroDocObj(fake_id, reST_doc_comments, true); BroDocObj* o = new BroDocObj(fake_id, reST_doc_comments, true);
o->SetRole(true);
if ( streq(fake_id->Name(), "Notice" ) ) if ( streq(fake_id->Name(), "Notice" ) )
current_reST_doc->AddNotice(o); current_reST_doc->AddNotice(o);
else else