Skip to content

Commit

Permalink
[fix] add missing declaration type 'macro' to the parser
Browse files Browse the repository at this point in the history
Related: #20
Closes: #19

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
  • Loading branch information
return42 committed Nov 18, 2022
1 parent 9d93a7e commit 90bb094
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 20 deletions.
36 changes: 36 additions & 0 deletions docs/linuxdoc-howto/all-in-a-tumble.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,3 +516,39 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map,
* Returns true if the given timings are valid.
*/
typedef bool v4l2_check_dv_timings_fnc(const struct v4l2_dv_timings *t, void *handle);


/* parse-SNIP: ADD_macro */
/**
* macro ADD - Function like macro to add two values
*
* @first: first value
* @second: second value
*
* Is replaced by a addition of @first and @second.
*/
#define ADD(first, second) (first) + (second)
/* parse-SNAP: */

/**
* iosys_map_wr_field - Write to a member of a struct in the iosys_map
*
* @map__: The iosys_map structure
* @struct_offset__: Offset from the beggining of the map, where the struct
* is located
* @struct_type__: The struct describing the layout of the mapping
* @field__: Member of the struct to read
* @val__: Value to write
*
* Write a value to the iosys_map considering its layout is described by a C
* struct starting at @struct_offset__. The field offset and size is calculated
* and the @val__ is written. If the field access would incur in un-aligned
* access, then either iosys_map_memcpy_to() needs to be used or the
* architecture must support it. Refer to iosys_map_rd_field() for expected
* usage and memory layout.
*/
#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({ \
struct_type__ *s; \
iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__), \
typeof(s->field__), val__); \
})
14 changes: 14 additions & 0 deletions docs/linuxdoc-howto/kernel-doc-syntax.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ they are marked appropriately in the output format.

Rendered example: :ref:`example.user_function`

.. _kernel-doc-syntax-macro:

macro
=====

Documenting macros is similar to documenting :ref:`kernel-doc-syntax-functions`.

.. kernel-doc:: ./all-in-a-tumble.h
:snippets: ADD_macro
:language: c
:linenos:

Rendered example: :ref:`example.ADD`

.. _kernel-doc-syntax-structs-unions:

structs, unions
Expand Down
59 changes: 39 additions & 20 deletions linuxdoc/kernel_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def __getitem__(self, group):
doc_com_body = RE(r"\s*\* ?")
doc_decl = RE(doc_com.pattern + r"(\w+)")
#doc_decl_ident = RE(r"\s*([\w\s]+?)\s*[\(\)]\s*[-:]")
doc_decl_ident = RE(doc_com.pattern + r"(struct|union|enum|typedef|function)\b\s*(\w+)(\(\))?")
doc_decl_ident = RE(doc_com.pattern + r"(struct|union|enum|typedef|function|macro)\b\s*(\w+)(\(\))?")
doc_decl_purpose = RE(r"[-:](.*)$")

# except pattern like "http://", a whitespace is required after the colon
Expand Down Expand Up @@ -699,6 +699,7 @@ def output_function_decl(
, parametertypes = None # ctx.parametertypes
, sections = None # ctx.sections
, purpose = None # ctx.decl_purpose
, decl_type = None # ctx.decl_type
, ):
raise NotImplementedError

Expand Down Expand Up @@ -811,7 +812,12 @@ def output_DOC(self, sections = None):
self.names["DOC"].append(header)

def output_function_decl(self, **kwargs):
self.names["function"].append(kwargs["function"])
if kwargs['decl_type'] == 'macro':
self.names["macro"].append(kwargs["function"])
elif kwargs['decl_type'] == 'typedef':
self.names["typedef"].append(kwargs["function"])
else:
self.names["function"].append(kwargs["function"])

def output_struct_decl(self, **kwargs):
self.names["struct"].append(kwargs["decl_name"])
Expand Down Expand Up @@ -1025,17 +1031,26 @@ def output_function_decl(
, parametertypes = None # ctx.parametertypes
, sections = None # ctx.sections
, purpose = None # ctx.decl_purpose
, ):
, decl_type = None # ctx.decl_type
):
self.parser.ctx.offset = self.parser.ctx.decl_offset

_c_type = decl_type
if _c_type == 'typedef':
# a function typedef is rendered as function
_c_type = 'function'

self.write_anchor(function)
self.write_header(function, sec_level=2)

_header_prefix = ''
if decl_type in ('macro', 'typedef'):
_header_prefix = '%s ' % decl_type
self.write_header(_header_prefix + function, sec_level=2)

if self.options.man_sect:
self.write("\n.. kernel-doc-man:: %s.%s\n" % (function, self.options.man_sect) )

# write function definition

self.write("\n.. c:function:: ")
self.write("\n.. c:%s:: " % _c_type)
if return_type and re.search(r"\s\*+$", return_type):
self.write(return_type, function, "(")
else:
Expand Down Expand Up @@ -1532,7 +1547,7 @@ def __init__(self, *args, **kwargs):
self.constants = dict()

self.decl_name = ""
self.decl_type = "" # [struct|union|enum|typedef|function]
self.decl_type = "" # [struct|union|enum|typedef|function|macro]
self.decl_purpose = ""
self.definition = "" # defintion of the struct|union|enum
self.return_type = "" # function's return type definition)
Expand Down Expand Up @@ -1625,7 +1640,7 @@ class Parser(SimpleLog):
LOG_FORMAT = "%(fname)s:%(line_no)s: :%(logclass)s: %(message)s\n"

# DOC_TYPES: types of documentation gathered by the parser
DOC_TYPES = ["DOC", "function", "struct", "union", "enum", "typedef"]
DOC_TYPES = ["DOC", "function", "struct", "union", "enum", "typedef", "macro"]

undescribed = "*undescribed*"

Expand Down Expand Up @@ -2149,11 +2164,11 @@ def state_3(self, line):
self.debug("FLAG: split_doc_state=1 / switch state 3 --> 5")
self.state = 5
self.split_doc_state = 1
if self.ctx.decl_type == 'function':
if self.ctx.decl_type in ('function', 'macro'):
self.error("odd construct, gathering documentation of a function"
" outside of the main block?!?")

elif self.ctx.decl_type == 'function':
elif self.ctx.decl_type in ('function', 'macro'):
self.process_state3_function(line)
else:
self.process_state3_type(line)
Expand Down Expand Up @@ -2237,14 +2252,14 @@ def process_state3_function(self, line):
line = C99_comments.sub("", line) # strip C99-style comments to end of line
line = line.strip()

stripProto = RE(r"([^\{]*)")
if MACRO_define.search(line) and self.ctx.decl_type != 'macro':
# fix declaration type to 'macro' whenever decalartion type 'macro'
# is missed in the DOC string.
self.ctx.decl_type = 'macro'

# ?!?!? MACDOC does not exists (any more)?
# if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) {
# do nothing
# }
stripProto = RE(r"([^\{]*)")

if line.startswith("#") and not MACRO_define.search(line):
if line.startswith("#") and self.ctx.decl_type != "macro":
# do nothing
pass
elif stripProto.match(line):
Expand Down Expand Up @@ -2565,7 +2580,9 @@ def dump_function(self, proto):
, parameterdescs = self.ctx.parameterdescs
, parametertypes = self.ctx.parametertypes
, sections = self.ctx.sections
, purpose = self.ctx.decl_purpose )
, purpose = self.ctx.decl_purpose
, decl_type = self.ctx.decl_type
)

def dump_DOC(self, name, cont):
self.dump_section(name, cont)
Expand Down Expand Up @@ -2813,7 +2830,9 @@ def dump_typedef(self, proto):
, parameterdescs = self.ctx.parameterdescs
, parametertypes = self.ctx.parametertypes
, sections = self.ctx.sections
, purpose = self.ctx.decl_purpose )
, purpose = self.ctx.decl_purpose
, decl_type = self.ctx.decl_type
)

else:
self.debug("dump_typedef(): '%(proto)s'", proto=proto)
Expand Down Expand Up @@ -3037,7 +3056,7 @@ def check_sections(self, decl_name, decl_type
err = False
break
if err:
if decl_type == "function":
if decl_type in ('function', 'macro'):
self.warn(
"excess function parameter '%(sect)s' description in '%(decl_name)s'"
, sect = sect, decl_name = decl_name
Expand Down

0 comments on commit 90bb094

Please sign in to comment.