History

docs: kdoc: move the prefix transforms out of dump_struct()

dump_struct is one of the longest functions in the kdoc_parser class, making it hard to read and reason about. Move the definition of the prefix transformations out of the function, join them with the definition of "attribute" (which was defined at the top of the file but only used here), and reformat the code slightly for shorter line widths. Just code movement in the end.

Jonathan Corbet committed 1 year ago

Commit 64cf83b1 parent 5fd513f1 file · +96 −83Browse files

Showing the changes to scripts (1 of 1 file). Show all

Unified · Split

scripts/lib/kdoc/kdoc_parser.py+96−83
@@ -54,8 +54,6 @@ doc_inline_start = KernRe(r'^\s*/\*\*\s*$', cache=False) · 53 unmodified lines
54doc_inline_sect = KernRe(r'\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)', cache=False)54doc_inline_sect = KernRe(r'\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)', cache=False)
55doc_inline_end = KernRe(r'^\s*\*/\s*$', cache=False)55doc_inline_end = KernRe(r'^\s*\*/\s*$', cache=False)
56doc_inline_oneline = KernRe(r'^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$', cache=False)56doc_inline_oneline = KernRe(r'^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$', cache=False)
57attribute = KernRe(r"__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)",
58 flags=re.I | re.S, cache=False)
59 57
60export_symbol = KernRe(r'^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*', cache=False)58export_symbol = KernRe(r'^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*', cache=False)
61export_symbol_ns = KernRe(r'^\s*EXPORT_SYMBOL_NS(_GPL)?\s*\(\s*(\w+)\s*,\s*"\S+"\)\s*', cache=False)59export_symbol_ns = KernRe(r'^\s*EXPORT_SYMBOL_NS(_GPL)?\s*\(\s*(\w+)\s*,\s*"\S+"\)\s*', cache=False)
@@ -74,6 +72,97 @@ doc_begin_func = KernRe(str(doc_com) + # initial " * ' · 12 unmodified lines
74 r'(?:[-:].*)?$', # description (not captured)72 r'(?:[-:].*)?$', # description (not captured)
75 cache = False)73 cache = False)
76 74
75#
76# Here begins a long set of transformations to turn structure member prefixes
77# and macro invocations into something we can parse and generate kdoc for.
78#
79struct_attribute = KernRe(r"__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)",
80 flags=re.I | re.S, cache=False)
81struct_args_pattern = r'([^,)]+)'
82
83struct_prefixes = [
84 # Strip attributes
85 (struct_attribute, ' '),
86 (KernRe(r'\s*__aligned\s*\([^;]*\)', re.S), ' '),
87 (KernRe(r'\s*__counted_by\s*\([^;]*\)', re.S), ' '),
88 (KernRe(r'\s*__counted_by_(le|be)\s*\([^;]*\)', re.S), ' '),
89 (KernRe(r'\s*__packed\s*', re.S), ' '),
90 (KernRe(r'\s*CRYPTO_MINALIGN_ATTR', re.S), ' '),
91 (KernRe(r'\s*____cacheline_aligned_in_smp', re.S), ' '),
92 (KernRe(r'\s*____cacheline_aligned', re.S), ' '),
93 #
94 # Unwrap struct_group macros based on this definition:
95 # __struct_group(TAG, NAME, ATTRS, MEMBERS...)
96 # which has variants like: struct_group(NAME, MEMBERS...)
97 # Only MEMBERS arguments require documentation.
98 #
99 # Parsing them happens on two steps:
100 #
101 # 1. drop struct group arguments that aren't at MEMBERS,
102 # storing them as STRUCT_GROUP(MEMBERS)
103 #
104 # 2. remove STRUCT_GROUP() ancillary macro.
105 #
106 # The original logic used to remove STRUCT_GROUP() using an
107 # advanced regex:
108 #
109 # \bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;
110 #
111 # with two patterns that are incompatible with
112 # Python re module, as it has:
113 #
114 # - a recursive pattern: (?1)
115 # - an atomic grouping: (?>...)
116 #
117 # I tried a simpler version: but it didn't work either:
118 # \bSTRUCT_GROUP\(([^\)]+)\)[^;]*;
119 #
120 # As it doesn't properly match the end parenthesis on some cases.
121 #
122 # So, a better solution was crafted: there's now a NestedMatch
123 # class that ensures that delimiters after a search are properly
124 # matched. So, the implementation to drop STRUCT_GROUP() will be
125 # handled in separate.
126 #
127 (KernRe(r'\bstruct_group\s*\(([^,]*,)', re.S), r'STRUCT_GROUP('),
128 (KernRe(r'\bstruct_group_attr\s*\(([^,]*,){2}', re.S), r'STRUCT_GROUP('),
129 (KernRe(r'\bstruct_group_tagged\s*\(([^,]*),([^,]*),', re.S), r'struct \1 \2; STRUCT_GROUP('),
130 (KernRe(r'\b__struct_group\s*\(([^,]*,){3}', re.S), r'STRUCT_GROUP('),
131 #
132 # Replace macros
133 #
134 # TODO: use NestedMatch for FOO($1, $2, ...) matches
135 #
136 # it is better to also move those to the NestedMatch logic,
137 # to ensure that parenthesis will be properly matched.
138 #
139 (KernRe(r'__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)', re.S),
140 r'DECLARE_BITMAP(\1, __ETHTOOL_LINK_MODE_MASK_NBITS)'),
141 (KernRe(r'DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)', re.S),
142 r'DECLARE_BITMAP(\1, PHY_INTERFACE_MODE_MAX)'),
143 (KernRe(r'DECLARE_BITMAP\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern + r'\)',
144 re.S), r'unsigned long \1[BITS_TO_LONGS(\2)]'),
145 (KernRe(r'DECLARE_HASHTABLE\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern + r'\)',
146 re.S), r'unsigned long \1[1 << ((\2) - 1)]'),
147 (KernRe(r'DECLARE_KFIFO\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern +
148 r',\s*' + struct_args_pattern + r'\)', re.S), r'\2 *\1'),
149 (KernRe(r'DECLARE_KFIFO_PTR\s*\(' + struct_args_pattern + r',\s*' +
150 struct_args_pattern + r'\)', re.S), r'\2 *\1'),
151 (KernRe(r'(?:__)?DECLARE_FLEX_ARRAY\s*\(' + struct_args_pattern + r',\s*' +
152 struct_args_pattern + r'\)', re.S), r'\1 \2[]'),
153 (KernRe(r'DEFINE_DMA_UNMAP_ADDR\s*\(' + struct_args_pattern + r'\)', re.S), r'dma_addr_t \1'),
154 (KernRe(r'DEFINE_DMA_UNMAP_LEN\s*\(' + struct_args_pattern + r'\)', re.S), r'__u32 \1'),
155]
156#
157# Regexes here are guaranteed to have the end limiter matching
158# the start delimiter. Yet, right now, only one replace group
159# is allowed.
160#
161struct_nested_prefixes = [
162 (re.compile(r'\bSTRUCT_GROUP\('), r'\1'),
163]
164
165
77#166#
78# A little helper to get rid of excess white space167# A little helper to get rid of excess white space
79#168#
@@ -578,91 +667,15 @@ class KernelDoc: · 498 unmodified lines
578 self.emit_msg(ln,667 self.emit_msg(ln,
579 f"expecting prototype for {decl_type} {self.entry.identifier}. Prototype was for {decl_type} {declaration_name} instead\n")668 f"expecting prototype for {decl_type} {self.entry.identifier}. Prototype was for {decl_type} {declaration_name} instead\n")
580 return669 return
581 670 #
582 args_pattern = r'([^,)]+)'671 # Go through the list of members applying all of our transformations.
583 672 #
584 sub_prefixes = [
585 # Strip attributes
586 (attribute, ' '),
587 (KernRe(r'\s*__aligned\s*\([^;]*\)', re.S), ' '),
588 (KernRe(r'\s*__counted_by\s*\([^;]*\)', re.S), ' '),
589 (KernRe(r'\s*__counted_by_(le|be)\s*\([^;]*\)', re.S), ' '),
590 (KernRe(r'\s*__packed\s*', re.S), ' '),
591 (KernRe(r'\s*CRYPTO_MINALIGN_ATTR', re.S), ' '),
592 (KernRe(r'\s*____cacheline_aligned_in_smp', re.S), ' '),
593 (KernRe(r'\s*____cacheline_aligned', re.S), ' '),
594
595 # Unwrap struct_group macros based on this definition:
596 # __struct_group(TAG, NAME, ATTRS, MEMBERS...)
597 # which has variants like: struct_group(NAME, MEMBERS...)
598 # Only MEMBERS arguments require documentation.
599 #
600 # Parsing them happens on two steps:
601 #
602 # 1. drop struct group arguments that aren't at MEMBERS,
603 # storing them as STRUCT_GROUP(MEMBERS)
604 #
605 # 2. remove STRUCT_GROUP() ancillary macro.
606 #
607 # The original logic used to remove STRUCT_GROUP() using an
608 # advanced regex:
609 #
610 # \bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;
611 #
612 # with two patterns that are incompatible with
613 # Python re module, as it has:
614 #
615 # - a recursive pattern: (?1)
616 # - an atomic grouping: (?>...)
617 #
618 # I tried a simpler version: but it didn't work either:
619 # \bSTRUCT_GROUP\(([^\)]+)\)[^;]*;
620 #
621 # As it doesn't properly match the end parenthesis on some cases.
622 #
623 # So, a better solution was crafted: there's now a NestedMatch
624 # class that ensures that delimiters after a search are properly
625 # matched. So, the implementation to drop STRUCT_GROUP() will be
626 # handled in separate.
627
628 (KernRe(r'\bstruct_group\s*\(([^,]*,)', re.S), r'STRUCT_GROUP('),
629 (KernRe(r'\bstruct_group_attr\s*\(([^,]*,){2}', re.S), r'STRUCT_GROUP('),
630 (KernRe(r'\bstruct_group_tagged\s*\(([^,]*),([^,]*),', re.S), r'struct \1 \2; STRUCT_GROUP('),
631 (KernRe(r'\b__struct_group\s*\(([^,]*,){3}', re.S), r'STRUCT_GROUP('),
632
633 # Replace macros
634 #
635 # TODO: use NestedMatch for FOO($1, $2, ...) matches
636 #
637 # it is better to also move those to the NestedMatch logic,
638 # to ensure that parenthesis will be properly matched.
639
640 (KernRe(r'__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)', re.S), r'DECLARE_BITMAP(\1, __ETHTOOL_LINK_MODE_MASK_NBITS)'),
641 (KernRe(r'DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)', re.S), r'DECLARE_BITMAP(\1, PHY_INTERFACE_MODE_MAX)'),
642 (KernRe(r'DECLARE_BITMAP\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'unsigned long \1[BITS_TO_LONGS(\2)]'),
643 (KernRe(r'DECLARE_HASHTABLE\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'unsigned long \1[1 << ((\2) - 1)]'),
644 (KernRe(r'DECLARE_KFIFO\s*\(' + args_pattern + r',\s*' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\2 *\1'),
645 (KernRe(r'DECLARE_KFIFO_PTR\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\2 *\1'),
646 (KernRe(r'(?:__)?DECLARE_FLEX_ARRAY\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\1 \2[]'),
647 (KernRe(r'DEFINE_DMA_UNMAP_ADDR\s*\(' + args_pattern + r'\)', re.S), r'dma_addr_t \1'),
648 (KernRe(r'DEFINE_DMA_UNMAP_LEN\s*\(' + args_pattern + r'\)', re.S), r'__u32 \1'),
649 ]
650
651 # Regexes here are guaranteed to have the end limiter matching
652 # the start delimiter. Yet, right now, only one replace group
653 # is allowed.
654
655 sub_nested_prefixes = [
656 (re.compile(r'\bSTRUCT_GROUP\('), r'\1'),
657 ]
658
659 members = trim_private_members(members)673 members = trim_private_members(members)
660 for search, sub in sub_prefixes:674 for search, sub in struct_prefixes:
661 members = search.sub(sub, members)675 members = search.sub(sub, members)
662 676
663 nested = NestedMatch()677 nested = NestedMatch()
664 678 for search, sub in struct_nested_prefixes:
665 for search, sub in sub_nested_prefixes:
666 members = nested.sub(search, sub, members)679 members = nested.sub(search, sub, members)
667 680
668 # Keeps the original declaration as-is681 # Keeps the original declaration as-is