2016-05-18 23:30:30 +03:00
# coding=utf-8
#
# Copyright © 2016 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Jani Nikula <jani.nikula@intel.com>
2016-05-31 18:09:12 +03:00
#
# Please make sure this works on both python2 and python3.
#
2016-05-18 23:30:30 +03:00
2017-08-31 22:21:29 +03:00
import codecs
2016-05-18 23:30:30 +03:00
import os
import subprocess
import sys
doc/sphinx: Track line-number of starting blocks
Design is pretty simple: kernel-doc inserts breadcrumbs with line
numbers, and sphinx picks them up. At first I went with a sphinx
comment, but inserting those at random places seriously upsets the
parser, and must be filtered. Hence why this version now uses "#define
LINEO " since one of these ever escape into output it's pretty clear
there is a bug.
It seems to work well, and at least the 2-3 errors where sphinx
complained about something that was not correct in kernel-doc text the
line numbers matched up perfectly.
v2: Instead of noodling around in the parser state machine, create
a ViewList and parse it ourselves. This seems to be the recommended
way, per Jani's suggestion.
v3:
- Split out ViewList pach. Splitting the kernel-doc changes from the
sphinx ones isn't possible, since emitting the LINENO lines wreaks
havoc with the rst formatting. We must filter them.
- Improve the regex per Jani's suggestions, and compile it just once
for speed.
- Now that LINENO lines are eaten, also add them to function parameter
descriptions. Much less content and offset than for in-line struct
member descriptions, but still nice to know which exact continuation
line upsets sphinx.
- Simplify/clarify the line +/-1 business a bit.
v4: Split out the scripts/kernel-doc changes and make line-numbers
opt-in, as suggested by Jani.
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: linux-doc@vger.kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2016-06-03 23:21:35 +03:00
import re
2016-06-07 12:13:56 +03:00
import glob
2016-05-18 23:30:30 +03:00
from docutils import nodes , statemachine
2016-06-02 15:59:18 +03:00
from docutils . statemachine import ViewList
2016-05-18 23:30:30 +03:00
from docutils . parsers . rst import directives
from sphinx . util . compat import Directive
2016-07-20 13:38:58 +03:00
from sphinx . ext . autodoc import AutodocReporter
2016-05-18 23:30:30 +03:00
2016-08-24 16:35:24 +03:00
__version__ = ' 1.0 '
2016-05-18 23:30:30 +03:00
class KernelDocDirective ( Directive ) :
""" Extract kernel-doc comments from the specified file """
required_argument = 1
optional_arguments = 4
option_spec = {
' doc ' : directives . unchanged_required ,
' functions ' : directives . unchanged_required ,
2016-06-07 12:13:56 +03:00
' export ' : directives . unchanged ,
' internal ' : directives . unchanged ,
2016-05-18 23:30:30 +03:00
}
has_content = False
def run ( self ) :
env = self . state . document . settings . env
doc/sphinx: Track line-number of starting blocks
Design is pretty simple: kernel-doc inserts breadcrumbs with line
numbers, and sphinx picks them up. At first I went with a sphinx
comment, but inserting those at random places seriously upsets the
parser, and must be filtered. Hence why this version now uses "#define
LINEO " since one of these ever escape into output it's pretty clear
there is a bug.
It seems to work well, and at least the 2-3 errors where sphinx
complained about something that was not correct in kernel-doc text the
line numbers matched up perfectly.
v2: Instead of noodling around in the parser state machine, create
a ViewList and parse it ourselves. This seems to be the recommended
way, per Jani's suggestion.
v3:
- Split out ViewList pach. Splitting the kernel-doc changes from the
sphinx ones isn't possible, since emitting the LINENO lines wreaks
havoc with the rst formatting. We must filter them.
- Improve the regex per Jani's suggestions, and compile it just once
for speed.
- Now that LINENO lines are eaten, also add them to function parameter
descriptions. Much less content and offset than for in-line struct
member descriptions, but still nice to know which exact continuation
line upsets sphinx.
- Simplify/clarify the line +/-1 business a bit.
v4: Split out the scripts/kernel-doc changes and make line-numbers
opt-in, as suggested by Jani.
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: linux-doc@vger.kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2016-06-03 23:21:35 +03:00
cmd = [ env . config . kerneldoc_bin , ' -rst ' , ' -enable-lineno ' ]
2016-05-18 23:30:30 +03:00
filename = env . config . kerneldoc_srctree + ' / ' + self . arguments [ 0 ]
2016-06-07 12:13:56 +03:00
export_file_patterns = [ ]
2016-05-18 23:30:30 +03:00
# Tell sphinx of the dependency
env . note_dependency ( os . path . abspath ( filename ) )
tab_width = self . options . get ( ' tab-width ' , self . state . document . settings . tab_width )
# FIXME: make this nicer and more robust against errors
if ' export ' in self . options :
cmd + = [ ' -export ' ]
2016-06-07 12:13:56 +03:00
export_file_patterns = str ( self . options . get ( ' export ' ) ) . split ( )
2016-05-18 23:30:30 +03:00
elif ' internal ' in self . options :
cmd + = [ ' -internal ' ]
2016-06-07 12:13:56 +03:00
export_file_patterns = str ( self . options . get ( ' internal ' ) ) . split ( )
2016-05-18 23:30:30 +03:00
elif ' doc ' in self . options :
cmd + = [ ' -function ' , str ( self . options . get ( ' doc ' ) ) ]
elif ' functions ' in self . options :
2016-06-08 10:25:40 +03:00
for f in str ( self . options . get ( ' functions ' ) ) . split ( ) :
2016-05-18 23:30:30 +03:00
cmd + = [ ' -function ' , f ]
2016-06-07 12:13:56 +03:00
for pattern in export_file_patterns :
for f in glob . glob ( env . config . kerneldoc_srctree + ' / ' + pattern ) :
env . note_dependency ( os . path . abspath ( f ) )
cmd + = [ ' -export-file ' , f ]
2016-05-18 23:30:30 +03:00
cmd + = [ filename ]
try :
env . app . verbose ( ' calling kernel-doc \' %s \' ' % ( " " . join ( cmd ) ) )
2017-08-31 22:21:29 +03:00
p = subprocess . Popen ( cmd , stdout = subprocess . PIPE , stderr = subprocess . PIPE )
2016-05-18 23:30:30 +03:00
out , err = p . communicate ( )
2017-08-31 22:21:29 +03:00
out , err = codecs . decode ( out , ' utf-8 ' ) , codecs . decode ( err , ' utf-8 ' )
2016-05-18 23:30:30 +03:00
if p . returncode != 0 :
sys . stderr . write ( err )
env . app . warn ( ' kernel-doc \' %s \' failed with return code %d ' % ( " " . join ( cmd ) , p . returncode ) )
return [ nodes . error ( None , nodes . paragraph ( text = " kernel-doc missing " ) ) ]
elif env . config . kerneldoc_verbosity > 0 :
sys . stderr . write ( err )
lines = statemachine . string2lines ( out , tab_width , convert_whitespace = True )
doc/sphinx: Track line-number of starting blocks
Design is pretty simple: kernel-doc inserts breadcrumbs with line
numbers, and sphinx picks them up. At first I went with a sphinx
comment, but inserting those at random places seriously upsets the
parser, and must be filtered. Hence why this version now uses "#define
LINEO " since one of these ever escape into output it's pretty clear
there is a bug.
It seems to work well, and at least the 2-3 errors where sphinx
complained about something that was not correct in kernel-doc text the
line numbers matched up perfectly.
v2: Instead of noodling around in the parser state machine, create
a ViewList and parse it ourselves. This seems to be the recommended
way, per Jani's suggestion.
v3:
- Split out ViewList pach. Splitting the kernel-doc changes from the
sphinx ones isn't possible, since emitting the LINENO lines wreaks
havoc with the rst formatting. We must filter them.
- Improve the regex per Jani's suggestions, and compile it just once
for speed.
- Now that LINENO lines are eaten, also add them to function parameter
descriptions. Much less content and offset than for in-line struct
member descriptions, but still nice to know which exact continuation
line upsets sphinx.
- Simplify/clarify the line +/-1 business a bit.
v4: Split out the scripts/kernel-doc changes and make line-numbers
opt-in, as suggested by Jani.
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: linux-doc@vger.kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2016-06-03 23:21:35 +03:00
result = ViewList ( )
lineoffset = 0 ;
line_regex = re . compile ( " ^#define LINENO ([0-9]+)$ " )
for line in lines :
match = line_regex . search ( line )
if match :
# sphinx counts lines from 0
lineoffset = int ( match . group ( 1 ) ) - 1
# we must eat our comments since the upset the markup
else :
2016-06-08 13:38:28 +03:00
result . append ( line , filename , lineoffset )
doc/sphinx: Track line-number of starting blocks
Design is pretty simple: kernel-doc inserts breadcrumbs with line
numbers, and sphinx picks them up. At first I went with a sphinx
comment, but inserting those at random places seriously upsets the
parser, and must be filtered. Hence why this version now uses "#define
LINEO " since one of these ever escape into output it's pretty clear
there is a bug.
It seems to work well, and at least the 2-3 errors where sphinx
complained about something that was not correct in kernel-doc text the
line numbers matched up perfectly.
v2: Instead of noodling around in the parser state machine, create
a ViewList and parse it ourselves. This seems to be the recommended
way, per Jani's suggestion.
v3:
- Split out ViewList pach. Splitting the kernel-doc changes from the
sphinx ones isn't possible, since emitting the LINENO lines wreaks
havoc with the rst formatting. We must filter them.
- Improve the regex per Jani's suggestions, and compile it just once
for speed.
- Now that LINENO lines are eaten, also add them to function parameter
descriptions. Much less content and offset than for in-line struct
member descriptions, but still nice to know which exact continuation
line upsets sphinx.
- Simplify/clarify the line +/-1 business a bit.
v4: Split out the scripts/kernel-doc changes and make line-numbers
opt-in, as suggested by Jani.
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: linux-doc@vger.kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2016-06-03 23:21:35 +03:00
lineoffset + = 1
2016-06-02 15:59:18 +03:00
node = nodes . section ( )
2016-07-20 13:38:58 +03:00
buf = self . state . memo . title_styles , self . state . memo . section_level , self . state . memo . reporter
self . state . memo . reporter = AutodocReporter ( result , self . state . memo . reporter )
self . state . memo . title_styles , self . state . memo . section_level = [ ] , 0
try :
self . state . nested_parse ( result , 0 , node , match_titles = 1 )
finally :
self . state . memo . title_styles , self . state . memo . section_level , self . state . memo . reporter = buf
2016-06-02 15:59:18 +03:00
return node . children
2016-07-20 13:38:58 +03:00
except Exception as e : # pylint: disable=W0703
2016-05-18 23:30:30 +03:00
env . app . warn ( ' kernel-doc \' %s \' processing failed with: %s ' %
( " " . join ( cmd ) , str ( e ) ) )
return [ nodes . error ( None , nodes . paragraph ( text = " kernel-doc missing " ) ) ]
def setup ( app ) :
app . add_config_value ( ' kerneldoc_bin ' , None , ' env ' )
app . add_config_value ( ' kerneldoc_srctree ' , None , ' env ' )
app . add_config_value ( ' kerneldoc_verbosity ' , 1 , ' env ' )
app . add_directive ( ' kernel-doc ' , KernelDocDirective )
2016-08-24 16:35:24 +03:00
return dict (
version = __version__ ,
parallel_read_safe = True ,
parallel_write_safe = True
)