diff --git a/Makefile b/Makefile index c5f4bf67ce..e0c2860873 100644 --- a/Makefile +++ b/Makefile @@ -11,11 +11,23 @@ VERSION_FULL=$(REPO)-`cat VERSION` VERSION_MIN=$(REPO)-`cat VERSION`-minimal HAVE_MODULES=git submodule | grep -v cmake >/dev/null -SUBDIRS = $(BUILD) -$(SUBDIRS):: configured - $(MAKE) -C $@ $(MAKECMDGOALS) +all: configured + $(MAKE) -C $(BUILD) $@ -all install install-aux doc docclean clean: $(SUBDIRS) +install: configured + $(MAKE) -C $(BUILD) $@ + +install-aux: configured + $(MAKE) -C $(BUILD) $@ + +clean: configured docclean + $(MAKE) -C $(BUILD) $@ + +doc: configured + $(MAKE) -C $(BUILD) $@ + +docclean: configured + $(MAKE) -C $(BUILD) $@ dist: @rm -rf $(VERSION_FULL) $(VERSION_FULL).tgz diff --git a/aux/binpac b/aux/binpac index 0f99acfbf6..34d9043740 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit 0f99acfbf6205830f0db699a75554262c26427f9 +Subproject commit 34d90437403e4129468f89acce0bd1a99813a2f4 diff --git a/aux/bro-aux b/aux/bro-aux index 1a7a9357fb..7ea5837b4b 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 1a7a9357fba88a43c90a39d8d72b42fa53b89b75 +Subproject commit 7ea5837b4ba8403731ca4a9875616c0ab501342f diff --git a/aux/broccoli b/aux/broccoli index a1a03c6868..d281350dbc 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit a1a03c686866bd30ee086ff933128055a20ebd56 +Subproject commit d281350dbcc19c24aa6b6d89a4edc08a5c74a790 diff --git a/aux/broctl b/aux/broctl index 03d39aa5d4..ed4d4ce1ad 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 03d39aa5d4ab24cd9b8e404a9ceb583d5270444c +Subproject commit ed4d4ce1add51f0e08e6e8d2f5f247c2cbb422da diff --git a/cmake b/cmake index 44f2985475..f0f7958639 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 44f2985475e5ff6cc9061683e21ef4b184bdfc7e +Subproject commit f0f7958639bb921985c1f58f1186da4b49b5d54d diff --git a/doc/_static/broxygen-extra.css b/doc/_static/broxygen-extra.css new file mode 100644 index 0000000000..dd56416783 --- /dev/null +++ b/doc/_static/broxygen-extra.css @@ -0,0 +1,3 @@ +.highlight { + background-color: #ffffff; +} diff --git a/doc/_static/broxygen.css b/doc/_static/broxygen.css deleted file mode 100644 index d9c39a8506..0000000000 --- a/doc/_static/broxygen.css +++ /dev/null @@ -1,16 +0,0 @@ -a:hover -{ - text-decoration:none; - color:#c24444; -} - -div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 -{ -background-color:#ffffff; -border-bottom: 1px solid #aaa; -} - -th.field-name -{ -white-space:nowrap; -} diff --git a/doc/_static/default.css_t b/doc/_static/default.css_t new file mode 100644 index 0000000000..34c2157b25 --- /dev/null +++ b/doc/_static/default.css_t @@ -0,0 +1,309 @@ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: {{ theme_bodyfont }}; + font-size: 100%; + background-color: {{ theme_footerbgcolor }}; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: {{ theme_sidebarbgcolor }}; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 {{ theme_sidebarwidth|toint }}px; +} + +div.body { + background-color: {{ theme_bgcolor }}; + color: {{ theme_textcolor }}; + padding: 0 20px 30px 20px; +} + +{%- if theme_rightsidebar|tobool %} +div.bodywrapper { + margin: 0 {{ theme_sidebarwidth|toint }}px 0 0; +} +{%- endif %} + +div.footer { + color: {{ theme_footertextcolor }}; + background-color: {{ theme_footerbgcolor }}; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: {{ theme_footertextcolor }}; + text-decoration: underline; +} + +div.related { + background-color: {{ theme_relbarbgcolor }}; + line-height: 30px; + color: {{ theme_relbartextcolor }}; +} + +div.related a { + color: {{ theme_relbarlinkcolor }}; +} + +div.sphinxsidebar { + {%- if theme_stickysidebar|tobool %} + top: 30px; + bottom: 0; + margin: 0; + position: fixed; + overflow: auto; + height: auto; + {%- endif %} + {%- if theme_rightsidebar|tobool %} + float: right; + {%- if theme_stickysidebar|tobool %} + right: 0; + {%- endif %} + {%- endif %} +} + +{%- if theme_stickysidebar|tobool %} +/* this is nice, but it it leads to hidden headings when jumping + to an anchor */ +/* +div.related { + position: fixed; +} + +div.documentwrapper { + margin-top: 30px; +} +*/ +{%- endif %} + +div.sphinxsidebar h3 { + font-family: {{ theme_bodyfont }}; + color: {{ theme_sidebartextcolor }}; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: {{ theme_sidebartextcolor }}; +} + +div.sphinxsidebar h4 { + font-family: {{ theme_bodyfont }}; + color: {{ theme_sidebartextcolor }}; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: {{ theme_sidebartextcolor }}; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: {{ theme_sidebartextcolor }}; +} + +div.sphinxsidebar a { + color: {{ theme_sidebarlinkcolor }}; +} + +div.sphinxsidebar input { + border: 1px solid {{ theme_sidebarlinkcolor }}; + font-family: sans-serif; + font-size: 1em; +} + +{% if theme_collapsiblesidebar|tobool %} +/* for collapsible sidebar */ +div#sidebarbutton { + background-color: {{ theme_sidebarbtncolor }}; +} +{% endif %} + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: {{ theme_linkcolor }}; + text-decoration: none; +} + +a:visited { + color: {{ theme_visitedlinkcolor }}; + text-decoration: none; +} + +{% if theme_externalrefs|tobool %} +a.external { + text-decoration: none; + border-bottom: 1px dashed {{ theme_linkcolor }}; +} + +a.external:hover { + text-decoration: none; + border-bottom: none; +} + +a.external:visited { + text-decoration: none; + border-bottom: 1px dashed {{ theme_visitedlinkcolor }}; +} +{% endif %} + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: {{ theme_bodyfont }}; + background-color: #ffffff; + font-weight: normal; + color: {{ theme_headtextcolor }}; + border-bottom: 1px solid #aaa; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { + font-family: {{ theme_headfont }}; + text-align: center; + border-bottom: none; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: {{ theme_headlinkcolor }}; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: {{ theme_headlinkcolor }}; + color: white; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: {{ theme_codebgcolor }}; + color: {{ theme_codetextcolor }}; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} + +.viewcode-back { + font-family: {{ theme_bodyfont }}; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +th.field-name +{ + white-space:nowrap; +} diff --git a/doc/_static/download.js b/doc/_static/download.js new file mode 100644 index 0000000000..82bfe502cb --- /dev/null +++ b/doc/_static/download.js @@ -0,0 +1,3 @@ +$(document).ready(function() { + $('.docutils.download').removeClass('download'); +}); diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html index 90c448037e..518718c55c 100644 --- a/doc/_templates/layout.html +++ b/doc/_templates/layout.html @@ -1,10 +1,10 @@ {% extends "!layout.html" %} -{% set css_files = css_files + ["_static/broxygen.css"] %} - {% block extrahead %} - + + + {% endblock %} {% block relbar2 %}{% endblock %} diff --git a/doc/conf.py.in b/doc/conf.py.in index e997796eda..72337b930f 100644 --- a/doc/conf.py.in +++ b/doc/conf.py.in @@ -59,7 +59,7 @@ release = '@VERSION@' # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -92,13 +92,15 @@ pygments_style = 'sphinx' # a list of builtin themes. html_theme = 'default' +html_last_updated_fmt = '%B %d, %Y' + # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { "rightsidebar": "true", "stickysidebar": "true", -"externalrefs": "true", +"externalrefs": "false", "footerbgcolor": "#333", "footertextcolor": "#ddd", "sidebarbgcolor": "#ffffff", diff --git a/doc/ext/bro.py b/doc/ext/bro.py index 7ec02f76a8..a4f0142ce3 100644 --- a/doc/ext/bro.py +++ b/doc/ext/bro.py @@ -4,6 +4,9 @@ def setup(Sphinx): Sphinx.add_domain(BroDomain) + Sphinx.add_node(see) + Sphinx.add_directive_to_domain('bro', 'see', SeeDirective) + Sphinx.connect('doctree-resolved', process_see_nodes) from sphinx import addnodes from sphinx.domains import Domain, ObjType, Index @@ -18,7 +21,57 @@ from docutils.parsers.rst import Directive from docutils.parsers.rst import directives from docutils.parsers.rst.roles import set_classes +class see(nodes.General, nodes.Element): + refs = [] + +class SeeDirective(Directive): + has_content = True + + def run(self): + n = see('') + n.refs = string.split(string.join(self.content)) + return [n] + +def process_see_nodes(app, doctree, fromdocname): + for node in doctree.traverse(see): + content = [] + para = nodes.paragraph() + para += nodes.Text("See also:", "See also:") + for name in node.refs: + join_str = " " + if name != node.refs[0]: + join_str = ", " + link_txt = join_str + name; + + if name not in app.env.domaindata['bro']['idtypes']: + # Just create the text and issue warning + app.env.warn(fromdocname, + 'unknown target for ".. bro:see:: %s"' % (name)) + para += nodes.Text(link_txt, link_txt) + else: + # Create a reference + typ = app.env.domaindata['bro']['idtypes'][name] + todocname = app.env.domaindata['bro']['objects'][(typ, name)] + + newnode = nodes.reference('', '') + innernode = nodes.literal(_(name), _(name)) + newnode['refdocname'] = todocname + newnode['refuri'] = app.builder.get_relative_uri( + fromdocname, todocname) + newnode['refuri'] += '#' + typ + '-' + name + newnode.append(innernode) + para += nodes.Text(join_str, join_str) + para += newnode + + content.append(para) + node.replace_self(content) + class BroGeneric(ObjectDescription): + def update_type_map(self, idname): + if 'idtypes' not in self.env.domaindata['bro']: + self.env.domaindata['bro']['idtypes'] = {} + self.env.domaindata['bro']['idtypes'][idname] = self.objtype + def add_target_and_index(self, name, sig, signode): targetname = self.objtype + '-' + name if targetname not in self.state.document.ids: @@ -29,9 +82,6 @@ class BroGeneric(ObjectDescription): objects = self.env.domaindata['bro']['objects'] key = (self.objtype, name) -# this is commented out mostly just to avoid having a special directive -# for events in order to avoid the duplicate warnings in that case - """ if key in objects: self.env.warn(self.env.docname, 'duplicate description of %s %s, ' % @@ -39,8 +89,9 @@ class BroGeneric(ObjectDescription): 'other instance in ' + self.env.doc2path(objects[key]), self.lineno) - """ objects[key] = self.env.docname + self.update_type_map(name) + indextext = self.get_index_text(self.objtype, name) if indextext: self.indexnode['entries'].append(('single', indextext, @@ -65,6 +116,8 @@ class BroNamespace(BroGeneric): objects = self.env.domaindata['bro']['objects'] key = (self.objtype, name) objects[key] = self.env.docname + self.update_type_map(name) + indextext = self.get_index_text(self.objtype, name) self.indexnode['entries'].append(('single', indextext, targetname, targetname)) @@ -91,10 +144,17 @@ class BroEnum(BroGeneric): objects = self.env.domaindata['bro']['objects'] key = (self.objtype, name) objects[key] = self.env.docname + self.update_type_map(name) + indextext = self.get_index_text(self.objtype, name) #self.indexnode['entries'].append(('single', indextext, # targetname, targetname)) m = sig.split() + if m[1] == "Notice::Type": + if 'notices' not in self.env.domaindata['bro']: + self.env.domaindata['bro']['notices'] = [] + self.env.domaindata['bro']['notices'].append( + (m[0], self.env.docname, targetname)) self.indexnode['entries'].append(('single', "%s (enum values); %s" % (m[1], m[0]), targetname, targetname)) @@ -113,6 +173,26 @@ class BroAttribute(BroGeneric): def get_index_text(self, objectname, name): return _('%s (attribute)') % (name) +class BroNotices(Index): + """ + Index subclass to provide the Bro notices index. + """ + + name = 'noticeindex' + localname = l_('Bro Notice Index') + shortname = l_('notices') + + def generate(self, docnames=None): + content = {} + for n in self.domain.env.domaindata['bro']['notices']: + modname = n[0].split("::")[0] + entries = content.setdefault(modname, []) + entries.append([n[0], 0, n[1], n[2], '', '', '']) + + content = sorted(content.iteritems()) + + return content, False + class BroDomain(Domain): """Bro domain.""" name = 'bro' @@ -140,8 +220,13 @@ class BroDomain(Domain): 'id': XRefRole(), 'enum': XRefRole(), 'attr': XRefRole(), + 'see': XRefRole(), } + indices = [ + BroNotices, + ] + initial_data = { 'objects': {}, # fullname -> docname, objtype } @@ -154,13 +239,24 @@ class BroDomain(Domain): def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): objects = self.data['objects'] - objtypes = self.objtypes_for_role(typ) - for objtype in objtypes: - if (objtype, target) in objects: - return make_refnode(builder, fromdocname, - objects[objtype, target], - objtype + '-' + target, - contnode, target + ' ' + objtype) + if typ == "see": + if target not in self.data['idtypes']: + self.env.warn(fromdocname, + 'unknown target for ":bro:see:`%s`"' % (target)) + return [] + objtype = self.data['idtypes'][target] + return make_refnode(builder, fromdocname, + objects[objtype, target], + objtype + '-' + target, + contnode, target + ' ' + objtype) + else: + objtypes = self.objtypes_for_role(typ) + for objtype in objtypes: + if (objtype, target) in objects: + return make_refnode(builder, fromdocname, + objects[objtype, target], + objtype + '-' + target, + contnode, target + ' ' + objtype) def get_objects(self): for (typ, name), docname in self.data['objects'].iteritems(): diff --git a/doc/index.rst b/doc/index.rst index 022552f3d4..ba3df81e7d 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -57,10 +57,11 @@ Other Bro Components components/pysubnettree/README components/trace-summary/README -Indices and tables ------------------- +Other Indices and References +---------------------------- -* :ref:`genindex` +* :ref:`General Index ` +* `Notice Index `_ * :ref:`search` Internal References diff --git a/doc/scripts/example.bro b/doc/scripts/example.bro index c239f2d2a2..d2d0ec6879 100644 --- a/doc/scripts/example.bro +++ b/doc/scripts/example.bro @@ -5,6 +5,16 @@ ##! (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 # Comments that use a single pound sign (#) are not significant to # a script's auto-generated documentation, but ones that use a diff --git a/testing/btest/Baseline/doc.autogen-reST-example/example.rst b/testing/btest/Baseline/doc.autogen-reST-example/example.rst index b76b9af59b..880fa0e171 100644 --- a/testing/btest/Baseline/doc.autogen-reST-example/example.rst +++ b/testing/btest/Baseline/doc.autogen-reST-example/example.rst @@ -15,6 +15,16 @@ these comments are transferred directly into the auto-generated .. 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 + :Imports: :doc:`policy/frameworks/software/vulnerable ` Summary