aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/bpf_helpers_doc.py
diff options
context:
space:
mode:
authorQuentin Monnet <quentin.monnet@netronome.com>2018-05-02 09:20:24 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-05-02 11:46:50 -0400
commit6f96674dbd8ca659769f1c65ca15638e50b69341 (patch)
treec755dc183829afcd09f9988a52da26842801b5c6 /scripts/bpf_helpers_doc.py
parenta2c7a98301d9f9bcfc4244de04252a04c0b68a79 (diff)
bpf: relax constraints on formatting for eBPF helper documentation
The Python script used to parse and extract eBPF helpers documentation from include/uapi/linux/bpf.h expects a very specific formatting for the descriptions (single dot represents a space, '>' stands for a tab): /* ... *.int bpf_helper(list of arguments) *.> Description *.> > Start of description *.> > Another line of description *.> > And yet another line of description *.> Return *.> > 0 on success, or a negative error in case of failure ... */ This is too strict, and painful for developers who wants to add documentation for new helpers. Worse, it is extremely difficult to check that the formatting is correct during reviews. Change the format expected by the script and make it more flexible. The script now works whether or not the initial space (right after the star) is present, and accepts both tabs and white spaces (or a combination of both) for indenting description sections and contents. Concretely, something like the following would now be supported: /* ... *int bpf_helper(list of arguments) *......Description *.> > Start of description... *> > Another line of description *..............And yet another line of description *> Return *.> ........0 on success, or a negative error in case of failure ... */ While at it, remove unnecessary carets from each regex used with match() in the script. They are redundant, as match() tries to match from the beginning of the string by default. v2: Remove unnecessary caret when a regex is used with match(). Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'scripts/bpf_helpers_doc.py')
-rwxr-xr-xscripts/bpf_helpers_doc.py14
1 files changed, 7 insertions, 7 deletions
diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py
index 30ba0fee36e4..8f59897fbda1 100755
--- a/scripts/bpf_helpers_doc.py
+++ b/scripts/bpf_helpers_doc.py
@@ -39,9 +39,9 @@ class Helper(object):
39 Break down helper function protocol into smaller chunks: return type, 39 Break down helper function protocol into smaller chunks: return type,
40 name, distincts arguments. 40 name, distincts arguments.
41 """ 41 """
42 arg_re = re.compile('^((const )?(struct )?(\w+|...))( (\**)(\w+))?$') 42 arg_re = re.compile('((const )?(struct )?(\w+|...))( (\**)(\w+))?$')
43 res = {} 43 res = {}
44 proto_re = re.compile('^(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') 44 proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$')
45 45
46 capture = proto_re.match(self.proto) 46 capture = proto_re.match(self.proto)
47 res['ret_type'] = capture.group(1) 47 res['ret_type'] = capture.group(1)
@@ -87,7 +87,7 @@ class HeaderParser(object):
87 # - Same as above, with "const" and/or "struct" in front of type 87 # - Same as above, with "const" and/or "struct" in front of type
88 # - "..." (undefined number of arguments, for bpf_trace_printk()) 88 # - "..." (undefined number of arguments, for bpf_trace_printk())
89 # There is at least one term ("void"), and at most five arguments. 89 # There is at least one term ("void"), and at most five arguments.
90 p = re.compile('^ \* ((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$') 90 p = re.compile(' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$')
91 capture = p.match(self.line) 91 capture = p.match(self.line)
92 if not capture: 92 if not capture:
93 raise NoHelperFound 93 raise NoHelperFound
@@ -95,7 +95,7 @@ class HeaderParser(object):
95 return capture.group(1) 95 return capture.group(1)
96 96
97 def parse_desc(self): 97 def parse_desc(self):
98 p = re.compile('^ \* \tDescription$') 98 p = re.compile(' \* ?(?:\t| {6,8})Description$')
99 capture = p.match(self.line) 99 capture = p.match(self.line)
100 if not capture: 100 if not capture:
101 # Helper can have empty description and we might be parsing another 101 # Helper can have empty description and we might be parsing another
@@ -109,7 +109,7 @@ class HeaderParser(object):
109 if self.line == ' *\n': 109 if self.line == ' *\n':
110 desc += '\n' 110 desc += '\n'
111 else: 111 else:
112 p = re.compile('^ \* \t\t(.*)') 112 p = re.compile(' \* ?(?:\t| {6,8})(?:\t| {8})(.*)')
113 capture = p.match(self.line) 113 capture = p.match(self.line)
114 if capture: 114 if capture:
115 desc += capture.group(1) + '\n' 115 desc += capture.group(1) + '\n'
@@ -118,7 +118,7 @@ class HeaderParser(object):
118 return desc 118 return desc
119 119
120 def parse_ret(self): 120 def parse_ret(self):
121 p = re.compile('^ \* \tReturn$') 121 p = re.compile(' \* ?(?:\t| {6,8})Return$')
122 capture = p.match(self.line) 122 capture = p.match(self.line)
123 if not capture: 123 if not capture:
124 # Helper can have empty retval and we might be parsing another 124 # Helper can have empty retval and we might be parsing another
@@ -132,7 +132,7 @@ class HeaderParser(object):
132 if self.line == ' *\n': 132 if self.line == ' *\n':
133 ret += '\n' 133 ret += '\n'
134 else: 134 else:
135 p = re.compile('^ \* \t\t(.*)') 135 p = re.compile(' \* ?(?:\t| {6,8})(?:\t| {8})(.*)')
136 capture = p.match(self.line) 136 capture = p.match(self.line)
137 if capture: 137 if capture:
138 ret += capture.group(1) + '\n' 138 ret += capture.group(1) + '\n'