mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Markus Heiser <markus.heiser@darmarit.de>
To: Jonathan Corbet <corbet@lwn.net>,
	Mauro Carvalho Chehab <mchehab@infradead.org>,
	Jani Nikula <jani.nikula@intel.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Matthew Wilcox <mawilcox@microsoft.com>
Cc: Markus Heiser <markus.heiser@darmarit.de>,
	"linux-doc @ vger . kernel . org List"
	<linux-doc@vger.kernel.org>,
	"linux-kernel @ vger . kernel . org List" 
	<linux-kernel@vger.kernel.org>
Subject: [RFC PATCH v1 5/6] kernel-doc: add kerneldoc-src2rst command
Date: Tue, 24 Jan 2017 20:52:43 +0100	[thread overview]
Message-ID: <1485287564-24205-6-git-send-email-markus.heiser@darmarit.de> (raw)
In-Reply-To: <1485287564-24205-1-git-send-email-markus.heiser@darmarit.de>

this patch adds a command to auto-generate documentation from kernel's
source tree.::

  scripts/kerneldoc-src2rst --help

E.g. to autodoc the kernel's ./include folder use::

  scripts/kerneldoc-src2rst ./include /tmp/test123

>From the resulting reST-doctree you can build HTML rendered output like
the one in [1]. I use it to see, if patches on the kernel_doc.py parser
cause a regression (compare reST before/after the patch). Autodoc the
whole source tree takes a long time. To speed up, the src2rst module
uses multiprocessing from [2]. This means, it consumes all your CPUs. If
you don't want this, use option '--threads=n'.

[1] https://h2626237.stratoserver.net/kernel/linux_src_doc/index.html
[2] https://docs.python.org/3.6/library/multiprocessing.html

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
---
 Documentation/sphinx/src2rst.py | 229 ++++++++++++++++++++++++++++++++++++++++
 scripts/kerneldoc-src2rst       |  11 ++
 2 files changed, 240 insertions(+)
 create mode 100755 Documentation/sphinx/src2rst.py
 create mode 100755 scripts/kerneldoc-src2rst

diff --git a/Documentation/sphinx/src2rst.py b/Documentation/sphinx/src2rst.py
new file mode 100755
index 0000000..d8d6e7b
--- /dev/null
+++ b/Documentation/sphinx/src2rst.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8; mode: python -*-
+# pylint: disable=C0103
+
+u"""
+    src2rst
+    ~~~~~~~
+
+    Implementation of the ``kerneldoc-src2rst`` command.
+
+    :copyright:  Copyright (C) 2016  Markus Heiser
+    :license:    GPL Version 2, June 1991 see Linux/COPYING for details.
+
+    The ``kerneldoc-src2rst`` command extracts documentation from Linux kernel's
+    source code comments, see ``--help``::
+
+        $ kerneldoc-src2rst --help
+
+"""
+
+# ------------------------------------------------------------------------------
+# imports
+# ------------------------------------------------------------------------------
+
+import sys
+import argparse
+import re
+import multiprocessing
+
+import six
+
+from fspath import FSPath, OS_ENV
+import kernel_doc as kerneldoc
+
+# ------------------------------------------------------------------------------
+# config
+# ------------------------------------------------------------------------------
+
+MARKUP = "kernel-doc" # "reST"
+MSG    = lambda msg: sys.__stderr__.write("INFO : %s\n" % msg)
+ERR    = lambda msg: sys.__stderr__.write("ERROR: %s\n" % msg)
+FATAL  = lambda msg: sys.__stderr__.write("FATAL: %s\n" % msg)
+IGNORE = ['kernel-doc.rst']
+
+TEMPLATE_INDEX=u"""\
+.. -*- coding: utf-8; mode: rst -*-
+
+================================================================================
+%(title)s
+================================================================================
+
+.. toctree::
+    :maxdepth: 1
+
+"""
+
+CMD     = None # global used by multiprocessing
+SRCTREE = FSPath(OS_ENV.get("srctree", ""))
+
+# ------------------------------------------------------------------------------
+def main():
+# ------------------------------------------------------------------------------
+
+    global CMD # pylint: disable=W0603, W0621
+
+    CLI = argparse.ArgumentParser(
+        description = ("Parse *kernel-doc* comments from source code")
+        , formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+
+    CLI.add_argument(
+        "srctree"
+        , help    = "Folder of source code."
+        , type    = lambda x: FSPath(x).ABSPATH)
+
+    CLI.add_argument(
+        "doctree"
+        , help    = "Folder to place reST documentation."
+        , type    = lambda x: FSPath(x).ABSPATH)
+
+    CLI.add_argument(
+        "--sloppy"
+        , action  = "store_true"
+        , help    = "Sloppy comment check, reports only severe errors.")
+
+    CLI.add_argument(
+        "--force"
+        , action  = "store_true"
+        , help    = "Don't stop if doctree exists.")
+
+    CLI.add_argument(
+        "--threads"
+        , type    =  int
+        , default = multiprocessing.cpu_count()
+        , help    = "Use up to n threads.")
+
+    CLI.add_argument(
+        "--markup"
+        , choices = ["reST", "kernel-doc", "auto"]
+        , default = "auto"
+        , help    = (
+            "Markup of the comments. Change this option only if you know"
+            " what you do. New comments must be marked up with reST!"))
+
+    CMD = CLI.parse_args()
+
+    if not CMD.srctree.EXISTS:
+        ERR("%s does not exists." % CMD.srctree)
+        sys.exit(42)
+
+    if not CMD.srctree.ISDIR:
+        ERR("%s is not a folder." % CMD.srctree)
+        sys.exit(42)
+
+    if not CMD.force and CMD.doctree.EXISTS:
+        ERR("%s is in the way, remove it first" % CMD.doctree)
+        sys.exit(42)
+
+    CMD.rst_files = set()
+    if CMD.markup == "auto":
+        CMD.rst_files = docgrep(SRCTREE/"Documentation")
+
+    pool = multiprocessing.Pool(CMD.threads)
+    pool.map(autodoc_file, gather_filenames(CMD))
+    pool.close()
+    pool.join()
+
+    insert_index_files(CMD.doctree)
+
+# ------------------------------------------------------------------------------
+def gather_filenames(cmd):
+# ------------------------------------------------------------------------------
+    MSG("gather files ...")
+
+    for fname in cmd.srctree.reMatchFind(r"^.*\.[ch]$"):
+        if fname.startswith(CMD.srctree/"Documentation"):
+            continue
+        yield fname
+
+# ------------------------------------------------------------------------------
+def autodoc_file(fname):
+# ------------------------------------------------------------------------------
+
+    fname  = fname.relpath(CMD.srctree)
+    markup = CMD.markup
+
+    if CMD.markup == "kernel-doc" and fname in CMD.rst_files:
+        markup = "reST"
+
+    opts = kerneldoc.ParseOptions(
+        rel_fname       = fname
+        , src_tree      = CMD.srctree
+        , verbose_warn  = not (CMD.sloppy)
+        , markup        = markup )
+
+    parser = kerneldoc.Parser(opts, kerneldoc.NullTranslator())
+    try:
+        parser.parse()
+    except Exception: # pylint: disable=W0703
+        FATAL("kernel-doc markup of %s seems buggy / can't parse" % opts.fname)
+        return
+
+    if not parser.ctx.dump_storage:
+        # no kernel-doc comments found
+        MSG("parsed: NONE comments: %s" % opts.fname)
+        return
+
+    MSG("parsed: %4d comments: %s" % (len(parser.ctx.dump_storage), opts.fname))
+
+    try:
+        rst = six.StringIO()
+        translator = kerneldoc.ReSTTranslator()
+        opts.out   = rst
+
+        # First try to output reST, this might fail, because the kernel-doc
+        # parser part is to tollerant ("bad lines", "function name and function
+        # declaration are different", etc ...).
+        parser.parse_dump_storage(translator=translator)
+
+        outFile = CMD.doctree / fname.replace(".","_") + ".rst"
+        outFile.DIRNAME.makedirs()
+        with outFile.openTextFile(mode="w") as out:
+            out.write(rst.getvalue())
+
+    except Exception: # pylint: disable=W0703
+        FATAL("kernel-doc markup of %s seems buggy / can't parse" % opts.fname)
+        return
+
+# ------------------------------------------------------------------------------
+def insert_index_files(folder):
+# ------------------------------------------------------------------------------
+
+    for folder, dirnames, filenames in folder.walk():
+        ctx = kerneldoc.Container( title = folder.FILENAME )
+        dirnames.sort()
+        filenames.sort()
+        indexFile = folder / "index.rst"
+        MSG("create index: %s" % indexFile)
+        with indexFile.openTextFile(mode="w") as index:
+            index.write(TEMPLATE_INDEX % ctx)
+            for d in dirnames:
+                index.write("    %s/index\n" % d.FILENAME)
+            for f in filenames:
+                if f.FILENAME == "index":
+                    continue
+                index.write("    %s\n" % f.FILENAME)
+
+# ------------------------------------------------------------------------------
+def docgrep(folder):
+# ------------------------------------------------------------------------------
+
+    # Hackisch script to grep all '.. kernel-doc::' directives. The assumption
+    # is, that comments from the source files used in those directives are
+    # allready migratetd to the reST format. I guess that (ATM) 95-99% of the
+    # comments are not migrated, those will be parsed with the old kernel-doc
+    # comment style introduced by the old DocBook toolchain.
+
+    pat = re.compile(r"^\s*\.\.\s+kernel-doc::\s*([^\s]+)\s*$")
+    out = set()
+    for rstFile in folder.reMatchFind(r".*\.rst"):
+        if rstFile.BASENAME in IGNORE:
+            continue
+        #print(rstFile)
+        with rstFile.openTextFile() as f:
+            for l in f:
+                match = pat.search(l)
+                if match:
+                    #print(match.group(1))
+                    out.add(match.group(1))
+    return sorted(out)
diff --git a/scripts/kerneldoc-src2rst b/scripts/kerneldoc-src2rst
new file mode 100755
index 0000000..6c5e8b1
--- /dev/null
+++ b/scripts/kerneldoc-src2rst
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+
+import sys
+from os import path
+
+linuxdoc = path.abspath(path.join(path.dirname(__file__), '..'))
+linuxdoc = path.join(linuxdoc, 'Documentation', 'sphinx')
+sys.path.insert(0, linuxdoc)
+
+import src2rst
+src2rst.main()
-- 
2.7.4

  parent reply	other threads:[~2017-01-24 19:53 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-24 19:52 [RFC PATCH v1 0/6] pure python kernel-doc parser and more Markus Heiser
2017-01-24 19:52 ` [RFC PATCH v1 1/6] kernel-doc: pure python kernel-doc parser (preparation) Markus Heiser
2017-01-24 19:52 ` [RFC PATCH v1 2/6] kernel-doc: replace kernel-doc perl parser with a pure python one (WIP) Markus Heiser
2017-01-25  0:13   ` Jonathan Corbet
2017-01-25  6:37     ` Daniel Vetter
2017-01-25  7:37       ` Markus Heiser
2017-01-25 10:24     ` Jani Nikula
2017-01-25 10:35       ` Daniel Vetter
2017-01-25 19:07       ` Markus Heiser
2017-01-25 20:59         ` Jani Nikula
2017-01-26  9:54           ` Markus Heiser
2017-01-26 10:16             ` Jani Nikula
2017-01-26 18:50         ` Jonathan Corbet
2017-01-26 19:26           ` Jani Nikula
2017-01-27  9:46             ` Markus Heiser
2017-01-24 19:52 ` [RFC PATCH v1 3/6] kernel-doc: add kerneldoc-lint command Markus Heiser
2017-01-25  6:38   ` Daniel Vetter
2017-01-25  8:21     ` Jani Nikula
2017-01-25  9:34       ` Markus Heiser
2017-01-25 10:08         ` Jani Nikula
2017-01-24 19:52 ` [RFC PATCH v1 4/6] kernel-doc: insert TODOs on kernel-doc errors Markus Heiser
2017-01-24 19:52 ` Markus Heiser [this message]
2017-01-24 19:52 ` [RFC PATCH v1 6/6] kernel-doc: add man page builder (target mandocs) Markus Heiser

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1485287564-24205-6-git-send-email-markus.heiser@darmarit.de \
    --to=markus.heiser@darmarit.de \
    --cc=corbet@lwn.net \
    --cc=daniel.vetter@ffwll.ch \
    --cc=jani.nikula@intel.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mawilcox@microsoft.com \
    --cc=mchehab@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®