Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / Documentation / sphinx / cdomain.py
CommitLineData
e8f5c617 1# -*- coding: utf-8; mode: python -*-
56cd8692 2# pylint: disable=W0141,C0113,C0103,C0325
e8f5c617
MH
3u"""
4 cdomain
5 ~~~~~~~
6
7 Replacement for the sphinx c-domain.
8
9 :copyright: Copyright (C) 2016 Markus Heiser
10 :license: GPL Version 2, June 1991 see Linux/COPYING for details.
2c645cd7
MH
11
12 List of customizations:
13
556aa6d5
MH
14 * Moved the *duplicate C object description* warnings for function
15 declarations in the nitpicky mode. See Sphinx documentation for
16 the config values for ``nitpick`` and ``nitpick_ignore``.
17
2c645cd7
MH
18 * Add option 'name' to the "c:function:" directive. With option 'name' the
19 ref-name of a function can be modified. E.g.::
20
21 .. c:function:: int ioctl( int fd, int request )
22 :name: VIDIOC_LOG_STATUS
23
24 The func-name (e.g. ioctl) remains in the output but the ref-name changed
25 from 'ioctl' to 'VIDIOC_LOG_STATUS'. The function is referenced by::
26
27 * :c:func:`VIDIOC_LOG_STATUS` or
28 * :any:`VIDIOC_LOG_STATUS` (``:any:`` needs sphinx 1.3)
56cd8692
MH
29
30 * Handle signatures of function-like macros well. Don't try to deduce
31 arguments types of function-like macros.
32
e8f5c617
MH
33"""
34
56cd8692 35from docutils import nodes
2c645cd7
MH
36from docutils.parsers.rst import directives
37
b495360e 38import sphinx
56cd8692
MH
39from sphinx import addnodes
40from sphinx.domains.c import c_funcptr_sig_re, c_sig_re
e8f5c617
MH
41from sphinx.domains.c import CObject as Base_CObject
42from sphinx.domains.c import CDomain as Base_CDomain
43
44__version__ = '1.0'
45
b495360e 46# Get Sphinx version
c46988ae 47major, minor, patch = sphinx.version_info[:3]
b495360e 48
e8f5c617
MH
49def setup(app):
50
51 app.override_domain(CDomain)
52
53 return dict(
54 version = __version__,
55 parallel_read_safe = True,
56 parallel_write_safe = True
57 )
58
59class CObject(Base_CObject):
60
61 """
62 Description of a C language object.
63 """
2c645cd7
MH
64 option_spec = {
65 "name" : directives.unchanged
66 }
67
56cd8692
MH
68 def handle_func_like_macro(self, sig, signode):
69 u"""Handles signatures of function-like macros.
70
71 If the objtype is 'function' and the the signature ``sig`` is a
72 function-like macro, the name of the macro is returned. Otherwise
73 ``False`` is returned. """
74
75 if not self.objtype == 'function':
76 return False
77
78 m = c_funcptr_sig_re.match(sig)
79 if m is None:
80 m = c_sig_re.match(sig)
81 if m is None:
82 raise ValueError('no match')
83
84 rettype, fullname, arglist, _const = m.groups()
85 arglist = arglist.strip()
86 if rettype or not arglist:
87 return False
88
89 arglist = arglist.replace('`', '').replace('\\ ', '') # remove markup
90 arglist = [a.strip() for a in arglist.split(",")]
91
92 # has the first argument a type?
93 if len(arglist[0].split(" ")) > 1:
94 return False
95
96 # This is a function-like macro, it's arguments are typeless!
97 signode += addnodes.desc_name(fullname, fullname)
98 paramlist = addnodes.desc_parameterlist()
99 signode += paramlist
100
101 for argname in arglist:
102 param = addnodes.desc_parameter('', '', noemph=True)
103 # separate by non-breaking space in the output
104 param += nodes.emphasis(argname, argname)
105 paramlist += param
106
107 return fullname
108
2c645cd7
MH
109 def handle_signature(self, sig, signode):
110 """Transform a C signature into RST nodes."""
56cd8692
MH
111
112 fullname = self.handle_func_like_macro(sig, signode)
113 if not fullname:
114 fullname = super(CObject, self).handle_signature(sig, signode)
115
2c645cd7
MH
116 if "name" in self.options:
117 if self.objtype == 'function':
118 fullname = self.options["name"]
119 else:
120 # FIXME: handle :name: value of other declaration types?
121 pass
122 return fullname
123
556aa6d5
MH
124 def add_target_and_index(self, name, sig, signode):
125 # for C API items we add a prefix since names are usually not qualified
126 # by a module name and so easily clash with e.g. section titles
127 targetname = 'c.' + name
128 if targetname not in self.state.document.ids:
129 signode['names'].append(targetname)
130 signode['ids'].append(targetname)
131 signode['first'] = (not self.names)
132 self.state.document.note_explicit_target(signode)
133 inv = self.env.domaindata['c']['objects']
134 if (name in inv and self.env.config.nitpicky):
135 if self.objtype == 'function':
136 if ('c:func', name) not in self.env.config.nitpick_ignore:
137 self.state_machine.reporter.warning(
138 'duplicate C object description of %s, ' % name +
139 'other instance in ' + self.env.doc2path(inv[name][0]),
140 line=self.lineno)
141 inv[name] = (self.env.docname, self.objtype)
142
143 indextext = self.get_index_text(name)
144 if indextext:
b495360e
MH
145 if major == 1 and minor < 4:
146 # indexnode's tuple changed in 1.4
147 # https://github.com/sphinx-doc/sphinx/commit/e6a5a3a92e938fcd75866b4227db9e0524d58f7c
148 self.indexnode['entries'].append(
149 ('single', indextext, targetname, ''))
150 else:
151 self.indexnode['entries'].append(
152 ('single', indextext, targetname, '', None))
e8f5c617
MH
153
154class CDomain(Base_CDomain):
155
156 """C language domain."""
157 name = 'c'
158 label = 'C'
159 directives = {
160 'function': CObject,
161 'member': CObject,
162 'macro': CObject,
163 'type': CObject,
164 'var': CObject,
165 }