Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) # Copyright 2019 Jonathan Corbet <corbet@lwn.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) # Apply kernel-specific tweaks after the initial document processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) # has been done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) from docutils import nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) import sphinx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) from sphinx import addnodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) if sphinx.version_info[0] < 2 or \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)    sphinx.version_info[0] == 2 and sphinx.version_info[1] < 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)     from sphinx.environment import NoUri
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)     from sphinx.errors import NoUri
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) import re
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) from itertools import chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) # Python 2 lacks re.ASCII...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)     ascii_p3 = re.ASCII
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) except AttributeError:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)     ascii_p3 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) # Regex nastiness.  Of course.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) # Try to identify "function()" that's not already marked up some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) # other way.  Sphinx doesn't like a lot of stuff right after a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) # :c:func: block (i.e. ":c:func:`mmap()`s" flakes out), so the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) # bit tries to restrict matches to things that won't create trouble.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) RE_function = re.compile(r'\b(([a-zA-Z_]\w+)\(\))', flags=ascii_p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) # Sphinx 2 uses the same :c:type role for struct, union, enum and typedef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) RE_generic_type = re.compile(r'\b(struct|union|enum|typedef)\s+([a-zA-Z_]\w+)',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)                              flags=ascii_p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) # Sphinx 3 uses a different C role for each one of struct, union, enum and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) # typedef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) RE_struct = re.compile(r'\b(struct)\s+([a-zA-Z_]\w+)', flags=ascii_p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) RE_union = re.compile(r'\b(union)\s+([a-zA-Z_]\w+)', flags=ascii_p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) RE_enum = re.compile(r'\b(enum)\s+([a-zA-Z_]\w+)', flags=ascii_p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) RE_typedef = re.compile(r'\b(typedef)\s+([a-zA-Z_]\w+)', flags=ascii_p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) # Detects a reference to a documentation page of the form Documentation/... with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) # an optional extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) RE_doc = re.compile(r'\bDocumentation(/[\w\-_/]+)(\.\w+)*')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) # Reserved C words that we should skip when cross-referencing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) Skipnames = [ 'for', 'if', 'register', 'sizeof', 'struct', 'unsigned' ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) # Many places in the docs refer to common system calls.  It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) # pointless to try to cross-reference them and, as has been known
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) # to happen, somebody defining a function by these names can lead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) # to the creation of incorrect and confusing cross references.  So
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) # just don't even try with these names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) Skipfuncs = [ 'open', 'close', 'read', 'write', 'fcntl', 'mmap',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)               'select', 'poll', 'fork', 'execve', 'clone', 'ioctl',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)               'socket' ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) def markup_refs(docname, app, node):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)     t = node.astext()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)     done = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)     repl = [ ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)     # Associate each regex with the function that will markup its matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)     markup_func_sphinx2 = {RE_doc: markup_doc_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)                            RE_function: markup_c_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)                            RE_generic_type: markup_c_ref}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)     markup_func_sphinx3 = {RE_doc: markup_doc_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)                            RE_function: markup_func_ref_sphinx3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)                            RE_struct: markup_c_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)                            RE_union: markup_c_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)                            RE_enum: markup_c_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)                            RE_typedef: markup_c_ref}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)     if sphinx.version_info[0] >= 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)         markup_func = markup_func_sphinx3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)         markup_func = markup_func_sphinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)     match_iterators = [regex.finditer(t) for regex in markup_func]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)     # Sort all references by the starting position in text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)     sorted_matches = sorted(chain(*match_iterators), key=lambda m: m.start())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)     for m in sorted_matches:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)         #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)         # Include any text prior to match as a normal text node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)         #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)         if m.start() > done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)             repl.append(nodes.Text(t[done:m.start()]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)         #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)         # Call the function associated with the regex that matched this text and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)         # append its return to the text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)         #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)         repl.append(markup_func[m.re](docname, app, m))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)         done = m.end()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)     if done < len(t):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)         repl.append(nodes.Text(t[done:]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)     return repl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) # In sphinx3 we can cross-reference to C macro and function, each one with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) # own C role, but both match the same regex, so we try both.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) def markup_func_ref_sphinx3(docname, app, match):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)     class_str = ['c-func', 'c-macro']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)     reftype_str = ['function', 'macro']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)     cdom = app.env.domains['c']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)     # Go through the dance of getting an xref out of the C domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)     target = match.group(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)     target_text = nodes.Text(match.group(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)     xref = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)     if not (target in Skipfuncs or target in Skipnames):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)         for class_s, reftype_s in zip(class_str, reftype_str):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)             lit_text = nodes.literal(classes=['xref', 'c', class_s])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)             lit_text += target_text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)             pxref = addnodes.pending_xref('', refdomain = 'c',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)                                           reftype = reftype_s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)                                           reftarget = target, modname = None,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)                                           classname = None)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)             #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)             # XXX The Latex builder will throw NoUri exceptions here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)             # work around that by ignoring them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)             #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)             try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)                 xref = cdom.resolve_xref(app.env, docname, app.builder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)                                          reftype_s, target, pxref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)                                          lit_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)             except NoUri:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)                 xref = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)             if xref:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)                 return xref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)     return target_text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) def markup_c_ref(docname, app, match):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)     class_str = {# Sphinx 2 only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)                  RE_function: 'c-func',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)                  RE_generic_type: 'c-type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)                  # Sphinx 3+ only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)                  RE_struct: 'c-struct',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)                  RE_union: 'c-union',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)                  RE_enum: 'c-enum',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)                  RE_typedef: 'c-type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)                  }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)     reftype_str = {# Sphinx 2 only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)                    RE_function: 'function',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)                    RE_generic_type: 'type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)                    # Sphinx 3+ only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)                    RE_struct: 'struct',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)                    RE_union: 'union',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)                    RE_enum: 'enum',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)                    RE_typedef: 'type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)                    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)     cdom = app.env.domains['c']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)     # Go through the dance of getting an xref out of the C domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)     target = match.group(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)     target_text = nodes.Text(match.group(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)     xref = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)     if not ((match.re == RE_function and target in Skipfuncs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)             or (target in Skipnames)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)         lit_text = nodes.literal(classes=['xref', 'c', class_str[match.re]])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)         lit_text += target_text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)         pxref = addnodes.pending_xref('', refdomain = 'c',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)                                       reftype = reftype_str[match.re],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)                                       reftarget = target, modname = None,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)                                       classname = None)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)         #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)         # XXX The Latex builder will throw NoUri exceptions here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)         # work around that by ignoring them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)         #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)         try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)             xref = cdom.resolve_xref(app.env, docname, app.builder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)                                      reftype_str[match.re], target, pxref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)                                      lit_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)         except NoUri:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)             xref = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)     # Return the xref if we got it; otherwise just return the plain text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)     if xref:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)         return xref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)         return target_text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) # Try to replace a documentation reference of the form Documentation/... with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) # cross reference to that page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) def markup_doc_ref(docname, app, match):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)     stddom = app.env.domains['std']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)     # Go through the dance of getting an xref out of the std domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)     target = match.group(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)     xref = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)     pxref = addnodes.pending_xref('', refdomain = 'std', reftype = 'doc',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)                                   reftarget = target, modname = None,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)                                   classname = None, refexplicit = False)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)     # XXX The Latex builder will throw NoUri exceptions here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)     # work around that by ignoring them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)     try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)         xref = stddom.resolve_xref(app.env, docname, app.builder, 'doc',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)                                    target, pxref, None)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)     except NoUri:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)         xref = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)     # Return the xref if we got it; otherwise just return the plain text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)     if xref:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)         return xref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)         return nodes.Text(match.group(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) def auto_markup(app, doctree, name):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)     # This loop could eventually be improved on.  Someday maybe we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)     # want a proper tree traversal with a lot of awareness of which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)     # kinds of nodes to prune.  But this works well for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)     # The nodes.literal test catches ``literal text``, its purpose is to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)     # avoid adding cross-references to functions that have been explicitly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)     # marked with cc:func:.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)     for para in doctree.traverse(nodes.paragraph):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)         for node in para.traverse(nodes.Text):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)             if not isinstance(node.parent, nodes.literal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)                 node.parent.replace(node, markup_refs(name, app, node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) def setup(app):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)     app.connect('doctree-resolved', auto_markup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)     return {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)         'parallel_read_safe': True,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)         'parallel_write_safe': True,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)         }