mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 23:28:20 +00:00
Initial implementation of a make doc
target to generate script docs.
This commit is contained in:
parent
bd523f2905
commit
5183ab409b
12 changed files with 964 additions and 2 deletions
|
@ -43,6 +43,11 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.csh
|
|||
"setenv BROPATH `${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev`\n")
|
||||
|
||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1)
|
||||
string(REPLACE "." " " version_numbers ${VERSION})
|
||||
separate_arguments(version_numbers)
|
||||
list(GET version_numbers 0 VERSION_MAJOR)
|
||||
list(GET version_numbers 1 VERSION_MINOR)
|
||||
set(VERSION_MAJ_MIN "${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
|
||||
set(EXTRA_COMPILE_FLAGS "-Wall -Wno-unused")
|
||||
|
||||
|
@ -162,8 +167,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(policy)
|
||||
#add_subdirectory(scripts)
|
||||
#add_subdirectory(doc)
|
||||
add_subdirectory(doc)
|
||||
|
||||
include(CheckOptionalBuildSources)
|
||||
|
||||
|
|
40
doc/CMakeLists.txt
Normal file
40
doc/CMakeLists.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
set(POLICY_SRC_DIR ${PROJECT_SOURCE_DIR}/policy)
|
||||
set(DOC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/out)
|
||||
set(DOC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source)
|
||||
set(DOC_SOURCE_WORKDIR ${CMAKE_CURRENT_BINARY_DIR}/source)
|
||||
|
||||
file(GLOB_RECURSE DOC_SOURCES FOLLOW_SYMLINKS "*")
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/conf.py
|
||||
@ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_reST_docs.py.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generate_reST_docs.py
|
||||
@ONLY)
|
||||
|
||||
add_custom_target(doc
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
${DOC_SOURCE_DIR}
|
||||
${DOC_SOURCE_WORKDIR}
|
||||
COMMAND python generate_reST_docs.py
|
||||
COMMAND sphinx-build
|
||||
-b html
|
||||
-c ${CMAKE_CURRENT_BINARY_DIR}
|
||||
-d ${DOC_OUTPUT_DIR}/doctrees
|
||||
${DOC_SOURCE_WORKDIR}
|
||||
${DOC_OUTPUT_DIR}/html
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "[Sphinx] Generating Script Documentation"
|
||||
VERBATIM
|
||||
# SOURCES just adds stuff to IDE projects as a convienience
|
||||
SOURCES ${DOC_SOURCES})
|
||||
|
||||
add_dependencies(doc bro)
|
||||
# TODO: add dependency that's a check for `python`, `sphinx-build`, etc.
|
||||
|
||||
add_custom_target(doc-clean
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory
|
||||
${CMAKE_CURRENT_BINARY_DIR}/source
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory
|
||||
${DOC_OUTPUT_DIR}
|
||||
VERBATIM)
|
215
doc/conf.py.in
Normal file
215
doc/conf.py.in
Normal file
|
@ -0,0 +1,215 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Bro documentation build configuration file, created by sphinx-quickstart
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('source/ext'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['bro']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['source/_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Bro'
|
||||
copyright = u'2011, Jon Siwek'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '@VERSION_MAJ_MIN@'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '@VERSION@'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# 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'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
show_authors = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# 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 = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['source/_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Brodoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Bro.tex', u'Bro Documentation',
|
||||
u'Jon Siwek', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'bro', u'Bro Documentation',
|
||||
[u'Jon Siwek'], 1)
|
||||
]
|
178
doc/example.bro
Normal file
178
doc/example.bro
Normal file
|
@ -0,0 +1,178 @@
|
|||
##! This is an example script that demonstrates how to document. 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
|
||||
##!
|
||||
##! :Author: Jon Siwek <jsiwek@ncsa.illinois.edu>
|
||||
|
||||
# Comments that use a single pound sign (#) are not significant to
|
||||
# a script's auto-generated documentation, but ones that use a
|
||||
# double pound sign (##) do matter. In some cases, like record
|
||||
# field comments, it's necessary to disambiguate the field with
|
||||
# which a comment associates: e.g. "##<" can be used on the same line
|
||||
# as a field to signify the comment relates to it and not the
|
||||
# following field. "##<" is not meant for general use, just
|
||||
# record/enum fields.
|
||||
#
|
||||
# Generally, the auto-doc comments (##) are associated with the
|
||||
# next declaration/identifier found in the script, but the doc framework
|
||||
# will track/render identifiers regardless of whether they have any
|
||||
# of these special comments associated with them.
|
||||
#
|
||||
# The first sentence contained within the "##"-stylized comments for
|
||||
# a given identifier is special in that it will be used as summary
|
||||
# text in a table containing all such identifiers and short summaries.
|
||||
# If there are no sentences (text terminated with '.'), then everything
|
||||
# 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 notice
|
||||
|
||||
# "module" statements are self-documenting
|
||||
module Example;
|
||||
|
||||
# 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 563",
|
||||
};
|
||||
|
||||
global example_ports = {
|
||||
443/tcp, 563/tcp,
|
||||
} &redef;
|
||||
|
||||
# redefinitions of "dpd_config" are self-documenting and
|
||||
# go into the generated doc's "Port Analysis" section
|
||||
redef dpd_config += {
|
||||
[ANALYZER_SSL] = [$ports = example_ports]
|
||||
};
|
||||
|
||||
# redefinitions of "Notice::Type" are self-documenting, but
|
||||
# more information can be supplied in two different ways
|
||||
redef enum Notice += {
|
||||
## 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,
|
||||
};
|
||||
|
||||
# Anything declared in the export section will show up in the rendered
|
||||
# documentation's "public interface" section
|
||||
|
||||
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
|
||||
|
||||
############## types ################
|
||||
|
||||
# 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.
|
||||
|
||||
## 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 "SimpleEnum" redef here
|
||||
redef enum SimpleEnum += {
|
||||
FOUR, ##< and some documentation for "FOUR"
|
||||
## also "FIVE" for good measure
|
||||
FIVE
|
||||
};
|
||||
|
||||
## general documentation for a type "SimpleRecord"
|
||||
## goes here.
|
||||
type SimpleRecord: record {
|
||||
## counts something
|
||||
field1: count;
|
||||
field2: bool; ##< toggles something
|
||||
};
|
||||
|
||||
|
||||
## 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;
|
||||
|
||||
############## 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.
|
||||
|
||||
## 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;
|
||||
|
||||
############## 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";
|
||||
|
||||
############## functions/events ############
|
||||
|
||||
## 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
|
||||
##
|
||||
## 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.
|
||||
## name: describe the argument here
|
||||
global an_event: event(name: string);
|
||||
}
|
||||
|
||||
# this function is documented in the "private interface" section
|
||||
# of generated documentation and any "##"-stylized comments would also
|
||||
# be rendered there
|
||||
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
|
||||
type PrivateRecord: record {
|
||||
field1: bool;
|
||||
field2: count;
|
||||
};
|
121
doc/scripts/generate_reST_docs.py.in
Executable file
121
doc/scripts/generate_reST_docs.py.in
Executable file
|
@ -0,0 +1,121 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import shutil
|
||||
import glob
|
||||
import string
|
||||
|
||||
BRO = "@CMAKE_BINARY_DIR@/src/bro"
|
||||
BROPATHDEV = "`@CMAKE_BINARY_DIR@/bro-path-dev`"
|
||||
BRO_ARGS = "--doc-scripts"
|
||||
DOC_DST_DIR = "@DOC_SOURCE_WORKDIR@/policy"
|
||||
BROPATH = subprocess.Popen("@CMAKE_BINARY_DIR@/bro-path-dev", shell=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.readline()
|
||||
|
||||
class BroToReST:
|
||||
bro_src_file = ""
|
||||
doc_src_file = ""
|
||||
load_via_stdin = False
|
||||
|
||||
def __init__(self, src_file, load_method=False, src_dir="@POLICY_SRC_DIR@"):
|
||||
self.bro_src_file = os.path.join(src_dir, src_file)
|
||||
self.load_via_stdin = load_method
|
||||
|
||||
# formulate doc_src_file from src_file
|
||||
filename = os.path.basename(src_file)
|
||||
basename, ext = os.path.splitext(filename)
|
||||
if ext == ".bro":
|
||||
self.doc_src_file = basename + ".rst"
|
||||
else:
|
||||
self.doc_src_file = filename + ".rst"
|
||||
|
||||
def __str__(self):
|
||||
return "bro_src_file: " + self.bro_src_file \
|
||||
+ "\ndoc_src_file: " + self.doc_src_file \
|
||||
+ "\ndoc_dst_file: " + os.path.join(DOC_DST_DIR, self.doc_src_file) \
|
||||
+ "\nstdin_load: %s" % self.load_via_stdin
|
||||
|
||||
def GenDoc(self):
|
||||
bro_src_basename = os.path.basename(self.bro_src_file)
|
||||
|
||||
if self.load_via_stdin:
|
||||
cmd = "echo '@load %s' | %s %s" % (bro_src_basename, BRO, BRO_ARGS)
|
||||
else:
|
||||
cmd = "%s %s %s" % (BRO, BRO_ARGS, self.bro_src_file)
|
||||
|
||||
p = subprocess.Popen(cmd, shell=True, env={"BROPATH": BROPATH})
|
||||
|
||||
if p.wait() == 0:
|
||||
shutil.copy(self.doc_src_file, DOC_DST_DIR)
|
||||
shutil.copy(self.bro_src_file, DOC_DST_DIR)
|
||||
|
||||
for leftover in glob.glob("*.rst"):
|
||||
os.remove(leftover)
|
||||
|
||||
def GenDocs(doc_list, load_method=False):
|
||||
for f in doc_list:
|
||||
doc = BroToReST(f, load_method)
|
||||
print "Generating reST document for " + f
|
||||
doc.GenDoc()
|
||||
|
||||
# search BROPATH for the script and return the absolute path to it
|
||||
def FindBroScript(src_file):
|
||||
for path in string.split(BROPATH, ":"):
|
||||
abs_path = os.path.join(path, src_file)
|
||||
if os.path.exists(abs_path):
|
||||
return abs_path
|
||||
|
||||
# Scripts that can be loaded by bro via command line argument
|
||||
# TODO: generate docs for more scripts
|
||||
docs = [
|
||||
"alarm.bro",
|
||||
"arp.bro",
|
||||
"conn.bro",
|
||||
"dhcp.bro",
|
||||
"dns.bro",
|
||||
"ftp.bro",
|
||||
"http.bro",
|
||||
"http-reply.bro",
|
||||
"http-request.bro",
|
||||
"irc.bro",
|
||||
"smtp.bro",
|
||||
"ssl.bro",
|
||||
"ssl-ciphers.bro",
|
||||
"ssl-errors.bro",
|
||||
"synflood.bro",
|
||||
"tcp.bro",
|
||||
"udp.bro",
|
||||
"weird.bro",
|
||||
]
|
||||
|
||||
# Scripts that can't be loaded by bro via command line argument (possible
|
||||
# due to dependency issues), but can be loaded via an @load on stdin
|
||||
stdin_docs = [
|
||||
"notice.bro",
|
||||
]
|
||||
|
||||
GenDocs(docs)
|
||||
GenDocs(stdin_docs, True)
|
||||
|
||||
BroToReST("example.bro", False, "@PROJECT_SOURCE_DIR@/doc").GenDoc()
|
||||
|
||||
# Generate documentation for stuff that's always loaded into bro by default
|
||||
cmd = "echo '' | %s %s" % (BRO, BRO_ARGS)
|
||||
p = subprocess.Popen(cmd, shell=True, env={"BROPATH": BROPATH})
|
||||
if p.wait() == 0:
|
||||
for doc in glob.glob("*.rst"):
|
||||
if doc == "<stdin>.rst":
|
||||
os.remove(doc)
|
||||
continue
|
||||
|
||||
basename, ext = os.path.splitext(doc)
|
||||
basename2, ext = os.path.splitext(basename)
|
||||
if ext == ".init":
|
||||
src_file = basename
|
||||
else:
|
||||
src_file = basename + ".bro"
|
||||
src_file = FindBroScript(src_file)
|
||||
shutil.copy(src_file, DOC_DST_DIR)
|
||||
shutil.copy(doc, DOC_DST_DIR)
|
||||
os.remove(doc)
|
64
doc/source/_static/showhide.js
Normal file
64
doc/source/_static/showhide.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
// make literal blocks corresponding to identifier initial values
|
||||
// hidden by default
|
||||
$(document).ready(function() {
|
||||
|
||||
var showText='(Show Value)';
|
||||
var hideText='(Hide Value)';
|
||||
|
||||
var is_visible = false;
|
||||
|
||||
// select field-list tables that come before a literal block
|
||||
tables = $('.highlight-python').prev('table.docutils.field-list');
|
||||
|
||||
tables.find('th.field-name').filter(function(index) {
|
||||
return $(this).html() == "Default :";
|
||||
}).next().append('<a href="#" class="toggleLink">'+showText+'</a>');
|
||||
|
||||
// hide all literal blocks that follow a field-list table
|
||||
tables.next('.highlight-python').hide();
|
||||
|
||||
// register handler for clicking a "toggle" link
|
||||
$('a.toggleLink').click(function() {
|
||||
is_visible = !is_visible;
|
||||
|
||||
$(this).html( (!is_visible) ? showText : hideText);
|
||||
|
||||
// the link is inside a <table><tbody><tr><td> and the next
|
||||
// literal block after the table is the literal block that we want
|
||||
// to show/hide
|
||||
$(this).parent().parent().parent().parent().next('.highlight-python').slideToggle('fast');
|
||||
|
||||
// override default link behavior
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
// make "Private Interface" sections hidden by default
|
||||
$(document).ready(function() {
|
||||
|
||||
var showText='Show Private Interface (for internal use)';
|
||||
var hideText='Hide Private Interface';
|
||||
|
||||
var is_visible = false;
|
||||
|
||||
// insert show/hide links
|
||||
$('#private-interface').children(":first-child").after('<a href="#" class="privateToggle">'+showText+'</a>');
|
||||
|
||||
// wrap all sub-sections in a new div that can be hidden/shown
|
||||
$('#private-interface').children(".section").wrapAll('<div class="private" />');
|
||||
|
||||
// hide the given class
|
||||
$('.private').hide();
|
||||
|
||||
// register handler for clicking a "toggle" link
|
||||
$('a.privateToggle').click(function() {
|
||||
is_visible = !is_visible;
|
||||
|
||||
$(this).html( (!is_visible) ? showText : hideText);
|
||||
|
||||
$('.private').slideToggle('fast');
|
||||
|
||||
// override default link behavior
|
||||
return false;
|
||||
});
|
||||
});
|
5
doc/source/_templates/layout.html
Normal file
5
doc/source/_templates/layout.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
{% extends "!layout.html" %}
|
||||
{% block extrahead %}
|
||||
<script type="text/javascript" src="{{ pathto('_static/showhide.js', 1) }}"></script>
|
||||
{{ super() }}
|
||||
{% endblock %}
|
121
doc/source/builtins.rst
Normal file
121
doc/source/builtins.rst
Normal file
|
@ -0,0 +1,121 @@
|
|||
Builtins
|
||||
========
|
||||
|
||||
Types
|
||||
-----
|
||||
|
||||
The Bro scripting language supports the following built-in types.
|
||||
|
||||
.. TODO: add documentation
|
||||
|
||||
.. bro:type:: void
|
||||
|
||||
.. bro:type:: bool
|
||||
|
||||
.. bro:type:: int
|
||||
|
||||
.. bro:type:: count
|
||||
|
||||
.. bro:type:: counter
|
||||
|
||||
.. bro:type:: double
|
||||
|
||||
.. bro:type:: time
|
||||
|
||||
.. bro:type:: interval
|
||||
|
||||
.. bro:type:: string
|
||||
|
||||
.. bro:type:: pattern
|
||||
|
||||
.. bro:type:: enum
|
||||
|
||||
.. bro:type:: timer
|
||||
|
||||
.. bro:type:: port
|
||||
|
||||
.. bro:type:: addr
|
||||
|
||||
.. bro:type:: net
|
||||
|
||||
.. bro:type:: subnet
|
||||
|
||||
.. bro:type:: any
|
||||
|
||||
.. bro:type:: table
|
||||
|
||||
.. bro:type:: union
|
||||
|
||||
.. bro:type:: record
|
||||
|
||||
.. bro:type:: types
|
||||
|
||||
.. bro:type:: func
|
||||
|
||||
.. bro:type:: file
|
||||
|
||||
.. bro:type:: vector
|
||||
|
||||
.. TODO: below are kind of "special cases" that bro knows about?
|
||||
|
||||
.. bro:type:: set
|
||||
|
||||
.. bro:type:: function
|
||||
|
||||
.. bro:type:: event
|
||||
|
||||
.. TODO: Notice will get documented as part of notice.bro, which can eventually
|
||||
be referenced here once that documentation is auto-generated.
|
||||
|
||||
.. bro:type:: Notice
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
The Bro scripting language supports the following built-in attributes.
|
||||
|
||||
.. TODO: add documentation
|
||||
|
||||
.. bro:attr:: &optional
|
||||
|
||||
.. bro:attr:: &default
|
||||
|
||||
.. bro:attr:: &redef
|
||||
|
||||
.. bro:attr:: &rotate_interval
|
||||
|
||||
.. bro:attr:: &rotate_size
|
||||
|
||||
.. bro:attr:: &add_func
|
||||
|
||||
.. bro:attr:: &delete_func
|
||||
|
||||
.. bro:attr:: &expire_func
|
||||
|
||||
.. bro:attr:: &read_expire
|
||||
|
||||
.. bro:attr:: &write_expire
|
||||
|
||||
.. bro:attr:: &create_expire
|
||||
|
||||
.. bro:attr:: &persistent
|
||||
|
||||
.. bro:attr:: &synchronized
|
||||
|
||||
.. bro:attr:: &postprocessor
|
||||
|
||||
.. bro:attr:: &encrypt
|
||||
|
||||
.. bro:attr:: &match
|
||||
|
||||
.. bro:attr:: &disable_print_hook
|
||||
|
||||
.. bro:attr:: &raw_output
|
||||
|
||||
.. bro:attr:: &mergeable
|
||||
|
||||
.. bro:attr:: &priority
|
||||
|
||||
.. bro:attr:: &group
|
||||
|
||||
.. bro:attr:: (&tracked)
|
19
doc/source/common.rst
Normal file
19
doc/source/common.rst
Normal file
|
@ -0,0 +1,19 @@
|
|||
Common Documentation
|
||||
====================
|
||||
|
||||
.. _common_port_analysis_doc:
|
||||
|
||||
Port Analysis
|
||||
-------------
|
||||
|
||||
TODO: add some stuff here
|
||||
|
||||
.. _common_packet_filter_doc:
|
||||
|
||||
Packet Filter
|
||||
-------------
|
||||
|
||||
TODO: add some stuff here
|
||||
|
||||
.. note:: Filters are only relevant when dynamic protocol detection (DPD)
|
||||
is explicitly turned off (Bro release 1.6 enabled DPD by default).
|
167
doc/source/ext/bro.py
Normal file
167
doc/source/ext/bro.py
Normal file
|
@ -0,0 +1,167 @@
|
|||
"""
|
||||
The Bro domain for Sphinx.
|
||||
"""
|
||||
|
||||
def setup(Sphinx):
|
||||
Sphinx.add_domain(BroDomain)
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains import Domain, ObjType, Index
|
||||
from sphinx.locale import l_, _
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util.nodes import make_refnode
|
||||
import string
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import Directive
|
||||
from docutils.parsers.rst import directives
|
||||
from docutils.parsers.rst.roles import set_classes
|
||||
|
||||
class BroGeneric(ObjectDescription):
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
targetname = self.objtype + '-' + name
|
||||
if targetname not in self.state.document.ids:
|
||||
signode['names'].append(targetname)
|
||||
signode['ids'].append(targetname)
|
||||
signode['first'] = (not self.names)
|
||||
self.state.document.note_explicit_target(signode)
|
||||
|
||||
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, ' %
|
||||
(self.objtype, name) +
|
||||
'other instance in ' +
|
||||
self.env.doc2path(objects[key]),
|
||||
self.lineno)
|
||||
"""
|
||||
objects[key] = self.env.docname
|
||||
indextext = self.get_index_text(self.objtype, name)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
targetname, targetname))
|
||||
|
||||
def get_index_text(self, objectname, name):
|
||||
return _('%s (%s)') % (name, self.objtype)
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
signode += addnodes.desc_name("", sig)
|
||||
return sig
|
||||
|
||||
class BroNamespace(BroGeneric):
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
targetname = self.objtype + '-' + name
|
||||
if targetname not in self.state.document.ids:
|
||||
signode['names'].append(targetname)
|
||||
signode['ids'].append(targetname)
|
||||
signode['first'] = (not self.names)
|
||||
self.state.document.note_explicit_target(signode)
|
||||
|
||||
objects = self.env.domaindata['bro']['objects']
|
||||
key = (self.objtype, name)
|
||||
objects[key] = self.env.docname
|
||||
indextext = self.get_index_text(self.objtype, name)
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
targetname, targetname))
|
||||
self.indexnode['entries'].append(('single',
|
||||
"namespaces; %s" % (sig),
|
||||
targetname, targetname))
|
||||
|
||||
def get_index_text(self, objectname, name):
|
||||
return _('%s (namespace); %s') % (name, self.env.docname)
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
signode += addnodes.desc_name("", sig)
|
||||
return sig
|
||||
|
||||
class BroEnum(BroGeneric):
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
targetname = self.objtype + '-' + name
|
||||
if targetname not in self.state.document.ids:
|
||||
signode['names'].append(targetname)
|
||||
signode['ids'].append(targetname)
|
||||
signode['first'] = (not self.names)
|
||||
self.state.document.note_explicit_target(signode)
|
||||
|
||||
objects = self.env.domaindata['bro']['objects']
|
||||
key = (self.objtype, name)
|
||||
objects[key] = self.env.docname
|
||||
indextext = self.get_index_text(self.objtype, name)
|
||||
#self.indexnode['entries'].append(('single', indextext,
|
||||
# targetname, targetname))
|
||||
m = sig.split()
|
||||
self.indexnode['entries'].append(('single',
|
||||
"%s (enum values); %s" % (m[1], m[0]),
|
||||
targetname, targetname))
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
m = sig.split()
|
||||
name = m[0]
|
||||
signode += addnodes.desc_name("", name)
|
||||
return name
|
||||
|
||||
class BroIdentifier(BroGeneric):
|
||||
def get_index_text(self, objectname, name):
|
||||
return name
|
||||
|
||||
class BroAttribute(BroGeneric):
|
||||
def get_index_text(self, objectname, name):
|
||||
return _('%s (attribute)') % (name)
|
||||
|
||||
class BroDomain(Domain):
|
||||
"""Bro domain."""
|
||||
name = 'bro'
|
||||
label = 'Bro'
|
||||
|
||||
object_types = {
|
||||
'type': ObjType(l_('type'), 'type'),
|
||||
'namespace': ObjType(l_('namespace'), 'namespace'),
|
||||
'id': ObjType(l_('id'), 'id'),
|
||||
'enum': ObjType(l_('enum'), 'enum'),
|
||||
'attr': ObjType(l_('attr'), 'attr'),
|
||||
}
|
||||
|
||||
directives = {
|
||||
'type': BroGeneric,
|
||||
'namespace': BroNamespace,
|
||||
'id': BroIdentifier,
|
||||
'enum': BroEnum,
|
||||
'attr': BroAttribute,
|
||||
}
|
||||
|
||||
roles = {
|
||||
'type': XRefRole(),
|
||||
'namespace': XRefRole(),
|
||||
'id': XRefRole(),
|
||||
'enum': XRefRole(),
|
||||
'attr': XRefRole(),
|
||||
}
|
||||
|
||||
initial_data = {
|
||||
'objects': {}, # fullname -> docname, objtype
|
||||
}
|
||||
|
||||
def clear_doc(self, docname):
|
||||
for (typ, name), doc in self.data['objects'].items():
|
||||
if doc == docname:
|
||||
del self.data['objects'][typ, name]
|
||||
|
||||
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)
|
||||
|
||||
def get_objects(self):
|
||||
for (typ, name), docname in self.data['objects'].iteritems():
|
||||
yield name, name, typ, docname, typ + '-' + name, 1
|
20
doc/source/index.rst
Normal file
20
doc/source/index.rst
Normal file
|
@ -0,0 +1,20 @@
|
|||
.. Bro documentation master file
|
||||
|
||||
Welcome to Bro's documentation!
|
||||
===============================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
common
|
||||
builtins
|
||||
policy/index
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
8
doc/source/policy/index.rst
Normal file
8
doc/source/policy/index.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
Policy Files
|
||||
============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
*
|
Loading…
Add table
Add a link
Reference in a new issue