summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/docs/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/docs/tools')
-rwxr-xr-xsrc/third_party/wiredtiger/src/docs/tools/doxfilter30
-rwxr-xr-xsrc/third_party/wiredtiger/src/docs/tools/doxfilter.py194
-rwxr-xr-xsrc/third_party/wiredtiger/src/docs/tools/doxypy.py414
-rwxr-xr-xsrc/third_party/wiredtiger/src/docs/tools/fixlinks.py67
-rwxr-xr-xsrc/third_party/wiredtiger/src/docs/tools/pyfilter30
5 files changed, 735 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/src/docs/tools/doxfilter b/src/third_party/wiredtiger/src/docs/tools/doxfilter
new file mode 100755
index 00000000000..298e23f6cbb
--- /dev/null
+++ b/src/third_party/wiredtiger/src/docs/tools/doxfilter
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Public Domain 2008-2012 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+tooldir=`dirname $0`
+
+python $tooldir/doxfilter.py "$@"
diff --git a/src/third_party/wiredtiger/src/docs/tools/doxfilter.py b/src/third_party/wiredtiger/src/docs/tools/doxfilter.py
new file mode 100755
index 00000000000..b2d5f857df1
--- /dev/null
+++ b/src/third_party/wiredtiger/src/docs/tools/doxfilter.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2016 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+
+# This Python script is run as part of generating the documentation for the
+# WiredTiger reference manual. It changes comments to Javadoc style
+# (i.e., from "/*!" to "/**"), because the latter are configured to not
+# search for brief descriptions at the beginning of pages.
+# It also processes any page marked with @m_page specially to create
+# multiple per-language versions of the page.
+
+import re, sys
+
+progname = 'doxfilter.py'
+linenum = 0
+filename = '<unknown>'
+
+def err(arg):
+ sys.stderr.write(filename + ':' + str(linenum) + ': ERROR: ' + arg + '\n')
+ sys.exit(1)
+
+def java_post_substitutions(source):
+ result = source
+ for datatype in [['WT_CONNECTION', 'Connection'],
+ ['WT_CURSOR', 'Cursor'],
+ ['WT_SESSION', 'Session'],
+ ['WT_ASYNC_OPTYPE', 'AsyncOpType'],
+ ['WT_ASYNC_OP', 'AsyncOp']]:
+ fromdt = datatype[0]
+ todt = datatype[1]
+
+ # e.g. replace("WT_CONNECTION::", "Connection.").
+ # replace("WT_CONNECTION", "Connection")
+ # replace("::WT_CONNECTION", "Connection")
+ # etc.
+ result = result.replace(fromdt + '::', todt + '.')
+ result = re.sub(r':*' + fromdt, todt, result)
+
+ # We fix back any 'ref' entries, since we don't have
+ # many java versions of these refered-to pages.
+ #
+ # Ideally, we'd have a way ('@m_ref'?) to indicate which
+ # ones could refer to a Java version.
+ result = result.replace('ref ' + todt + '.', 'ref ' + fromdt + '::')
+ result = result.replace('::wiredtiger_open', '\c wiredtiger.open')
+ return result
+
+def process_lang(lang, lines):
+ result = ''
+ lang_ext = '.' + lang
+ class_suffix = None
+ if lang == 'c':
+ lang_suffix = ""
+ lang_desc=""
+ elif lang == 'java':
+ lang_suffix = "_lang_java"
+ lang_desc=" in Java"
+ else:
+ err('@m_page contains illegal lang: ' + lang)
+ condstack = [True]
+ linenum = 0
+ mif_pat = re.compile(r'^\s*@m_if{([^,}]*)}')
+ melse_pat = re.compile(r'^\s*@m_else\s*$')
+ mendif_pat = re.compile(r'^\s*@m_endif\s*$')
+ mpage_pat = re.compile(r'@m_page{{([^}]*)},([^,}]*),([^}]*)}')
+ mpage_rep = r'@page \2' + lang_suffix + r' \3 ' + lang_desc
+ ref_pat = re.compile(r'@ref\s+(\w*)')
+ ref_rep = r'@ref \1' + lang_suffix
+ snip_pat = re.compile(r'@snippet ex_([^.]*)[.]c\s+(.*)')
+ snip_rep = r'@snippet ex_\1' + lang_ext + r' \2'
+ section_pat = re.compile(r'(^@\w*section)\s+(\w*)')
+ section_rep = r'\1 \2' + lang_suffix
+ subpage_pat = re.compile(r'@subpage\s+(\w*)')
+ subpage_rep = r'@subpage \1' + lang_suffix
+ exref_pat = re.compile(r'@ex_ref{ex_([^.]*)[.]c}')
+ if lang == 'c':
+ exref_rep = r'@ex_ref{ex_\1' + lang_ext + '}'
+ else:
+ # Though we have java examples, we don't have references
+ # to them working yet, so strip the @ex_ref.
+ exref_rep = r'ex_\1' + lang_ext
+
+ # Any remaining @m_foo{...} aliases are
+ # diverted to @c_foo{...} or @java_foo{...}
+ mgeneric_pat = re.compile(r'@m_([^ }]*)')
+ mgeneric_rep = r'@' + lang + r'_\1'
+ for line in lines:
+ linenum += 1
+ if lang != 'c':
+ line = re.sub(exref_pat, exref_rep, line)
+ line = re.sub(ref_pat, ref_rep, line)
+ line = re.sub(section_pat, section_rep, line)
+ line = re.sub(snip_pat, snip_rep, line)
+ line = re.sub(mpage_pat, mpage_rep, line)
+ line = re.sub(subpage_pat, subpage_rep, line)
+ if '@m_if' in line:
+ m = re.search(mif_pat, line)
+ if not m:
+ err('@m_if incorrect syntax')
+ iflang = m.groups()[0]
+ if iflang != 'java' and iflang != 'c':
+ err('@m_if unknown language')
+ condstack.append(iflang == lang)
+ elif '@m_else' in line:
+ if not re.search(melse_pat, line):
+ err('@m_else has extraneous stuff')
+ if len(condstack) <= 1:
+ err('@m_else missing if')
+ condstack[-1] = not condstack[-1]
+ elif '@m_endif' in line:
+ if not re.search(mendif_pat, line):
+ err('@m_endif has extraneous stuff')
+ if len(condstack) <= 1:
+ err('@m_endif missing if')
+ condstack.pop()
+ else:
+ if condstack[-1]:
+ # Do generic @m_... macros last
+ line = re.sub(mgeneric_pat,
+ mgeneric_rep, line)
+ result += line + '\n'
+ if lang == 'java':
+ result = java_post_substitutions(result)
+ if len(condstack) != 1:
+ err('non matching @m_if/@m_endif')
+ return result
+
+# Collect all lines between @m_page and the comment end to
+# be processed multiple times, once for each language.
+def process_multilang(source):
+ result = ''
+ in_mpage = False
+ mpage_content = []
+ mpage_pat = re.compile(r'@m_page{{([^}]*)},([^,}]*),([^}]*)}')
+ mpage_end_pat = re.compile(r'\*/')
+ for line in source.split('\n'):
+ m = re.search(mpage_pat, line)
+ if line.count('@m_page') > 0 and not m:
+ err('@m_page incorrect syntax')
+ if m:
+ if in_mpage:
+ err('multiple @m_page without end of comment')
+ else:
+ in_mpage = True
+ langs = m.groups()[0].split(',')
+ if in_mpage:
+ mpage_content.append(line)
+ else:
+ result += line + '\n'
+ if re.search(mpage_end_pat, line):
+ if in_mpage:
+ in_mpage = False
+ for lang in langs:
+ result += process_lang(lang, mpage_content)
+ mpage_content = []
+ return result
+
+def process(source):
+ source = source.replace(r'/*!', r'/**')
+ if '@m_' in source:
+ source = process_multilang(source)
+ return source
+
+if __name__ == '__main__':
+ for f in sys.argv[1:]:
+ filename = f
+ with open(f, 'r') as infile:
+ sys.stdout.write(process(infile.read()))
+ sys.exit(0)
diff --git a/src/third_party/wiredtiger/src/docs/tools/doxypy.py b/src/third_party/wiredtiger/src/docs/tools/doxypy.py
new file mode 100755
index 00000000000..54fef5f03a5
--- /dev/null
+++ b/src/third_party/wiredtiger/src/docs/tools/doxypy.py
@@ -0,0 +1,414 @@
+#!/usr/bin/env python
+
+__applicationName__ = "doxypy"
+__blurb__ = """
+doxypy is an input filter for Doxygen. It preprocesses python
+files so that docstrings of classes and functions are reformatted
+into Doxygen-conform documentation blocks.
+"""
+
+__doc__ = __blurb__ + \
+"""
+In order to make Doxygen preprocess files through doxypy, simply
+add the following lines to your Doxyfile:
+ FILTER_SOURCE_FILES = YES
+ INPUT_FILTER = "python /path/to/doxypy.py"
+"""
+
+__version__ = "0.4.2"
+__date__ = "14th October 2009"
+__website__ = "http://code.foosel.org/doxypy"
+
+__author__ = (
+ "Philippe 'demod' Neumann (doxypy at demod dot org)",
+ "Gina 'foosel' Haeussge (gina at foosel dot net)"
+)
+
+__licenseName__ = "GPL v2"
+__license__ = """This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import sys
+import re
+
+from optparse import OptionParser, OptionGroup
+
+class FSM(object):
+ """Implements a finite state machine.
+
+ Transitions are given as 4-tuples, consisting of an origin state, a target
+ state, a condition for the transition (given as a reference to a function
+ which gets called with a given piece of input) and a pointer to a function
+ to be called upon the execution of the given transition.
+ """
+
+ """
+ @var transitions holds the transitions
+ @var current_state holds the current state
+ @var current_input holds the current input
+ @var current_transition hold the currently active transition
+ """
+
+ def __init__(self, start_state=None, transitions=[]):
+ self.transitions = transitions
+ self.current_state = start_state
+ self.current_input = None
+ self.current_transition = None
+
+ def setStartState(self, state):
+ self.current_state = state
+
+ def addTransition(self, from_state, to_state, condition, callback):
+ self.transitions.append([from_state, to_state, condition, callback])
+
+ def makeTransition(self, input):
+ """Makes a transition based on the given input.
+
+ @param input input to parse by the FSM
+ """
+ for transition in self.transitions:
+ [from_state, to_state, condition, callback] = transition
+ if from_state == self.current_state:
+ match = condition(input)
+ if match:
+ self.current_state = to_state
+ self.current_input = input
+ self.current_transition = transition
+ if options.debug:
+ print >>sys.stderr, "# FSM: executing (%s -> %s) for line '%s'" % (from_state, to_state, input)
+ callback(match)
+ return
+
+class Doxypy(object):
+ def __init__(self):
+ string_prefixes = "[uU]?[rR]?"
+
+ self.start_single_comment_re = re.compile("^\s*%s(''')" % string_prefixes)
+ self.end_single_comment_re = re.compile("(''')\s*$")
+
+ self.start_double_comment_re = re.compile("^\s*%s(\"\"\")" % string_prefixes)
+ self.end_double_comment_re = re.compile("(\"\"\")\s*$")
+
+ self.single_comment_re = re.compile("^\s*%s(''').*(''')\s*$" % string_prefixes)
+ self.double_comment_re = re.compile("^\s*%s(\"\"\").*(\"\"\")\s*$" % string_prefixes)
+
+ self.defclass_re = re.compile("^(\s*)(def .+:|class .+:)")
+ self.empty_re = re.compile("^\s*$")
+ self.hashline_re = re.compile("^\s*#.*$")
+ self.importline_re = re.compile("^\s*(import |from .+ import)")
+
+ self.multiline_defclass_start_re = re.compile("^(\s*)(def|class)(\s.*)?$")
+ self.multiline_defclass_end_re = re.compile(":\s*$")
+
+ ## Transition list format
+ # ["FROM", "TO", condition, action]
+ transitions = [
+ ### FILEHEAD
+
+ # single line comments
+ ["FILEHEAD", "FILEHEAD", self.single_comment_re.search, self.appendCommentLine],
+ ["FILEHEAD", "FILEHEAD", self.double_comment_re.search, self.appendCommentLine],
+
+ # multiline comments
+ ["FILEHEAD", "FILEHEAD_COMMENT_SINGLE", self.start_single_comment_re.search, self.appendCommentLine],
+ ["FILEHEAD_COMMENT_SINGLE", "FILEHEAD", self.end_single_comment_re.search, self.appendCommentLine],
+ ["FILEHEAD_COMMENT_SINGLE", "FILEHEAD_COMMENT_SINGLE", self.catchall, self.appendCommentLine],
+ ["FILEHEAD", "FILEHEAD_COMMENT_DOUBLE", self.start_double_comment_re.search, self.appendCommentLine],
+ ["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD", self.end_double_comment_re.search, self.appendCommentLine],
+ ["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD_COMMENT_DOUBLE", self.catchall, self.appendCommentLine],
+
+ # other lines
+ ["FILEHEAD", "FILEHEAD", self.empty_re.search, self.appendFileheadLine],
+ ["FILEHEAD", "FILEHEAD", self.hashline_re.search, self.appendFileheadLine],
+ ["FILEHEAD", "FILEHEAD", self.importline_re.search, self.appendFileheadLine],
+ ["FILEHEAD", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch],
+ ["FILEHEAD", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.resetCommentSearch],
+ ["FILEHEAD", "DEFCLASS_BODY", self.catchall, self.appendFileheadLine],
+
+ ### DEFCLASS
+
+ # single line comments
+ ["DEFCLASS", "DEFCLASS_BODY", self.single_comment_re.search, self.appendCommentLine],
+ ["DEFCLASS", "DEFCLASS_BODY", self.double_comment_re.search, self.appendCommentLine],
+
+ # multiline comments
+ ["DEFCLASS", "COMMENT_SINGLE", self.start_single_comment_re.search, self.appendCommentLine],
+ ["COMMENT_SINGLE", "DEFCLASS_BODY", self.end_single_comment_re.search, self.appendCommentLine],
+ ["COMMENT_SINGLE", "COMMENT_SINGLE", self.catchall, self.appendCommentLine],
+ ["DEFCLASS", "COMMENT_DOUBLE", self.start_double_comment_re.search, self.appendCommentLine],
+ ["COMMENT_DOUBLE", "DEFCLASS_BODY", self.end_double_comment_re.search, self.appendCommentLine],
+ ["COMMENT_DOUBLE", "COMMENT_DOUBLE", self.catchall, self.appendCommentLine],
+
+ # other lines
+ ["DEFCLASS", "DEFCLASS", self.empty_re.search, self.appendDefclassLine],
+ ["DEFCLASS", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch],
+ ["DEFCLASS", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.resetCommentSearch],
+ ["DEFCLASS", "DEFCLASS_BODY", self.catchall, self.stopCommentSearch],
+
+ ### DEFCLASS_BODY
+
+ ["DEFCLASS_BODY", "DEFCLASS", self.defclass_re.search, self.startCommentSearch],
+ ["DEFCLASS_BODY", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.startCommentSearch],
+ ["DEFCLASS_BODY", "DEFCLASS_BODY", self.catchall, self.appendNormalLine],
+
+ ### DEFCLASS_MULTI
+ ["DEFCLASS_MULTI", "DEFCLASS", self.multiline_defclass_end_re.search, self.appendDefclassLine],
+ ["DEFCLASS_MULTI", "DEFCLASS_MULTI", self.catchall, self.appendDefclassLine],
+ ]
+
+ self.fsm = FSM("FILEHEAD", transitions)
+ self.outstream = sys.stdout
+
+ self.output = []
+ self.comment = []
+ self.filehead = []
+ self.defclass = []
+ self.indent = ""
+
+ def __closeComment(self):
+ """Appends any open comment block and triggering block to the output."""
+
+ if options.autobrief:
+ if len(self.comment) == 1 \
+ or (len(self.comment) > 2 and self.comment[1].strip() == ''):
+ self.comment[0] = self.__docstringSummaryToBrief(self.comment[0])
+
+ if self.comment:
+ block = self.makeCommentBlock()
+ self.output.extend(block)
+
+ if self.defclass:
+ self.output.extend(self.defclass)
+
+ def __docstringSummaryToBrief(self, line):
+ """Adds \\brief to the docstrings summary line.
+
+ A \\brief is prepended, provided no other doxygen command is at the
+ start of the line.
+ """
+ stripped = line.strip()
+ if stripped and not stripped[0] in ('@', '\\'):
+ return "\\brief " + line
+ else:
+ return line
+
+ def __flushBuffer(self):
+ """Flushes the current outputbuffer to the outstream."""
+ if self.output:
+ try:
+ if options.debug:
+ print >>sys.stderr, "# OUTPUT: ", self.output
+ print >>self.outstream, "\n".join(self.output)
+ self.outstream.flush()
+ except IOError:
+ # Fix for FS#33. Catches "broken pipe" when doxygen closes
+ # stdout prematurely upon usage of INPUT_FILTER, INLINE_SOURCES
+ # and FILTER_SOURCE_FILES.
+ pass
+ self.output = []
+
+ def catchall(self, input):
+ """The catchall-condition, always returns true."""
+ return True
+
+ def resetCommentSearch(self, match):
+ """Restarts a new comment search for a different triggering line.
+
+ Closes the current commentblock and starts a new comment search.
+ """
+ if options.debug:
+ print >>sys.stderr, "# CALLBACK: resetCommentSearch"
+ self.__closeComment()
+ self.startCommentSearch(match)
+
+ def startCommentSearch(self, match):
+ """Starts a new comment search.
+
+ Saves the triggering line, resets the current comment and saves
+ the current indentation.
+ """
+ if options.debug:
+ print >>sys.stderr, "# CALLBACK: startCommentSearch"
+ self.defclass = [self.fsm.current_input]
+ self.comment = []
+ self.indent = match.group(1)
+
+ def stopCommentSearch(self, match):
+ """Stops a comment search.
+
+ Closes the current commentblock, resets the triggering line and
+ appends the current line to the output.
+ """
+ if options.debug:
+ print >>sys.stderr, "# CALLBACK: stopCommentSearch"
+ self.__closeComment()
+
+ self.defclass = []
+ self.output.append(self.fsm.current_input)
+
+ def appendFileheadLine(self, match):
+ """Appends a line in the FILEHEAD state.
+
+ Closes the open comment block, resets it and appends the current line.
+ """
+ if options.debug:
+ print >>sys.stderr, "# CALLBACK: appendFileheadLine"
+ self.__closeComment()
+ self.comment = []
+ self.output.append(self.fsm.current_input)
+
+ def appendCommentLine(self, match):
+ """Appends a comment line.
+
+ The comment delimiter is removed from multiline start and ends as
+ well as singleline comments.
+ """
+ if options.debug:
+ print >>sys.stderr, "# CALLBACK: appendCommentLine"
+ (from_state, to_state, condition, callback) = self.fsm.current_transition
+
+ # single line comment
+ if (from_state == "DEFCLASS" and to_state == "DEFCLASS_BODY") \
+ or (from_state == "FILEHEAD" and to_state == "FILEHEAD"):
+ # remove comment delimiter from begin and end of the line
+ activeCommentDelim = match.group(1)
+ line = self.fsm.current_input
+ self.comment.append(line[line.find(activeCommentDelim)+len(activeCommentDelim):line.rfind(activeCommentDelim)])
+
+ if (to_state == "DEFCLASS_BODY"):
+ self.__closeComment()
+ self.defclass = []
+ # multiline start
+ elif from_state == "DEFCLASS" or from_state == "FILEHEAD":
+ # remove comment delimiter from begin of the line
+ activeCommentDelim = match.group(1)
+ line = self.fsm.current_input
+ self.comment.append(line[line.find(activeCommentDelim)+len(activeCommentDelim):])
+ # multiline end
+ elif to_state == "DEFCLASS_BODY" or to_state == "FILEHEAD":
+ # remove comment delimiter from end of the line
+ activeCommentDelim = match.group(1)
+ line = self.fsm.current_input
+ self.comment.append(line[0:line.rfind(activeCommentDelim)])
+ if (to_state == "DEFCLASS_BODY"):
+ self.__closeComment()
+ self.defclass = []
+ # in multiline comment
+ else:
+ # just append the comment line
+ self.comment.append(self.fsm.current_input)
+
+ def appendNormalLine(self, match):
+ """Appends a line to the output."""
+ if options.debug:
+ print >>sys.stderr, "# CALLBACK: appendNormalLine"
+ self.output.append(self.fsm.current_input)
+
+ def appendDefclassLine(self, match):
+ """Appends a line to the triggering block."""
+ if options.debug:
+ print >>sys.stderr, "# CALLBACK: appendDefclassLine"
+ self.defclass.append(self.fsm.current_input)
+
+ def makeCommentBlock(self):
+ """Indents the current comment block with respect to the current
+ indentation level.
+
+ @returns a list of indented comment lines
+ """
+ doxyStart = "##"
+ commentLines = self.comment
+
+ commentLines = map(lambda x: "%s# %s" % (self.indent, x), commentLines)
+ l = [self.indent + doxyStart]
+ l.extend(commentLines)
+
+ return l
+
+ def parse(self, input):
+ """Parses a python file given as input string and returns the doxygen-
+ compatible representation.
+
+ @param input the python code to parse
+ @returns the modified python code
+ """
+ lines = input.split("\n")
+
+ for line in lines:
+ self.fsm.makeTransition(line)
+
+ if self.fsm.current_state == "DEFCLASS":
+ self.__closeComment()
+
+ return "\n".join(self.output)
+
+ def parseFile(self, filename):
+ """Parses a python file given as input string and returns the doxygen-
+ compatible representation.
+
+ @param input the python code to parse
+ @returns the modified python code
+ """
+ f = open(filename, 'r')
+
+ for line in f:
+ self.parseLine(line.rstrip('\r\n'))
+ if self.fsm.current_state == "DEFCLASS":
+ self.__closeComment()
+ self.__flushBuffer()
+ f.close()
+
+ def parseLine(self, line):
+ """Parse one line of python and flush the resulting output to the
+ outstream.
+
+ @param line the python code line to parse
+ """
+ self.fsm.makeTransition(line)
+ self.__flushBuffer()
+
+def optParse():
+ """Parses commandline options."""
+ parser = OptionParser(prog=__applicationName__, version="%prog " + __version__)
+
+ parser.set_usage("%prog [options] filename")
+ parser.add_option("--autobrief",
+ action="store_true", dest="autobrief",
+ help="use the docstring summary line as \\brief description"
+ )
+ parser.add_option("--debug",
+ action="store_true", dest="debug",
+ help="enable debug output on stderr"
+ )
+
+ ## parse options
+ global options
+ (options, filename) = parser.parse_args()
+
+ if not filename:
+ print >>sys.stderr, "No filename given."
+ sys.exit(-1)
+
+ return filename[0]
+
+def main():
+ """Starts the parser on the file given by the filename as the first
+ argument on the commandline.
+ """
+ filename = optParse()
+ fsm = Doxypy()
+ fsm.parseFile(filename)
+
+if __name__ == "__main__":
+ main()
diff --git a/src/third_party/wiredtiger/src/docs/tools/fixlinks.py b/src/third_party/wiredtiger/src/docs/tools/fixlinks.py
new file mode 100755
index 00000000000..7163246e3bd
--- /dev/null
+++ b/src/third_party/wiredtiger/src/docs/tools/fixlinks.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2016 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# This Python script is run as part of generating the documentation for the
+# WiredTiger Python API. It runs after doxypy, and turns method names in
+# comments into references to the corresponding function in the C API.
+
+import re, sys
+
+def process(source):
+ # Replace standard struct wrapper wording
+ source = re.sub(r'(\s+#.*)Proxy of C (\w+) struct',
+ lambda m: ('%sPython wrapper around C ::%s%s@copydoc ::%s' %
+ (m.group(1), m.group(2).strip('_').upper(), m.group(1),
+ m.group(2).strip('_').upper())), source)
+
+ # Replace lowercase class names with upper case
+ source = re.sub(r'(\s+#.*)__(wt_\w+)::',
+ lambda m: ('%s%s::' % (m.group(1), m.group(2).upper())), source)
+
+ # Replace "char" with "string" in comments
+ source = re.sub(r'(\s+#.*)\bconst char \*', r'\1string', source)
+ source = re.sub(r'(\s+#.*)\bchar const \*', r'\1string', source)
+ source = re.sub(r'(\s+#.*)\bchar\b', r'\1string', source)
+
+ # Copy documentation -- methods, then global functions
+ source = re.sub(r'(\s+# )(\w+)\(self, (connection|cursor|session).*',
+ lambda m: ('%s%s%s@copydoc WT_%s::%s' %
+ (m.group(0), m.group(1), m.group(1), m.group(3).upper(), m.group(2))),
+ source)
+
+ source = re.sub(r'(\s+# )(wiredtiger_\w+)\(.*',
+ lambda m: ('%s%s%s@copydoc ::%s' %
+ (m.group(0), m.group(1), m.group(1), m.group(2))), source)
+
+ # Replace "self, handle" with "self" -- these are typedef'ed away
+ source = re.sub(r'(\s+#.*self),
+ (?:connection|cursor|session)', r'\1', source)
+ return source
+
+if __name__ == '__main__':
+ sys.stdout.write(process(sys.stdin.read()))
diff --git a/src/third_party/wiredtiger/src/docs/tools/pyfilter b/src/third_party/wiredtiger/src/docs/tools/pyfilter
new file mode 100755
index 00000000000..7ef80325bd1
--- /dev/null
+++ b/src/third_party/wiredtiger/src/docs/tools/pyfilter
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Public Domain 2008-2012 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+tooldir=`dirname $0`
+
+python $tooldir/doxypy.py "$@" | python $tooldir/fixlinks.py