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

View file

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

View file

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

View file

@ -50,10 +50,25 @@ public:
bool HasDocumentation() const { return reST_doc_strings &&
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:
std::list<std::string>* reST_doc_strings;
const ID* broID;
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:
};

View file

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

View file

@ -51,6 +51,7 @@ public:
void PushIndent();
void PopIndent();
void PopIndentNoNL();
int GetIndentLevel() const { return indent_level; }
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(name);
}
d->PushIndent();
d->NL();
if ( type )
{
d->Add(".. bro:type:: ");
d->Add(":Type: ");
if ( ! is_type && type->GetTypeID() )
{
d->Add("`");
d->Add(":bro:type:`");
d->Add(type->GetTypeID());
d->Add("`");
}
else
type->DescribeReST(d);
d->NL();
}
if ( attrs )
{
d->Add(":Attributes: ");
attrs->DescribeReST(d);
d->NL();
}
if ( val && type &&
type->InternalType() != TYPE_INTERNAL_OTHER &&
type->InternalType() != TYPE_INTERNAL_VOID )
{
d->NL();
d->Add(".. bro:val:: ");
d->Add(":Init: ");
val->DescribeReST(d);
d->NL();
}
}
#ifdef DEBUG

View file

@ -85,7 +85,7 @@ public:
// Adds type and value to description.
void DescribeExtended(ODesc* d) const;
// 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;
static ID* Unserialize(UnserialInfo* info);

View file

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

View file

@ -576,7 +576,9 @@ void Val::Describe(ODesc* d) const
void Val::DescribeReST(ODesc* d) const
{
d->Add("``");
ValDescribeReST(d);
d->Add("``");
}
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);
}
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
// 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);
fake_id->SetType(cur_enum_type_doc);
type->SetTypeID(copy_string(name));
fake_id->MakeType();
return fake_id;
}
@ -995,6 +996,7 @@ decl:
ID* fake_id = create_dummy_id($3->Name(), cur_enum_type_doc);
cur_enum_type_doc = 0;
BroDocObj* o = new BroDocObj(fake_id, reST_doc_comments, true);
o->SetRole(true);
if ( streq(fake_id->Name(), "Notice" ) )
current_reST_doc->AddNotice(o);
else