summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/.gitignore1
-rw-r--r--Documentation/DocBook/Makefile7
-rw-r--r--Documentation/Makefile.sphinx63
-rw-r--r--Documentation/conf.py414
-rw-r--r--Documentation/index.rst23
-rw-r--r--Documentation/sphinx/convert_template.sed18
-rw-r--r--Documentation/sphinx/kernel-doc.py127
-rw-r--r--Documentation/sphinx/post_convert.sed23
-rwxr-xr-xDocumentation/sphinx/tmplcvt19
-rw-r--r--Makefile5
-rwxr-xr-xscripts/kernel-doc392
11 files changed, 948 insertions, 144 deletions
diff --git a/Documentation/.gitignore b/Documentation/.gitignore
new file mode 100644
index 000000000000..53752db253e3
--- /dev/null
+++ b/Documentation/.gitignore
@@ -0,0 +1 @@
+output
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index d70f9b68174e..e0c7e1e0590b 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -33,10 +33,6 @@ 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)
@@ -63,6 +59,9 @@ installmandocs: mandocs
sort -k 2 -k 1 | uniq -f 1 | sed -e 's: :/:' | \
xargs install -m 644 -t /usr/local/man/man9/
+# no-op for the DocBook toolchain
+epubdocs:
+
###
#External programs used
KERNELDOCXMLREF = $(srctree)/scripts/kernel-doc-xml-ref
diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx
new file mode 100644
index 000000000000..addf32309bc3
--- /dev/null
+++ b/Documentation/Makefile.sphinx
@@ -0,0 +1,63 @@
+# -*- makefile -*-
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXBUILD = sphinx-build
+SPHINXOPTS =
+PAPER =
+BUILDDIR = $(obj)/output
+
+# 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 " SKIP Sphinx $@ target."
+
+else # HAVE_SPHINX
+
+# User-friendly check for rst2pdf
+HAVE_RST2PDF := $(shell if python -c "import rst2pdf" >/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 = -D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src)
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+quiet_cmd_sphinx = SPHINX $@
+ cmd_sphinx = $(SPHINXBUILD) -b $2 $(ALLSPHINXOPTS) $(BUILDDIR)/$2
+
+htmldocs:
+ $(call cmd,sphinx,html)
+
+pdfdocs:
+ifeq ($(HAVE_RST2PDF),0)
+ $(warning The Python 'rst2pdf' module was not found. Make sure you have the module installed to produce PDF output.)
+ @echo " SKIP Sphinx $@ target."
+else # HAVE_RST2PDF
+ $(call cmd,sphinx,pdf)
+endif # HAVE_RST2PDF
+
+epubdocs:
+ $(call cmd,sphinx,epub)
+
+xmldocs:
+ $(call cmd,sphinx,xml)
+
+# no-ops for the Sphinx toolchain
+sgmldocs:
+psdocs:
+mandocs:
+installmandocs:
+
+cleandocs:
+ $(Q)rm -rf $(BUILDDIR)
+
+endif # HAVE_SPHINX
diff --git a/Documentation/conf.py b/Documentation/conf.py
new file mode 100644
index 000000000000..6cc41a0555a3
--- /dev/null
+++ b/Documentation/conf.py
@@ -0,0 +1,414 @@
+# -*- coding: utf-8 -*-
+#
+# The Linux Kernel 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
+
+# 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'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['kernel-doc']
+
+# Gracefully handle missing rst2pdf.
+try:
+ import rst2pdf
+ extensions += ['rst2pdf.pdfbuilder']
+except ImportError:
+ pass
+
+# 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 = 'The Linux Kernel'
+copyright = '2016, The kernel development community'
+author = 'The kernel 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:
+ sys.stderr.write('Warning: Could not extract kernel version\n')
+ 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 = 'C'
+
+# -- 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 = ['_static']
+
+# 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 = 'TheLinuxKerneldoc'
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+
+# Latex figure (float) alignment
+#'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'TheLinuxKernel.tex', 'The Linux Kernel Documentation',
+ 'The kernel 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, 'thelinuxkernel', 'The Linux Kernel 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, 'TheLinuxKernel', 'The Linux Kernel Documentation',
+ author, 'TheLinuxKernel', '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 = [
+ ('index', u'Kernel', u'Kernel', 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 = '..'
diff --git a/Documentation/index.rst b/Documentation/index.rst
new file mode 100644
index 000000000000..71a276f34c7f
--- /dev/null
+++ b/Documentation/index.rst
@@ -0,0 +1,23 @@
+.. The Linux Kernel documentation master file, created by
+ sphinx-quickstart on Fri Feb 12 13:51:46 2016.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to The Linux Kernel's documentation!
+============================================
+
+Nothing for you to see here *yet*. Please move along.
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/Documentation/sphinx/convert_template.sed b/Documentation/sphinx/convert_template.sed
new file mode 100644
index 000000000000..c1503fcca4ec
--- /dev/null
+++ b/Documentation/sphinx/convert_template.sed
@@ -0,0 +1,18 @@
+#
+# Pandoc doesn't grok <function> or <structname>, so convert them
+# ahead of time.
+#
+# Use the following escapes to pass through pandoc:
+# $bq = "`"
+# $lt = "<"
+# $gt = ">"
+#
+s%<function>\([^<(]\+\)()</function>%:c:func:$bq\1()$bq%g
+s%<function>\([^<(]\+\)</function>%:c:func:$bq\1()$bq%g
+s%<structname>struct *\([^<]\+\)</structname>%:c:type:$bqstruct \1 $lt\1$gt$bq%g
+s%struct <structname>\([^<]\+\)</structname>%:c:type:$bqstruct \1 $lt\1$gt$bq%g
+s%<structname>\([^<]\+\)</structname>%:c:type:$bqstruct \1 $lt\1$gt$bq%g
+#
+# Wrap docproc directives in para and code blocks.
+#
+s%^\(!.*\)$%<para><code>DOCPROC: \1</code></para>%
diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py
new file mode 100644
index 000000000000..4adfb0e91ecc
--- /dev/null
+++ b/Documentation/sphinx/kernel-doc.py
@@ -0,0 +1,127 @@
+# 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 os
+import subprocess
+import sys
+import re
+
+from docutils import nodes, statemachine
+from docutils.statemachine import ViewList
+from docutils.parsers.rst import directives
+from sphinx.util.compat import Directive
+
+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.flag,
+ 'internal': directives.flag,
+ }
+ 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]
+
+ # 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)
+ source = filename
+
+ # FIXME: make this nicer and more robust against errors
+ if 'export' in self.options:
+ cmd += ['-export']
+ elif 'internal' in self.options:
+ cmd += ['-internal']
+ 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]
+
+ cmd += [filename]
+
+ try:
+ env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd)))
+
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
+ out, err = p.communicate()
+
+ # python2 needs conversion to unicode.
+ # python3 with universal_newlines=True returns strings.
+ if sys.version_info.major < 3:
+ out, err = unicode(out, 'utf-8'), unicode(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, source, lineoffset)
+ lineoffset += 1
+
+ node = nodes.section()
+ node.document = self.state.document
+ self.state.nested_parse(result, self.content_offset, node)
+
+ return node.children
+
+ except Exception as e:
+ 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)
diff --git a/Documentation/sphinx/post_convert.sed b/Documentation/sphinx/post_convert.sed
new file mode 100644
index 000000000000..392770bac53b
--- /dev/null
+++ b/Documentation/sphinx/post_convert.sed
@@ -0,0 +1,23 @@
+#
+# Unescape.
+#
+s/$bq/`/g
+s/$lt/</g
+s/$gt/>/g
+#
+# pandoc thinks that both "_" needs to be escaped. Remove the extra
+# backslashes.
+#
+s/\\_/_/g
+#
+# Unwrap docproc directives.
+#
+s/^``DOCPROC: !E\(.*\)``$/.. kernel-doc:: \1\n :export:/
+s/^``DOCPROC: !I\(.*\)``$/.. kernel-doc:: \1\n :internal:/
+s/^``DOCPROC: !F\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :functions: \2/
+s/^``DOCPROC: !P\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :doc: \2/
+s/^``DOCPROC: \(!.*\)``$/.. WARNING: DOCPROC directive not supported: \1/
+#
+# Trim trailing whitespace.
+#
+s/[[:space:]]*$//
diff --git a/Documentation/sphinx/tmplcvt b/Documentation/sphinx/tmplcvt
new file mode 100755
index 000000000000..909a73065e0a
--- /dev/null
+++ b/Documentation/sphinx/tmplcvt
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Convert a template file into something like RST
+#
+# fix <function>
+# feed to pandoc
+# fix \_
+# title line?
+#
+
+in=$1
+rst=$2
+tmp=$rst.tmp
+
+cp $in $tmp
+sed --in-place -f convert_template.sed $tmp
+pandoc -s -S -f docbook -t rst -o $rst $tmp
+sed --in-place -f post_convert.sed $rst
+rm $tmp
diff --git a/Makefile b/Makefile
index 0f70de63cfdb..8908a51b895a 100644
--- a/Makefile
+++ b/Makefile
@@ -1412,8 +1412,11 @@ $(help-board-dirs): help-%:
# Documentation targets
# ---------------------------------------------------------------------------
-%docs: scripts_basic FORCE
+DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs
+PHONY += $(DOC_TARGETS)
+$(DOC_TARGETS): scripts_basic FORCE
$(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype
+ $(Q)$(MAKE) $(build)=Documentation -f $(srctree)/Documentation/Makefile.sphinx $@
$(Q)$(MAKE) $(build)=Documentation/DocBook $@
else # KBUILD_EXTMOD
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 2fc8fad5195e..5192213c5005 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -59,6 +59,12 @@ Output format selection (mutually exclusive):
-text Output plain text format.
Output selection (mutually exclusive):
+ -export Only output documentation for symbols that have been
+ exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()
+ in the same FILE.
+ -internal Only output documentation for symbols that have NOT been
+ exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()
+ in the same FILE.
-function NAME Only output documentation for the given function(s)
or DOC: section title(s). All other functions and DOC:
sections are ignored. May be specified multiple times.
@@ -68,6 +74,8 @@ Output selection (mutually exclusive):
Output selection modifiers:
-no-doc-sections Do not output DOC: sections.
+ -enable-lineno Enable output of #define LINENO lines. Only works with
+ reStructuredText format.
Other parameters:
-v Verbose output, more warnings and other information.
@@ -206,6 +214,10 @@ my $type_struct_xml = '\\&amp;((struct\s*)*[_\w]+)';
my $type_env = '(\$\w+)';
my $type_enum_full = '\&(enum)\s*([_\w]+)';
my $type_struct_full = '\&(struct)\s*([_\w]+)';
+my $type_typedef_full = '\&(typedef)\s*([_\w]+)';
+my $type_union_full = '\&(union)\s*([_\w]+)';
+my $type_member = '\&([_\w]+)((\.|->)[_\w]+)';
+my $type_member_func = $type_member . '\(\)';
# Output conversion substitutions.
# One for each output format
@@ -274,10 +286,16 @@ my $blankline_text = "";
# rst-mode
my @highlights_rst = (
[$type_constant, "``\$1``"],
- [$type_func, "\\:c\\:func\\:`\$1`"],
+ # Note: need to escape () to avoid func matching later
+ [$type_member_func, "\\:c\\:type\\:`\$1\$2\\\\(\\\\) <\$1>`"],
+ [$type_member, "\\:c\\:type\\:`\$1\$2 <\$1>`"],
+ [$type_func, "\\:c\\:func\\:`\$1()`"],
[$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
[$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
- [$type_struct, "\\:c\\:type\\:`struct \$1 <\$1>`"],
+ [$type_typedef_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
+ [$type_union_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
+ # in rst this can refer to any type
+ [$type_struct, "\\:c\\:type\\:`\$1`"],
[$type_param, "**\$1**"]
);
my $blankline_rst = "\n";
@@ -303,10 +321,19 @@ my $verbose = 0;
my $output_mode = "man";
my $output_preformatted = 0;
my $no_doc_sections = 0;
+my $enable_lineno = 0;
my @highlights = @highlights_man;
my $blankline = $blankline_man;
my $modulename = "Kernel API";
-my $function_only = 0;
+
+use constant {
+ OUTPUT_ALL => 0, # output all symbols and doc sections
+ OUTPUT_INCLUDE => 1, # output only specified symbols
+ OUTPUT_EXCLUDE => 2, # output everything except specified symbols
+ OUTPUT_EXPORTED => 3, # output exported symbols
+ OUTPUT_INTERNAL => 4, # output non-exported symbols
+};
+my $output_selection = OUTPUT_ALL;
my $show_not_found = 0;
my @build_time;
@@ -327,6 +354,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
# CAVEAT EMPTOR! Some of the others I localised may not want to be, which
# could cause "use of undefined value" or other bugs.
my ($function, %function_table, %parametertypes, $declaration_purpose);
+my $declaration_start_line;
my ($type, $declaration_name, $return_type);
my ($newsection, $newcontents, $prototype, $brcount, %source_map);
@@ -344,52 +372,61 @@ my $section_counter = 0;
my $lineprefix="";
-# states
-# 0 - normal code
-# 1 - looking for function name
-# 2 - scanning field start.
-# 3 - scanning prototype.
-# 4 - documentation block
-# 5 - gathering documentation outside main block
+# Parser states
+use constant {
+ STATE_NORMAL => 0, # normal code
+ STATE_NAME => 1, # looking for function name
+ STATE_FIELD => 2, # scanning field start
+ STATE_PROTO => 3, # scanning prototype
+ STATE_DOCBLOCK => 4, # documentation block
+ STATE_INLINE => 5, # gathering documentation outside main block
+};
my $state;
my $in_doc_sect;
-# Split Doc State
-# 0 - Invalid (Before start or after finish)
-# 1 - Is started (the /** was found inside a struct)
-# 2 - The @parameter header was found, start accepting multi paragraph text.
-# 3 - Finished (the */ was found)
-# 4 - Error - Comment without header was found. Spit a warning as it's not
-# proper kernel-doc and ignore the rest.
-my $split_doc_state;
+# Inline documentation state
+use constant {
+ STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE)
+ STATE_INLINE_NAME => 1, # looking for member name (@foo:)
+ STATE_INLINE_TEXT => 2, # looking for member documentation
+ STATE_INLINE_END => 3, # done
+ STATE_INLINE_ERROR => 4, # error - Comment without header was found.
+ # Spit a warning as it's not
+ # proper kernel-doc and ignore the rest.
+};
+my $inline_doc_state;
#declaration types: can be
# 'function', 'struct', 'union', 'enum', 'typedef'
my $decl_type;
-my $doc_special = "\@\%\$\&";
-
my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
my $doc_end = '\*/';
my $doc_com = '\s*\*\s*';
my $doc_com_body = '\s*\* ?';
my $doc_decl = $doc_com . '(\w+)';
-my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)';
+# @params and a strictly limited set of supported section names
+my $doc_sect = $doc_com . '\s*(\@\w+|description|context|returns?)\s*:(.*)';
my $doc_content = $doc_com_body . '(.*)';
my $doc_block = $doc_com . 'DOC:\s*(.*)?';
-my $doc_split_start = '^\s*/\*\*\s*$';
-my $doc_split_sect = '\s*\*\s*(@[\w\s]+):(.*)';
-my $doc_split_end = '^\s*\*/\s*$';
+my $doc_inline_start = '^\s*/\*\*\s*$';
+my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)';
+my $doc_inline_end = '^\s*\*/\s*$';
+my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;';
-my %constants;
my %parameterdescs;
+my %parameterdesc_start_lines;
my @parameterlist;
my %sections;
my @sectionlist;
+my %section_start_lines;
my $sectcheck;
my $struct_actual;
my $contents = "";
+my $new_start_line = 0;
+
+# the canonical section names. see also $doc_sect above.
my $section_default = "Description"; # default section
my $section_intro = "Introduction";
my $section = $section_default;
@@ -437,19 +474,27 @@ while ($ARGV[0] =~ m/^-(.*)/) {
} elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
$modulename = shift @ARGV;
} elsif ($cmd eq "-function") { # to only output specific functions
- $function_only = 1;
+ $output_selection = OUTPUT_INCLUDE;
$function = shift @ARGV;
$function_table{$function} = 1;
- } elsif ($cmd eq "-nofunction") { # to only output specific functions
- $function_only = 2;
+ } elsif ($cmd eq "-nofunction") { # output all except specific functions
+ $output_selection = OUTPUT_EXCLUDE;
$function = shift @ARGV;
$function_table{$function} = 1;
+ } elsif ($cmd eq "-export") { # only exported symbols
+ $output_selection = OUTPUT_EXPORTED;
+ %function_table = ()
+ } elsif ($cmd eq "-internal") { # only non-exported symbols
+ $output_selection = OUTPUT_INTERNAL;
+ %function_table = ()
} elsif ($cmd eq "-v") {
$verbose = 1;
} elsif (($cmd eq "-h") || ($cmd eq "--help")) {
usage();
} elsif ($cmd eq '-no-doc-sections') {
$no_doc_sections = 1;
+ } elsif ($cmd eq '-enable-lineno') {
+ $enable_lineno = 1;
} elsif ($cmd eq '-show-not-found') {
$show_not_found = 1;
}
@@ -467,6 +512,13 @@ sub get_kernel_version() {
return $version;
}
+#
+sub print_lineno {
+ my $lineno = shift;
+ if ($enable_lineno && defined($lineno)) {
+ print "#define LINENO " . $lineno . "\n";
+ }
+}
##
# dumps section contents to arrays/hashes intended for that purpose.
#
@@ -475,28 +527,32 @@ sub dump_section {
my $name = shift;
my $contents = join "\n", @_;
- if ($name =~ m/$type_constant/) {
- $name = $1;
-# print STDERR "constant section '$1' = '$contents'\n";
- $constants{$name} = $contents;
- } elsif ($name =~ m/$type_param/) {
+ if ($name =~ m/$type_param/) {
# print STDERR "parameter def '$1' = '$contents'\n";
$name = $1;
$parameterdescs{$name} = $contents;
$sectcheck = $sectcheck . $name . " ";
+ $parameterdesc_start_lines{$name} = $new_start_line;
+ $new_start_line = 0;
} elsif ($name eq "@\.\.\.") {
# print STDERR "parameter def '...' = '$contents'\n";
$name = "...";
$parameterdescs{$name} = $contents;
$sectcheck = $sectcheck . $name . " ";
+ $parameterdesc_start_lines{$name} = $new_start_line;
+ $new_start_line = 0;
} else {
# print STDERR "other section '$name' = '$contents'\n";
if (defined($sections{$name}) && ($sections{$name} ne "")) {
- print STDERR "${file}:$.: error: duplicate section name '$name'\n";
- ++$errors;
+ print STDERR "${file}:$.: warning: duplicate section name '$name'\n";
+ ++$warnings;
+ $sections{$name} .= $contents;
+ } else {
+ $sections{$name} = $contents;
+ push @sectionlist, $name;
+ $section_start_lines{$name} = $new_start_line;
+ $new_start_line = 0;
}
- $sections{$name} = $contents;
- push @sectionlist, $name;
}
}
@@ -512,15 +568,17 @@ sub dump_doc_section {
return;
}
- if (($function_only == 0) ||
- ( $function_only == 1 && defined($function_table{$name})) ||
- ( $function_only == 2 && !defined($function_table{$name})))
+ if (($output_selection == OUTPUT_ALL) ||
+ ($output_selection == OUTPUT_INCLUDE &&
+ defined($function_table{$name})) ||
+ ($output_selection == OUTPUT_EXCLUDE &&
+ !defined($function_table{$name})))
{
dump_section($file, $name, $contents);
output_blockhead({'sectionlist' => \@sectionlist,
'sections' => \%sections,
'module' => $modulename,
- 'content-only' => ($function_only != 0), });
+ 'content-only' => ($output_selection != OUTPUT_ALL), });
}
}
@@ -1736,7 +1794,10 @@ sub output_blockhead_rst(%) {
my ($parameter, $section);
foreach $section (@{$args{'sectionlist'}}) {
- print "**$section**\n\n";
+ if ($output_selection != OUTPUT_INCLUDE) {
+ print "**$section**\n\n";
+ }
+ print_lineno($section_start_lines{$section});
output_highlight_rst($args{'sections'}{$section});
print "\n";
}
@@ -1753,19 +1814,14 @@ sub output_highlight_rst {
die $@ if $@;
foreach $line (split "\n", $contents) {
- if ($line eq "") {
- print $lineprefix, $blankline;
- } else {
- $line =~ s/\\\\\\/\&/g;
- print $lineprefix, $line;
- }
- print "\n";
+ print $lineprefix . $line . "\n";
}
}
sub output_function_rst(%) {
my %args = %{$_[0]};
my ($parameter, $section);
+ my $oldprefix = $lineprefix;
my $start;
print ".. c:function:: ";
@@ -1790,29 +1846,37 @@ sub output_function_rst(%) {
print $type . " " . $parameter;
}
}
- print ")\n\n " . $args{'purpose'} . "\n\n";
+ print ")\n\n";
+ print_lineno($declaration_start_line);
+ $lineprefix = " ";
+ output_highlight_rst($args{'purpose'});
+ print "\n";
- print ":Parameters:\n\n";
+ print "**Parameters**\n\n";
+ $lineprefix = " ";
foreach $parameter (@{$args{'parameterlist'}}) {
my $parameter_name = $parameter;
#$parameter_name =~ s/\[.*//;
$type = $args{'parametertypes'}{$parameter};
if ($type ne "") {
- print " ``$type $parameter``\n";
+ print "``$type $parameter``\n";
} else {
- print " ``$parameter``\n";
+ print "``$parameter``\n";
}
- if ($args{'parameterdescs'}{$parameter_name} ne $undescribed) {
- my $oldprefix = $lineprefix;
- $lineprefix = " ";
+
+ print_lineno($parameterdesc_start_lines{$parameter_name});
+
+ if (defined($args{'parameterdescs'}{$parameter_name}) &&
+ $args{'parameterdescs'}{$parameter_name} ne $undescribed) {
output_highlight_rst($args{'parameterdescs'}{$parameter_name});
- $lineprefix = $oldprefix;
} else {
- print "\n _undescribed_\n";
+ print " *undescribed*\n";
}
print "\n";
}
+
+ $lineprefix = $oldprefix;
output_section_rst(@_);
}
@@ -1820,10 +1884,11 @@ sub output_section_rst(%) {
my %args = %{$_[0]};
my $section;
my $oldprefix = $lineprefix;
- $lineprefix = " ";
+ $lineprefix = "";
foreach $section (@{$args{'sectionlist'}}) {
- print ":$section:\n\n";
+ print "**$section**\n\n";
+ print_lineno($section_start_lines{$section});
output_highlight_rst($args{'sections'}{$section});
print "\n";
}
@@ -1834,24 +1899,28 @@ sub output_section_rst(%) {
sub output_enum_rst(%) {
my %args = %{$_[0]};
my ($parameter);
+ my $oldprefix = $lineprefix;
my $count;
my $name = "enum " . $args{'enum'};
print "\n\n.. c:type:: " . $name . "\n\n";
- print " " . $args{'purpose'} . "\n\n";
+ print_lineno($declaration_start_line);
+ $lineprefix = " ";
+ output_highlight_rst($args{'purpose'});
+ print "\n";
- print "..\n\n:Constants:\n\n";
- my $oldprefix = $lineprefix;
- $lineprefix = " ";
+ print "**Constants**\n\n";
+ $lineprefix = " ";
foreach $parameter (@{$args{'parameterlist'}}) {
- print " `$parameter`\n";
+ print "``$parameter``\n";
if ($args{'parameterdescs'}{$parameter} ne $undescribed) {
output_highlight_rst($args{'parameterdescs'}{$parameter});
} else {
- print " undescribed\n";
+ print " *undescribed*\n";
}
print "\n";
}
+
$lineprefix = $oldprefix;
output_section_rst(@_);
}
@@ -1859,30 +1928,37 @@ sub output_enum_rst(%) {
sub output_typedef_rst(%) {
my %args = %{$_[0]};
my ($parameter);
- my $count;
+ my $oldprefix = $lineprefix;
my $name = "typedef " . $args{'typedef'};
- ### FIXME: should the name below contain "typedef" or not?
print "\n\n.. c:type:: " . $name . "\n\n";
- print " " . $args{'purpose'} . "\n\n";
+ print_lineno($declaration_start_line);
+ $lineprefix = " ";
+ output_highlight_rst($args{'purpose'});
+ print "\n";
+ $lineprefix = $oldprefix;
output_section_rst(@_);
}
sub output_struct_rst(%) {
my %args = %{$_[0]};
my ($parameter);
+ my $oldprefix = $lineprefix;
my $name = $args{'type'} . " " . $args{'struct'};
print "\n\n.. c:type:: " . $name . "\n\n";
- print " " . $args{'purpose'} . "\n\n";
+ print_lineno($declaration_start_line);
+ $lineprefix = " ";
+ output_highlight_rst($args{'purpose'});
+ print "\n";
- print ":Definition:\n\n";
- print " ::\n\n";
+ print "**Definition**\n\n";
+ print "::\n\n";
print " " . $args{'type'} . " " . $args{'struct'} . " {\n";
foreach $parameter (@{$args{'parameterlist'}}) {
if ($parameter =~ /^#/) {
- print " " . "$parameter\n";
+ print " " . "$parameter\n";
next;
}
@@ -1903,7 +1979,8 @@ sub output_struct_rst(%) {
}
print " };\n\n";
- print ":Members:\n\n";
+ print "**Members**\n\n";
+ $lineprefix = " ";
foreach $parameter (@{$args{'parameterlist'}}) {
($parameter =~ /^#/) && next;
@@ -1912,14 +1989,14 @@ sub output_struct_rst(%) {
($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
- print " `$type $parameter`" . "\n";
- my $oldprefix = $lineprefix;
- $lineprefix = " ";
+ print_lineno($parameterdesc_start_lines{$parameter_name});
+ print "``$type $parameter``\n";
output_highlight_rst($args{'parameterdescs'}{$parameter_name});
- $lineprefix = $oldprefix;
print "\n";
}
print "\n";
+
+ $lineprefix = $oldprefix;
output_section_rst(@_);
}
@@ -1969,9 +2046,13 @@ sub output_declaration {
my $name = shift;
my $functype = shift;
my $func = "output_${functype}_$output_mode";
- if (($function_only==0) ||
- ( $function_only == 1 && defined($function_table{$name})) ||
- ( $function_only == 2 && !($functype eq "function" && defined($function_table{$name}))))
+ if (($output_selection == OUTPUT_ALL) ||
+ (($output_selection == OUTPUT_INCLUDE ||
+ $output_selection == OUTPUT_EXPORTED) &&
+ defined($function_table{$name})) ||
+ (($output_selection == OUTPUT_EXCLUDE ||
+ $output_selection == OUTPUT_INTERNAL) &&
+ !($functype eq "function" && defined($function_table{$name}))))
{
&$func(@_);
$section_counter++;
@@ -2471,7 +2552,6 @@ sub dump_function($$) {
sub reset_state {
$function = "";
- %constants = ();
%parameterdescs = ();
%parametertypes = ();
@parameterlist = ();
@@ -2481,8 +2561,8 @@ sub reset_state {
$struct_actual = "";
$prototype = "";
- $state = 0;
- $split_doc_state = 0;
+ $state = STATE_NORMAL;
+ $inline_doc_state = STATE_INLINE_NA;
}
sub tracepoint_munge($) {
@@ -2545,7 +2625,7 @@ sub syscall_munge() {
}
}
-sub process_state3_function($$) {
+sub process_proto_function($$) {
my $x = shift;
my $file = shift;
@@ -2575,7 +2655,7 @@ sub process_state3_function($$) {
}
}
-sub process_state3_type($$) {
+sub process_proto_type($$) {
my $x = shift;
my $file = shift;
@@ -2657,6 +2737,7 @@ sub process_file($) {
my $in_purpose = 0;
my $initial_section_counter = $section_counter;
my ($orig_file) = @_;
+ my $leading_space;
if (defined($ENV{'SRCTREE'})) {
$file = "$ENV{'SRCTREE'}" . "/" . $orig_file;
@@ -2674,6 +2755,17 @@ sub process_file($) {
return;
}
+ # two passes for -export and -internal
+ if ($output_selection == OUTPUT_EXPORTED ||
+ $output_selection == OUTPUT_INTERNAL) {
+ while (<IN>) {
+ if (/$export_symbol/o) {
+ $function_table{$2} = 1;
+ }
+ }
+ seek(IN, 0, 0);
+ }
+
$. = 1;
$section_counter = 0;
@@ -2681,15 +2773,18 @@ sub process_file($) {
while (s/\\\s*$//) {
$_ .= <IN>;
}
- if ($state == 0) {
+ if ($state == STATE_NORMAL) {
if (/$doc_start/o) {
- $state = 1; # next line is always the function name
+ $state = STATE_NAME; # next line is always the function name
$in_doc_sect = 0;
+ $declaration_start_line = $. + 1;
}
- } elsif ($state == 1) { # this line is the function name (always)
+ } elsif ($state == STATE_NAME) {# this line is the function name (always)
if (/$doc_block/o) {
- $state = 4;
+ $state = STATE_DOCBLOCK;
$contents = "";
+ $new_start_line = $. + 1;
+
if ( $1 eq "" ) {
$section = $section_intro;
} else {
@@ -2702,7 +2797,12 @@ sub process_file($) {
$identifier = $1;
}
- $state = 2;
+ $state = STATE_FIELD;
+ # if there's no @param blocks need to set up default section
+ # here
+ $contents = "";
+ $section = $section_default;
+ $new_start_line = $. + 1;
if (/-(.*)/) {
# strip leading/trailing/multiple spaces
$descr= $1;
@@ -2740,13 +2840,25 @@ sub process_file($) {
print STDERR "${file}:$.: warning: Cannot understand $_ on line $.",
" - I thought it was a doc line\n";
++$warnings;
- $state = 0;
+ $state = STATE_NORMAL;
}
- } elsif ($state == 2) { # look for head: lines, and include content
- if (/$doc_sect/o) {
+ } elsif ($state == STATE_FIELD) { # look for head: lines, and include content
+ if (/$doc_sect/i) { # case insensitive for supported section names
$newsection = $1;
$newcontents = $2;
+ # map the supported section names to the canonical names
+ if ($newsection =~ m/^description$/i) {
+ $newsection = $section_default;
+ } elsif ($newsection =~ m/^context$/i) {
+ $newsection = $section_context;
+ } elsif ($newsection =~ m/^returns?$/i) {
+ $newsection = $section_return;
+ } elsif ($newsection =~ m/^\@return$/) {
+ # special: @return is a section, not a param description
+ $newsection = $section_return;
+ }
+
if (($contents ne "") && ($contents ne "\n")) {
if (!$in_doc_sect && $verbose) {
print STDERR "${file}:$.: warning: contents before sections\n";
@@ -2759,14 +2871,16 @@ sub process_file($) {
$in_doc_sect = 1;
$in_purpose = 0;
$contents = $newcontents;
+ $new_start_line = $.;
+ while ((substr($contents, 0, 1) eq " ") ||
+ substr($contents, 0, 1) eq "\t") {
+ $contents = substr($contents, 1);
+ }
if ($contents ne "") {
- while ((substr($contents, 0, 1) eq " ") ||
- substr($contents, 0, 1) eq "\t") {
- $contents = substr($contents, 1);
- }
$contents .= "\n";
}
$section = $newsection;
+ $leading_space = undef;
} elsif (/$doc_end/) {
if (($contents ne "") && ($contents ne "\n")) {
dump_section($file, $section, xml_escape($contents));
@@ -2780,7 +2894,7 @@ sub process_file($) {
}
$prototype = "";
- $state = 3;
+ $state = STATE_PROTO;
$brcount = 0;
# print STDERR "end of doc comment, looking for prototype\n";
} elsif (/$doc_content/) {
@@ -2791,6 +2905,7 @@ sub process_file($) {
dump_section($file, $section, xml_escape($contents));
$section = $section_default;
$contents = "";
+ $new_start_line = $.;
} else {
$contents .= "\n";
}
@@ -2801,87 +2916,86 @@ sub process_file($) {
$declaration_purpose .= " " . xml_escape($1);
$declaration_purpose =~ s/\s+/ /g;
} else {
- $contents .= $1 . "\n";
+ my $cont = $1;
+ if ($section =~ m/^@/ || $section eq $section_context) {
+ if (!defined $leading_space) {
+ if ($cont =~ m/^(\s+)/) {
+ $leading_space = $1;
+ } else {
+ $leading_space = "";
+ }
+ }
+
+ $cont =~ s/^$leading_space//;
+ }
+ $contents .= $cont . "\n";
}
} else {
# i dont know - bad line? ignore.
print STDERR "${file}:$.: warning: bad line: $_";
++$warnings;
}
- } elsif ($state == 5) { # scanning for split parameters
+ } elsif ($state == STATE_INLINE) { # scanning for inline parameters
# First line (state 1) needs to be a @parameter
- if ($split_doc_state == 1 && /$doc_split_sect/o) {
+ if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) {
$section = $1;
$contents = $2;
+ $new_start_line = $.;
if ($contents ne "") {
while ((substr($contents, 0, 1) eq " ") ||
substr($contents, 0, 1) eq "\t") {
$contents = substr($contents, 1);
}
- $contents .= "\n";
+ $contents .= "\n";
}
- $split_doc_state = 2;
+ $inline_doc_state = STATE_INLINE_TEXT;
# Documentation block end */
- } elsif (/$doc_split_end/) {
+ } elsif (/$doc_inline_end/) {
if (($contents ne "") && ($contents ne "\n")) {
dump_section($file, $section, xml_escape($contents));
$section = $section_default;
$contents = "";
}
- $state = 3;
- $split_doc_state = 0;
+ $state = STATE_PROTO;
+ $inline_doc_state = STATE_INLINE_NA;
# Regular text
} elsif (/$doc_content/) {
- if ($split_doc_state == 2) {
+ if ($inline_doc_state == STATE_INLINE_TEXT) {
$contents .= $1 . "\n";
- } elsif ($split_doc_state == 1) {
- $split_doc_state = 4;
+ # nuke leading blank lines
+ if ($contents =~ /^\s*$/) {
+ $contents = "";
+ }
+ } elsif ($inline_doc_state == STATE_INLINE_NAME) {
+ $inline_doc_state = STATE_INLINE_ERROR;
print STDERR "Warning(${file}:$.): ";
print STDERR "Incorrect use of kernel-doc format: $_";
++$warnings;
}
}
- } elsif ($state == 3) { # scanning for function '{' (end of prototype)
- if (/$doc_split_start/) {
- $state = 5;
- $split_doc_state = 1;
+ } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype)
+ if (/$doc_inline_start/) {
+ $state = STATE_INLINE;
+ $inline_doc_state = STATE_INLINE_NAME;
} elsif ($decl_type eq 'function') {
- process_state3_function($_, $file);
+ process_proto_function($_, $file);
} else {
- process_state3_type($_, $file);
+ process_proto_type($_, $file);
}
- } elsif ($state == 4) {
- # Documentation block
- if (/$doc_block/) {
- dump_doc_section($file, $section, xml_escape($contents));
- $contents = "";
- $function = "";
- %constants = ();
- %parameterdescs = ();
- %parametertypes = ();
- @parameterlist = ();
- %sections = ();
- @sectionlist = ();
- $prototype = "";
- if ( $1 eq "" ) {
- $section = $section_intro;
- } else {
- $section = $1;
- }
- }
- elsif (/$doc_end/)
+ } elsif ($state == STATE_DOCBLOCK) {
+ if (/$doc_end/)
{
dump_doc_section($file, $section, xml_escape($contents));
+ $section = $section_default;
$contents = "";
$function = "";
- %constants = ();
%parameterdescs = ();
%parametertypes = ();
@parameterlist = ();
%sections = ();
@sectionlist = ();
$prototype = "";
- $state = 0;
+ $state = STATE_NORMAL;
}
elsif (/$doc_content/)
{
@@ -2898,7 +3012,7 @@ sub process_file($) {
}
if ($initial_section_counter == $section_counter) {
print STDERR "${file}:1: warning: no structured comments found\n";
- if (($function_only == 1) && ($show_not_found == 1)) {
+ if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) {
print STDERR " Was looking for '$_'.\n" for keys %function_table;
}
if ($output_mode eq "xml") {