The Linux kernel moved to sphinx-based documentation and got rid of the DocBook based documentation quite a while ago. Hence, the DocBook documentation for U-Boot should be converted as well. To achieve this, import the necessary files from Linux v4.17, and convert the current DocBook documentation (three files altogether) to sphinx/reStructuredText. For now, all old DocBook documentation was merged into a single handbook, tentatively named "U-Boot Hacker Manual". For some source files, the documentation style was changed to comply with kernel-doc; no functional changes were applied. Signed-off-by: Mario Six <mario.six@gdsys.cc>lime2-spi
parent
5448ff33f2
commit
78a88f7930
@ -0,0 +1,2 @@ |
||||
output |
||||
*.pyc |
@ -0,0 +1,124 @@ |
||||
# -*- makefile -*-
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
subdir-y :=
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXOPTS =
|
||||
SPHINXDIRS = .
|
||||
_SPHINXDIRS = $(patsubst $(srctree)/Documentation/%/conf.py,%,$(wildcard $(srctree)/Documentation/*/conf.py))
|
||||
SPHINX_CONF = conf.py
|
||||
PAPER =
|
||||
BUILDDIR = $(obj)/output
|
||||
PDFLATEX = xelatex
|
||||
LATEXOPTS = -interaction=batchmode
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
||||
|
||||
ifeq ($(HAVE_SPHINX),0) |
||||
|
||||
.DEFAULT: |
||||
$(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.)
|
||||
@echo
|
||||
@./scripts/sphinx-pre-install
|
||||
@echo " SKIP Sphinx $@ target."
|
||||
|
||||
else # HAVE_SPHINX
|
||||
|
||||
# User-friendly check for pdflatex
|
||||
HAVE_PDFLATEX := $(shell if which $(PDFLATEX) >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
KERNELDOC = $(srctree)/scripts/kernel-doc
|
||||
KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC)
|
||||
ALLSPHINXOPTS = $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
# commands; the 'cmd' from scripts/Kbuild.include is not *loopable*
|
||||
loop_cmd = $(echo-cmd) $(cmd_$(1)) || exit;
|
||||
|
||||
# $2 sphinx builder e.g. "html"
|
||||
# $3 name of the build subfolder / e.g. "media", used as:
|
||||
# * dest folder relative to $(BUILDDIR) and
|
||||
# * cache folder relative to $(BUILDDIR)/.doctrees
|
||||
# $4 dest subfolder e.g. "man" for man pages at media/man
|
||||
# $5 reST source folder relative to $(srctree)/$(src),
|
||||
# e.g. "media" for the linux-tv book-set at ./Documentation/media
|
||||
|
||||
quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
|
||||
cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media $2 && \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
|
||||
$(SPHINXBUILD) \
|
||||
-b $2 \
|
||||
-c $(abspath $(srctree)/$(src)) \
|
||||
-d $(abspath $(BUILDDIR)/.doctrees/$3) \
|
||||
-D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) \
|
||||
$(ALLSPHINXOPTS) \
|
||||
$(abspath $(srctree)/$(src)/$5) \
|
||||
$(abspath $(BUILDDIR)/$3/$4)
|
||||
|
||||
htmldocs: |
||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var)))
|
||||
|
||||
linkcheckdocs: |
||||
@$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,linkcheck,$(var),,$(var)))
|
||||
|
||||
latexdocs: |
||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,latex,$(var),latex,$(var)))
|
||||
|
||||
ifeq ($(HAVE_PDFLATEX),0) |
||||
|
||||
pdfdocs: |
||||
$(warning The '$(PDFLATEX)' command was not found. Make sure you have it installed and in PATH to produce PDF output.)
|
||||
@echo " SKIP Sphinx $@ target."
|
||||
|
||||
else # HAVE_PDFLATEX
|
||||
|
||||
pdfdocs: latexdocs |
||||
$(foreach var,$(SPHINXDIRS), $(MAKE) PDFLATEX=$(PDFLATEX) LATEXOPTS="$(LATEXOPTS)" -C $(BUILDDIR)/$(var)/latex || exit;)
|
||||
|
||||
endif # HAVE_PDFLATEX
|
||||
|
||||
epubdocs: |
||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,epub,$(var),epub,$(var)))
|
||||
|
||||
xmldocs: |
||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,xml,$(var),xml,$(var)))
|
||||
|
||||
endif # HAVE_SPHINX
|
||||
|
||||
# The following targets are independent of HAVE_SPHINX, and the rules should
|
||||
# work or silently pass without Sphinx.
|
||||
|
||||
refcheckdocs: |
||||
$(Q)cd $(srctree);scripts/documentation-file-ref-check
|
||||
|
||||
cleandocs: |
||||
$(Q)rm -rf $(BUILDDIR)
|
||||
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
|
||||
|
||||
dochelp: |
||||
@echo ' Linux kernel internal documentation in different formats from ReST:'
|
||||
@echo ' htmldocs - HTML'
|
||||
@echo ' latexdocs - LaTeX'
|
||||
@echo ' pdfdocs - PDF'
|
||||
@echo ' epubdocs - EPUB'
|
||||
@echo ' xmldocs - XML'
|
||||
@echo ' linkcheckdocs - check for broken external links (will connect to external hosts)'
|
||||
@echo ' refcheckdocs - check for references to non-existing files under Documentation'
|
||||
@echo ' cleandocs - clean all generated files'
|
||||
@echo
|
||||
@echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2'
|
||||
@echo ' valid values for SPHINXDIRS are: $(_SPHINXDIRS)'
|
||||
@echo
|
||||
@echo ' make SPHINX_CONF={conf-file} [target] use *additional* sphinx-build'
|
||||
@echo ' configuration. This is e.g. useful to build with nit-picking config.'
|
||||
@echo
|
||||
@echo ' Default location for the generated documents is Documentation/output'
|
@ -0,0 +1,528 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# |
||||
# The U-Boot documentation build configuration file, created by |
||||
# sphinx-quickstart on Fri Feb 12 13:51:46 2016. |
||||
# |
||||
# This file is execfile()d with the current directory set to its |
||||
# containing dir. |
||||
# |
||||
# Note that not all possible configuration values are present in this |
||||
# autogenerated file. |
||||
# |
||||
# All configuration values have a default; values that are commented out |
||||
# serve to show the default. |
||||
|
||||
import sys |
||||
import os |
||||
import sphinx |
||||
|
||||
# Get Sphinx version |
||||
major, minor, patch = sphinx.version_info[:3] |
||||
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory, |
||||
# add these directories to sys.path here. If the directory is relative to the |
||||
# documentation root, use os.path.abspath to make it absolute, like shown here. |
||||
sys.path.insert(0, os.path.abspath('sphinx')) |
||||
from load_config import loadConfig |
||||
|
||||
# -- General configuration ------------------------------------------------ |
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here. |
||||
needs_sphinx = '1.3' |
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be |
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom |
||||
# ones. |
||||
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain', 'kfigure'] |
||||
|
||||
# The name of the math extension changed on Sphinx 1.4 |
||||
if major == 1 and minor > 3: |
||||
extensions.append("sphinx.ext.imgmath") |
||||
else: |
||||
extensions.append("sphinx.ext.pngmath") |
||||
|
||||
# Add any paths that contain templates here, relative to this directory. |
||||
templates_path = ['_templates'] |
||||
|
||||
# The suffix(es) of source filenames. |
||||
# You can specify multiple suffix as a list of string: |
||||
# source_suffix = ['.rst', '.md'] |
||||
source_suffix = '.rst' |
||||
|
||||
# The encoding of source files. |
||||
#source_encoding = 'utf-8-sig' |
||||
|
||||
# The master toctree document. |
||||
master_doc = 'index' |
||||
|
||||
# General information about the project. |
||||
project = 'Das U-Boot' |
||||
copyright = 'The U-Boot development community' |
||||
author = 'The U-Boot development community' |
||||
|
||||
# The version info for the project you're documenting, acts as replacement for |
||||
# |version| and |release|, also used in various other places throughout the |
||||
# built documents. |
||||
# |
||||
# In a normal build, version and release are are set to KERNELVERSION and |
||||
# KERNELRELEASE, respectively, from the Makefile via Sphinx command line |
||||
# arguments. |
||||
# |
||||
# The following code tries to extract the information by reading the Makefile, |
||||
# when Sphinx is run directly (e.g. by Read the Docs). |
||||
try: |
||||
makefile_version = None |
||||
makefile_patchlevel = None |
||||
for line in open('../Makefile'): |
||||
key, val = [x.strip() for x in line.split('=', 2)] |
||||
if key == 'VERSION': |
||||
makefile_version = val |
||||
elif key == 'PATCHLEVEL': |
||||
makefile_patchlevel = val |
||||
if makefile_version and makefile_patchlevel: |
||||
break |
||||
except: |
||||
pass |
||||
finally: |
||||
if makefile_version and makefile_patchlevel: |
||||
version = release = makefile_version + '.' + makefile_patchlevel |
||||
else: |
||||
version = release = "unknown version" |
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation |
||||
# for a list of supported languages. |
||||
# |
||||
# This is also used if you do content translation via gettext catalogs. |
||||
# Usually you set "language" from the command line for these cases. |
||||
language = None |
||||
|
||||
# There are two options for replacing |today|: either, you set today to some |
||||
# non-false value, then it is used: |
||||
#today = '' |
||||
# Else, today_fmt is used as the format for a strftime call. |
||||
#today_fmt = '%B %d, %Y' |
||||
|
||||
# List of patterns, relative to source directory, that match files and |
||||
# directories to ignore when looking for source files. |
||||
exclude_patterns = ['output'] |
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all |
||||
# documents. |
||||
#default_role = None |
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text. |
||||
#add_function_parentheses = True |
||||
|
||||
# If true, the current module name will be prepended to all description |
||||
# unit titles (such as .. function::). |
||||
#add_module_names = True |
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the |
||||
# output. They are ignored by default. |
||||
#show_authors = False |
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use. |
||||
pygments_style = 'sphinx' |
||||
|
||||
# A list of ignored prefixes for module index sorting. |
||||
#modindex_common_prefix = [] |
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents. |
||||
#keep_warnings = False |
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing. |
||||
todo_include_todos = False |
||||
|
||||
primary_domain = 'c' |
||||
highlight_language = 'none' |
||||
|
||||
# -- Options for HTML output ---------------------------------------------- |
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for |
||||
# a list of builtin themes. |
||||
|
||||
# The Read the Docs theme is available from |
||||
# - https://github.com/snide/sphinx_rtd_theme |
||||
# - https://pypi.python.org/pypi/sphinx_rtd_theme |
||||
# - python-sphinx-rtd-theme package (on Debian) |
||||
try: |
||||
import sphinx_rtd_theme |
||||
html_theme = 'sphinx_rtd_theme' |
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] |
||||
except ImportError: |
||||
sys.stderr.write('Warning: The Sphinx \'sphinx_rtd_theme\' HTML theme was not found. Make sure you have the theme installed to produce pretty HTML output. Falling back to the default theme.\n') |
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme |
||||
# further. For a list of options available for each theme, see the |
||||
# documentation. |
||||
#html_theme_options = {} |
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory. |
||||
#html_theme_path = [] |
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to |
||||
# "<project> v<release> documentation". |
||||
#html_title = None |
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title. |
||||
#html_short_title = None |
||||
|
||||
# The name of an image file (relative to this directory) to place at the top |
||||
# of the sidebar. |
||||
#html_logo = None |
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the |
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
||||
# pixels large. |
||||
#html_favicon = None |
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here, |
||||
# relative to this directory. They are copied after the builtin static files, |
||||
# so a file named "default.css" will overwrite the builtin "default.css". |
||||
|
||||
html_static_path = ['sphinx-static'] |
||||
|
||||
html_context = { |
||||
'css_files': [ |
||||
'_static/theme_overrides.css', |
||||
], |
||||
} |
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or |
||||
# .htaccess) here, relative to this directory. These files are copied |
||||
# directly to the root of the documentation. |
||||
#html_extra_path = [] |
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
||||
# using the given strftime format. |
||||
#html_last_updated_fmt = '%b %d, %Y' |
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to |
||||
# typographically correct entities. |
||||
#html_use_smartypants = True |
||||
|
||||
# Custom sidebar templates, maps document names to template names. |
||||
#html_sidebars = {} |
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to |
||||
# template names. |
||||
#html_additional_pages = {} |
||||
|
||||
# If false, no module index is generated. |
||||
#html_domain_indices = True |
||||
|
||||
# If false, no index is generated. |
||||
#html_use_index = True |
||||
|
||||
# If true, the index is split into individual pages for each letter. |
||||
#html_split_index = False |
||||
|
||||
# If true, links to the reST sources are added to the pages. |
||||
#html_show_sourcelink = True |
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
||||
#html_show_sphinx = True |
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
||||
#html_show_copyright = True |
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will |
||||
# contain a <link> tag referring to it. The value of this option must be the |
||||
# base URL from which the finished HTML is served. |
||||
#html_use_opensearch = '' |
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml"). |
||||
#html_file_suffix = None |
||||
|
||||
# Language to be used for generating the HTML full-text search index. |
||||
# Sphinx supports the following languages: |
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' |
||||
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' |
||||
#html_search_language = 'en' |
||||
|
||||
# A dictionary with options for the search language support, empty by default. |
||||
# Now only 'ja' uses this config value |
||||
#html_search_options = {'type': 'default'} |
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that |
||||
# implements a search results scorer. If empty, the default will be used. |
||||
#html_search_scorer = 'scorer.js' |
||||
|
||||
# Output file base name for HTML help builder. |
||||
htmlhelp_basename = 'TheUBootdoc' |
||||
|
||||
# -- Options for LaTeX output --------------------------------------------- |
||||
|
||||
latex_elements = { |
||||
# The paper size ('letterpaper' or 'a4paper'). |
||||
'papersize': 'a4paper', |
||||
|
||||
# The font size ('10pt', '11pt' or '12pt'). |
||||
'pointsize': '8pt', |
||||
|
||||
# Latex figure (float) alignment |
||||
#'figure_align': 'htbp', |
||||
|
||||
# Don't mangle with UTF-8 chars |
||||
'inputenc': '', |
||||
'utf8extra': '', |
||||
|
||||
# Additional stuff for the LaTeX preamble. |
||||
'preamble': ''' |
||||
% Use some font with UTF-8 support with XeLaTeX |
||||
\\usepackage{fontspec} |
||||
\\setsansfont{DejaVu Serif} |
||||
\\setromanfont{DejaVu Sans} |
||||
\\setmonofont{DejaVu Sans Mono} |
||||
|
||||
''' |
||||
} |
||||
|
||||
# Fix reference escape troubles with Sphinx 1.4.x |
||||
if major == 1 and minor > 3: |
||||
latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n' |
||||
|
||||
if major == 1 and minor <= 4: |
||||
latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}' |
||||
elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)): |
||||
latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=1in' |
||||
latex_elements['preamble'] += '\\fvset{fontsize=auto}\n' |
||||
|
||||
# Customize notice background colors on Sphinx < 1.6: |
||||
if major == 1 and minor < 6: |
||||
latex_elements['preamble'] += ''' |
||||
\\usepackage{ifthen} |
||||
|
||||
% Put notes in color and let them be inside a table |
||||
\\definecolor{NoteColor}{RGB}{204,255,255} |
||||
\\definecolor{WarningColor}{RGB}{255,204,204} |
||||
\\definecolor{AttentionColor}{RGB}{255,255,204} |
||||
\\definecolor{ImportantColor}{RGB}{192,255,204} |
||||
\\definecolor{OtherColor}{RGB}{204,204,204} |
||||
\\newlength{\\mynoticelength} |
||||
\\makeatletter\\newenvironment{coloredbox}[1]{% |
||||
\\setlength{\\fboxrule}{1pt} |
||||
\\setlength{\\fboxsep}{7pt} |
||||
\\setlength{\\mynoticelength}{\\linewidth} |
||||
\\addtolength{\\mynoticelength}{-2\\fboxsep} |
||||
\\addtolength{\\mynoticelength}{-2\\fboxrule} |
||||
\\begin{lrbox}{\\@tempboxa}\\begin{minipage}{\\mynoticelength}}{\\end{minipage}\\end{lrbox}% |
||||
\\ifthenelse% |
||||
{\\equal{\\py@noticetype}{note}}% |
||||
{\\colorbox{NoteColor}{\\usebox{\\@tempboxa}}}% |
||||
{% |
||||
\\ifthenelse% |
||||
{\\equal{\\py@noticetype}{warning}}% |
||||
{\\colorbox{WarningColor}{\\usebox{\\@tempboxa}}}% |
||||
{% |
||||
\\ifthenelse% |
||||
{\\equal{\\py@noticetype}{attention}}% |
||||
{\\colorbox{AttentionColor}{\\usebox{\\@tempboxa}}}% |
||||
{% |
||||
\\ifthenelse% |
||||
{\\equal{\\py@noticetype}{important}}% |
||||
{\\colorbox{ImportantColor}{\\usebox{\\@tempboxa}}}% |
||||
{\\colorbox{OtherColor}{\\usebox{\\@tempboxa}}}% |
||||
}% |
||||
}% |
||||
}% |
||||
}\\makeatother |
||||
|
||||
\\makeatletter |
||||
\\renewenvironment{notice}[2]{% |
||||
\\def\\py@noticetype{#1} |
||||
\\begin{coloredbox}{#1} |
||||
\\bf\\it |
||||
\\par\\strong{#2} |
||||
\\csname py@noticestart@#1\\endcsname |
||||
} |
||||
{ |
||||
\\csname py@noticeend@\\py@noticetype\\endcsname |
||||
\\end{coloredbox} |
||||
} |
||||
\\makeatother |
||||
|
||||
''' |
||||
|
||||
# With Sphinx 1.6, it is possible to change the Bg color directly |
||||
# by using: |
||||
# \definecolor{sphinxnoteBgColor}{RGB}{204,255,255} |
||||
# \definecolor{sphinxwarningBgColor}{RGB}{255,204,204} |
||||
# \definecolor{sphinxattentionBgColor}{RGB}{255,255,204} |
||||
# \definecolor{sphinximportantBgColor}{RGB}{192,255,204} |
||||
# |
||||
# However, it require to use sphinx heavy box with: |
||||
# |
||||
# \renewenvironment{sphinxlightbox} {% |
||||
# \\begin{sphinxheavybox} |
||||
# } |
||||
# \\end{sphinxheavybox} |
||||
# } |
||||
# |
||||
# Unfortunately, the implementation is buggy: if a note is inside a |
||||
# table, it isn't displayed well. So, for now, let's use boring |
||||
# black and white notes. |
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples |
||||
# (source start file, target name, title, |
||||
# author, documentclass [howto, manual, or own class]). |
||||
# Sorted in alphabetical order |
||||
latex_documents = [ |
||||
('index', 'u-boot-hacker-manual.tex', 'U-Boot Hacker Manual', |
||||
'The U-Boot development community', 'manual'), |
||||
] |
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of |
||||
# the title page. |
||||
#latex_logo = None |
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts, |
||||
# not chapters. |
||||
#latex_use_parts = False |
||||
|
||||
# If true, show page references after internal links. |
||||
#latex_show_pagerefs = False |
||||
|
||||
# If true, show URL addresses after external links. |
||||
#latex_show_urls = False |
||||
|
||||
# Documents to append as an appendix to all manuals. |
||||
#latex_appendices = [] |
||||
|
||||
# If false, no module index is generated. |
||||
#latex_domain_indices = True |
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------- |
||||
|
||||
# One entry per manual page. List of tuples |
||||
# (source start file, name, description, authors, manual section). |
||||
man_pages = [ |
||||
(master_doc, 'dasuboot', 'The U-Boot Documentation', |
||||
[author], 1) |
||||
] |
||||
|
||||
# If true, show URL addresses after external links. |
||||
#man_show_urls = False |
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------- |
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples |
||||
# (source start file, target name, title, author, |
||||
# dir menu entry, description, category) |
||||
texinfo_documents = [ |
||||
(master_doc, 'DasUBoot', 'The U-Boot Documentation', |
||||
author, 'DasUBoot', 'One line description of project.', |
||||
'Miscellaneous'), |
||||
] |
||||
|
||||
# Documents to append as an appendix to all manuals. |
||||
#texinfo_appendices = [] |
||||
|
||||
# If false, no module index is generated. |
||||
#texinfo_domain_indices = True |
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'. |
||||
#texinfo_show_urls = 'footnote' |
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu. |
||||
#texinfo_no_detailmenu = False |
||||
|
||||
|
||||
# -- Options for Epub output ---------------------------------------------- |
||||
|
||||
# Bibliographic Dublin Core info. |
||||
epub_title = project |
||||
epub_author = author |
||||
epub_publisher = author |
||||
epub_copyright = copyright |
||||
|
||||
# The basename for the epub file. It defaults to the project name. |
||||
#epub_basename = project |
||||
|
||||
# The HTML theme for the epub output. Since the default themes are not |
||||
# optimized for small screen space, using the same theme for HTML and epub |
||||
# output is usually not wise. This defaults to 'epub', a theme designed to save |
||||
# visual space. |
||||
#epub_theme = 'epub' |
||||
|
||||
# The language of the text. It defaults to the language option |
||||
# or 'en' if the language is not set. |
||||
#epub_language = '' |
||||
|
||||
# The scheme of the identifier. Typical schemes are ISBN or URL. |
||||
#epub_scheme = '' |
||||
|
||||
# The unique identifier of the text. This can be a ISBN number |
||||
# or the project homepage. |
||||
#epub_identifier = '' |
||||
|
||||
# A unique identification for the text. |
||||
#epub_uid = '' |
||||
|
||||
# A tuple containing the cover image and cover page html template filenames. |
||||
#epub_cover = () |
||||
|
||||
# A sequence of (type, uri, title) tuples for the guide element of content.opf. |
||||
#epub_guide = () |
||||
|
||||
# HTML files that should be inserted before the pages created by sphinx. |
||||
# The format is a list of tuples containing the path and title. |
||||
#epub_pre_files = [] |
||||
|
||||
# HTML files that should be inserted after the pages created by sphinx. |
||||
# The format is a list of tuples containing the path and title. |
||||
#epub_post_files = [] |
||||
|
||||
# A list of files that should not be packed into the epub file. |
||||
epub_exclude_files = ['search.html'] |
||||
|
||||
# The depth of the table of contents in toc.ncx. |
||||
#epub_tocdepth = 3 |
||||
|
||||
# Allow duplicate toc entries. |
||||
#epub_tocdup = True |
||||
|
||||
# Choose between 'default' and 'includehidden'. |
||||
#epub_tocscope = 'default' |
||||
|
||||
# Fix unsupported image types using the Pillow. |
||||
#epub_fix_images = False |
||||
|
||||
# Scale large images. |
||||
#epub_max_image_width = 0 |
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'. |
||||
#epub_show_urls = 'inline' |
||||
|
||||
# If false, no index is generated. |
||||
#epub_use_index = True |
||||
|
||||
#======= |
||||
# rst2pdf |
||||
# |
||||
# Grouping the document tree into PDF files. List of tuples |
||||
# (source start file, target name, title, author, options). |
||||
# |
||||
# See the Sphinx chapter of http://ralsina.me/static/manual.pdf |
||||
# |
||||
# FIXME: Do not add the index file here; the result will be too big. Adding |
||||
# multiple PDF files here actually tries to get the cross-referencing right |
||||
# *between* PDF files. |
||||
pdf_documents = [ |
||||
('uboot-documentation', u'U-Boot', u'U-Boot', u'J. Random Bozo'), |
||||
] |
||||
|
||||
# kernel-doc extension configuration for running Sphinx directly (e.g. by Read |
||||
# the Docs). In a normal build, these are supplied from the Makefile via command |
||||
# line arguments. |
||||
kerneldoc_bin = '../scripts/kernel-doc' |
||||
kerneldoc_srctree = '..' |
||||
|
||||
# ------------------------------------------------------------------------------ |
||||
# Since loadConfig overwrites settings from the global namespace, it has to be |
||||
# the last statement in the conf.py file |
||||
# ------------------------------------------------------------------------------ |
||||
loadConfig(globals()) |
@ -0,0 +1,117 @@ |
||||
==================== |
||||
U-Boot Hacker Manual |
||||
==================== |
||||
|
||||
Linker-Generated Arrays |
||||
======================= |
||||
|
||||
A linker list is constructed by grouping together linker input |
||||
sections, each containing one entry of the list. Each input section |
||||
contains a constant initialized variable which holds the entry's |
||||
content. Linker list input sections are constructed from the list |
||||
and entry names, plus a prefix which allows grouping all lists |
||||
together. Assuming _list and _entry are the list and entry names, |
||||
then the corresponding input section name is |
||||
|
||||
:: |
||||
|
||||
.u_boot_list_ + 2_ + @_list + _2_ + @_entry |
||||
|
||||
and the C variable name is |
||||
|
||||
:: |
||||
|
||||
_u_boot_list + _2_ + @_list + _2_ + @_entry |
||||
|
||||
This ensures uniqueness for both input section and C variable name. |
||||
|
||||
Note that the names differ only in the first character, "." for the |
||||
section and "_" for the variable, so that the linker cannot confuse |
||||
section and symbol names. From now on, both names will be referred |
||||
to as |
||||
|
||||
:: |
||||
|
||||
%u_boot_list_ + 2_ + @_list + _2_ + @_entry |
||||
|
||||
Entry variables need never be referred to directly. |
||||
|
||||
The naming scheme for input sections allows grouping all linker lists |
||||
into a single linker output section and grouping all entries for a |
||||
single list. |
||||
|
||||
Note the two '_2_' constant components in the names: their presence |
||||
allows putting a start and end symbols around a list, by mapping |
||||
these symbols to sections names with components "1" (before) and |
||||
"3" (after) instead of "2" (within). |
||||
Start and end symbols for a list can generally be defined as |
||||
|
||||
:: |
||||
|
||||
%u_boot_list_2_ + @_list + _1_... |
||||
%u_boot_list_2_ + @_list + _3_... |
||||
|
||||
Start and end symbols for the whole of the linker lists area can be |
||||
defined as |
||||
|
||||
:: |
||||
|
||||
%u_boot_list_1_... |
||||
%u_boot_list_3_... |
||||
|
||||
Here is an example of the sorted sections which result from a list |
||||
"array" made up of three entries : "first", "second" and "third", |
||||
iterated at least once. |
||||
|
||||
:: |
||||
|
||||
.u_boot_list_2_array_1 |
||||
.u_boot_list_2_array_2_first |
||||
.u_boot_list_2_array_2_second |
||||
.u_boot_list_2_array_2_third |
||||
.u_boot_list_2_array_3 |
||||
|
||||
If lists must be divided into sublists (e.g. for iterating only on |
||||
part of a list), one can simply give the list a name of the form |
||||
'outer_2_inner', where 'outer' is the global list name and 'inner' |
||||
is the sub-list name. Iterators for the whole list should use the |
||||
global list name ("outer"); iterators for only a sub-list should use |
||||
the full sub-list name ("outer_2_inner"). |
||||
|
||||
Here is an example of the sections generated from a global list |
||||
named "drivers", two sub-lists named "i2c" and "pci", and iterators |
||||
defined for the whole list and each sub-list: |
||||
|
||||
:: |
||||
|
||||
%u_boot_list_2_drivers_1 |
||||
%u_boot_list_2_drivers_2_i2c_1 |
||||
%u_boot_list_2_drivers_2_i2c_2_first |
||||
%u_boot_list_2_drivers_2_i2c_2_first |
||||
%u_boot_list_2_drivers_2_i2c_2_second |
||||
%u_boot_list_2_drivers_2_i2c_2_third |
||||
%u_boot_list_2_drivers_2_i2c_3 |
||||
%u_boot_list_2_drivers_2_pci_1 |
||||
%u_boot_list_2_drivers_2_pci_2_first |
||||
%u_boot_list_2_drivers_2_pci_2_second |
||||
%u_boot_list_2_drivers_2_pci_2_third |
||||
%u_boot_list_2_drivers_2_pci_3 |
||||
%u_boot_list_2_drivers_3 |
||||
|
||||
.. kernel-doc:: include/linker_lists.h |
||||
:internal: |
||||
|
||||
Serial system |
||||
============= |
||||
|
||||
.. kernel-doc:: drivers/serial/serial.c |
||||
:internal: |
||||
|
||||
The U-Boot EFI subsystem |
||||
======================== |
||||
|
||||
Boot services |
||||
------------- |
||||
|
||||
.. kernel-doc:: lib/efi_loader/efi_boottime.c |
||||
:internal: |
@ -0,0 +1,38 @@ |
||||
# Rules to convert a .h file to inline RST documentation
|
||||
|
||||
SRC_DIR=$(srctree)/Documentation/media
|
||||
PARSER = $(srctree)/Documentation/sphinx/parse-headers.pl
|
||||
API = $(srctree)/include
|
||||
|
||||
FILES = linker_lists.h.rst
|
||||
|
||||
TARGETS := $(addprefix $(BUILDDIR)/, $(FILES))
|
||||
|
||||
gen_rst = \
|
||||
echo ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions; \
|
||||
${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
|
||||
|
||||
quiet_gen_rst = echo ' PARSE $(patsubst $(srctree)/%,%,$<)'; \
|
||||
${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
|
||||
|
||||
silent_gen_rst = ${gen_rst}
|
||||
|
||||
$(BUILDDIR)/linker_lists.h.rst: ${API}/linker_lists.h ${PARSER} $(SRC_DIR)/linker_lists.h.rst.exceptions |
||||
@$($(quiet)gen_rst)
|
||||
|
||||
# Media build rules
|
||||
|
||||
.PHONY: all html epub xml latex |
||||
|
||||
all: $(IMGDOT) $(BUILDDIR) ${TARGETS} |
||||
html: all |
||||
epub: all |
||||
xml: all |
||||
latex: $(IMGPDF) all |
||||
linkcheck: |
||||
|
||||
clean: |
||||
-rm -f $(DOTTGT) $(IMGTGT) ${TARGETS} 2>/dev/null
|
||||
|
||||
$(BUILDDIR): |
||||
$(Q)mkdir -p $@
|
@ -0,0 +1,89 @@ |
||||
/* -*- coding: utf-8; mode: css -*- |
||||
* |
||||
* Sphinx HTML theme customization: read the doc |
||||
* |
||||
*/ |
||||
|
||||
/* Interim: Code-blocks with line nos - lines and line numbers don't line up. |
||||
* see: https://github.com/rtfd/sphinx_rtd_theme/issues/419 |
||||
*/ |
||||
|
||||
div[class^="highlight"] pre { |
||||
line-height: normal; |
||||
} |
||||
.rst-content .highlight > pre { |
||||
line-height: normal; |
||||
} |
||||
|
||||
@media screen { |
||||
|
||||
/* content column |
||||
* |
||||
* RTD theme's default is 800px as max width for the content, but we have |
||||
* tables with tons of columns, which need the full width of the view-port. |
||||
*/ |
||||
|
||||
.wy-nav-content{max-width: none; } |
||||
|
||||
/* table: |
||||
* |
||||
* - Sequences of whitespace should collapse into a single whitespace. |
||||
* - make the overflow auto (scrollbar if needed) |
||||
* - align caption "left" ("center" is unsuitable on vast tables) |
||||
*/ |
||||
|
||||
.wy-table-responsive table td { white-space: normal; } |
||||
.wy-table-responsive { overflow: auto; } |
||||
.rst-content table.docutils caption { text-align: left; font-size: 100%; } |
||||
|
||||
/* captions: |
||||
* |
||||
* - captions should have 100% (not 85%) font size |
||||
* - hide the permalink symbol as long as link is not hovered |
||||
*/ |
||||
|
||||
.toc-title { |
||||
font-size: 150%; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
caption, .wy-table caption, .rst-content table.field-list caption { |
||||
font-size: 100%; |
||||
} |
||||
caption a.headerlink { opacity: 0; } |
||||
caption a.headerlink:hover { opacity: 1; } |
||||
|
||||
/* Menu selection and keystrokes */ |
||||
|
||||
span.menuselection { |
||||
color: blue; |
||||
font-family: "Courier New", Courier, monospace |
||||
} |
||||
|
||||
code.kbd, code.kbd span { |
||||
color: white; |
||||
background-color: darkblue; |
||||
font-weight: bold; |
||||
font-family: "Courier New", Courier, monospace |
||||
} |
||||
|
||||
/* fix bottom margin of lists items */ |
||||
|
||||
.rst-content .section ul li:last-child, .rst-content .section ul li p:last-child { |
||||
margin-bottom: 12px; |
||||
} |
||||
|
||||
/* inline literal: drop the borderbox, padding and red color */ |
||||
|
||||
code, .rst-content tt, .rst-content code { |
||||
color: inherit; |
||||
border: none; |
||||
padding: unset; |
||||
background: inherit; |
||||
font-size: 85%; |
||||
} |
||||
|
||||
.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal { |
||||
color: inherit; |
||||
} |
||||
} |
@ -0,0 +1,165 @@ |
||||
# -*- coding: utf-8; mode: python -*- |
||||
# pylint: disable=W0141,C0113,C0103,C0325 |
||||
u""" |
||||
cdomain |
||||
~~~~~~~ |
||||
|
||||
Replacement for the sphinx c-domain. |
||||
|
||||
:copyright: Copyright (C) 2016 Markus Heiser |
||||
:license: GPL Version 2, June 1991 see Linux/COPYING for details. |
||||
|
||||
List of customizations: |
||||
|
||||
* Moved the *duplicate C object description* warnings for function |
||||
declarations in the nitpicky mode. See Sphinx documentation for |
||||
the config values for ``nitpick`` and ``nitpick_ignore``. |
||||
|
||||
* Add option 'name' to the "c:function:" directive. With option 'name' the |
||||
ref-name of a function can be modified. E.g.:: |
||||
|
||||
.. c:function:: int ioctl( int fd, int request ) |
||||
:name: VIDIOC_LOG_STATUS |
||||
|
||||
The func-name (e.g. ioctl) remains in the output but the ref-name changed |
||||
from 'ioctl' to 'VIDIOC_LOG_STATUS'. The function is referenced by:: |
||||
|
||||
* :c:func:`VIDIOC_LOG_STATUS` or |
||||
* :any:`VIDIOC_LOG_STATUS` (``:any:`` needs sphinx 1.3) |
||||
|
||||
* Handle signatures of function-like macros well. Don't try to deduce |
||||
arguments types of function-like macros. |
||||
|
||||
""" |
||||
|
||||
from docutils import nodes |
||||
from docutils.parsers.rst import directives |
||||
|
||||
import sphinx |
||||
from sphinx import addnodes |
||||
from sphinx.domains.c import c_funcptr_sig_re, c_sig_re |
||||
from sphinx.domains.c import CObject as Base_CObject |
||||
from sphinx.domains.c import CDomain as Base_CDomain |
||||
|
||||
__version__ = '1.0' |
||||
|
||||
# Get Sphinx version |
||||
major, minor, patch = sphinx.version_info[:3] |
||||
|
||||
def setup(app): |
||||
|
||||
app.override_domain(CDomain) |
||||
|
||||
return dict( |
||||
version = __version__, |
||||
parallel_read_safe = True, |
||||
parallel_write_safe = True |
||||
) |
||||
|
||||
class CObject(Base_CObject): |
||||
|
||||
""" |
||||
Description of a C language object. |
||||
""" |
||||
option_spec = { |
||||
"name" : directives.unchanged |
||||
} |
||||
|
||||
def handle_func_like_macro(self, sig, signode): |
||||
u"""Handles signatures of function-like macros. |
||||
|
||||
If the objtype is 'function' and the the signature ``sig`` is a |
||||
function-like macro, the name of the macro is returned. Otherwise |
||||
``False`` is returned. """ |
||||
|
||||
if not self.objtype == 'function': |
||||
return False |
||||
|
||||
m = c_funcptr_sig_re.match(sig) |
||||
if m is None: |
||||
m = c_sig_re.match(sig) |
||||
if m is None: |
||||
raise ValueError('no match') |
||||
|
||||
rettype, fullname, arglist, _const = m.groups() |
||||
arglist = arglist.strip() |
||||
if rettype or not arglist: |
||||
return False |
||||
|
||||
arglist = arglist.replace('`', '').replace('\\ ', '') # remove markup |
||||
arglist = [a.strip() for a in arglist.split(",")] |
||||
|
||||
# has the first argument a type? |
||||
if len(arglist[0].split(" ")) > 1: |
||||
return False |
||||
|
||||
# This is a function-like macro, it's arguments are typeless! |
||||
signode += addnodes.desc_name(fullname, fullname) |
||||
paramlist = addnodes.desc_parameterlist() |
||||
signode += paramlist |
||||
|
||||
for argname in arglist: |
||||
param = addnodes.desc_parameter('', '', noemph=True) |
||||
# separate by non-breaking space in the output |
||||
param += nodes.emphasis(argname, argname) |
||||
paramlist += param |
||||
|
||||
return fullname |
||||
|
||||
def handle_signature(self, sig, signode): |
||||
"""Transform a C signature into RST nodes.""" |
||||
|
||||
fullname = self.handle_func_like_macro(sig, signode) |
||||
if not fullname: |
||||
fullname = super(CObject, self).handle_signature(sig, signode) |
||||
|
||||
if "name" in self.options: |
||||
if self.objtype == 'function': |
||||
fullname = self.options["name"] |
||||
else: |
||||
# FIXME: handle :name: value of other declaration types? |
||||
pass |
||||
return fullname |
||||
|
||||
def add_target_and_index(self, name, sig, signode): |
||||
# for C API items we add a prefix since names are usually not qualified |
||||
# by a module name and so easily clash with e.g. section titles |
||||
targetname = 'c.' + name |
||||
if targetname not in self.state.document.ids: |
||||
signode['names'].append(targetname) |
||||
signode['ids'].append(targetname) |
||||
signode['first'] = (not self.names) |
||||
self.state.document.note_explicit_target(signode) |
||||
inv = self.env.domaindata['c']['objects'] |
||||
if (name in inv and self.env.config.nitpicky): |
||||
if self.objtype == 'function': |
||||
if ('c:func', name) not in self.env.config.nitpick_ignore: |
||||
self.state_machine.reporter.warning( |
||||
'duplicate C object description of %s, ' % name + |
||||
'other instance in ' + self.env.doc2path(inv[name][0]), |
||||
line=self.lineno) |
||||
inv[name] = (self.env.docname, self.objtype) |
||||
|
||||
indextext = self.get_index_text(name) |
||||
if indextext: |
||||
if major == 1 and minor < 4: |
||||
# indexnode's tuple changed in 1.4 |
||||
# https://github.com/sphinx-doc/sphinx/commit/e6a5a3a92e938fcd75866b4227db9e0524d58f7c |
||||
self.indexnode['entries'].append( |
||||
('single', indextext, targetname, '')) |
||||
else: |
||||
self.indexnode['entries'].append( |
||||
('single', indextext, targetname, '', None)) |
||||
|
||||
class CDomain(Base_CDomain): |
||||
|
||||
"""C language domain.""" |
||||
name = 'c' |
||||
label = 'C' |
||||
directives = { |
||||
'function': CObject, |
||||
'member': CObject, |
||||
'macro': CObject, |
||||
'type': CObject, |
||||
'var': CObject, |
||||
} |
@ -0,0 +1,190 @@ |
||||
#!/usr/bin/env python3 |
||||
# -*- coding: utf-8; mode: python -*- |
||||
# pylint: disable=R0903, C0330, R0914, R0912, E0401 |
||||
|
||||
u""" |
||||
kernel-include |
||||
~~~~~~~~~~~~~~ |
||||
|
||||
Implementation of the ``kernel-include`` reST-directive. |
||||
|
||||
:copyright: Copyright (C) 2016 Markus Heiser |
||||
:license: GPL Version 2, June 1991 see linux/COPYING for details. |
||||
|
||||
The ``kernel-include`` reST-directive is a replacement for the ``include`` |
||||
directive. The ``kernel-include`` directive expand environment variables in |
||||
the path name and allows to include files from arbitrary locations. |
||||
|
||||
.. hint:: |
||||
|
||||
Including files from arbitrary locations (e.g. from ``/etc``) is a |
||||
security risk for builders. This is why the ``include`` directive from |
||||
docutils *prohibit* pathnames pointing to locations *above* the filesystem |
||||
tree where the reST document with the include directive is placed. |
||||
|
||||
Substrings of the form $name or ${name} are replaced by the value of |
||||
environment variable name. Malformed variable names and references to |
||||
non-existing variables are left unchanged. |
||||
""" |
||||
|
||||
# ============================================================================== |
||||
# imports |
||||
# ============================================================================== |
||||
|
||||
import os.path |
||||
|
||||
from docutils import io, nodes, statemachine |
||||
from docutils.utils.error_reporting import SafeString, ErrorString |
||||
from docutils.parsers.rst import directives |
||||
from docutils.parsers.rst.directives.body import CodeBlock, NumberLines |
||||
from docutils.parsers.rst.directives.misc import Include |
||||
|
||||
__version__ = '1.0' |
||||
|
||||
# ============================================================================== |
||||
def setup(app): |
||||
# ============================================================================== |
||||
|
||||
app.add_directive("kernel-include", KernelInclude) |
||||
return dict( |
||||
version = __version__, |
||||
parallel_read_safe = True, |
||||
parallel_write_safe = True |
||||
) |
||||
|
||||
# ============================================================================== |
||||
class KernelInclude(Include): |
||||
# ============================================================================== |
||||
|
||||
u"""KernelInclude (``kernel-include``) directive""" |
||||
|
||||
def run(self): |
||||
path = os.path.realpath( |
||||
os.path.expandvars(self.arguments[0])) |
||||
|
||||
# to get a bit security back, prohibit /etc: |
||||
if path.startswith(os.sep + "etc"): |
||||
raise self.severe( |
||||
'Problems with "%s" directive, prohibited path: %s' |
||||
% (self.name, path)) |
||||
|
||||
self.arguments[0] = path |
||||
|
||||
#return super(KernelInclude, self).run() # won't work, see HINTs in _run() |
||||
return self._run() |
||||
|
||||
def _run(self): |
||||
"""Include a file as part of the content of this reST file.""" |
||||
|
||||
# HINT: I had to copy&paste the whole Include.run method. I'am not happy |
||||
# with this, but due to security reasons, the Include.run method does |
||||
# not allow absolute or relative pathnames pointing to locations *above* |
||||
# the filesystem tree where the reST document is placed. |
||||
|
||||
if not self.state.document.settings.file_insertion_enabled: |
||||
raise self.warning('"%s" directive disabled.' % self.name) |
||||
source = self.state_machine.input_lines.source( |
||||
self.lineno - self.state_machine.input_offset - 1) |
||||
source_dir = os.path.dirname(os.path.abspath(source)) |
||||
path = directives.path(self.arguments[0]) |
||||
if path.startswith('<') and path.endswith('>'): |
||||
path = os.path.join(self.standard_include_path, path[1:-1]) |
||||
path = os.path.normpath(os.path.join(source_dir, path)) |
||||
|
||||
# HINT: this is the only line I had to change / commented out: |
||||
#path = utils.relative_path(None, path) |
||||
|
||||
path = nodes.reprunicode(path) |
||||
encoding = self.options.get( |
||||
'encoding', self.state.document.settings.input_encoding) |
||||
e_handler=self.state.document.settings.input_encoding_error_handler |
||||
tab_width = self.options.get( |
||||
'tab-width', self.state.document.settings.tab_width) |
||||
try: |
||||
self.state.document.settings.record_dependencies.add(path) |
||||
include_file = io.FileInput(source_path=path, |
||||
encoding=encoding, |
||||
error_handler=e_handler) |
||||
except UnicodeEncodeError as error: |
||||
raise self.severe('Problems with "%s" directive path:\n' |
||||
'Cannot encode input file path "%s" ' |
||||
'(wrong locale?).' % |
||||
(self.name, SafeString(path))) |
||||
except IOError as error: |
||||
raise self.severe('Problems with "%s" directive path:\n%s.' % |
||||
(self.name, ErrorString(error))) |
||||
startline = self.options.get('start-line', None) |
||||
endline = self.options.get('end-line', None) |
||||
try: |
||||
if startline or (endline is not None): |
||||
lines = include_file.readlines() |
||||
rawtext = ''.join(lines[startline:endline]) |
||||
else: |
||||
rawtext = include_file.read() |
||||
except UnicodeError as error: |
||||
raise self.severe('Problem with "%s" directive:\n%s' % |
||||
(self.name, ErrorString(error))) |
||||
# start-after/end-before: no restrictions on newlines in match-text, |
||||
# and no restrictions on matching inside lines vs. line boundaries |
||||
after_text = self.options.get('start-after', None) |
||||
if after_text: |
||||
# skip content in rawtext before *and incl.* a matching text |
||||
after_index = rawtext.find(after_text) |
||||
if after_index < 0: |
||||
raise self.severe('Problem with "start-after" option of "%s" ' |
||||
'directive:\nText not found.' % self.name) |
||||
rawtext = rawtext[after_index + len(after_text):] |
||||
before_text = self.options.get('end-before', None) |
||||
if before_text: |
||||
# skip content in rawtext after *and incl.* a matching text |
||||
before_index = rawtext.find(before_text) |
||||
if before_index < 0: |
||||
raise self.severe('Problem with "end-before" option of "%s" ' |
||||
'directive:\nText not found.' % self.name) |
||||
rawtext = rawtext[:before_index] |
||||
|
||||
include_lines = statemachine.string2lines(rawtext, tab_width, |
||||
convert_whitespace=True) |
||||
if 'literal' in self.options: |
||||
# Convert tabs to spaces, if `tab_width` is positive. |
||||
if tab_width >= 0: |
||||
text = rawtext.expandtabs(tab_width) |
||||
else: |
||||
text = rawtext |
||||
literal_block = nodes.literal_block(rawtext, source=path, |
||||
classes=self.options.get('class', [])) |
||||
literal_block.line = 1 |
||||
self.add_name(literal_block) |
||||
if 'number-lines' in self.options: |
||||
try: |
||||
startline = int(self.options['number-lines'] or 1) |
||||
except ValueError: |
||||
raise self.error(':number-lines: with non-integer ' |
||||
'start value') |
||||
endline = startline + len(include_lines) |
||||
if text.endswith('\n'): |
||||
text = text[:-1] |
||||
tokens = NumberLines([([], text)], startline, endline) |
||||
for classes, value in tokens: |
||||
if classes: |
||||
literal_block += nodes.inline(value, value, |
||||
classes=classes) |
||||
else: |
||||
literal_block += nodes.Text(value, value) |
||||
else: |
||||
literal_block += nodes.Text(text, text) |
||||
return [literal_block] |
||||
if 'code' in self.options: |
||||
self.options['source'] = path |
||||
codeblock = CodeBlock(self.name, |
||||
[self.options.pop('code')], # arguments |
||||
self.options, |
||||
include_lines, # content |
||||
self.lineno, |
||||
self.content_offset, |
||||
self.block_text, |
||||
self.state, |
||||
self.state_machine) |
||||
return codeblock.run() |
||||
self.state_machine.insert_input(include_lines, path) |
||||
return [] |
@ -0,0 +1,146 @@ |
||||
# 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> |
||||
# |
||||
# Please make sure this works on both python2 and python3. |
||||
# |
||||
|
||||
import codecs |
||||
import os |
||||
import subprocess |
||||
import sys |
||||
import re |
||||
import glob |
||||
|
||||
from docutils import nodes, statemachine |
||||
from docutils.statemachine import ViewList |
||||
from docutils.parsers.rst import directives, Directive |
||||
from sphinx.ext.autodoc import AutodocReporter |
||||
|
||||
__version__ = '1.0' |
||||
|
||||
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, |
||||
'export': directives.unchanged, |
||||
'internal': directives.unchanged, |
||||
} |
||||
has_content = False |
||||
|
||||
def run(self): |
||||
env = self.state.document.settings.env |
||||
cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] |
||||
|
||||
filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] |
||||
export_file_patterns = [] |
||||
|
||||
# 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'] |
||||
export_file_patterns = str(self.options.get('export')).split() |
||||
elif 'internal' in self.options: |
||||
cmd += ['-internal'] |
||||
export_file_patterns = str(self.options.get('internal')).split() |
||||
elif 'doc' in self.options: |
||||
cmd += ['-function', str(self.options.get('doc'))] |
||||
elif 'functions' in self.options: |
||||
for f in str(self.options.get('functions')).split(): |
||||
cmd += ['-function', f] |
||||
|
||||
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] |
||||
|
||||
cmd += [filename] |
||||
|
||||
try: |
||||
env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) |
||||
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
||||
out, err = p.communicate() |
||||
|
||||
out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') |
||||
|
||||
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) |
||||
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: |
||||
result.append(line, filename, lineoffset) |
||||
lineoffset += 1 |
||||
|
||||
node = nodes.section() |
||||
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 |
||||
|
||||
return node.children |
||||
|
||||
except Exception as e: # pylint: disable=W0703 |
||||
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) |
||||
|
||||
return dict( |
||||
version = __version__, |
||||
parallel_read_safe = True, |
||||
parallel_write_safe = True |
||||
) |
@ -0,0 +1,551 @@ |
||||
# -*- coding: utf-8; mode: python -*- |
||||
# pylint: disable=C0103, R0903, R0912, R0915 |
||||
u""" |
||||
scalable figure and image handling |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Sphinx extension which implements scalable image handling. |
||||
|
||||
:copyright: Copyright (C) 2016 Markus Heiser |
||||
:license: GPL Version 2, June 1991 see Linux/COPYING for details. |
||||
|
||||
The build for image formats depend on image's source format and output's |
||||
destination format. This extension implement methods to simplify image |
||||
handling from the author's POV. Directives like ``kernel-figure`` implement |
||||
methods *to* always get the best output-format even if some tools are not |
||||
installed. For more details take a look at ``convert_image(...)`` which is |
||||
the core of all conversions. |
||||
|
||||
* ``.. kernel-image``: for image handling / a ``.. image::`` replacement |
||||
|
||||
* ``.. kernel-figure``: for figure handling / a ``.. figure::`` replacement |
||||
|
||||
* ``.. kernel-render``: for render markup / a concept to embed *render* |
||||
markups (or languages). Supported markups (see ``RENDER_MARKUP_EXT``) |
||||
|
||||
- ``DOT``: render embedded Graphviz's **DOC** |
||||
- ``SVG``: render embedded Scalable Vector Graphics (**SVG**) |
||||
- ... *developable* |
||||
|
||||
Used tools: |
||||
|
||||
* ``dot(1)``: Graphviz (http://www.graphviz.org). If Graphviz is not |
||||
available, the DOT language is inserted as literal-block. |
||||
|
||||
* SVG to PDF: To generate PDF, you need at least one of this tools: |
||||
|
||||
- ``convert(1)``: ImageMagick (https://www.imagemagick.org) |
||||
|
||||
List of customizations: |
||||
|
||||
* generate PDF from SVG / used by PDF (LaTeX) builder |
||||
|
||||
* generate SVG (html-builder) and PDF (latex-builder) from DOT files. |
||||
DOT: see http://www.graphviz.org/content/dot-language |
||||
|
||||
""" |
||||
|
||||
import os |
||||
from os import path |
||||
import subprocess |
||||
from hashlib import sha1 |
||||
import sys |
||||
|
||||
from docutils import nodes |
||||
from docutils.statemachine import ViewList |
||||
from docutils.parsers.rst import directives |
||||
from docutils.parsers.rst.directives import images |
||||
import sphinx |
||||
|
||||
from sphinx.util.nodes import clean_astext |
||||
from six import iteritems |
||||
|
||||
PY3 = sys.version_info[0] == 3 |
||||
|
||||
if PY3: |
||||
_unicode = str |
||||
else: |
||||
_unicode = unicode |
||||
|
||||
# Get Sphinx version |
||||
major, minor, patch = sphinx.version_info[:3] |
||||
if major == 1 and minor > 3: |
||||
# patches.Figure only landed in Sphinx 1.4 |
||||
from sphinx.directives.patches import Figure # pylint: disable=C0413 |
||||
else: |
||||
Figure = images.Figure |
||||
|
||||
__version__ = '1.0.0' |
||||
|
||||
# simple helper |
||||
# ------------- |
||||
|
||||
def which(cmd): |
||||
"""Searches the ``cmd`` in the ``PATH`` environment. |
||||
|
||||
This *which* searches the PATH for executable ``cmd`` . First match is |
||||
returned, if nothing is found, ``None` is returned. |
||||
""" |
||||
envpath = os.environ.get('PATH', None) or os.defpath |
||||
for folder in envpath.split(os.pathsep): |
||||
fname = folder + os.sep + cmd |
||||
if path.isfile(fname): |
||||
return fname |
||||
|
||||
def mkdir(folder, mode=0o775): |
||||
if not path.isdir(folder): |
||||
os.makedirs(folder, mode) |
||||
|
||||
def file2literal(fname): |
||||
with open(fname, "r") as src: |
||||
data = src.read() |
||||
node = nodes.literal_block(data, data) |
||||
return node |
||||
|
||||
def isNewer(path1, path2): |
||||
"""Returns True if ``path1`` is newer than ``path2`` |
||||
|
||||
If ``path1`` exists and is newer than ``path2`` the function returns |
||||
``True`` is returned otherwise ``False`` |
||||
""" |
||||
return (path.exists(path1) |
||||
and os.stat(path1).st_ctime > os.stat(path2).st_ctime) |
||||
|
||||
def pass_handle(self, node): # pylint: disable=W0613 |
||||
pass |
||||
|
||||
# setup conversion tools and sphinx extension |
||||
# ------------------------------------------- |
||||
|
||||
# Graphviz's dot(1) support |
||||
dot_cmd = None |
||||
|
||||
# ImageMagick' convert(1) support |
||||
convert_cmd = None |
||||
|
||||
|
||||
def setup(app): |
||||
# check toolchain first |
||||
app.connect('builder-inited', setupTools) |
||||
|
||||
# image handling |
||||
app.add_directive("kernel-image", KernelImage) |
||||
app.add_node(kernel_image, |
||||
html = (visit_kernel_image, pass_handle), |
||||
latex = (visit_kernel_image, pass_handle), |
||||
texinfo = (visit_kernel_image, pass_handle), |
||||
text = (visit_kernel_image, pass_handle), |
||||
man = (visit_kernel_image, pass_handle), ) |
||||
|
||||
# figure handling |
||||
app.add_directive("kernel-figure", KernelFigure) |
||||
app.add_node(kernel_figure, |
||||
html = (visit_kernel_figure, pass_handle), |
||||
latex = (visit_kernel_figure, pass_handle), |
||||
texinfo = (visit_kernel_figure, pass_handle), |
||||
text = (visit_kernel_figure, pass_handle), |
||||
man = (visit_kernel_figure, pass_handle), ) |
||||
|
||||
# render handling |
||||
app.add_directive('kernel-render', KernelRender) |
||||
app.add_node(kernel_render, |
||||
html = (visit_kernel_render, pass_handle), |
||||
latex = (visit_kernel_render, pass_handle), |
||||
texinfo = (visit_kernel_render, pass_handle), |
||||
text = (visit_kernel_render, pass_handle), |
||||
man = (visit_kernel_render, pass_handle), ) |
||||
|
||||
app.connect('doctree-read', add_kernel_figure_to_std_domain) |
||||
|
||||
return dict( |
||||
version = __version__, |
||||
parallel_read_safe = True, |
||||
parallel_write_safe = True |
||||
) |
||||
|
||||
|
||||
def setupTools(app): |
||||
u""" |
||||
Check available build tools and log some *verbose* messages. |
||||
|
||||
This function is called once, when the builder is initiated. |
||||
""" |
||||
global dot_cmd, convert_cmd # pylint: disable=W0603 |
||||
app.verbose("kfigure: check installed tools ...") |
||||
|
||||
dot_cmd = which('dot') |
||||
convert_cmd = which('convert') |
||||
|
||||
if dot_cmd: |
||||
app.verbose("use dot(1) from: " + dot_cmd) |
||||
else: |
||||
app.warn("dot(1) not found, for better output quality install " |
||||
"graphviz from http://www.graphviz.org") |
||||
if convert_cmd: |
||||
app.verbose("use convert(1) from: " + convert_cmd) |
||||
else: |
||||
app.warn( |
||||
"convert(1) not found, for SVG to PDF conversion install " |
||||
"ImageMagick (https://www.imagemagick.org)") |
||||
|
||||
|
||||
# integrate conversion tools |
||||
# -------------------------- |
||||
|
||||
RENDER_MARKUP_EXT = { |
||||
# The '.ext' must be handled by convert_image(..) function's *in_ext* input. |
||||
# <name> : <.ext> |
||||
'DOT' : '.dot', |
||||
'SVG' : '.svg' |
||||
} |
||||
|
||||
def convert_image(img_node, translator, src_fname=None): |
||||
"""Convert a image node for the builder. |
||||
|
||||
Different builder prefer different image formats, e.g. *latex* builder |
||||
prefer PDF while *html* builder prefer SVG format for images. |
||||
|
||||
This function handles output image formats in dependence of source the |
||||
format (of the image) and the translator's output format. |
||||
""" |
||||
app = translator.builder.app |
||||
|
||||
fname, in_ext = path.splitext(path.basename(img_node['uri'])) |
||||
if src_fname is None: |
||||
src_fname = path.join(translator.builder.srcdir, img_node['uri']) |
||||
if not path.exists(src_fname): |
||||
src_fname = path.join(translator.builder.outdir, img_node['uri']) |
||||
|
||||
dst_fname = None |
||||
|
||||
# in kernel builds, use 'make SPHINXOPTS=-v' to see verbose messages |
||||
|
||||
app.verbose('assert best format for: ' + img_node['uri']) |
||||
|
||||
if in_ext == '.dot': |
||||
|
||||
if not dot_cmd: |
||||
app.verbose("dot from graphviz not available / include DOT raw.") |
||||
img_node.replace_self(file2literal(src_fname)) |
||||
|
||||
elif translator.builder.format == 'latex': |
||||
dst_fname = path.join(translator.builder.outdir, fname + '.pdf') |
||||
img_node['uri'] = fname + '.pdf' |
||||
img_node['candidates'] = {'*': fname + '.pdf'} |
||||
|
||||
|
||||
elif translator.builder.format == 'html': |
||||
dst_fname = path.join( |
||||
translator.builder.outdir, |
||||
translator.builder.imagedir, |
||||
fname + '.svg') |
||||
img_node['uri'] = path.join( |
||||
translator.builder.imgpath, fname + '.svg') |
||||
img_node['candidates'] = { |
||||
'*': path.join(translator.builder.imgpath, fname + '.svg')} |
||||
|
||||
else: |
||||
# all other builder formats will include DOT as raw |
||||
img_node.replace_self(file2literal(src_fname)) |
||||
|
||||
elif in_ext == '.svg': |
||||
|
||||
if translator.builder.format == 'latex': |
||||
if convert_cmd is None: |
||||
app.verbose("no SVG to PDF conversion available / include SVG raw.") |
||||
img_node.replace_self(file2literal(src_fname)) |
||||
else: |
||||
dst_fname = path.join(translator.builder.outdir, fname + '.pdf') |
||||
img_node['uri'] = fname + '.pdf' |
||||
img_node['candidates'] = {'*': fname + '.pdf'} |
||||
|
||||
if dst_fname: |
||||
# the builder needs not to copy one more time, so pop it if exists. |
||||
translator.builder.images.pop(img_node['uri'], None) |
||||
_name = dst_fname[len(translator.builder.outdir) + 1:] |
||||
|
||||
if isNewer(dst_fname, src_fname): |
||||
app.verbose("convert: {out}/%s already exists and is newer" % _name) |
||||
|
||||
else: |
||||
ok = False |
||||
mkdir(path.dirname(dst_fname)) |
||||
|
||||
if in_ext == '.dot': |
||||
app.verbose('convert DOT to: {out}/' + _name) |
||||
ok = dot2format(app, src_fname, dst_fname) |
||||
|
||||
elif in_ext == '.svg': |
||||
app.verbose('convert SVG to: {out}/' + _name) |
||||
ok = svg2pdf(app, src_fname, dst_fname) |
||||
|
||||
if not ok: |
||||
img_node.replace_self(file2literal(src_fname)) |
||||
|
||||
|
||||
def dot2format(app, dot_fname, out_fname): |
||||
"""Converts DOT file to ``out_fname`` using ``dot(1)``. |
||||
|
||||
* ``dot_fname`` pathname of the input DOT file, including extension ``.dot`` |
||||
* ``out_fname`` pathname of the output file, including format extension |
||||
|
||||
The *format extension* depends on the ``dot`` command (see ``man dot`` |
||||
option ``-Txxx``). Normally you will use one of the following extensions: |
||||
|
||||
- ``.ps`` for PostScript, |
||||
- ``.svg`` or ``svgz`` for Structured Vector Graphics, |
||||
- ``.fig`` for XFIG graphics and |
||||
- ``.png`` or ``gif`` for common bitmap graphics. |
||||
|
||||
""" |
||||
out_format = path.splitext(out_fname)[1][1:] |
||||
cmd = [dot_cmd, '-T%s' % out_format, dot_fname] |
||||
exit_code = 42 |
||||
|
||||
with open(out_fname, "w") as out: |
||||
exit_code = subprocess.call(cmd, stdout = out) |
||||
if exit_code != 0: |
||||
app.warn("Error #%d when calling: %s" % (exit_code, " ".join(cmd))) |
||||
return bool(exit_code == 0) |
||||
|
||||
def svg2pdf(app, svg_fname, pdf_fname): |
||||
"""Converts SVG to PDF with ``convert(1)`` command. |
||||
|
||||
Uses ``convert(1)`` from ImageMagick (https://www.imagemagick.org) for |
||||
conversion. Returns ``True`` on success and ``False`` if an error occurred. |
||||
|
||||
* ``svg_fname`` pathname of the input SVG file with extension (``.svg``) |
||||
* ``pdf_name`` pathname of the output PDF file with extension (``.pdf``) |
||||
|
||||
""" |
||||
cmd = [convert_cmd, svg_fname, pdf_fname] |
||||
# use stdout and stderr from parent |
||||
exit_code = subprocess.call(cmd) |
||||
if exit_code != 0: |
||||
app.warn("Error #%d when calling: %s" % (exit_code, " ".join(cmd))) |
||||
return bool(exit_code == 0) |
||||
|
||||
|
||||
# image handling |
||||
# --------------------- |
||||
|
||||
def visit_kernel_image(self, node): # pylint: disable=W0613 |
||||
"""Visitor of the ``kernel_image`` Node. |
||||
|
||||
Handles the ``image`` child-node with the ``convert_image(...)``. |
||||
""" |
||||
img_node = node[0] |
||||
convert_image(img_node, self) |
||||
|
||||
class kernel_image(nodes.image): |
||||
"""Node for ``kernel-image`` directive.""" |
||||
pass |
||||
|
||||
class KernelImage(images.Image): |
||||
u"""KernelImage directive |
||||
|
||||
Earns everything from ``.. image::`` directive, except *remote URI* and |
||||
*glob* pattern. The KernelImage wraps a image node into a |
||||
kernel_image node. See ``visit_kernel_image``. |
||||
""" |
||||
|
||||
def run(self): |
||||
uri = self.arguments[0] |
||||
if uri.endswith('.*') or uri.find('://') != -1: |
||||
raise self.severe( |
||||
'Error in "%s: %s": glob pattern and remote images are not allowed' |
||||
% (self.name, uri)) |
||||
result = images.Image.run(self) |
||||
if len(result) == 2 or isinstance(result[0], nodes.system_message): |
||||
return result |
||||
(image_node,) = result |
||||
# wrap image node into a kernel_image node / see visitors |
||||
node = kernel_image('', image_node) |
||||
return [node] |
||||
|
||||
# figure handling |
||||
# --------------------- |
||||
|
||||
def visit_kernel_figure(self, node): # pylint: disable=W0613 |
||||
"""Visitor of the ``kernel_figure`` Node. |
||||
|
||||
Handles the ``image`` child-node with the ``convert_image(...)``. |
||||
""" |
||||
img_node = node[0][0] |
||||
convert_image(img_node, self) |
||||
|
||||
class kernel_figure(nodes.figure): |
||||
"""Node for ``kernel-figure`` directive.""" |
||||
|
||||
class KernelFigure(Figure): |
||||
u"""KernelImage directive |
||||
|
||||
Earns everything from ``.. figure::`` directive, except *remote URI* and |
||||
*glob* pattern. The KernelFigure wraps a figure node into a kernel_figure |
||||
node. See ``visit_kernel_figure``. |
||||
""" |
||||
|
||||
def run(self): |
||||
uri = self.arguments[0] |
||||
if uri.endswith('.*') or uri.find('://') != -1: |
||||
raise self.severe( |
||||
'Error in "%s: %s":' |
||||
' glob pattern and remote images are not allowed' |
||||
% (self.name, uri)) |
||||
result = Figure.run(self) |
||||
if len(result) == 2 or isinstance(result[0], nodes.system_message): |
||||
return result |
||||
(figure_node,) = result |
||||
# wrap figure node into a kernel_figure node / see visitors |
||||
node = kernel_figure('', figure_node) |
||||
return [node] |
||||
|
||||
|
||||
# render handling |
||||
# --------------------- |
||||
|
||||
def visit_kernel_render(self, node): |
||||
"""Visitor of the ``kernel_render`` Node. |
||||
|
||||
If rendering tools available, save the markup of the ``literal_block`` child |
||||
node into a file and replace the ``literal_block`` node with a new created |
||||
``image`` node, pointing to the saved markup file. Afterwards, handle the |
||||
image child-node with the ``convert_image(...)``. |
||||
""" |
||||
app = self.builder.app |
||||
srclang = node.get('srclang') |
||||
|
||||
app.verbose('visit kernel-render node lang: "%s"' % (srclang)) |
||||
|
||||
tmp_ext = RENDER_MARKUP_EXT.get(srclang, None) |
||||
if tmp_ext is None: |
||||
app.warn('kernel-render: "%s" unknown / include raw.' % (srclang)) |
||||
return |
||||
|
||||
if not dot_cmd and tmp_ext == '.dot': |
||||
app.verbose("dot from graphviz not available / include raw.") |
||||
return |
||||
|
||||
literal_block = node[0] |
||||
|
||||
code = literal_block.astext() |
||||
hashobj = code.encode('utf-8') # str(node.attributes) |
||||
fname = path.join('%s-%s' % (srclang, sha1(hashobj).hexdigest())) |
||||
|
||||
tmp_fname = path.join( |
||||
self.builder.outdir, self.builder.imagedir, fname + tmp_ext) |
||||
|
||||
if not path.isfile(tmp_fname): |
||||
mkdir(path.dirname(tmp_fname)) |
||||
with open(tmp_fname, "w") as out: |
||||
out.write(code) |
||||
|
||||
img_node = nodes.image(node.rawsource, **node.attributes) |
||||
img_node['uri'] = path.join(self.builder.imgpath, fname + tmp_ext) |
||||
img_node['candidates'] = { |
||||
'*': path.join(self.builder.imgpath, fname + tmp_ext)} |
||||
|
||||
literal_block.replace_self(img_node) |
||||
convert_image(img_node, self, tmp_fname) |
||||
|
||||
|
||||
class kernel_render(nodes.General, nodes.Inline, nodes.Element): |
||||
"""Node for ``kernel-render`` directive.""" |
||||
pass |
||||
|
||||
class KernelRender(Figure): |
||||
u"""KernelRender directive |
||||
|
||||
Render content by external tool. Has all the options known from the |
||||
*figure* directive, plus option ``caption``. If ``caption`` has a |
||||
value, a figure node with the *caption* is inserted. If not, a image node is |
||||
inserted. |
||||
|
||||
The KernelRender directive wraps the text of the directive into a |
||||
literal_block node and wraps it into a kernel_render node. See |
||||
``visit_kernel_render``. |
||||
""" |
||||
has_content = True |
||||
required_arguments = 1 |
||||
optional_arguments = 0 |
||||
final_argument_whitespace = False |
||||
|
||||
# earn options from 'figure' |
||||
option_spec = Figure.option_spec.copy() |
||||
option_spec['caption'] = directives.unchanged |
||||
|
||||
def run(self): |
||||
return [self.build_node()] |
||||
|
||||
def build_node(self): |
||||
|
||||
srclang = self.arguments[0].strip() |
||||
if srclang not in RENDER_MARKUP_EXT.keys(): |
||||
return [self.state_machine.reporter.warning( |
||||
'Unknown source language "%s", use one of: %s.' % ( |
||||
srclang, ",".join(RENDER_MARKUP_EXT.keys())), |
||||
line=self.lineno)] |
||||
|
||||
code = '\n'.join(self.content) |
||||
if not code.strip(): |
||||
return [self.state_machine.reporter.warning( |
||||
'Ignoring "%s" directive without content.' % ( |
||||
self.name), |
||||
line=self.lineno)] |
||||
|
||||
node = kernel_render() |
||||
node['alt'] = self.options.get('alt','') |
||||
node['srclang'] = srclang |
||||
literal_node = nodes.literal_block(code, code) |
||||
node += literal_node |
||||
|
||||
caption = self.options.get('caption') |
||||
if caption: |
||||
# parse caption's content |
||||
parsed = nodes.Element() |
||||
self.state.nested_parse( |
||||
ViewList([caption], source=''), self.content_offset, parsed) |
||||
caption_node = nodes.caption( |
||||
parsed[0].rawsource, '', *parsed[0].children) |
||||
caption_node.source = parsed[0].source |
||||
caption_node.line = parsed[0].line |
||||
|
||||
figure_node = nodes.figure('', node) |
||||
for k,v in self.options.items(): |
||||
figure_node[k] = v |
||||
figure_node += caption_node |
||||
|
||||
node = figure_node |
||||
|
||||
return node |
||||
|
||||
def add_kernel_figure_to_std_domain(app, doctree): |
||||
"""Add kernel-figure anchors to 'std' domain. |
||||
|
||||
The ``StandardDomain.process_doc(..)`` method does not know how to resolve |
||||
the caption (label) of ``kernel-figure`` directive (it only knows about |
||||
standard nodes, e.g. table, figure etc.). Without any additional handling |
||||
this will result in a 'undefined label' for kernel-figures. |
||||
|
||||
This handle adds labels of kernel-figure to the 'std' domain labels. |
||||
""" |
||||
|
||||
std = app.env.domains["std"] |
||||
docname = app.env.docname |
||||
labels = std.data["labels"] |
||||
|
||||
for name, explicit in iteritems(doctree.nametypes): |
||||
if not explicit: |
||||
continue |
||||
labelid = doctree.nameids[name] |
||||
if labelid is None: |
||||
continue |
||||
node = doctree.ids[labelid] |
||||
|
||||
if node.tagname == 'kernel_figure': |
||||
for n in node.next_node(): |
||||
if n.tagname == 'caption': |
||||
sectname = clean_astext(n) |
||||
# add label to std domain |
||||
labels[name] = docname, labelid, sectname |
||||
break |
@ -0,0 +1,32 @@ |
||||
# -*- coding: utf-8; mode: python -*- |
||||
# pylint: disable=R0903, C0330, R0914, R0912, E0401 |
||||
|
||||
import os |
||||
import sys |
||||
from sphinx.util.pycompat import execfile_ |
||||
|
||||
# ------------------------------------------------------------------------------ |
||||
def loadConfig(namespace): |
||||
# ------------------------------------------------------------------------------ |
||||
|
||||
u"""Load an additional configuration file into *namespace*. |
||||
|
||||
The name of the configuration file is taken from the environment |
||||
``SPHINX_CONF``. The external configuration file extends (or overwrites) the |
||||
configuration values from the origin ``conf.py``. With this you are able to |
||||
maintain *build themes*. """ |
||||
|
||||
config_file = os.environ.get("SPHINX_CONF", None) |
||||
if (config_file is not None |
||||
and os.path.normpath(namespace["__file__"]) != os.path.normpath(config_file) ): |
||||
config_file = os.path.abspath(config_file) |
||||
|
||||
if os.path.isfile(config_file): |
||||
sys.stdout.write("load additional sphinx-config: %s\n" % config_file) |
||||
config = namespace.copy() |
||||
config['__file__'] = config_file |
||||
execfile_(config_file, config) |
||||
del config['__file__'] |
||||
namespace.update(config) |
||||
else: |
||||
sys.stderr.write("WARNING: additional sphinx-config not found: %s\n" % config_file) |
@ -0,0 +1,401 @@ |
||||
#!/usr/bin/perl |
||||
use strict; |
||||
use Text::Tabs; |
||||
use Getopt::Long; |
||||
use Pod::Usage; |
||||
|
||||
my $debug; |
||||
my $help; |
||||
my $man; |
||||
|
||||
GetOptions( |
||||
"debug" => \$debug, |
||||
'usage|?' => \$help, |
||||
'help' => \$man |
||||
) or pod2usage(2); |
||||
|
||||
pod2usage(1) if $help; |
||||
pod2usage(-exitstatus => 0, -verbose => 2) if $man; |
||||
pod2usage(2) if (scalar @ARGV < 2 || scalar @ARGV > 3); |
||||
|
||||
my ($file_in, $file_out, $file_exceptions) = @ARGV; |
||||
|
||||
my $data; |
||||
my %ioctls; |
||||
my %defines; |
||||
my %typedefs; |
||||
my %enums; |
||||
my %enum_symbols; |
||||
my %structs; |
||||
|
||||
require Data::Dumper if ($debug); |
||||
|
||||
# |
||||
# read the file and get identifiers |
||||
# |
||||
|
||||
my $is_enum = 0; |
||||
my $is_comment = 0; |
||||
open IN, $file_in or die "Can't open $file_in"; |
||||
while (<IN>) { |
||||
$data .= $_; |
||||
|
||||
my $ln = $_; |
||||
if (!$is_comment) { |
||||
$ln =~ s,/\*.*(\*/),,g; |
||||
|
||||
$is_comment = 1 if ($ln =~ s,/\*.*,,); |
||||
} else { |
||||
if ($ln =~ s,^(.*\*/),,) { |
||||
$is_comment = 0; |
||||
} else { |
||||
next; |
||||
} |
||||
} |
||||
|
||||
if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) { |
||||
my $s = $1; |
||||
my $n = $1; |
||||
$n =~ tr/A-Z/a-z/; |
||||
$n =~ tr/_/-/; |
||||
|
||||
$enum_symbols{$s} = "\\ :ref:`$s <$n>`\\ "; |
||||
|
||||
$is_enum = 0 if ($is_enum && m/\}/); |
||||
next; |
||||
} |
||||
$is_enum = 0 if ($is_enum && m/\}/); |
||||
|
||||
if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) { |
||||
my $s = $1; |
||||
my $n = $1; |
||||
$n =~ tr/A-Z/a-z/; |
||||
|
||||
$ioctls{$s} = "\\ :ref:`$s <$n>`\\ "; |
||||
next; |
||||
} |
||||
|
||||
if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) { |
||||
my $s = $1; |
||||
my $n = $1; |
||||
$n =~ tr/A-Z/a-z/; |
||||
$n =~ tr/_/-/; |
||||
|
||||
$defines{$s} = "\\ :ref:`$s <$n>`\\ "; |
||||
next; |
||||
} |
||||
|
||||
if ($ln =~ m/^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);/) { |
||||
my $s = $2; |
||||
my $n = $3; |
||||
|
||||
$typedefs{$n} = "\\ :c:type:`$n <$s>`\\ "; |
||||
next; |
||||
} |
||||
if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/ |
||||
|| $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/ |
||||
|| $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/ |
||||
|| $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) { |
||||
my $s = $1; |
||||
|
||||
$enums{$s} = "enum :c:type:`$s`\\ "; |
||||
|
||||
$is_enum = $1; |
||||
next; |
||||
} |
||||
if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/ |
||||
|| $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/ |
||||
|| $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/ |
||||
|| $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/ |
||||
) { |
||||
my $s = $1; |
||||
|
||||
$structs{$s} = "struct :c:type:`$s`\\ "; |
||||
next; |
||||
} |
||||
} |
||||
close IN; |
||||
|
||||
# |
||||
# Handle multi-line typedefs |
||||
# |
||||
|
||||
my @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g, |
||||
$data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,); |
||||
foreach my $m (@matches) { |
||||
my $s = $m; |
||||
|
||||
$typedefs{$s} = "\\ :c:type:`$s`\\ "; |
||||
next; |
||||
} |
||||
|
||||
# |
||||
# Handle exceptions, if any |
||||
# |
||||
|
||||
my %def_reftype = ( |
||||
"ioctl" => ":ref", |
||||
"define" => ":ref", |
||||
"symbol" => ":ref", |
||||
"typedef" => ":c:type", |
||||
"enum" => ":c:type", |
||||
"struct" => ":c:type", |
||||
); |
||||
|
||||
if ($file_exceptions) { |
||||
open IN, $file_exceptions or die "Can't read $file_exceptions"; |
||||
while (<IN>) { |
||||
next if (m/^\s*$/ || m/^\s*#/); |
||||
|
||||
# Parsers to ignore a symbol |
||||
|
||||
if (m/^ignore\s+ioctl\s+(\S+)/) { |
||||
delete $ioctls{$1} if (exists($ioctls{$1})); |
||||
next; |
||||
} |
||||
if (m/^ignore\s+define\s+(\S+)/) { |
||||
delete $defines{$1} if (exists($defines{$1})); |
||||
next; |
||||
} |
||||
if (m/^ignore\s+typedef\s+(\S+)/) { |
||||
delete $typedefs{$1} if (exists($typedefs{$1})); |
||||
next; |
||||
} |
||||
if (m/^ignore\s+enum\s+(\S+)/) { |
||||
delete $enums{$1} if (exists($enums{$1})); |
||||
next; |
||||
} |
||||
if (m/^ignore\s+struct\s+(\S+)/) { |
||||
delete $structs{$1} if (exists($structs{$1})); |
||||
next; |
||||
} |
||||
if (m/^ignore\s+symbol\s+(\S+)/) { |
||||
delete $enum_symbols{$1} if (exists($enum_symbols{$1})); |
||||
next; |
||||
} |
||||
|
||||
# Parsers to replace a symbol |
||||
my ($type, $old, $new, $reftype); |
||||
|
||||
if (m/^replace\s+(\S+)\s+(\S+)\s+(\S+)/) { |
||||
$type = $1; |
||||
$old = $2; |
||||
$new = $3; |
||||
} else { |
||||
die "Can't parse $file_exceptions: $_"; |
||||
} |
||||
|
||||
if ($new =~ m/^\:c\:(data|func|macro|type)\:\`(.+)\`/) { |
||||
$reftype = ":c:$1"; |
||||
$new = $2; |
||||
} elsif ($new =~ m/\:ref\:\`(.+)\`/) { |
||||
$reftype = ":ref"; |
||||
$new = $1; |
||||
} else { |
||||
$reftype = $def_reftype{$type}; |
||||
} |
||||
$new = "$reftype:`$old <$new>`"; |
||||
|
||||
if ($type eq "ioctl") { |
||||
$ioctls{$old} = $new if (exists($ioctls{$old})); |
||||
next; |
||||
} |
||||
if ($type eq "define") { |
||||
$defines{$old} = $new if (exists($defines{$old})); |
||||
next; |
||||
} |
||||
if ($type eq "symbol") { |
||||
$enum_symbols{$old} = $new if (exists($enum_symbols{$old})); |
||||
next; |
||||
} |
||||
if ($type eq "typedef") { |
||||
$typedefs{$old} = $new if (exists($typedefs{$old})); |
||||
next; |
||||
} |
||||
if ($type eq "enum") { |
||||
$enums{$old} = $new if (exists($enums{$old})); |
||||
next; |
||||
} |
||||
if ($type eq "struct") { |
||||
$structs{$old} = $new if (exists($structs{$old})); |
||||
next; |
||||
} |
||||
|
||||
die "Can't parse $file_exceptions: $_"; |
||||
} |
||||
} |
||||
|
||||
if ($debug) { |
||||
print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls); |
||||
print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs); |
||||
print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums); |
||||
print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs); |
||||
print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines); |
||||
print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols); |
||||
} |
||||
|
||||
# |
||||
# Align block |
||||
# |
||||
$data = expand($data); |
||||
$data = " " . $data; |
||||
$data =~ s/\n/\n /g; |
||||
$data =~ s/\n\s+$/\n/g; |
||||
$data =~ s/\n\s+\n/\n\n/g; |
||||
|
||||
# |
||||
# Add escape codes for special characters |
||||
# |
||||
$data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g; |
||||
|
||||
$data =~ s,DEPRECATED,**DEPRECATED**,g; |
||||
|
||||
# |
||||
# Add references |
||||
# |
||||
|
||||
my $start_delim = "[ \n\t\(\=\*\@]"; |
||||
my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)"; |
||||
|
||||
foreach my $r (keys %ioctls) { |
||||
my $s = $ioctls{$r}; |
||||
|
||||
$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; |
||||
|
||||
print "$r -> $s\n" if ($debug); |
||||
|
||||
$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
||||
} |
||||
|
||||
foreach my $r (keys %defines) { |
||||
my $s = $defines{$r}; |
||||
|
||||
$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; |
||||
|
||||
print "$r -> $s\n" if ($debug); |
||||
|
||||
$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
||||
} |
||||
|
||||
foreach my $r (keys %enum_symbols) { |
||||
my $s = $enum_symbols{$r}; |
||||
|
||||
$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; |
||||
|
||||
print "$r -> $s\n" if ($debug); |
||||
|
||||
$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
||||
} |
||||
|
||||
foreach my $r (keys %enums) { |
||||
my $s = $enums{$r}; |
||||
|
||||
$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; |
||||
|
||||
print "$r -> $s\n" if ($debug); |
||||
|
||||
$data =~ s/enum\s+($r)$end_delim/$s$2/g; |
||||
} |
||||
|
||||
foreach my $r (keys %structs) { |
||||
my $s = $structs{$r}; |
||||
|
||||
$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; |
||||
|
||||
print "$r -> $s\n" if ($debug); |
||||
|
||||
$data =~ s/struct\s+($r)$end_delim/$s$2/g; |
||||
} |
||||
|
||||
foreach my $r (keys %typedefs) { |
||||
my $s = $typedefs{$r}; |
||||
|
||||
$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; |
||||
|
||||
print "$r -> $s\n" if ($debug); |
||||
$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
||||
} |
||||
|
||||
$data =~ s/\\ ([\n\s])/\1/g; |
||||
|
||||
# |
||||
# Generate output file |
||||
# |
||||
|
||||
my $title = $file_in; |
||||
$title =~ s,.*/,,; |
||||
|
||||
open OUT, "> $file_out" or die "Can't open $file_out"; |
||||
print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n"; |
||||
print OUT "$title\n"; |
||||
print OUT "=" x length($title); |
||||
print OUT "\n\n.. parsed-literal::\n\n"; |
||||
print OUT $data; |
||||
close OUT; |
||||
|
||||
__END__ |
||||
|
||||
=head1 NAME |
||||
|
||||
parse_headers.pl - parse a C file, in order to identify functions, structs, |
||||
enums and defines and create cross-references to a Sphinx book. |
||||
|
||||
=head1 SYNOPSIS |
||||
|
||||
B<parse_headers.pl> [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>] |
||||
|
||||
Where <options> can be: --debug, --help or --man. |
||||
|
||||
=head1 OPTIONS |
||||
|
||||
=over 8 |
||||
|
||||
=item B<--debug> |
||||
|
||||
Put the script in verbose mode, useful for debugging. |
||||
|
||||
=item B<--usage> |
||||
|
||||
Prints a brief help message and exits. |
||||
|
||||
=item B<--help> |
||||
|
||||
Prints a more detailed help message and exits. |
||||
|
||||
=back |
||||
|
||||
=head1 DESCRIPTION |
||||
|
||||
Convert a C header or source file (C_FILE), into a ReStructured Text |
||||
included via ..parsed-literal block with cross-references for the |
||||
documentation files that describe the API. It accepts an optional |
||||
EXCEPTIONS_FILE with describes what elements will be either ignored or |
||||
be pointed to a non-default reference. |
||||
|
||||
The output is written at the (OUT_FILE). |
||||
|
||||
It is capable of identifying defines, functions, structs, typedefs, |
||||
enums and enum symbols and create cross-references for all of them. |
||||
It is also capable of distinguish #define used for specifying a Linux |
||||
ioctl. |
||||
|
||||
The EXCEPTIONS_FILE contain two rules to allow ignoring a symbol or |
||||
to replace the default references by a custom one. |
||||
|
||||
Please read Documentation/doc-guide/parse-headers.rst at the Kernel's |
||||
tree for more details. |
||||
|
||||
=head1 BUGS |
||||
|
||||
Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org> |
||||
|
||||
=head1 COPYRIGHT |
||||
|
||||
Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. |
||||
|
||||
License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. |
||||
|
||||
This is free software: you are free to change and redistribute it. |
||||
There is NO WARRANTY, to the extent permitted by law. |
||||
|
||||
=cut |
@ -0,0 +1,3 @@ |
||||
docutils==0.12 |
||||
Sphinx==1.4.9 |
||||
sphinx_rtd_theme |
@ -0,0 +1,376 @@ |
||||
#!/usr/bin/env python3 |
||||
# -*- coding: utf-8; mode: python -*- |
||||
# pylint: disable=C0330, R0903, R0912 |
||||
|
||||
u""" |
||||
flat-table |
||||
~~~~~~~~~~ |
||||
|
||||
Implementation of the ``flat-table`` reST-directive. |
||||
|
||||
:copyright: Copyright (C) 2016 Markus Heiser |
||||
:license: GPL Version 2, June 1991 see linux/COPYING for details. |
||||
|
||||
The ``flat-table`` (:py:class:`FlatTable`) is a double-stage list similar to |
||||
the ``list-table`` with some additional features: |
||||
|
||||
* *column-span*: with the role ``cspan`` a cell can be extended through |
||||
additional columns |
||||
|
||||
* *row-span*: with the role ``rspan`` a cell can be extended through |
||||
additional rows |
||||
|
||||
* *auto span* rightmost cell of a table row over the missing cells on the |
||||
right side of that table-row. With Option ``:fill-cells:`` this behavior |
||||
can changed from *auto span* to *auto fill*, which automaticly inserts |
||||
(empty) cells instead of spanning the last cell. |
||||
|
||||
Options: |
||||
|
||||
* header-rows: [int] count of header rows |
||||
* stub-columns: [int] count of stub columns |
||||
* widths: [[int] [int] ... ] widths of columns |
||||
* fill-cells: instead of autospann missing cells, insert missing cells |
||||
|
||||
roles: |
||||
|
||||
* cspan: [int] additionale columns (*morecols*) |
||||
* rspan: [int] additionale rows (*morerows*) |
||||
""" |
||||
|
||||
# ============================================================================== |
||||
# imports |
||||
# ============================================================================== |
||||
|
||||
import sys |
||||
|
||||
from docutils import nodes |
||||
from docutils.parsers.rst import directives, roles |
||||
from docutils.parsers.rst.directives.tables import Table |
||||
from docutils.utils import SystemMessagePropagation |
||||
|
||||
# ============================================================================== |
||||
# common globals |
||||
# ============================================================================== |
||||
|
||||
# The version numbering follows numbering of the specification |
||||
# (Documentation/books/kernel-doc-HOWTO). |
||||
__version__ = '1.0' |
||||
|
||||
PY3 = sys.version_info[0] == 3 |
||||
PY2 = sys.version_info[0] == 2 |
||||
|
||||
if PY3: |
||||
# pylint: disable=C0103, W0622 |
||||
unicode = str |
||||
basestring = str |
||||
|
||||
# ============================================================================== |
||||
def setup(app): |
||||
# ============================================================================== |
||||
|
||||
app.add_directive("flat-table", FlatTable) |
||||
roles.register_local_role('cspan', c_span) |
||||
roles.register_local_role('rspan', r_span) |
||||
|
||||
return dict( |
||||
version = __version__, |
||||
parallel_read_safe = True, |
||||
parallel_write_safe = True |
||||
) |
||||
|
||||
# ============================================================================== |
||||
def c_span(name, rawtext, text, lineno, inliner, options=None, content=None): |
||||
# ============================================================================== |
||||
# pylint: disable=W0613 |
||||
|
||||
options = options if options is not None else {} |
||||
content = content if content is not None else [] |
||||
nodelist = [colSpan(span=int(text))] |
||||
msglist = [] |
||||
return nodelist, msglist |
||||
|
||||
# ============================================================================== |
||||
def r_span(name, rawtext, text, lineno, inliner, options=None, content=None): |
||||
# ============================================================================== |
||||
# pylint: disable=W0613 |
||||
|
||||
options = options if options is not None else {} |
||||
content = content if content is not None else [] |
||||
nodelist = [rowSpan(span=int(text))] |
||||
msglist = [] |
||||
return nodelist, msglist |
||||
|
||||
|
||||
# ============================================================================== |
||||
class rowSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321 |
||||
class colSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321 |
||||
# ============================================================================== |
||||
|
||||
# ============================================================================== |
||||
class FlatTable(Table): |
||||
# ============================================================================== |
||||
|
||||
u"""FlatTable (``flat-table``) directive""" |
||||
|
||||
option_spec = { |
||||
'name': directives.unchanged |
||||
, 'class': directives.class_option |
||||
, 'header-rows': directives.nonnegative_int |
||||
, 'stub-columns': directives.nonnegative_int |
||||
, 'widths': directives.positive_int_list |
||||
, 'fill-cells' : directives.flag } |
||||
|
||||
def run(self): |
||||
|
||||
if not self.content: |
||||
error = self.state_machine.reporter.error( |
||||
'The "%s" directive is empty; content required.' % self.name, |
||||
nodes.literal_block(self.block_text, self.block_text), |
||||
line=self.lineno) |
||||
return [error] |
||||
|
||||
title, messages = self.make_title() |
||||
node = nodes.Element() # anonymous container for parsing |
||||
self.state.nested_parse(self.content, self.content_offset, node) |
||||
|
||||
tableBuilder = ListTableBuilder(self) |
||||
tableBuilder.parseFlatTableNode(node) |
||||
tableNode = tableBuilder.buildTableNode() |
||||
# SDK.CONSOLE() # print --> tableNode.asdom().toprettyxml() |
||||
if title: |
||||
tableNode.insert(0, title) |
||||
return [tableNode] + messages |
||||
|
||||
|
||||
# ============================================================================== |
||||
class ListTableBuilder(object): |
||||
# ============================================================================== |
||||
|
||||
u"""Builds a table from a double-stage list""" |
||||
|
||||
def __init__(self, directive): |
||||
self.directive = directive |
||||
self.rows = [] |
||||
self.max_cols = 0 |
||||
|
||||
def buildTableNode(self): |
||||
|
||||
colwidths = self.directive.get_column_widths(self.max_cols) |
||||
if isinstance(colwidths, tuple): |
||||
# Since docutils 0.13, get_column_widths returns a (widths, |
||||
# colwidths) tuple, where widths is a string (i.e. 'auto'). |
||||
# See https://sourceforge.net/p/docutils/patches/120/. |
||||
colwidths = colwidths[1] |
||||
stub_columns = self.directive.options.get('stub-columns', 0) |
||||
header_rows = self.directive.options.get('header-rows', 0) |
||||
|
||||
table = nodes.table() |
||||
tgroup = nodes.tgroup(cols=len(colwidths)) |
||||
table += tgroup |
||||
|
||||
|
||||
for colwidth in colwidths: |
||||
colspec = nodes.colspec(colwidth=colwidth) |
||||
# FIXME: It seems, that the stub method only works well in the |
||||
# absence of rowspan (observed by the html buidler, the docutils-xml |
||||
# build seems OK). This is not extraordinary, because there exists |
||||
# no table directive (except *this* flat-table) which allows to |
||||
# define coexistent of rowspan and stubs (there was no use-case |
||||
# before flat-table). This should be reviewed (later). |
||||
if stub_columns: |
||||
colspec.attributes['stub'] = 1 |
||||
stub_columns -= 1 |
||||
tgroup += colspec |
||||
stub_columns = self.directive.options.get('stub-columns', 0) |
||||
|
||||
if header_rows: |
||||
thead = nodes.thead() |
||||
tgroup += thead |
||||
for row in self.rows[:header_rows]: |
||||
thead += self.buildTableRowNode(row) |
||||
|
||||
tbody = nodes.tbody() |
||||
tgroup += tbody |
||||
|
||||
for row in self.rows[header_rows:]: |
||||
tbody += self.buildTableRowNode(row) |
||||
return table |
||||
|
||||
def buildTableRowNode(self, row_data, classes=None): |
||||
classes = [] if classes is None else classes |
||||
row = nodes.row() |
||||
for cell in row_data: |
||||
if cell is None: |
||||
continue |
||||
cspan, rspan, cellElements = cell |
||||
|
||||
attributes = {"classes" : classes} |
||||
if rspan: |
||||
attributes['morerows'] = rspan |
||||
if cspan: |
||||
attributes['morecols'] = cspan |
||||
entry = nodes.entry(**attributes) |
||||
entry.extend(cellElements) |
||||
row += entry |
||||
return row |
||||
|
||||
def raiseError(self, msg): |
||||
error = self.directive.state_machine.reporter.error( |
||||
msg |
||||
, nodes.literal_block(self.directive.block_text |
||||
, self.directive.block_text) |
||||
, line = self.directive.lineno ) |
||||
raise SystemMessagePropagation(error) |
||||
|
||||
def parseFlatTableNode(self, node): |
||||
u"""parses the node from a :py:class:`FlatTable` directive's body""" |
||||
|
||||
if len(node) != 1 or not isinstance(node[0], nodes.bullet_list): |
||||
self.raiseError( |
||||
'Error parsing content block for the "%s" directive: ' |
||||
'exactly one bullet list expected.' % self.directive.name ) |
||||
|
||||
for rowNum, rowItem in enumerate(node[0]): |
||||
row = self.parseRowItem(rowItem, rowNum) |
||||
self.rows.append(row) |
||||
self.roundOffTableDefinition() |
||||
|
||||
def roundOffTableDefinition(self): |
||||
u"""Round off the table definition. |
||||
|
||||
This method rounds off the table definition in :py:member:`rows`. |
||||
|
||||
* This method inserts the needed ``None`` values for the missing cells |
||||
arising from spanning cells over rows and/or columns. |
||||
|
||||
* recount the :py:member:`max_cols` |
||||
|
||||
* Autospan or fill (option ``fill-cells``) missing cells on the right |
||||
side of the table-row |
||||
""" |
||||
|
||||
y = 0 |
||||
while y < len(self.rows): |
||||
x = 0 |
||||
|
||||
while x < len(self.rows[y]): |
||||
cell = self.rows[y][x] |
||||
if cell is None: |
||||
x += 1 |
||||
continue |
||||
cspan, rspan = cell[:2] |
||||
# handle colspan in current row |
||||
for c in range(cspan): |
||||
try: |
||||
self.rows[y].insert(x+c+1, None) |
||||
except: # pylint: disable=W0702 |
||||
# the user sets ambiguous rowspans |
||||
pass # SDK.CONSOLE() |
||||
# handle colspan in spanned rows |
||||
for r in range(rspan): |
||||
for c in range(cspan + 1): |
||||
try: |
||||
self.rows[y+r+1].insert(x+c, None) |
||||
except: # pylint: disable=W0702 |
||||
# the user sets ambiguous rowspans |
||||
pass # SDK.CONSOLE() |
||||
x += 1 |
||||
y += 1 |
||||
|
||||
# Insert the missing cells on the right side. For this, first |
||||
# re-calculate the max columns. |
||||
|
||||
for row in self.rows: |
||||
if self.max_cols < len(row): |
||||
self.max_cols = len(row) |
||||
|
||||
# fill with empty cells or cellspan? |
||||
|
||||
fill_cells = False |
||||
if 'fill-cells' in self.directive.options: |
||||
fill_cells = True |
||||
|
||||
for row in self.rows: |
||||
x = self.max_cols - len(row) |
||||
if x and not fill_cells: |
||||
if row[-1] is None: |
||||
row.append( ( x - 1, 0, []) ) |
||||
else: |
||||
cspan, rspan, content = row[-1] |
||||
row[-1] = (cspan + x, rspan, content) |
||||
elif x and fill_cells: |
||||
for i in range(x): |
||||
row.append( (0, 0, nodes.comment()) ) |
||||
|
||||
def pprint(self): |
||||
# for debugging |
||||
retVal = "[ " |
||||
for row in self.rows: |
||||
retVal += "[ " |
||||
for col in row: |
||||
if col is None: |
||||
retVal += ('%r' % col) |
||||
retVal += "\n , " |
||||
else: |
||||
content = col[2][0].astext() |
||||
if len (content) > 30: |
||||
content = content[:30] + "..." |
||||
retVal += ('(cspan=%s, rspan=%s, %r)' |
||||
% (col[0], col[1], content)) |
||||
retVal += "]\n , " |
||||
retVal = retVal[:-2] |
||||
retVal += "]\n , " |
||||
retVal = retVal[:-2] |
||||
return retVal + "]" |
||||
|
||||
def parseRowItem(self, rowItem, rowNum): |
||||
row = [] |
||||
childNo = 0 |
||||
error = False |
||||
cell = None |
||||
target = None |
||||
|
||||
for child in rowItem: |
||||
if (isinstance(child , nodes.comment) |
||||
or isinstance(child, nodes.system_message)): |
||||
pass |
||||
elif isinstance(child , nodes.target): |
||||
target = child |
||||
elif isinstance(child, nodes.bullet_list): |
||||
childNo += 1 |
||||
cell = child |
||||
else: |
||||
error = True |
||||
break |
||||
|
||||
if childNo != 1 or error: |
||||
self.raiseError( |
||||
'Error parsing content block for the "%s" directive: ' |
||||
'two-level bullet list expected, but row %s does not ' |
||||
'contain a second-level bullet list.' |
||||
% (self.directive.name, rowNum + 1)) |
||||
|
||||
for cellItem in cell: |
||||
cspan, rspan, cellElements = self.parseCellItem(cellItem) |
||||
if target is not None: |
||||
cellElements.insert(0, target) |
||||
row.append( (cspan, rspan, cellElements) ) |
||||
return row |
||||
|
||||
def parseCellItem(self, cellItem): |
||||
# search and remove cspan, rspan colspec from the first element in |
||||
# this listItem (field). |
||||
cspan = rspan = 0 |
||||
if not len(cellItem): |
||||
return cspan, rspan, [] |
||||
for elem in cellItem[0]: |
||||
if isinstance(elem, colSpan): |
||||
cspan = elem.get("span") |
||||
elem.parent.remove(elem) |
||||
continue |
||||
if isinstance(elem, rowSpan): |
||||
rspan = elem.get("span") |
||||
elem.parent.remove(elem) |
||||
continue |
||||
return cspan, rspan, cellItem[:] |
@ -1,15 +0,0 @@ |
||||
*.xml |
||||
*.ps |
||||
*.pdf |
||||
*.html |
||||
*.9.gz |
||||
*.9 |
||||
*.aux |
||||
*.dvi |
||||
*.log |
||||
*.out |
||||
*.png |
||||
*.gif |
||||
*.svg |
||||
media-indices.tmpl |
||||
media-entities.tmpl |
@ -1,222 +0,0 @@ |
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
###
|
||||
# This makefile is used to generate the kernel documentation,
|
||||
# primarily based on in-line comments in various source files.
|
||||
# See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how
|
||||
# to document the SRC - and how to read it.
|
||||
# To add a new book the only step required is to add the book to the
|
||||
# list of DOCBOOKS.
|
||||
|
||||
DOCBOOKS := efi.xml linker_lists.xml stdio.xml
|
||||
|
||||
###
|
||||
# The build process is as follows (targets):
|
||||
# (xmldocs) [by docproc]
|
||||
# file.tmpl --> file.xml +--> file.ps (psdocs) [by db2ps or xmlto]
|
||||
# +--> file.pdf (pdfdocs) [by db2pdf or xmlto]
|
||||
# +--> DIR=file (htmldocs) [by xmlto]
|
||||
# +--> man/ (mandocs) [by xmlto]
|
||||
|
||||
|
||||
# for PDF and PS output you can choose between xmlto and docbook-utils tools
|
||||
PDF_METHOD = $(prefer-db2x)
|
||||
PS_METHOD = $(prefer-db2x)
|
||||
|
||||
|
||||
###
|
||||
# The targets that may be used.
|
||||
PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs
|
||||
|
||||
targets += $(DOCBOOKS)
|
||||
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
|
||||
xmldocs: $(BOOKS) |
||||
sgmldocs: xmldocs |
||||
|
||||
PS := $(patsubst %.xml, %.ps, $(BOOKS))
|
||||
psdocs: $(PS) |
||||
|
||||
PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
|
||||
pdfdocs: $(PDF) |
||||
|
||||
HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
|
||||
htmldocs: $(HTML) |
||||
$(call build_main_index)
|
||||
$(call build_images)
|
||||
$(call install_media_images)
|
||||
|
||||
MAN := $(patsubst %.xml, %.9, $(BOOKS))
|
||||
mandocs: $(MAN) |
||||
$(if $(wildcard $(obj)/man/*.9),gzip -f $(obj)/man/*.9)
|
||||
|
||||
installmandocs: mandocs |
||||
mkdir -p /usr/local/man/man9/
|
||||
install $(obj)/man/*.9.gz /usr/local/man/man9/
|
||||
|
||||
###
|
||||
#External programs used
|
||||
KERNELDOC = $(srctree)/scripts/kernel-doc
|
||||
DOCPROC = $(objtree)/scripts/docproc
|
||||
|
||||
XMLTOFLAGS = -m $(srctree)/$(src)/stylesheet.xsl
|
||||
XMLTOFLAGS += --skip-validation
|
||||
|
||||
###
|
||||
# DOCPROC is used for two purposes:
|
||||
# 1) To generate a dependency list for a .tmpl file
|
||||
# 2) To preprocess a .tmpl file and call kernel-doc with
|
||||
# appropriate parameters.
|
||||
# The following rules are used to generate the .xml documentation
|
||||
# required to generate the final targets. (ps, pdf, html).
|
||||
quiet_cmd_docproc = DOCPROC $@
|
||||
cmd_docproc = SRCTREE=$(srctree)/ $(DOCPROC) doc $< >$@
|
||||
define rule_docproc |
||||
set -e; \
|
||||
$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
|
||||
$(cmd_$(1)); \
|
||||
( \
|
||||
echo 'cmd_$@ := $(cmd_$(1))'; \
|
||||
echo $@: `SRCTREE=$(srctree) $(DOCPROC) depend $<`; \
|
||||
) > $(dir $@).$(notdir $@).cmd
|
||||
endef |
||||
|
||||
%.xml: %.tmpl $(KERNELDOC) $(DOCPROC) FORCE |
||||
$(call if_changed_rule,docproc)
|
||||
|
||||
# Tell kbuild to always build the programs
|
||||
always := $(hostprogs-y)
|
||||
|
||||
notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \
|
||||
exit 1
|
||||
db2xtemplate = db2TYPE -o $(dir $@) $<
|
||||
xmltotemplate = xmlto TYPE $(XMLTOFLAGS) -o $(dir $@) $<
|
||||
|
||||
# determine which methods are available
|
||||
ifeq ($(shell which db2ps >/dev/null 2>&1 && echo found),found) |
||||
use-db2x = db2x
|
||||
prefer-db2x = db2x
|
||||
else |
||||
use-db2x = notfound
|
||||
prefer-db2x = $(use-xmlto)
|
||||
endif |
||||
ifeq ($(shell which xmlto >/dev/null 2>&1 && echo found),found) |
||||
use-xmlto = xmlto
|
||||
prefer-xmlto = xmlto
|
||||
else |
||||
use-xmlto = notfound
|
||||
prefer-xmlto = $(use-db2x)
|
||||
endif |
||||
|
||||
# the commands, generated from the chosen template
|
||||
quiet_cmd_db2ps = PS $@
|
||||
cmd_db2ps = $(subst TYPE,ps, $($(PS_METHOD)template))
|
||||
%.ps : %.xml |
||||
$(call cmd,db2ps)
|
||||
|
||||
quiet_cmd_db2pdf = PDF $@
|
||||
cmd_db2pdf = $(subst TYPE,pdf, $($(PDF_METHOD)template))
|
||||
%.pdf : %.xml |
||||
$(call cmd,db2pdf)
|
||||
|
||||
|
||||
index = index.html
|
||||
main_idx = $(obj)/$(index)
|
||||
build_main_index = rm -rf $(main_idx); \
|
||||
echo '<h1>U-Boot Bootloader HTML Documentation</h1>' >> $(main_idx) && \
|
||||
echo '<h2>U-Boot Version: $(UBOOTVERSION)</h2>' >> $(main_idx) && \
|
||||
cat $(HTML) >> $(main_idx)
|
||||
|
||||
quiet_cmd_db2html = HTML $@
|
||||
cmd_db2html = xmlto html $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
|
||||
echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \
|
||||
$(patsubst %.html,%,$(notdir $@))</a><p>' > $@
|
||||
|
||||
%.html: %.xml |
||||
@(which xmlto > /dev/null 2>&1) || \
|
||||
(echo "*** You need to install xmlto ***"; \
|
||||
exit 1)
|
||||
@rm -rf $@ $(patsubst %.html,%,$@)
|
||||
$(call cmd,db2html)
|
||||
@if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \
|
||||
cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi
|
||||
|
||||
quiet_cmd_db2man = MAN $@
|
||||
cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man $< ; fi
|
||||
%.9 : %.xml |
||||
@(which xmlto > /dev/null 2>&1) || \
|
||||
(echo "*** You need to install xmlto ***"; \
|
||||
exit 1)
|
||||
$(Q)mkdir -p $(obj)/man
|
||||
$(call cmd,db2man)
|
||||
@touch $@
|
||||
|
||||
###
|
||||
# Rules to generate postscripts and PNG images from .fig format files
|
||||
quiet_cmd_fig2eps = FIG2EPS $@
|
||||
cmd_fig2eps = fig2dev -Leps $< $@
|
||||
|
||||
%.eps: %.fig |
||||
@(which fig2dev > /dev/null 2>&1) || \
|
||||
(echo "*** You need to install transfig ***"; \
|
||||
exit 1)
|
||||
$(call cmd,fig2eps)
|
||||
|
||||
quiet_cmd_fig2png = FIG2PNG $@
|
||||
cmd_fig2png = fig2dev -Lpng $< $@
|
||||
|
||||
%.png: %.fig |
||||
@(which fig2dev > /dev/null 2>&1) || \
|
||||
(echo "*** You need to install transfig ***"; \
|
||||
exit 1)
|
||||
$(call cmd,fig2png)
|
||||
|
||||
###
|
||||
# Rule to convert a .c file to inline XML documentation
|
||||
gen_xml = :
|
||||
quiet_gen_xml = echo ' GEN $@'
|
||||
silent_gen_xml = :
|
||||
%.xml: %.c |
||||
@$($(quiet)gen_xml)
|
||||
@( \
|
||||
echo "<programlisting>"; \
|
||||
expand --tabs=8 < $< | \
|
||||
sed -e "s/&/\\&/g" \
|
||||
-e "s/</\\</g" \
|
||||
-e "s/>/\\>/g"; \
|
||||
echo "</programlisting>") > $@
|
||||
|
||||
###
|
||||
# Help targets as used by the top-level makefile
|
||||
dochelp: |
||||
@echo ' U-Boot bootloader internal documentation in different formats:'
|
||||
@echo ' htmldocs - HTML'
|
||||
@echo ' pdfdocs - PDF'
|
||||
@echo ' psdocs - Postscript'
|
||||
@echo ' xmldocs - XML DocBook'
|
||||
@echo ' mandocs - man pages'
|
||||
@echo ' installmandocs - install man pages generated by mandocs'
|
||||
@echo ' cleandocs - clean all generated DocBook files'
|
||||
|
||||
###
|
||||
# Temporary files left by various tools
|
||||
clean-files := $(DOCBOOKS) \
|
||||
$(patsubst %.xml, %.dvi, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.aux, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.tex, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.log, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.out, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.ps, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.pdf, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.html, $(DOCBOOKS)) \
|
||||
$(patsubst %.xml, %.9, $(DOCBOOKS)) \
|
||||
$(index)
|
||||
|
||||
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
|
||||
|
||||
cleandocs: |
||||
$(Q)rm -f $(call objectify, $(clean-files))
|
||||
$(Q)rm -rf $(call objectify, $(clean-dirs))
|
||||
|
||||
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||
# information in a variable se we can use it in if_changed and friends.
|
||||
|
||||
.PHONY: $(PHONY) |
@ -1,16 +0,0 @@ |
||||
body { |
||||
font-family: sans-serif; |
||||
} |
||||
|
||||
.programlisting { |
||||
font-family: monospace; |
||||
font-size: 1em; |
||||
display: block; |
||||
padding: 10px; |
||||
border: 1px solid #aaa; |
||||
color: #000; |
||||
background-color: #eee; |
||||
overflow: auto; |
||||
margin: 1em 0em; |
||||
border-radius: 6px; |
||||
} |
@ -1,17 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" |
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> |
||||
|
||||
<book id="UBootEFI"> |
||||
<bookinfo> |
||||
<title>The U-Boot EFI subsystem</title> |
||||
</bookinfo> |
||||
|
||||
<toc></toc> |
||||
|
||||
<chapter id="BootServices"> |
||||
<title>Boot services</title> |
||||
!Ilib/efi_loader/efi_boottime.c |
||||
</chapter> |
||||
|
||||
</book> |
@ -1,46 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" |
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> |
||||
|
||||
<book id="UBootLGArrays"> |
||||
<bookinfo> |
||||
<title>The U-Boot Linker-Generated Arrays</title> |
||||
|
||||
<legalnotice> |
||||
<para> |
||||
This documentation is free software; you can redistribute |
||||
it and/or modify it under the terms of the GNU General Public |
||||
License as published by the Free Software Foundation; either |
||||
version 2 of the License, or (at your option) any later |
||||
version. |
||||
</para> |
||||
|
||||
<para> |
||||
This program is distributed in the hope that it will be |
||||
useful, but WITHOUT ANY WARRANTY; without even the implied |
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||||
See the GNU General Public License for more details. |
||||
</para> |
||||
|
||||
<para> |
||||
You should have received a copy of the GNU General Public |
||||
License along with this program; if not, write to the Free |
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
MA 02111-1307 USA |
||||
</para> |
||||
|
||||
<para> |
||||
For more details see the file COPYING in the source |
||||
distribution of U-Boot Bootloader. |
||||
</para> |
||||
</legalnotice> |
||||
</bookinfo> |
||||
|
||||
<toc></toc> |
||||
|
||||
<chapter id="adt"> |
||||
<title>Linker-Generated Arrays</title> |
||||
!Iinclude/linker_lists.h |
||||
</chapter> |
||||
|
||||
</book> |
@ -1,46 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" |
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> |
||||
|
||||
<book id="UBootSTDIO"> |
||||
<bookinfo> |
||||
<title>The U-Boot STDIO subsystem</title> |
||||
|
||||
<legalnotice> |
||||
<para> |
||||
This documentation is free software; you can redistribute |
||||
it and/or modify it under the terms of the GNU General Public |
||||
License as published by the Free Software Foundation; either |
||||
version 2 of the License, or (at your option) any later |
||||
version. |
||||
</para> |
||||
|
||||
<para> |
||||
This program is distributed in the hope that it will be |
||||
useful, but WITHOUT ANY WARRANTY; without even the implied |
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||||
See the GNU General Public License for more details. |
||||
</para> |
||||
|
||||
<para> |
||||
You should have received a copy of the GNU General Public |
||||
License along with this program; if not, write to the Free |
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
MA 02111-1307 USA |
||||
</para> |
||||
|
||||
<para> |
||||
For more details see the file COPYING in the source |
||||
distribution of U-Boot Bootloader. |
||||
</para> |
||||
</legalnotice> |
||||
</bookinfo> |
||||
|
||||
<toc></toc> |
||||
|
||||
<chapter id="adt"> |
||||
<title>U-Boot Serial subsystem</title> |
||||
!Idrivers/serial/serial.c |
||||
</chapter> |
||||
|
||||
</book> |
@ -1,10 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
||||
<param name="chunk.quietly">1</param> |
||||
<param name="funcsynopsis.style">ansi</param> |
||||
<param name="funcsynopsis.tabular.threshold">80</param> |
||||
<param name="callout.graphics">0</param> |
||||
<!-- <param name="paper.type">A4</param> --> |
||||
<param name="generate.section.toc.level">2</param> |
||||
<param name="use.id.as.filename">1</param> |
||||
</stylesheet> |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue