2020-11-30 18:36:33 +03:00
# coding=utf-8
# SPDX-License-Identifier: GPL-2.0
#
u """
kernel - feat
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Implementation of the ` ` kernel - feat ` ` reST - directive .
: copyright : Copyright ( C ) 2016 Markus Heiser
: copyright : Copyright ( C ) 2016 - 2019 Mauro Carvalho Chehab
: maintained - by : Mauro Carvalho Chehab < mchehab + samsung @kernel.org >
: license : GPL Version 2 , June 1991 see Linux / COPYING for details .
The ` ` kernel - feat ` ` ( : py : class : ` KernelFeat ` ) directive calls the
scripts / get_feat . pl script to parse the Kernel ABI files .
Overview of directive ' s argument and options.
. . code - block : : rst
. . kernel - feat : : < ABI directory location >
: debug :
The argument ` ` < ABI directory location > ` ` is required . It contains the
location of the ABI files to be parsed .
` ` debug ` `
Inserts a code - block with the * raw * reST . Sometimes it is helpful to see
what reST is generated .
"""
import codecs
import os
2022-03-26 13:27:20 +03:00
import re
2020-11-30 18:36:33 +03:00
import subprocess
import sys
from os import path
from docutils import nodes , statemachine
from docutils . statemachine import ViewList
from docutils . parsers . rst import directives , Directive
from docutils . utils . error_reporting import ErrorString
2021-02-02 02:26:25 +03:00
from sphinx . util . docutils import switch_source_input
2020-11-30 18:36:33 +03:00
__version__ = ' 1.0 '
def setup ( app ) :
app . add_directive ( " kernel-feat " , KernelFeat )
return dict (
version = __version__
, parallel_read_safe = True
, parallel_write_safe = True
)
class KernelFeat ( Directive ) :
u """ KernelFeat (``kernel-feat``) directive """
required_arguments = 1
optional_arguments = 2
has_content = False
final_argument_whitespace = True
option_spec = {
" debug " : directives . flag
}
def warn ( self , message , * * replace ) :
replace [ " fname " ] = self . state . document . current_source
replace [ " line_no " ] = replace . get ( " line_no " , self . lineno )
message = ( " %(fname)s : %(line_no)s : [kernel-feat WARN] : " + message ) % replace
self . state . document . settings . env . app . warn ( message , prefix = " " )
def run ( self ) :
doc = self . state . document
if not doc . settings . file_insertion_enabled :
raise self . warning ( " docutils: file insertion disabled " )
env = doc . settings . env
cwd = path . dirname ( doc . current_source )
2022-03-26 13:27:20 +03:00
cmd = " get_feat.pl rest --enable-fname --dir "
2020-11-30 18:36:33 +03:00
cmd + = self . arguments [ 0 ]
if len ( self . arguments ) > 1 :
cmd + = " --arch " + self . arguments [ 1 ]
srctree = path . abspath ( os . environ [ " srctree " ] )
fname = cmd
# extend PATH with $(srctree)/scripts
path_env = os . pathsep . join ( [
srctree + os . sep + " scripts " ,
os . environ [ " PATH " ]
] )
shell_env = os . environ . copy ( )
shell_env [ " PATH " ] = path_env
shell_env [ " srctree " ] = srctree
lines = self . runCmd ( cmd , shell = True , cwd = cwd , env = shell_env )
2022-03-26 13:27:20 +03:00
line_regex = re . compile ( " ^ \ . \ . FILE ( \ S+)$ " )
out_lines = " "
for line in lines . split ( " \n " ) :
match = line_regex . search ( line )
if match :
fname = match . group ( 1 )
# Add the file to Sphinx build dependencies
env . note_dependency ( os . path . abspath ( fname ) )
else :
out_lines + = line + " \n "
nodeList = self . nestedParse ( out_lines , fname )
2020-11-30 18:36:33 +03:00
return nodeList
def runCmd ( self , cmd , * * kwargs ) :
2021-12-22 09:23:54 +03:00
u """ Run command ``cmd`` and return its stdout as unicode. """
2020-11-30 18:36:33 +03:00
try :
proc = subprocess . Popen (
cmd
, stdout = subprocess . PIPE
, stderr = subprocess . PIPE
, * * kwargs
)
out , err = proc . communicate ( )
out , err = codecs . decode ( out , ' utf-8 ' ) , codecs . decode ( err , ' utf-8 ' )
if proc . returncode != 0 :
raise self . severe (
u " command ' %s ' failed with return code %d "
% ( cmd , proc . returncode )
)
except OSError as exc :
raise self . severe ( u " problems with ' %s ' directive: %s . "
% ( self . name , ErrorString ( exc ) ) )
return out
def nestedParse ( self , lines , fname ) :
content = ViewList ( )
node = nodes . section ( )
if " debug " in self . options :
code_block = " \n \n .. code-block:: rst \n :linenos: \n "
for l in lines . split ( " \n " ) :
code_block + = " \n " + l
lines = code_block + " \n \n "
for c , l in enumerate ( lines . split ( " \n " ) ) :
content . append ( l , fname , c )
buf = self . state . memo . title_styles , self . state . memo . section_level , self . state . memo . reporter
2021-02-02 02:26:25 +03:00
with switch_source_input ( self . state , content ) :
self . state . nested_parse ( content , 0 , node , match_titles = 1 )
2020-11-30 18:36:33 +03:00
return node . children