genrest: Generate RST links in a less hacky way

Use the new Kconfiglib expression printing customization functionality
to get rid of the hacky expr_str() overriding.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
This commit is contained in:
Ulf Magnusson 2018-08-10 07:13:51 +02:00 committed by Anas Nashif
parent 6686efb838
commit bf8efdbf5b

View file

@ -9,38 +9,41 @@ import textwrap
import kconfiglib
# "Extend" the standard kconfiglib.expr_str() to turn references to defined
# Kconfig symbols into RST links. Symbol.__str__() will then use the extended
# version.
#
# This is a bit hacky, but better than reimplementing Symbol.__str__() and/or
# kconfiglib.expr_str().
def expr_str_rst(expr):
# Skip constant and undefined symbols by checking if expr.nodes is empty
if isinstance(expr, kconfiglib.Symbol) and expr.nodes:
# The "\ " avoids RST issues for !CONFIG_FOO -- see
# http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#character-level-inline-markup
return r"\ :option:`{0} <CONFIG_{0}>`".format(expr.name)
def rst_link(sc):
# Returns an RST link (string) for the symbol/choice 'sc', or the normal
# Kconfig expression format (e.g. just the name) for 'sc' if it can't be
# turned into a link.
# Choices appear as dependencies of choice symbols.
#
# Use a :ref: instead of an :option:. With an :option:, we'd have to have
# an '.. option::' in the choice reference page as well. That would make
# the internal choice ID show up in the documentation.
#
# Note that the first pair of <...> is non-syntactic here. We just display
# choices links within <> in the documentation.
if isinstance(expr, kconfiglib.Choice):
if isinstance(sc, kconfiglib.Symbol):
# Skip constant and undefined symbols by checking if expr.nodes is
# empty
if sc.nodes:
# The "\ " avoids RST issues for !CONFIG_FOO -- see
# http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#character-level-inline-markup
return r"\ :option:`{0} <CONFIG_{0}>`".format(sc.name)
elif isinstance(sc, kconfiglib.Choice):
# Choices appear as dependencies of choice symbols.
#
# Use a :ref: instead of an :option:. With an :option:, we'd have to have
# an '.. option::' in the choice reference page as well. That would make
# the internal choice ID show up in the documentation.
#
# Note that the first pair of <...> is non-syntactic here. We just display
# choices links within <> in the documentation.
return r"\ :ref:`<{}> <{}>`" \
.format(choice_desc(expr), choice_id(expr))
.format(choice_desc(sc), choice_id(sc))
# We'll end up back in expr_str_rst() when expr_str_orig() does recursive
# calls for subexpressions
return expr_str_orig(expr)
# Can't turn 'sc' into a link. Use the standard Kconfig format.
return kconfiglib.standard_sc_expr_str(sc)
expr_str_orig = kconfiglib.expr_str
kconfiglib.expr_str = expr_str_rst
def expr_str(expr):
# Returns the Kconfig representation of 'expr', with symbols/choices turned
# into RST links
return kconfiglib.expr_str(expr, rst_link)
INDEX_RST_HEADER = """.. _configuration:
@ -202,7 +205,7 @@ def direct_deps_rst(sc):
"===================\n\n" \
"{}\n\n" \
"*(Includes any dependencies from if's and menus.)*\n\n" \
.format(kconfiglib.expr_str(sc.direct_dep))
.format(expr_str(sc.direct_dep))
def defaults_rst(sc):
@ -219,9 +222,9 @@ def defaults_rst(sc):
if sc.defaults:
for value, cond in sc.defaults:
rst += "- " + kconfiglib.expr_str(value)
rst += "- " + expr_str(value)
if cond is not sc.kconfig.y:
rst += " if " + kconfiglib.expr_str(cond)
rst += " if " + expr_str(cond)
rst += "\n"
else:
@ -250,7 +253,7 @@ def choice_syms_rst(choice):
for sym in choice.syms:
# Generates a link
rst += "- {}\n".format(kconfiglib.expr_str(sym))
rst += "- {}\n".format(expr_str(sym))
return rst + "\n"
@ -279,8 +282,7 @@ def select_imply_rst(sym):
# In both cases, we can split on AND and pick the first
# operand.
# kconfiglib.expr_str() generates a link
rst += "- {}\n".format(kconfiglib.expr_str(
rst += "- {}\n".format(rst_link(
kconfiglib.split_expr(select, kconfiglib.AND)[0]))
rst += "\n"
@ -329,7 +331,7 @@ def kconfig_definition_rst(sc):
"At ``{}:{}``, in menu ``{}``:\n\n"
".. parsed-literal::\n\n"
"{}".format(node.filename, node.linenr, menu_path(node),
textwrap.indent(str(node), " "*4))
textwrap.indent(node.custom_str(rst_link), " "*4))
for node in sc.nodes)
rst += "\n\n*(Definitions include propagated dependencies, " \