 57d4c86b2b
			
		
	
	57d4c86b2b
	
	
	
		
			
			Also, removed the one from modules/python/src2/cv.py and cleared its executable bit, since it's not a script.
		
			
				
	
	
		
			1625 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1625 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python
 | |
| # -*- coding: utf-8 -*-
 | |
| """
 | |
|     ocv domain, a modified copy of sphinx.domains.cpp + shpinx.domains.python.
 | |
|                             The original copyright is below
 | |
|     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
|     The OpenCV C/C++/Python/Java/... language domain.
 | |
| 
 | |
|     :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
 | |
|     :license: BSD, see LICENSE for details.
 | |
| """
 | |
| 
 | |
| import re
 | |
| from copy import deepcopy
 | |
| 
 | |
| from docutils import nodes
 | |
| from docutils.parsers.rst import directives
 | |
| 
 | |
| from sphinx import addnodes
 | |
| from sphinx.roles import XRefRole
 | |
| from sphinx.locale import l_, _
 | |
| from sphinx.domains import Domain, ObjType
 | |
| from sphinx.directives import ObjectDescription
 | |
| from sphinx.util.nodes import make_refnode
 | |
| from sphinx.util.compat import Directive
 | |
| from sphinx.util.docfields import Field, GroupedField, TypedField
 | |
| 
 | |
| ########################### Python Part ###########################
 | |
| 
 | |
| # REs for Python signatures
 | |
| py_sig_re = re.compile(
 | |
|     r'''^ ([\w.]*\.)?            # class name(s)
 | |
|           (\w+)  \s*             # thing name
 | |
|           (?: \((.*)\)           # optional: arguments
 | |
|            (?:\s* -> \s* (.*))?  #           return annotation
 | |
|           )? $                   # and nothing more
 | |
|           ''', re.VERBOSE)
 | |
| 
 | |
| 
 | |
| def _pseudo_parse_arglist(signode, arglist):
 | |
|     """"Parse" a list of arguments separated by commas.
 | |
| 
 | |
|     Arguments can have "optional" annotations given by enclosing them in
 | |
|     brackets.  Currently, this will split at any comma, even if it's inside a
 | |
|     string literal (e.g. default argument value).
 | |
|     """
 | |
|     paramlist = addnodes.desc_parameterlist()
 | |
|     stack = [paramlist]
 | |
|     try:
 | |
|         for argument in arglist.split(','):
 | |
|             argument = argument.strip()
 | |
|             ends_open = ends_close = 0
 | |
|             while argument.startswith('['):
 | |
|                 stack.append(addnodes.desc_optional())
 | |
|                 stack[-2] += stack[-1]
 | |
|                 argument = argument[1:].strip()
 | |
|             while argument.startswith(']'):
 | |
|                 stack.pop()
 | |
|                 argument = argument[1:].strip()
 | |
|             while argument.endswith(']'):
 | |
|                 ends_close += 1
 | |
|                 argument = argument[:-1].strip()
 | |
|             while argument.endswith('['):
 | |
|                 ends_open += 1
 | |
|                 argument = argument[:-1].strip()
 | |
|             if argument:
 | |
|                 stack[-1] += addnodes.desc_parameter(argument, argument, noemph=True)
 | |
|             while ends_open:
 | |
|                 stack.append(addnodes.desc_optional())
 | |
|                 stack[-2] += stack[-1]
 | |
|                 ends_open -= 1
 | |
|             while ends_close:
 | |
|                 stack.pop()
 | |
|                 ends_close -= 1
 | |
|         if len(stack) != 1:
 | |
|             raise IndexError
 | |
|     except IndexError:
 | |
|         # if there are too few or too many elements on the stack, just give up
 | |
|         # and treat the whole argument list as one argument, discarding the
 | |
|         # already partially populated paramlist node
 | |
|         signode += addnodes.desc_parameterlist()
 | |
|         signode[-1] += addnodes.desc_parameter(arglist, arglist)
 | |
|     else:
 | |
|         signode += paramlist
 | |
| 
 | |
| 
 | |
| class OCVPyObject(ObjectDescription):
 | |
|     """
 | |
|     Description of a general Python object.
 | |
|     """
 | |
|     option_spec = {
 | |
|         'noindex': directives.flag,
 | |
|         'module': directives.unchanged,
 | |
|     }
 | |
| 
 | |
|     doc_field_types = [
 | |
|         TypedField('parameter', label=l_('Parameters'),
 | |
|                    names=('param', 'parameter', 'arg', 'argument',
 | |
|                           'keyword', 'kwarg', 'kwparam'),
 | |
|                    typerolename='obj', typenames=('paramtype', 'type'),
 | |
|                    can_collapse=True),
 | |
|         TypedField('variable', label=l_('Variables'), rolename='obj',
 | |
|                    names=('var', 'ivar', 'cvar'),
 | |
|                    typerolename='obj', typenames=('vartype',),
 | |
|                    can_collapse=True),
 | |
|         GroupedField('exceptions', label=l_('Raises'), rolename='exc',
 | |
|                      names=('raises', 'raise', 'exception', 'except'),
 | |
|                      can_collapse=True),
 | |
|         Field('returnvalue', label=l_('Returns'), has_arg=False,
 | |
|               names=('returns', 'return')),
 | |
|         Field('returntype', label=l_('Return type'), has_arg=False,
 | |
|               names=('rtype',)),
 | |
|     ]
 | |
| 
 | |
|     def get_signature_prefix(self, sig):
 | |
|         """
 | |
|         May return a prefix to put before the object name in the signature.
 | |
|         """
 | |
|         return ''
 | |
| 
 | |
|     def needs_arglist(self):
 | |
|         """
 | |
|         May return true if an empty argument list is to be generated even if
 | |
|         the document contains none.
 | |
|         """
 | |
|         return False
 | |
| 
 | |
|     def handle_signature(self, sig, signode):
 | |
|         """
 | |
|         Transform a Python signature into RST nodes.
 | |
|         Returns (fully qualified name of the thing, classname if any).
 | |
| 
 | |
|         If inside a class, the current class name is handled intelligently:
 | |
|         * it is stripped from the displayed name if present
 | |
|         * it is added to the full name (return value) if not present
 | |
|         """
 | |
|         signode += nodes.strong("Python:", "Python:")
 | |
|         signode += addnodes.desc_name(" ", " ")
 | |
|         m = py_sig_re.match(sig)
 | |
|         if m is None:
 | |
|             raise ValueError
 | |
|         name_prefix, name, arglist, retann = m.groups()
 | |
| 
 | |
|         # determine module and class name (if applicable), as well as full name
 | |
|         modname = self.options.get(
 | |
|             'module', self.env.temp_data.get('py:module'))
 | |
|         classname = self.env.temp_data.get('py:class')
 | |
|         if classname:
 | |
|             add_module = False
 | |
|             if name_prefix and name_prefix.startswith(classname):
 | |
|                 fullname = name_prefix + name
 | |
|                 # class name is given again in the signature
 | |
|                 name_prefix = name_prefix[len(classname):].lstrip('.')
 | |
|             elif name_prefix:
 | |
|                 # class name is given in the signature, but different
 | |
|                 # (shouldn't happen)
 | |
|                 fullname = classname + '.' + name_prefix + name
 | |
|             else:
 | |
|                 # class name is not given in the signature
 | |
|                 fullname = classname + '.' + name
 | |
|         else:
 | |
|             add_module = True
 | |
|             if name_prefix:
 | |
|                 classname = name_prefix.rstrip('.')
 | |
|                 fullname = name_prefix + name
 | |
|             else:
 | |
|                 classname = ''
 | |
|                 fullname = name
 | |
| 
 | |
|         signode['module'] = modname
 | |
|         signode['class'] = classname
 | |
|         signode['fullname'] = fullname
 | |
| 
 | |
|         sig_prefix = self.get_signature_prefix(sig)
 | |
|         if sig_prefix:
 | |
|             signode += addnodes.desc_annotation(sig_prefix, sig_prefix)
 | |
| 
 | |
|         if name_prefix:
 | |
|             signode += addnodes.desc_addname(name_prefix, name_prefix)
 | |
|         # exceptions are a special case, since they are documented in the
 | |
|         # 'exceptions' module.
 | |
|         elif add_module and self.env.config.add_module_names:
 | |
|             modname = self.options.get(
 | |
|                 'module', self.env.temp_data.get('py:module'))
 | |
|             if modname and modname != 'exceptions':
 | |
|                 nodetext = modname + '.'
 | |
|                 signode += addnodes.desc_addname(nodetext, nodetext)
 | |
| 
 | |
|         signode += addnodes.desc_name(name, name)
 | |
|         if not arglist:
 | |
|             if self.needs_arglist():
 | |
|                 # for callables, add an empty parameter list
 | |
|                 signode += addnodes.desc_parameterlist()
 | |
|             if retann:
 | |
|                 signode += addnodes.desc_returns(retann, retann)
 | |
|             return fullname, name_prefix
 | |
|         _pseudo_parse_arglist(signode, arglist)
 | |
|         if retann:
 | |
|             signode += addnodes.desc_returns(retann, retann)
 | |
|         return fullname, name_prefix
 | |
| 
 | |
|     def get_index_text(self, modname, name):
 | |
|         """
 | |
|         Return the text for the index entry of the object.
 | |
|         """
 | |
|         raise NotImplementedError('must be implemented in subclasses')
 | |
| 
 | |
|     def add_target_and_index(self, name_cls, sig, signode):
 | |
|         modname = self.options.get(
 | |
|             'module', self.env.temp_data.get('py:module'))
 | |
|         fullname = (modname and modname + '.' or '') + name_cls[0]
 | |
|         # note target
 | |
|         if fullname not in self.state.document.ids:
 | |
|             signode['names'].append(fullname)
 | |
|             signode['ids'].append(fullname)
 | |
|             signode['first'] = (not self.names)
 | |
|             self.state.document.note_explicit_target(signode)
 | |
|             objects = self.env.domaindata['ocv']['objects']
 | |
|             if fullname in objects:
 | |
|                 self.env.warn(
 | |
|                     self.env.docname,
 | |
|                     'duplicate object description of %s, ' % fullname +
 | |
|                     'other instance in ' +
 | |
|                     self.env.doc2path(objects[fullname][0]) +
 | |
|                     ', use :noindex: for one of them',
 | |
|                     self.lineno)
 | |
|             objects.setdefault(fullname, (self.env.docname, self.objtype, name_cls[0]))
 | |
| 
 | |
|         indextext = self.get_index_text(modname, name_cls)
 | |
|         if indextext:
 | |
|             self.indexnode['entries'].append(('single', indextext,
 | |
|                                               fullname, fullname))
 | |
| 
 | |
|     def before_content(self):
 | |
|         # needed for automatic qualification of members (reset in subclasses)
 | |
|         self.clsname_set = False
 | |
| 
 | |
|     def after_content(self):
 | |
|         if self.clsname_set:
 | |
|             self.env.temp_data['py:class'] = None
 | |
| 
 | |
| class OCVPyModulelevel(OCVPyObject):
 | |
|     """
 | |
|     Description of an object on module level (functions, data).
 | |
|     """
 | |
|     directive_prefix = 'py'
 | |
| 
 | |
|     def needs_arglist(self):
 | |
|         return self.objtype == self.__class__.directive_prefix + 'function'
 | |
| 
 | |
|     def get_index_text(self, modname, name_cls):
 | |
|         if self.objtype == self.__class__.directive_prefix + 'function':
 | |
|             if not modname:
 | |
|                 fname = name_cls[0]
 | |
|                 if not fname.startswith("cv") and not fname.startswith("cv2"):
 | |
|                     return _('%s() (Python function)') % fname
 | |
|                 pos = fname.find(".")
 | |
|                 modname = fname[:pos]
 | |
|                 fname = fname[pos+1:]
 | |
|                 return _('%s() (Python function in %s)') % (fname, modname)
 | |
|             return _('%s() (Python function in %s)') % (name_cls[0], modname)
 | |
|         elif self.objtype == 'pydata':
 | |
|             if not modname:
 | |
|                 return _('%s (Python variable)') % name_cls[0]
 | |
|             return _('%s (in module %s)') % (name_cls[0], modname)
 | |
|         else:
 | |
|             return ''
 | |
| 
 | |
| class OCVPyOldModulelevel(OCVPyModulelevel):
 | |
|     directive_prefix = 'pyold'
 | |
|     pass
 | |
| 
 | |
| class OCVPyXRefRole(XRefRole):
 | |
|     def process_link(self, env, refnode, has_explicit_title, title, target):
 | |
|         refnode['ocv:module'] = env.temp_data.get('ocv:module')
 | |
|         refnode['ocv:class'] = env.temp_data.get('ocv:class')
 | |
|         if not has_explicit_title:
 | |
|             title = title.lstrip('.')   # only has a meaning for the target
 | |
|             target = target.lstrip('~') # only has a meaning for the title
 | |
|             # if the first character is a tilde, don't display the module/class
 | |
|             # parts of the contents
 | |
|             if title[0:1] == '~':
 | |
|                 title = title[1:]
 | |
|                 dot = title.rfind('.')
 | |
|                 if dot != -1:
 | |
|                     title = title[dot+1:]
 | |
|         # if the first character is a dot, search more specific namespaces first
 | |
|         # else search builtins first
 | |
|         if target[0:1] == '.':
 | |
|             target = target[1:]
 | |
|             refnode['refspecific'] = True
 | |
|         return title, target
 | |
| 
 | |
| 
 | |
| ########################### C/C++/Java Part ###########################
 | |
| 
 | |
| _identifier_re    = re.compile(r'(~?\b[a-zA-Z_][a-zA-Z0-9_]*\b)')
 | |
| _argument_name_re = re.compile(r'(~?\b[a-zA-Z_][a-zA-Z0-9_]*\b(?:\[\d*\])?|\.\.\.)')
 | |
| _whitespace_re = re.compile(r'\s+(?u)')
 | |
| _string_re = re.compile(r"[LuU8]?('([^'\\]*(?:\\.[^'\\]*)*)'"
 | |
|                         r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S)
 | |
| _visibility_re = re.compile(r'\b(public|private|protected)\b')
 | |
| _operator_re = re.compile(r'''(?x)
 | |
|         \[\s*\]
 | |
|     |   \(\s*\)
 | |
|     |   (<<|>>)=?
 | |
|     |   \+\+ | -- | ->\*?
 | |
|     |   [!<>=/*%+|&^-]=?
 | |
|     |   ~ | && | \| | \|\|
 | |
|     |   \,
 | |
| ''')
 | |
| 
 | |
| _id_shortwords = {
 | |
|     'char':                 'c',
 | |
|     'signed char':          'c',
 | |
|     'unsigned char':        'C',
 | |
|     'int':                  'i',
 | |
|     'signed int':           'i',
 | |
|     'unsigned int':         'U',
 | |
|     'long':                 'l',
 | |
|     'signed long':          'l',
 | |
|     'unsigned long':        'L',
 | |
|     'bool':                 'b',
 | |
|     'size_t':               's',
 | |
|     'std::string':          'ss',
 | |
|     'std::ostream':         'os',
 | |
|     'std::istream':         'is',
 | |
|     'std::iostream':        'ios',
 | |
|     'std::vector':          'v',
 | |
|     'std::map':             'm',
 | |
|     'operator[]':           'subscript-operator',
 | |
|     'operator()':           'call-operator',
 | |
|     'operator!':            'not-operator',
 | |
|     'operator<':            'lt-operator',
 | |
|     'operator<=':           'lte-operator',
 | |
|     'operator>':            'gt-operator',
 | |
|     'operator>=':           'gte-operator',
 | |
|     'operator=':            'assign-operator',
 | |
|     'operator/':            'div-operator',
 | |
|     'operator*':            'mul-operator',
 | |
|     'operator%':            'mod-operator',
 | |
|     'operator+':            'add-operator',
 | |
|     'operator-':            'sub-operator',
 | |
|     'operator|':            'or-operator',
 | |
|     'operator&':            'and-operator',
 | |
|     'operator^':            'xor-operator',
 | |
|     'operator&&':           'sand-operator',
 | |
|     'operator||':           'sor-operator',
 | |
|     'operator==':           'eq-operator',
 | |
|     'operator!=':           'neq-operator',
 | |
|     'operator<<':           'lshift-operator',
 | |
|     'operator>>':           'rshift-operator',
 | |
|     'operator-=':           'sub-assign-operator',
 | |
|     'operator+=':           'add-assign-operator',
 | |
|     'operator*-':           'mul-assign-operator',
 | |
|     'operator/=':           'div-assign-operator',
 | |
|     'operator%=':           'mod-assign-operator',
 | |
|     'operator&=':           'and-assign-operator',
 | |
|     'operator|=':           'or-assign-operator',
 | |
|     'operator<<=':          'lshift-assign-operator',
 | |
|     'operator>>=':          'rshift-assign-operator',
 | |
|     'operator^=':           'xor-assign-operator',
 | |
|     'operator,':            'comma-operator',
 | |
|     'operator->':           'pointer-operator',
 | |
|     'operator->*':          'pointer-by-pointer-operator',
 | |
|     'operator~':            'inv-operator',
 | |
|     'operator++':           'inc-operator',
 | |
|     'operator--':           'dec-operator',
 | |
|     'operator new':         'new-operator',
 | |
|     'operator new[]':       'new-array-operator',
 | |
|     'operator delete':      'delete-operator',
 | |
|     'operator delete[]':    'delete-array-operator'
 | |
| }
 | |
| 
 | |
| 
 | |
| class DefinitionError(Exception):
 | |
| 
 | |
|     def __init__(self, description):
 | |
|         self.description = description
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return self.description
 | |
| 
 | |
|     def __str__(self):
 | |
|         return unicode(self.encode('utf-8'))
 | |
| 
 | |
| 
 | |
| class DefExpr(object):
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         raise NotImplementedError()
 | |
| 
 | |
|     def __eq__(self, other):
 | |
|         if type(self) is not type(other):
 | |
|             return False
 | |
|         try:
 | |
|             for key, value in self.__dict__.iteritems():
 | |
|                 if value != getattr(other, value):
 | |
|                     return False
 | |
|         except AttributeError:
 | |
|             return False
 | |
|         return True
 | |
| 
 | |
|     def __ne__(self, other):
 | |
|         return not self.__eq__(other)
 | |
| 
 | |
|     def clone(self):
 | |
|         """Close a definition expression node"""
 | |
|         return deepcopy(self)
 | |
| 
 | |
|     def get_id(self):
 | |
|         """Returns the id for the node"""
 | |
|         return u''
 | |
| 
 | |
|     def get_name(self):
 | |
|         """Returns the name.  Returns either `None` or a node with
 | |
|         a name you might call :meth:`split_owner` on.
 | |
|         """
 | |
|         return None
 | |
| 
 | |
|     def split_owner(self):
 | |
|         """Nodes returned by :meth:`get_name` can split off their
 | |
|         owning parent.  This function returns the owner and the
 | |
|         name as a tuple of two items.  If a node does not support
 | |
|         it, it returns None as owner and self as name.
 | |
|         """
 | |
|         return None, self
 | |
| 
 | |
|     def prefix(self, prefix):
 | |
|         """Prefixes a name node (a node returned by :meth:`get_name`)."""
 | |
|         raise NotImplementedError()
 | |
| 
 | |
|     def __str__(self):
 | |
|         return unicode(self).encode('utf-8')
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return '<%s %s>' % (self.__class__.__name__, self)
 | |
| 
 | |
| 
 | |
| class PrimaryDefExpr(DefExpr):
 | |
| 
 | |
|     def get_name(self):
 | |
|         return self
 | |
| 
 | |
|     def prefix(self, prefix):
 | |
|         if isinstance(prefix, PathDefExpr):
 | |
|             prefix = prefix.clone()
 | |
|             prefix.path.append(self)
 | |
|             return prefix
 | |
|         return PathDefExpr([prefix, self])
 | |
| 
 | |
| 
 | |
| class NameDefExpr(PrimaryDefExpr):
 | |
| 
 | |
|     def __init__(self, name):
 | |
|         self.name = name
 | |
| 
 | |
|     def get_id(self):
 | |
|         name = _id_shortwords.get(self.name)
 | |
|         if name is not None:
 | |
|             return name
 | |
|         return self.name.replace(u' ', u'-')
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return unicode(self.name)
 | |
| 
 | |
| 
 | |
| class PathDefExpr(PrimaryDefExpr):
 | |
| 
 | |
|     def __init__(self, parts):
 | |
|         self.path = parts
 | |
| 
 | |
|     def get_id(self):
 | |
|         rv = u'::'.join(x.get_id() for x in self.path)
 | |
|         return _id_shortwords.get(rv, rv)
 | |
| 
 | |
|     def split_owner(self):
 | |
|         if len(self.path) > 1:
 | |
|             return PathDefExpr(self.path[:-1]), self.path[-1]
 | |
|         return None, self
 | |
| 
 | |
|     def prefix(self, prefix):
 | |
|         if isinstance(prefix, PathDefExpr):
 | |
|             prefix = prefix.clone()
 | |
|             prefix.path.extend(self.path)
 | |
|             return prefix
 | |
|         return PathDefExpr([prefix] + self.path)
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return u'::'.join(map(unicode, self.path))
 | |
| 
 | |
| 
 | |
| class TemplateDefExpr(PrimaryDefExpr):
 | |
| 
 | |
|     def __init__(self, typename, args):
 | |
|         self.typename = typename
 | |
|         self.args = args
 | |
| 
 | |
|     def split_owner(self):
 | |
|         owner, typename = self.typename.split_owner()
 | |
|         return owner, TemplateDefExpr(typename, self.args)
 | |
| 
 | |
|     def get_id(self):
 | |
|         return u'%s:%s:' % (self.typename.get_id(),
 | |
|                             u'.'.join(x.get_id() for x in self.args))
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return u'%s<%s>' % (self.typename, u', '.join(map(unicode, self.args)))
 | |
| 
 | |
| 
 | |
| class WrappingDefExpr(DefExpr):
 | |
| 
 | |
|     def __init__(self, typename):
 | |
|         self.typename = typename
 | |
| 
 | |
|     def get_name(self):
 | |
|         return self.typename.get_name()
 | |
| 
 | |
| 
 | |
| class ModifierDefExpr(WrappingDefExpr):
 | |
| 
 | |
|     def __init__(self, typename, modifiers):
 | |
|         WrappingDefExpr.__init__(self, typename)
 | |
|         self.modifiers = modifiers
 | |
| 
 | |
|     def get_id(self):
 | |
|         pieces = [_id_shortwords.get(unicode(x), unicode(x))
 | |
|                   for x in self.modifiers]
 | |
|         pieces.append(self.typename.get_id())
 | |
|         return u'-'.join(pieces)
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return u' '.join(map(unicode, list(self.modifiers) + [self.typename]))
 | |
| 
 | |
| 
 | |
| class PtrDefExpr(WrappingDefExpr):
 | |
| 
 | |
|     def get_id(self):
 | |
|         return self.typename.get_id() + u'P'
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return u'%s*' % self.typename
 | |
| 
 | |
| 
 | |
| class RefDefExpr(WrappingDefExpr):
 | |
| 
 | |
|     def get_id(self):
 | |
|         return self.typename.get_id() + u'R'
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return u'%s&' % self.typename
 | |
| 
 | |
| 
 | |
| class ConstDefExpr(WrappingDefExpr):
 | |
| 
 | |
|     def __init__(self, typename, prefix=False):
 | |
|         WrappingDefExpr.__init__(self, typename)
 | |
|         self.prefix = prefix
 | |
| 
 | |
|     def get_id(self):
 | |
|         return self.typename.get_id() + u'C'
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return (self.prefix and u'const %s' or u'%s const') % self.typename
 | |
| 
 | |
| class ConstTemplateDefExpr(WrappingDefExpr):
 | |
| 
 | |
|     def __init__(self, typename, prefix=False):
 | |
|         WrappingDefExpr.__init__(self, typename)
 | |
|         self.prefix = prefix
 | |
| 
 | |
|     def get_id(self):
 | |
|         return self.typename.get_id() + u'C'
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return (self.prefix and u'const %s' or u'%s const') % self.typename
 | |
| 
 | |
| 
 | |
| class CastOpDefExpr(PrimaryDefExpr):
 | |
| 
 | |
|     def __init__(self, typename):
 | |
|         self.typename = typename
 | |
| 
 | |
|     def get_id(self):
 | |
|         return u'castto-%s-operator' % self.typename.get_id()
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return u'operator %s' % self.typename
 | |
| 
 | |
| 
 | |
| class ArgumentDefExpr(DefExpr):
 | |
| 
 | |
|     def __init__(self, type, name, default=None):
 | |
|         self.name = name
 | |
|         self.type = type
 | |
|         self.default = default
 | |
| 
 | |
|     def get_name(self):
 | |
|         return self.name.get_name()
 | |
| 
 | |
|     def get_id(self):
 | |
|         if self.type is None:
 | |
|             return 'X'
 | |
|         return self.type.get_id()
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         return (u'%s %s' % (self.type or u'', self.name or u'')).strip() + \
 | |
|                (self.default is not None and u'=%s' % self.default or u'')
 | |
| 
 | |
| 
 | |
| class NamedDefExpr(DefExpr):
 | |
| 
 | |
|     def __init__(self, name, visibility, static):
 | |
|         self.name = name
 | |
|         self.visibility = visibility
 | |
|         self.static = static
 | |
| 
 | |
|     def get_name(self):
 | |
|         return self.name.get_name()
 | |
| 
 | |
|     def get_modifiers(self):
 | |
|         rv = []
 | |
|         if self.visibility != 'public':
 | |
|             rv.append(self.visibility)
 | |
|         if self.static:
 | |
|             rv.append(u'static')
 | |
|         return rv
 | |
| 
 | |
| 
 | |
| class TypeObjDefExpr(NamedDefExpr):
 | |
| 
 | |
|     def __init__(self, name, visibility, static, typename):
 | |
|         NamedDefExpr.__init__(self, name, visibility, static)
 | |
|         self.typename = typename
 | |
| 
 | |
|     def get_id(self):
 | |
|         if self.typename is None:
 | |
|             return self.name.get_id()
 | |
|         return u'%s__%s' % (self.name.get_id(), self.typename.get_id())
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         buf = self.get_modifiers()
 | |
|         if self.typename is None:
 | |
|             buf.append(unicode(self.name))
 | |
|         else:
 | |
|             buf.extend(map(unicode, (self.typename, self.name)))
 | |
|         return u' '.join(buf)
 | |
| 
 | |
| 
 | |
| class MemberObjDefExpr(NamedDefExpr):
 | |
| 
 | |
|     def __init__(self, name, visibility, static, typename, value):
 | |
|         NamedDefExpr.__init__(self, name, visibility, static)
 | |
|         self.typename = typename
 | |
|         self.value = value
 | |
| 
 | |
|     def get_id(self):
 | |
|         return u'%s__%s' % (self.name.get_id(), self.typename.get_id())
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         buf = self.get_modifiers()
 | |
|         buf.append(u'%s %s' % (self.typename, self.name))
 | |
|         if self.value is not None:
 | |
|             buf.append(u'= %s' % self.value)
 | |
|         return u' '.join(buf)
 | |
| 
 | |
| 
 | |
| class FuncDefExpr(NamedDefExpr):
 | |
| 
 | |
|     def __init__(self, name, visibility, static, explicit, rv,
 | |
|                  signature, const, pure_virtual, virtual):
 | |
|         NamedDefExpr.__init__(self, name, visibility, static)
 | |
|         self.rv = rv
 | |
|         self.signature = signature
 | |
|         self.explicit = explicit
 | |
|         self.const = const
 | |
|         self.pure_virtual = pure_virtual
 | |
|         self.virtual = virtual
 | |
| 
 | |
|     def get_id(self):
 | |
|         return u'%s%s%s' % (
 | |
|             self.name.get_id(),
 | |
|             self.signature and u'__' +
 | |
|                 u'.'.join(x.get_id() for x in self.signature) or u'',
 | |
|             self.const and u'C' or u''
 | |
|         )
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         buf = self.get_modifiers()
 | |
|         if self.explicit:
 | |
|             buf.append(u'explicit')
 | |
|         if self.virtual:
 | |
|             buf.append(u'virtual')
 | |
|         if self.rv is not None:
 | |
|             buf.append(unicode(self.rv))
 | |
|         buf.append(u'%s(%s)' % (self.name, u', '.join(
 | |
|             map(unicode, self.signature))))
 | |
|         if self.const:
 | |
|             buf.append(u'const')
 | |
|         if self.pure_virtual:
 | |
|             buf.append(u'= 0')
 | |
|         return u' '.join(buf)
 | |
| 
 | |
| 
 | |
| class ClassDefExpr(NamedDefExpr):
 | |
| 
 | |
|     def __init__(self, name, visibility, static, parents = None):
 | |
|         NamedDefExpr.__init__(self, name, visibility, static)
 | |
|         self.parents = parents
 | |
| 
 | |
|     def get_id(self):
 | |
|         return self.name.get_id()
 | |
| 
 | |
|     def __unicode__(self):
 | |
|         buf = self.get_modifiers()
 | |
|         buf.append(unicode(self.name))
 | |
|         return u' '.join(buf)
 | |
| 
 | |
| 
 | |
| class DefinitionParser(object):
 | |
| 
 | |
|     # mapping of valid type modifiers.  if the set is None it means
 | |
|     # the modifier can prefix all types, otherwise only the types
 | |
|     # (actually more keywords) in the set.  Also check
 | |
|     # _guess_typename when changing this.
 | |
|     _modifiers = {
 | |
|         'volatile':     None,
 | |
|         'register':     None,
 | |
|         'mutable':      None,
 | |
|         'const':        None,
 | |
|         'typename':     None,
 | |
|         'unsigned':     set(('char', 'short', 'int', 'long')),
 | |
|         'signed':       set(('char', 'short', 'int', 'long')),
 | |
|         'short':        set(('int',)),
 | |
|         'long':         set(('int', 'long', 'double'))
 | |
|     }
 | |
| 
 | |
|     def __init__(self, definition):
 | |
|         self.definition = definition.strip()
 | |
|         self.pos = 0
 | |
|         self.end = len(self.definition)
 | |
|         self.last_match = None
 | |
|         self._previous_state = (0, None)
 | |
| 
 | |
|     def fail(self, msg):
 | |
|         raise DefinitionError('Invalid definition: %s [error at %d]\n  %s' %
 | |
|             (msg, self.pos, self.definition))
 | |
| 
 | |
|     def match(self, regex):
 | |
|         match = regex.match(self.definition, self.pos)
 | |
|         if match is not None:
 | |
|             self._previous_state = (self.pos, self.last_match)
 | |
|             self.pos = match.end()
 | |
|             self.last_match = match
 | |
|             return True
 | |
|         return False
 | |
| 
 | |
|     def backout(self):
 | |
|         self.pos, self.last_match = self._previous_state
 | |
| 
 | |
|     def skip_string(self, string):
 | |
|         strlen = len(string)
 | |
|         if self.definition[self.pos:self.pos + strlen] == string:
 | |
|             self.pos += strlen
 | |
|             return True
 | |
|         return False
 | |
| 
 | |
|     def skip_word(self, word):
 | |
|         return self.match(re.compile(r'\b%s\b' % re.escape(word)))
 | |
| 
 | |
|     def skip_ws(self):
 | |
|         return self.match(_whitespace_re)
 | |
| 
 | |
|     @property
 | |
|     def eof(self):
 | |
|         return self.pos >= self.end
 | |
| 
 | |
|     @property
 | |
|     def current_char(self):
 | |
|         try:
 | |
|             return self.definition[self.pos]
 | |
|         except IndexError:
 | |
|             return 'EOF'
 | |
| 
 | |
|     @property
 | |
|     def matched_text(self):
 | |
|         if self.last_match is not None:
 | |
|             return self.last_match.group()
 | |
| 
 | |
|     def _parse_operator(self):
 | |
|         self.skip_ws()
 | |
|         # thank god, a regular operator definition
 | |
|         if self.match(_operator_re):
 | |
|             return NameDefExpr('operator' +
 | |
|                                 _whitespace_re.sub('', self.matched_text))
 | |
|         # new/delete operator?
 | |
|         for allocop in 'new', 'delete':
 | |
|             if not self.skip_word(allocop):
 | |
|                 continue
 | |
|             self.skip_ws()
 | |
|             if self.skip_string('['):
 | |
|                 self.skip_ws()
 | |
|                 if not self.skip_string(']'):
 | |
|                     self.fail('expected "]" for ' + allocop)
 | |
|                 allocop += '[]'
 | |
|             return NameDefExpr('operator ' + allocop)
 | |
| 
 | |
|         # oh well, looks like a cast operator definition.
 | |
|         # In that case, eat another type.
 | |
|         type = self._parse_type()
 | |
|         return CastOpDefExpr(type)
 | |
| 
 | |
|     def _parse_name(self):
 | |
|         if not self.match(_argument_name_re):
 | |
|             self.fail('expected name')
 | |
|         identifier = self.matched_text
 | |
| 
 | |
|         # strictly speaking, operators are not regular identifiers
 | |
|         # but because operator is a keyword, it might not be used
 | |
|         # for variable names anyways, so we can safely parse the
 | |
|         # operator here as identifier
 | |
|         if identifier == 'operator':
 | |
|             return self._parse_operator()
 | |
| 
 | |
|         return NameDefExpr(identifier)
 | |
| 
 | |
|     def _guess_typename(self, path):
 | |
|         if not path:
 | |
|             return [], 'int'
 | |
|         # for the long type, we don't want the int in there
 | |
|         if 'long' in path:
 | |
|             path = [x for x in path if x != 'int']
 | |
|             # remove one long
 | |
|             path.remove('long')
 | |
|             return path, 'long'
 | |
|         if path[-1] in ('int', 'char'):
 | |
|             return path[:-1], path[-1]
 | |
|         return path, 'int'
 | |
| 
 | |
|     def _attach_crefptr(self, expr, is_const=False):
 | |
|         if is_const:
 | |
|             expr = ConstDefExpr(expr, prefix=True)
 | |
|         while 1:
 | |
|             self.skip_ws()
 | |
|             if self.skip_word('const'):
 | |
|                 expr = ConstDefExpr(expr)
 | |
|             elif self.skip_string('*'):
 | |
|                 expr = PtrDefExpr(expr)
 | |
|             elif self.skip_string('&'):
 | |
|                 expr = RefDefExpr(expr)
 | |
|             else:
 | |
|                 return expr
 | |
| 
 | |
|     def _peek_const(self, path):
 | |
|         try:
 | |
|             path.remove('const')
 | |
|             return True
 | |
|         except ValueError:
 | |
|             return False
 | |
| 
 | |
|     def _parse_builtin(self, modifier):
 | |
|         path = [modifier]
 | |
|         following = self._modifiers[modifier]
 | |
|         while 1:
 | |
|             self.skip_ws()
 | |
|             if not self.match(_identifier_re):
 | |
|                 break
 | |
|             identifier = self.matched_text
 | |
|             if identifier in following:
 | |
|                 path.append(identifier)
 | |
|                 following = self._modifiers[modifier]
 | |
|                 assert following
 | |
|             else:
 | |
|                 self.backout()
 | |
|                 break
 | |
| 
 | |
|         is_const = self._peek_const(path)
 | |
|         modifiers, typename = self._guess_typename(path)
 | |
|         rv = ModifierDefExpr(NameDefExpr(typename), modifiers)
 | |
|         return self._attach_crefptr(rv, is_const)
 | |
| 
 | |
|     def _parse_type_expr(self):
 | |
|         typename = self._parse_name()
 | |
|         if typename and self.skip_string('['):
 | |
|             typename.name += '['
 | |
|             if self.match(re.compile(r'\d*')):
 | |
|                 typename.name += self.last_match.group(0)
 | |
|             typename.name += ']'
 | |
|             if not self.skip_string(']'):
 | |
|                 self.fail('expected type')
 | |
|         self.skip_ws()
 | |
|         if not self.skip_string('<'):
 | |
|             return typename
 | |
| 
 | |
|         args = []
 | |
|         while 1:
 | |
|             self.skip_ws()
 | |
|             if self.skip_string('>'):
 | |
|                 break
 | |
|             if args:
 | |
|                 if not self.skip_string(','):
 | |
|                     self.fail('"," or ">" in template expected')
 | |
|                 self.skip_ws()
 | |
|             args.append(self._parse_type(True))
 | |
|         return TemplateDefExpr(typename, args)
 | |
| 
 | |
|     def _parse_type(self, in_template=False):
 | |
|         self.skip_ws()
 | |
|         result = []
 | |
|         modifiers = []
 | |
| 
 | |
|         if self.match(re.compile(r'template\w*<([^>]*)>')):
 | |
|             args = self.last_match.group(1).split(',')
 | |
|             args = [a.strip() for a in args]
 | |
|             modifiers.append(TemplateDefExpr('template', args))
 | |
| 
 | |
|         # if there is a leading :: or not, we don't care because we
 | |
|         # treat them exactly the same.  Buf *if* there is one, we
 | |
|         # don't have to check for type modifiers
 | |
|         if not self.skip_string('::'):
 | |
|             self.skip_ws()
 | |
|             while self.match(_identifier_re):
 | |
|                 modifier = self.matched_text
 | |
|                 if modifier in self._modifiers:
 | |
|                     following = self._modifiers[modifier]
 | |
|                     # if the set is not none, there is a limited set
 | |
|                     # of types that might follow.  It is technically
 | |
|                     # impossible for a template to follow, so what
 | |
|                     # we do is go to a different function that just
 | |
|                     # eats types
 | |
|                     if following is not None:
 | |
|                         return self._parse_builtin(modifier)
 | |
|                     modifiers.append(modifier)
 | |
|                 else:
 | |
|                     self.backout()
 | |
|                     break
 | |
| 
 | |
|         while 1:
 | |
|             self.skip_ws()
 | |
|             if (in_template and self.current_char in ',>') or \
 | |
|                (result and not self.skip_string('::')) or \
 | |
|                self.eof:
 | |
|                 break
 | |
|             result.append(self._parse_type_expr())
 | |
| 
 | |
|         if not result:
 | |
|             self.fail('expected type')
 | |
|         if len(result) == 1:
 | |
|             rv = result[0]
 | |
|         else:
 | |
|             rv = PathDefExpr(result)
 | |
|         is_const = self._peek_const(modifiers)
 | |
|         if is_const:
 | |
|             rv = ConstDefExpr(rv, prefix=True)
 | |
|         if modifiers:
 | |
|             rv = ModifierDefExpr(rv, modifiers)
 | |
|         return self._attach_crefptr(rv, False)
 | |
| 
 | |
|     def _parse_default_expr(self):
 | |
|         self.skip_ws()
 | |
|         if self.match(_string_re):
 | |
|             return self.matched_text
 | |
|         paren_stack_depth = 0
 | |
|         max_pos = len(self.definition)
 | |
|         rv_start = self.pos
 | |
|         while 1:
 | |
|             idx0 = self.definition.find('(', self.pos)
 | |
|             idx1 = self.definition.find(',', self.pos)
 | |
|             idx2 = self.definition.find(')', self.pos)
 | |
|             if idx0 < 0:
 | |
|                 idx0 = max_pos
 | |
|             if idx1 < 0:
 | |
|                 idx1 = max_pos
 | |
|             if idx2 < 0:
 | |
|                 idx2 = max_pos
 | |
|             idx = min(idx0, idx1, idx2)
 | |
|             if idx >= max_pos:
 | |
|                 self.fail('unexpected end in default expression')
 | |
|             if idx == idx0:
 | |
|                 paren_stack_depth += 1
 | |
|             elif idx == idx2:
 | |
|                 paren_stack_depth -= 1
 | |
|                 if paren_stack_depth < 0:
 | |
|                     break
 | |
|             elif paren_stack_depth == 0:
 | |
|                 break
 | |
|             self.pos = idx+1
 | |
| 
 | |
|         rv = self.definition[rv_start:idx]
 | |
|         self.pos = idx
 | |
|         return rv
 | |
| 
 | |
|     def _parse_signature(self):
 | |
|         if r'CvStatModel::train' in self.definition:
 | |
|             # hack to skip parsing of problematic definition
 | |
|             self.pos = self.end
 | |
|             return [ArgumentDefExpr("const Mat&", "train_data", None), ArgumentDefExpr(None, self.definition[self.definition.find("["):-1], None)], False, True
 | |
| 
 | |
|         self.skip_ws()
 | |
|         if not self.skip_string('('):
 | |
|             self.fail('expected parentheses for function')
 | |
| 
 | |
|         args = []
 | |
|         while 1:
 | |
|             self.skip_ws()
 | |
|             if self.eof:
 | |
|                 self.fail('missing closing parentheses')
 | |
|             if self.skip_string(')'):
 | |
|                 break
 | |
|             if args:
 | |
|                 if not self.skip_string(','):
 | |
|                     self.fail('expected comma between arguments')
 | |
|                 self.skip_ws()
 | |
| 
 | |
|             argtype = self._parse_type()
 | |
|             self.skip_ws()
 | |
|             if unicode(argtype) == u"...":
 | |
|                 if not self.skip_string(')'):
 | |
|                     self.fail("var arg must be the last argument")
 | |
|                 args.append(ArgumentDefExpr(None, argtype, None))
 | |
|                 break
 | |
|             argname = default = None
 | |
|             if self.skip_string('='):
 | |
|                 self.pos += 1
 | |
|                 default = self._parse_default_expr()
 | |
|             elif self.current_char not in ',)':
 | |
|                 argname = self._parse_name()
 | |
|                 self.skip_ws()
 | |
|                 if self.skip_string('='):
 | |
|                     default = self._parse_default_expr()
 | |
| 
 | |
|             args.append(ArgumentDefExpr(argtype, argname, default))
 | |
|         self.skip_ws()
 | |
|         const = self.skip_word('const')
 | |
|         if const:
 | |
|             self.skip_ws()
 | |
|         if self.skip_string('='):
 | |
|             self.skip_ws()
 | |
|             if not (self.skip_string('0') or \
 | |
|                     self.skip_word('NULL') or \
 | |
|                     self.skip_word('nullptr')):
 | |
|                 self.fail('pure virtual functions must be defined with '
 | |
|                           'either 0, NULL or nullptr, other macros are '
 | |
|                           'not allowed')
 | |
|             pure_virtual = True
 | |
|         else:
 | |
|             pure_virtual = False
 | |
|         return args, const, pure_virtual
 | |
| 
 | |
|     def _parse_visibility_static(self):
 | |
|         visibility =  'public'
 | |
|         if self.match(_visibility_re):
 | |
|             visibility = self.matched_text
 | |
|         static = self.skip_word('static')
 | |
|         return visibility, static
 | |
| 
 | |
|     def parse_type(self):
 | |
|         return self._parse_type()
 | |
| 
 | |
|     def parse_type_object(self):
 | |
|         visibility, static = self._parse_visibility_static()
 | |
|         typename = self._parse_type()
 | |
|         self.skip_ws()
 | |
|         if not self.eof:
 | |
|             name = self._parse_type()
 | |
|         else:
 | |
|             name = typename
 | |
|             typename = None
 | |
|         return TypeObjDefExpr(name, visibility, static, typename)
 | |
| 
 | |
|     def parse_member_object(self):
 | |
|         visibility, static = self._parse_visibility_static()
 | |
|         typename = self._parse_type()
 | |
|         name = self._parse_type()
 | |
|         self.skip_ws()
 | |
|         if self.skip_string('='):
 | |
|             value = self.read_rest().strip()
 | |
|         else:
 | |
|             value = None
 | |
|         return MemberObjDefExpr(name, visibility, static, typename, value)
 | |
| 
 | |
|     def parse_enum_member_object(self):
 | |
|         visibility, static = self._parse_visibility_static()
 | |
|         typename = None
 | |
|         name = self._parse_type()
 | |
|         self.skip_ws()
 | |
|         if self.skip_string('='):
 | |
|             value = self.read_rest().strip()
 | |
|         else:
 | |
|             value = None
 | |
|         return MemberObjDefExpr(name, visibility, static, typename, value)
 | |
| 
 | |
|     def parse_function(self):
 | |
|         visibility, static = self._parse_visibility_static()
 | |
|         if self.skip_word('explicit'):
 | |
|             explicit = True
 | |
|             self.skip_ws()
 | |
|         else:
 | |
|             explicit = False
 | |
|         if self.skip_word('virtual'):
 | |
|             virtual = True
 | |
|             self.skip_ws()
 | |
|         else:
 | |
|             virtual = False
 | |
|         rv = self._parse_type()
 | |
|         self.skip_ws()
 | |
|         # some things just don't have return values
 | |
|         if self.current_char == '(':
 | |
|             name = rv
 | |
|             rv = None
 | |
|         else:
 | |
|             name = self._parse_type()
 | |
|         return FuncDefExpr(name, visibility, static, explicit,  rv,
 | |
|                            *self._parse_signature(), virtual = virtual)
 | |
| 
 | |
|     def parse_class(self):
 | |
|         visibility, static = self._parse_visibility_static()
 | |
|         typename = self._parse_type()
 | |
|         parent = None
 | |
|         self.skip_ws()
 | |
|         parents = []
 | |
|         if self.skip_string(':'):
 | |
|             while not self.eof:
 | |
|                 self.skip_ws()
 | |
|                 classname_pos = self.pos
 | |
|                 pvisibility, pstatic = self._parse_visibility_static()
 | |
|                 if pstatic:
 | |
|                     self.fail('unsepected static keyword, got %r' %
 | |
|                           self.definition[self.classname_pos:])
 | |
|                 parents.append(ClassDefExpr(self._parse_type(), pvisibility, pstatic))
 | |
|                 if not self.skip_string(','):
 | |
|                     break
 | |
|         return ClassDefExpr(typename, visibility, static, parents)
 | |
| 
 | |
|     def read_rest(self):
 | |
|         rv = self.definition[self.pos:]
 | |
|         self.pos = self.end
 | |
|         return rv
 | |
| 
 | |
|     def assert_end(self):
 | |
|         self.skip_ws()
 | |
|         if not self.eof:
 | |
|             self.fail('expected end of definition, got %r' %
 | |
|                       self.definition[self.pos:])
 | |
| 
 | |
| 
 | |
| class OCVObject(ObjectDescription):
 | |
|     """Description of a C++ language object."""
 | |
| 
 | |
|     langname = "C++"
 | |
|     ismember = False
 | |
| 
 | |
|     doc_field_types = [
 | |
|         TypedField('parameter', label=l_('Parameters'),
 | |
|                    names=('param', 'parameter', 'arg', 'argument'),
 | |
|                    typerolename='type', typenames=('type',)),
 | |
|         Field('returnvalue', label=l_('Returns'), has_arg=False,
 | |
|               names=('returns', 'return')),
 | |
|         Field('returntype', label=l_('Return type'), has_arg=False,
 | |
|               names=('rtype',)),
 | |
|     ]
 | |
| 
 | |
|     def attach_name(self, node, name):
 | |
|         owner, name = name.split_owner()
 | |
|         varname = unicode(name)
 | |
|         if owner is not None:
 | |
|             owner = unicode(owner) + '::'
 | |
|             node += addnodes.desc_addname(owner, owner)
 | |
|         node += addnodes.desc_name(varname, varname)
 | |
| 
 | |
|     def attach_type(self, node, type):
 | |
|         # XXX: link to c?
 | |
|         text = unicode(type)
 | |
|         pnode = addnodes.pending_xref(
 | |
|             '', refdomain='ocv', reftype='type',
 | |
|             reftarget=text, modname=None, classname=None)
 | |
|         pnode['ocv:parent'] = self.env.temp_data.get('ocv:parent')
 | |
|         pnode += nodes.Text(text)
 | |
|         node += pnode
 | |
| 
 | |
|     def attach_modifiers(self, node, obj):
 | |
|         if not self.__class__.ismember:
 | |
|             lname = self.__class__.langname
 | |
|             node += nodes.strong(lname + ":", lname + ":")
 | |
|             node += addnodes.desc_name(" ", " ")
 | |
| 
 | |
|         if obj.visibility != 'public':
 | |
|             node += addnodes.desc_annotation(obj.visibility,
 | |
|                                              obj.visibility)
 | |
|             node += nodes.Text(' ')
 | |
|         if obj.static:
 | |
|             node += addnodes.desc_annotation('static', 'static')
 | |
|             node += nodes.Text(' ')
 | |
| 
 | |
|     def add_target_and_index(self, sigobj, sig, signode):
 | |
|         theid = sig#obj.get_id()
 | |
|         theid = re.sub(r" +", " ", theid)
 | |
|         if self.objtype == 'emember':
 | |
|             theid = re.sub(r" ?=.*", "", theid)
 | |
|         theid = re.sub(r"=[^,()]+\([^)]*?\)[^,)]*(,|\))", "\\1", theid)
 | |
|         theid = re.sub(r"=\w*[^,)(]+(,|\))", "\\1", theid)
 | |
|         theid = theid.replace("( ", "(").replace(" )", ")")
 | |
|         name = unicode(sigobj.name)
 | |
|         if theid not in self.state.document.ids:
 | |
|             signode['names'].append(theid)
 | |
|             signode['ids'].append(theid)
 | |
|             signode['first'] = (not self.names)
 | |
|             self.state.document.note_explicit_target(signode)
 | |
| 
 | |
|             #self.env.domaindata['ocv']['objects'].setdefault(name,
 | |
|                 #(self.env.docname, self.objtype, theid))
 | |
|             self.env.domaindata['ocv']['objects'].setdefault(theid,
 | |
|                 (self.env.docname, self.objtype, theid))
 | |
|             self.env.domaindata['ocv']['objects2'].setdefault(name,
 | |
|                 (self.env.docname, self.objtype, theid))
 | |
| 
 | |
|         indextext = self.get_index_text(name)
 | |
|         if indextext:
 | |
|             self.indexnode['entries'].append(('single', indextext, theid, name))
 | |
| 
 | |
|     def before_content(self):
 | |
|         lastname = self.names and self.names[-1]
 | |
|         if lastname and not self.env.temp_data.get('ocv:parent'):
 | |
|             assert isinstance(lastname, NamedDefExpr)
 | |
|             self.env.temp_data['ocv:parent'] = lastname.name
 | |
|             self.parentname_set = True
 | |
|         else:
 | |
|             self.parentname_set = False
 | |
| 
 | |
|     def after_content(self):
 | |
|         if self.parentname_set:
 | |
|             self.env.temp_data['ocv:parent'] = None
 | |
| 
 | |
|     def parse_definition(self, parser):
 | |
|         raise NotImplementedError()
 | |
| 
 | |
|     def describe_signature(self, signode, arg):
 | |
|         raise NotImplementedError()
 | |
| 
 | |
|     def handle_signature(self, sig, signode):
 | |
|         parser = DefinitionParser(sig)
 | |
|         try:
 | |
|             rv = self.parse_definition(parser)
 | |
|             parser.assert_end()
 | |
|         except DefinitionError, e:
 | |
|             self.env.warn(self.env.docname,
 | |
|                           e.description, self.lineno)
 | |
|             raise ValueError
 | |
|         self.describe_signature(signode, rv)
 | |
| 
 | |
|         parent = self.env.temp_data.get('ocv:parent')
 | |
|         if parent is not None:
 | |
|             rv = rv.clone()
 | |
|             rv.name = rv.name.prefix(parent)
 | |
|         return rv
 | |
| 
 | |
| 
 | |
| class OCVClassObject(OCVObject):
 | |
|     object_annotation = "class "
 | |
|     object_long_name = "class"
 | |
| 
 | |
|     def attach_modifiers(self, node, obj, skip_visibility = 'public'):
 | |
|         if obj.visibility != skip_visibility:
 | |
|             node += addnodes.desc_annotation(obj.visibility,
 | |
|                                              obj.visibility)
 | |
|             node += nodes.Text(' ')
 | |
|         if obj.static:
 | |
|             node += addnodes.desc_annotation('static', 'static')
 | |
|             node += nodes.Text(' ')
 | |
| 
 | |
|     def get_index_text(self, name):
 | |
|         return _('%s (C++ %s)') % (name, self.__class__.object_long_name)
 | |
| 
 | |
|     def parse_definition(self, parser):
 | |
|         return parser.parse_class()
 | |
| 
 | |
|     def describe_signature(self, signode, cls):
 | |
|         self.attach_modifiers(signode, cls)
 | |
|         signode += addnodes.desc_annotation(self.__class__.object_annotation, self.__class__.object_annotation)
 | |
|         self.attach_name(signode, cls.name)
 | |
|         first_parent = True
 | |
|         for p in cls.parents:
 | |
|             if first_parent:
 | |
|                 signode += nodes.Text(' : ')
 | |
|                 first_parent = False
 | |
|             else:
 | |
|                 signode += nodes.Text(', ')
 | |
|             self.attach_modifiers(signode, p, None)
 | |
|             self.attach_name(signode, p.name)
 | |
| 
 | |
| class OCVStructObject(OCVClassObject):
 | |
|     object_annotation = "struct "
 | |
|     object_long_name = "structure"
 | |
| 
 | |
| class OCVTypeObject(OCVObject):
 | |
| 
 | |
|     def get_index_text(self, name):
 | |
|         if self.objtype == 'type':
 | |
|             return _('%s (C++ type)') % name
 | |
|         return ''
 | |
| 
 | |
|     def parse_definition(self, parser):
 | |
|         return parser.parse_type_object()
 | |
| 
 | |
|     def describe_signature(self, signode, obj):
 | |
|         self.attach_modifiers(signode, obj)
 | |
|         signode += addnodes.desc_annotation('type ', 'type ')
 | |
|         if obj.typename is not None:
 | |
|             self.attach_type(signode, obj.typename)
 | |
|             signode += nodes.Text(' ')
 | |
|         self.attach_name(signode, obj.name)
 | |
| 
 | |
| class OCVEnumObject(OCVObject):
 | |
| 
 | |
|     def get_index_text(self, name):
 | |
|         if self.objtype == 'enum':
 | |
|             return _('%s (enum)') % name
 | |
|         return ''
 | |
| 
 | |
|     def parse_definition(self, parser):
 | |
|         return parser.parse_type_object()
 | |
| 
 | |
|     def describe_signature(self, signode, obj):
 | |
|         self.attach_modifiers(signode, obj)
 | |
|         signode += addnodes.desc_annotation('enum ', 'enum ')
 | |
|         if obj.typename is not None:
 | |
|             self.attach_type(signode, obj.typename)
 | |
|             signode += nodes.Text(' ')
 | |
|         self.attach_name(signode, obj.name)
 | |
| 
 | |
| 
 | |
| class OCVMemberObject(OCVObject):
 | |
|     ismember = True
 | |
| 
 | |
|     def get_index_text(self, name):
 | |
|         if self.objtype == 'member':
 | |
|             return _('%s (C++ member)') % name
 | |
|         return ''
 | |
| 
 | |
|     def parse_definition(self, parser):
 | |
|         parent_class = self.env.temp_data.get('ocv:parent')
 | |
|         if parent_class is None:
 | |
|             parser.fail("missing parent structure/class")
 | |
|         return parser.parse_member_object()
 | |
| 
 | |
|     def describe_signature(self, signode, obj):
 | |
|         self.attach_modifiers(signode, obj)
 | |
|         if obj.typename:
 | |
|             self.attach_type(signode, obj.typename)
 | |
|             signode += nodes.Text(' ')
 | |
|         self.attach_name(signode, obj.name)
 | |
|         if obj.value is not None:
 | |
|             signode += nodes.Text(u' = ' + obj.value)
 | |
| 
 | |
| class OCVEnumMemberObject(OCVMemberObject):
 | |
|     def parse_definition(self, parser):
 | |
|         # parent_class = self.env.temp_data.get('ocv:parent')
 | |
|         # if parent_class is None:
 | |
|         #     parser.fail("missing parent structure/class")
 | |
|         return parser.parse_enum_member_object()
 | |
| 
 | |
| class OCVFunctionObject(OCVObject):
 | |
| 
 | |
|     def attach_function(self, node, func):
 | |
|         owner, name = func.name.split_owner()
 | |
|         if owner is not None:
 | |
|             owner = unicode(owner) + '::'
 | |
|             node += addnodes.desc_addname(owner, owner)
 | |
| 
 | |
|         # cast operator is special.  in this case the return value
 | |
|         # is reversed.
 | |
|         if isinstance(name, CastOpDefExpr):
 | |
|             node += addnodes.desc_name('operator', 'operator')
 | |
|             node += nodes.Text(u' ')
 | |
|             self.attach_type(node, name.typename)
 | |
|         else:
 | |
|             funcname = unicode(name)
 | |
|             node += addnodes.desc_name(funcname, funcname)
 | |
| 
 | |
|         paramlist = addnodes.desc_parameterlist()
 | |
|         for arg in func.signature:
 | |
|             param = addnodes.desc_parameter('', '', noemph=True)
 | |
|             if arg.type is not None:
 | |
|                 self.attach_type(param, arg.type)
 | |
|                 param += nodes.Text(u' ')
 | |
|             #param += nodes.emphasis(unicode(arg.name), unicode(arg.name))
 | |
|             sbrIdx = unicode(arg.name).find("[")
 | |
|             if sbrIdx < 0:
 | |
|                 param += nodes.strong(unicode(arg.name), unicode(arg.name))
 | |
|             else:
 | |
|                 param += nodes.strong(unicode(arg.name)[:sbrIdx], unicode(arg.name)[:sbrIdx])
 | |
|                 param += nodes.Text(unicode(arg.name)[sbrIdx:])
 | |
|             if arg.default is not None:
 | |
|                 def_ = u'=' + unicode(arg.default)
 | |
|                 #param += nodes.emphasis(def_, def_)
 | |
|                 param += nodes.Text(def_)
 | |
|             paramlist += param
 | |
| 
 | |
|         node += paramlist
 | |
|         if func.const:
 | |
|             node += addnodes.desc_addname(' const', ' const')
 | |
|         if func.pure_virtual:
 | |
|             node += addnodes.desc_addname(' = 0', ' = 0')
 | |
| 
 | |
|     def get_index_text(self, name):
 | |
|         lname = self.__class__.langname
 | |
|         if lname == "C" and name.startswith("cv"):
 | |
|             name = name[2:]
 | |
|         return _('%s (%s function)') % (name, lname)
 | |
| 
 | |
|     def parse_definition(self, parser):
 | |
|         return parser.parse_function()
 | |
| 
 | |
|     def describe_signature(self, signode, func):
 | |
|         self.attach_modifiers(signode, func)
 | |
|         if func.explicit:
 | |
|             signode += addnodes.desc_annotation('explicit', 'explicit')
 | |
|             signode += nodes.Text(' ')
 | |
|         if func.virtual:
 | |
|             signode += addnodes.desc_annotation('virtual', 'virtual')
 | |
|             signode += nodes.Text(' ')
 | |
|         # return value is None for things with a reverse return value
 | |
|         # such as casting operator definitions or constructors
 | |
|         # and destructors.
 | |
|         if func.rv is not None:
 | |
|             self.attach_type(signode, func.rv)
 | |
|         signode += nodes.Text(u' ')
 | |
|         self.attach_function(signode, func)
 | |
| 
 | |
| 
 | |
| class OCVCurrentNamespace(Directive):
 | |
|     """This directive is just to tell Sphinx that we're documenting
 | |
|     stuff in namespace foo.
 | |
|     """
 | |
| 
 | |
|     has_content = False
 | |
|     required_arguments = 1
 | |
|     optional_arguments = 0
 | |
|     final_argument_whitespace = True
 | |
|     option_spec = {}
 | |
| 
 | |
|     def run(self):
 | |
|         env = self.state.document.settings.env
 | |
|         if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
 | |
|             env.temp_data['ocv:prefix'] = None
 | |
|         else:
 | |
|             parser = DefinitionParser(self.arguments[0])
 | |
|             try:
 | |
|                 prefix = parser.parse_type()
 | |
|                 parser.assert_end()
 | |
|             except DefinitionError, e:
 | |
|                 self.env.warn(self.env.docname,
 | |
|                               e.description, self.lineno)
 | |
|             else:
 | |
|                 env.temp_data['ocv:prefix'] = prefix
 | |
|         return []
 | |
| 
 | |
| 
 | |
| class OCVXRefRole(XRefRole):
 | |
| 
 | |
|     def process_link(self, env, refnode, has_explicit_title, title, target):
 | |
|         refnode['ocv:parent'] = env.temp_data.get('ocv:parent')
 | |
|         if not has_explicit_title:
 | |
|             target = target.lstrip('~') # only has a meaning for the title
 | |
|             # if the first character is a tilde, don't display the module/class
 | |
|             # parts of the contents
 | |
|             if title[:1] == '~':
 | |
|                 title = title[1:]
 | |
|                 dcolon = title.rfind('::')
 | |
|                 if dcolon != -1:
 | |
|                     title = title[dcolon + 2:]
 | |
|         return title, target
 | |
| 
 | |
| 
 | |
| class OCVCFunctionObject(OCVFunctionObject):
 | |
|     langname = "C"
 | |
| 
 | |
| class OCVJavaFunctionObject(OCVFunctionObject):
 | |
|     langname = "Java"
 | |
| 
 | |
| 
 | |
| class OCVDomain(Domain):
 | |
|     """OpenCV C++ language domain."""
 | |
|     name = 'ocv'
 | |
|     label = 'C++'
 | |
|     object_types = {
 | |
|         'class':    ObjType(l_('class'),    'class'),
 | |
|         'struct':    ObjType(l_('struct'),    'struct'),
 | |
|         'function': ObjType(l_('function'), 'func', 'funcx'),
 | |
|         'cfunction': ObjType(l_('cfunction'), 'cfunc', 'cfuncx'),
 | |
|         'jfunction': ObjType(l_('jfunction'), 'jfunc', 'jfuncx'),
 | |
|         'pyfunction': ObjType(l_('pyfunction'), 'pyfunc'),
 | |
|         'pyoldfunction': ObjType(l_('pyoldfunction'), 'pyoldfunc'),
 | |
|         'member':   ObjType(l_('member'),   'member'),
 | |
|         'emember':   ObjType(l_('emember'),   'emember'),
 | |
|         'type':     ObjType(l_('type'),     'type'),
 | |
|         'enum':     ObjType(l_('enum'),     'enum')
 | |
|     }
 | |
| 
 | |
|     directives = {
 | |
|         'class':        OCVClassObject,
 | |
|         'struct':       OCVStructObject,
 | |
|         'function':     OCVFunctionObject,
 | |
|         'cfunction':    OCVCFunctionObject,
 | |
|         'jfunction':    OCVJavaFunctionObject,
 | |
|         'pyfunction':   OCVPyModulelevel,
 | |
|         'pyoldfunction':   OCVPyOldModulelevel,
 | |
|         'member':       OCVMemberObject,
 | |
|         'emember':      OCVEnumMemberObject,
 | |
|         'type':         OCVTypeObject,
 | |
|         'enum':         OCVEnumObject,
 | |
|         'namespace':    OCVCurrentNamespace
 | |
|     }
 | |
|     roles = {
 | |
|         'class':  OCVXRefRole(),
 | |
|         'struct':  OCVXRefRole(),
 | |
|         'func' :  OCVXRefRole(fix_parens=True),
 | |
|         'funcx' :  OCVXRefRole(),
 | |
|         'cfunc' :  OCVXRefRole(fix_parens=True),
 | |
|         'cfuncx' :  OCVXRefRole(),
 | |
|         'jfunc' :  OCVXRefRole(fix_parens=True),
 | |
|         'jfuncx' :  OCVXRefRole(),
 | |
|         'pyfunc' :  OCVPyXRefRole(),
 | |
|         'pyoldfunc' :  OCVPyXRefRole(),
 | |
|         'member': OCVXRefRole(),
 | |
|         'emember': OCVXRefRole(),
 | |
|         'type':   OCVXRefRole(),
 | |
|         'enum':   OCVXRefRole()
 | |
|     }
 | |
|     initial_data = {
 | |
|         'objects': {},  # fullname -> docname, objtype
 | |
|     }
 | |
| 
 | |
|     def __init__(self, env):
 | |
|         Domain.__init__(self, env)
 | |
|         self.data['objects2'] = {}
 | |
| 
 | |
|     def clear_doc(self, docname):
 | |
|         for fullname, (fn, _, _) in self.data['objects'].items():
 | |
|             if fn == docname:
 | |
|                 del self.data['objects'][fullname]
 | |
| 
 | |
|     def resolve_xref(self, env, fromdocname, builder,
 | |
|                      typ, target, node, contnode):
 | |
|         def _create_refnode(expr):
 | |
|             name = unicode(expr)
 | |
|             if "type" in self.objtypes_for_role(typ):
 | |
|                 return None
 | |
|             if "cfunction" in self.objtypes_for_role(typ):
 | |
|                 if not name.startswith(u'cv'):
 | |
|                     name = u'cv' + name
 | |
|             dict = self.data['objects']
 | |
|             if name not in dict:
 | |
|                 dict = self.data['objects2']
 | |
|             if name not in dict:
 | |
|                 refdoc = node.get('refdoc', fromdocname)
 | |
|                 env.warn(refdoc, 'unresolved reference: %r - %r' % (target, typ), node.line)
 | |
|                 return None
 | |
|             obj = dict[name]
 | |
|             if obj[1] not in self.objtypes_for_role(typ):
 | |
|                 return None
 | |
|             title = obj[2]
 | |
|             if "class" in self.objtypes_for_role(typ):
 | |
|                 title = u"class " + title
 | |
|             elif "struct" in self.objtypes_for_role(typ):
 | |
|                 title = u"struct " + title
 | |
|             return make_refnode(builder, fromdocname, obj[0], obj[2],
 | |
|                                 contnode, title)
 | |
| 
 | |
|         parser = DefinitionParser(target)
 | |
|         try:
 | |
|             expr = parser.parse_type().get_name()
 | |
|             parser.skip_ws()
 | |
|             if not parser.eof or expr is None:
 | |
|                 raise DefinitionError('')
 | |
|         except DefinitionError:
 | |
|             refdoc = node.get('refdoc', fromdocname)
 | |
|             env.warn(refdoc, 'unparseable C++ definition: %r' % target,
 | |
|                      node.line)
 | |
|             return None
 | |
| 
 | |
|         parent = node['ocv:parent']
 | |
| 
 | |
|         rv = _create_refnode(expr)
 | |
|         if rv is not None or parent is None:
 | |
|             return rv
 | |
|         parent = parent.get_name()
 | |
| 
 | |
|         rv = _create_refnode(expr.prefix(parent))
 | |
|         if rv is not None:
 | |
|             return rv
 | |
| 
 | |
|         parent, name = parent.split_owner()
 | |
|         return _create_refnode(expr.prefix(parent))
 | |
| 
 | |
|     def get_objects(self):
 | |
|         for refname, (docname, type, theid) in self.data['objects'].iteritems():
 | |
|             yield (refname, refname, type, docname, refname, 1)
 | |
| 
 | |
|     def get_type_name(self, type, primary=False):
 | |
|         """
 | |
|         Return full name for given ObjType.
 | |
|         """
 | |
|         if primary:
 | |
|             return type.lname
 | |
| 
 | |
|         return {
 | |
|             'class':         _('C++ class'),
 | |
|             'struct':        _('C/C++ struct'),
 | |
|             'function':      _('C++ function'),
 | |
|             'cfunction':     _('C function'),
 | |
|             'jfunction':     _('Java method'),
 | |
|             'pyfunction':    _('Python function'),
 | |
|             'pyoldfunction': _('Legacy Python function'),
 | |
|             'member':        _('C++ member'),
 | |
|             'emember':       _('enum member'),
 | |
|             'type':          _('C/C++ type'),
 | |
|             'enum':          _('C/C++ enum'),
 | |
|             'namespace':     _('C++ namespace'),
 | |
|             }.get(type.lname, _('%s %s') % (self.label, type.lname))
 | |
| 
 | |
| def setup(app):
 | |
|     app.add_domain(OCVDomain)
 |