@@ -89,6 +89,8 @@ def __init__(self, filename):
8989 self .commands = []
9090 self .desc_unique_helpers = set ()
9191 self .define_unique_helpers = []
92+ self .desc_syscalls = []
93+ self .enum_syscalls = []
9294
9395 def parse_element (self ):
9496 proto = self .parse_symbol ()
@@ -103,7 +105,7 @@ def parse_helper(self):
103105 return Helper (proto = proto , desc = desc , ret = ret )
104106
105107 def parse_symbol (self ):
106- p = re .compile (' \* ?(. +)$' )
108+ p = re .compile (' \* ?(BPF\w +)$' )
107109 capture = p .match (self .line )
108110 if not capture :
109111 raise NoSyscallCommandFound
@@ -181,26 +183,55 @@ def parse_ret(self, proto):
181183 raise Exception ("No return found for " + proto )
182184 return ret
183185
184- def seek_to (self , target , help_message ):
186+ def seek_to (self , target , help_message , discard_lines = 1 ):
185187 self .reader .seek (0 )
186188 offset = self .reader .read ().find (target )
187189 if offset == - 1 :
188190 raise Exception (help_message )
189191 self .reader .seek (offset )
190192 self .reader .readline ()
191- self .reader .readline ()
193+ for _ in range (discard_lines ):
194+ self .reader .readline ()
192195 self .line = self .reader .readline ()
193196
194- def parse_syscall (self ):
197+ def parse_desc_syscall (self ):
195198 self .seek_to ('* DOC: eBPF Syscall Commands' ,
196199 'Could not find start of eBPF syscall descriptions list' )
197200 while True :
198201 try :
199202 command = self .parse_element ()
200203 self .commands .append (command )
204+ self .desc_syscalls .append (command .proto )
205+
201206 except NoSyscallCommandFound :
202207 break
203208
209+ def parse_enum_syscall (self ):
210+ self .seek_to ('enum bpf_cmd {' ,
211+ 'Could not find start of bpf_cmd enum' , 0 )
212+ # Searches for either one or more BPF\w+ enums
213+ bpf_p = re .compile ('\s*(BPF\w+)+' )
214+ # Searches for an enum entry assigned to another entry,
215+ # for e.g. BPF_PROG_RUN = BPF_PROG_TEST_RUN, which is
216+ # not documented hence should be skipped in check to
217+ # determine if the right number of syscalls are documented
218+ assign_p = re .compile ('\s*(BPF\w+)\s*=\s*(BPF\w+)' )
219+ bpf_cmd_str = ''
220+ while True :
221+ capture = assign_p .match (self .line )
222+ if capture :
223+ # Skip line if an enum entry is assigned to another entry
224+ self .line = self .reader .readline ()
225+ continue
226+ capture = bpf_p .match (self .line )
227+ if capture :
228+ bpf_cmd_str += self .line
229+ else :
230+ break
231+ self .line = self .reader .readline ()
232+ # Find the number of occurences of BPF\w+
233+ self .enum_syscalls = re .findall ('(BPF\w+)+' , bpf_cmd_str )
234+
204235 def parse_desc_helpers (self ):
205236 self .seek_to ('* Start of BPF helper function descriptions:' ,
206237 'Could not find start of eBPF helper descriptions list' )
@@ -234,7 +265,8 @@ def parse_define_helpers(self):
234265 self .define_unique_helpers = re .findall ('FN\(\w+\)' , fn_defines_str )
235266
236267 def run (self ):
237- self .parse_syscall ()
268+ self .parse_desc_syscall ()
269+ self .parse_enum_syscall ()
238270 self .parse_desc_helpers ()
239271 self .parse_define_helpers ()
240272 self .reader .close ()
@@ -266,6 +298,25 @@ def print_all(self):
266298 self .print_one (elem )
267299 self .print_footer ()
268300
301+ def elem_number_check (self , desc_unique_elem , define_unique_elem , type , instance ):
302+ """
303+ Checks the number of helpers/syscalls documented within the header file
304+ description with those defined as part of enum/macro and raise an
305+ Exception if they don't match.
306+ """
307+ nr_desc_unique_elem = len (desc_unique_elem )
308+ nr_define_unique_elem = len (define_unique_elem )
309+ if nr_desc_unique_elem != nr_define_unique_elem :
310+ exception_msg = '''
311+ The number of unique %s in description (%d) doesn\' t match the number of unique %s defined in %s (%d)
312+ ''' % (type , nr_desc_unique_elem , type , instance , nr_define_unique_elem )
313+ if nr_desc_unique_elem < nr_define_unique_elem :
314+ # Function description is parsed until no helper is found (which can be due to
315+ # misformatting). Hence, only print the first missing/misformatted helper/enum.
316+ exception_msg += '''
317+ The description for %s is not present or formatted correctly.
318+ ''' % (define_unique_elem [nr_desc_unique_elem ])
319+ raise Exception (exception_msg )
269320
270321class PrinterRST (Printer ):
271322 """
@@ -326,26 +377,6 @@ def print_elem(self, elem):
326377
327378 print ('' )
328379
329- def helper_number_check (desc_unique_helpers , define_unique_helpers ):
330- """
331- Checks the number of functions documented within the header file
332- with those present as part of #define __BPF_FUNC_MAPPER and raise an
333- Exception if they don't match.
334- """
335- nr_desc_unique_helpers = len (desc_unique_helpers )
336- nr_define_unique_helpers = len (define_unique_helpers )
337- if nr_desc_unique_helpers != nr_define_unique_helpers :
338- helper_exception = '''
339- The number of unique helpers in description (%d) doesn\' t match the number of unique helpers defined in __BPF_FUNC_MAPPER (%d)
340- ''' % (nr_desc_unique_helpers , nr_define_unique_helpers )
341- if nr_desc_unique_helpers < nr_define_unique_helpers :
342- # Function description is parsed until no helper is found (which can be due to
343- # misformatting). Hence, only print the first missing/misformatted function.
344- helper_exception += '''
345- The description for %s is not present or formatted correctly.
346- ''' % (define_unique_helpers [nr_desc_unique_helpers ])
347- raise Exception (helper_exception )
348-
349380class PrinterHelpersRST (PrinterRST ):
350381 """
351382 A printer for dumping collected information about helpers as a ReStructured
@@ -355,7 +386,7 @@ class PrinterHelpersRST(PrinterRST):
355386 """
356387 def __init__ (self , parser ):
357388 self .elements = parser .helpers
358- helper_number_check (parser .desc_unique_helpers , parser .define_unique_helpers )
389+ self . elem_number_check (parser .desc_unique_helpers , parser .define_unique_helpers , 'helper' , '__BPF_FUNC_MAPPER' )
359390
360391 def print_header (self ):
361392 header = '''\
@@ -529,6 +560,7 @@ class PrinterSyscallRST(PrinterRST):
529560 """
530561 def __init__ (self , parser ):
531562 self .elements = parser .commands
563+ self .elem_number_check (parser .desc_syscalls , parser .enum_syscalls , 'syscall' , 'bpf_cmd' )
532564
533565 def print_header (self ):
534566 header = '''\
@@ -560,7 +592,7 @@ class PrinterHelpers(Printer):
560592 """
561593 def __init__ (self , parser ):
562594 self .elements = parser .helpers
563- helper_number_check (parser .desc_unique_helpers , parser .define_unique_helpers )
595+ self . elem_number_check (parser .desc_unique_helpers , parser .define_unique_helpers , 'helper' , '__BPF_FUNC_MAPPER' )
564596
565597 type_fwds = [
566598 'struct bpf_fib_lookup' ,
0 commit comments