r = KernRe(r'^(\w+)\s+') if r.search(prototype): return_type = '' declaration_name = r.group(1) func_macro = True found = True else: # # Apply the initial transformations. # prototype = self.xforms.apply("func", prototype) # Yes, this truly is vile. We are looking for: # 1. Return type (may be nothing if we're looking at a macro) # 2. Function name # 3. Function parameters. # # All the while we have to watch out for function pointer parameters # (which IIRC is what the two sections are for), C types (these # regexps don't even start to express all the possibilities), and # so on. # # If you mess with these regexps, it's a good idea to check that # the following functions' documentation still comes out right: # - parport_register_device (function pointer parameters) # - atomic_set (macro) # - pci_match_device, __copy_to_user (long return type) name = r'\w+' type1 = r'(?:[\w\s]+)?' type2 = r'(?:[\w\s]+\*+)+' # # Attempt to match first on (args) with no internal parentheses; this # lets us easily filter out __acquires() and other post-args stuff. If # that fails, just grab the rest of the line to the last closing # parenthesis. # proto_args = r'\(([^\(]*|.*)\)' # # (Except for the simple macro case) attempt to split up the prototype # in the various ways we understand. # if not found: patterns = [ rf'^()({name})\s*{proto_args}', rf'^({type1})\s+({name})\s*{proto_args}', rf'^({type2})\s*({name})\s*{proto_args}', ] for p in patterns: r = KernRe(p) if r.match(prototype): return_type = r.group(1) declaration_name = r.group(2) args = r.group(3) self.create_parameter_list(ln, decl_type, args, ',', declaration_name) found = True break # # Parsing done; make sure that things are as we expect. # if not found: self.emit_msg(ln, f"cannot understand function prototype: '{prototype}'") return if self.entry.identifier != declaration_name: self.emit_msg(ln, f"expecting prototype for {self.entry.identifier}(). " f"Prototype was for {declaration_name}() instead") return self.check_sections(ln, declaration_name, "function") self.check_return_section(ln, declaration_name, return_type) # # Store the result. # self.output_declaration(decl_type, declaration_name, source=source, typedef=('typedef' in return_type), functiontype=return_type, purpose=self.entry.declaration_purpose, func_macro=func_macro) def dump_typedef(self, ln, proto, source): """ Store a ``typedef`` inside self.entries array. """ # # We start by looking for function typedefs. # typedef_type = r'typedef((?:\s+[\w*]+\b){0,7}\s+(?:\w+\b|\*+))\s*' typedef_ident = r'\*?\s*(\w\S+)\s*' typedef_args = r'\s*\((.*)\);' source = source typedef1 = KernRe(typedef_type + r'\(' + typedef_ident + r'\)' + typedef_args) typedef2 = KernRe(typedef_type + typedef_ident + typedef_args) # Parse function typedef prototypes for r in [typedef1, typedef2]: if not r.match(proto): continue return_type = r.group(1).strip() declaration_name = r.group(2) args = r.group(3) if self.entry.identifier != declaration_name: self.emit_msg(ln, f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n") return self.create_parameter_list(ln, 'function', args, ',', declaration_name) self.output_declaration('function', declaration_name, source=source, typedef=True, functiontype=return_type, purpose=self.entry.declaration_purpose) return # # Not a function, try to parse a simple typedef. # r = KernRe(r'typedef.*\s+(\w+)\s*;') if r.match(proto): declaration_name = r.group(1) if self.entry.identifier != declaration_name: self.emit_msg(ln, f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n") return self.output_declaration('typedef', declaration_name, source=source, purpose=self.entry.declaration_purpose) return self.emit_msg(ln, "error: Cannot parse typedef!") @staticmethod def process_export(function_set, line): """ process ``EXPORT_SYMBOL*`` tags This method doesn't use any variable from the class, so declare it with a staticmethod decorator. """ # We support documenting some exported symbols with different # names. A horrible hack. suffixes = [ '_noprof' ] # Note: it accepts only one EXPORT_SYMBOL* per line, as having # multiple export lines would violate Kernel coding style. if export_symbol.search(line): symbol = export_symbol.group(2) elif export_symbol_ns.search(line): symbol = export_symbol_ns.group(2) else: return False # # Found an export, trim out any special suffixes # for suffix in suffixes: # Be backward compatible with Python < 3.9 if symbol.endswith(suffix): symbol = symbol[:-len(suffix)] function_set.add(symbol) return True def process_normal(self, ln, line, source): """ STATE_NORMAL: looking for the ``/**`` to begin everything. """ if not doc_start.match(line): return # start a new entry self.reset_state(ln) # next line is always the function name self.state = state.NAME def process_name(self, ln, line, source): """ STATE_NAME: Looking for the "name - description" line """ # # Check for a DOC: block and handle them specially. # if doc_block.search(line): if not doc_block.group(1): self.entry.begin_section(ln, "Introduction") else: self.entry.begin_section(ln, doc_block.group(1)) self.entry.identifier = self.entry.section self.state = state.DOCBLOCK # # Otherwise we're looking for a normal kerneldoc declaration line. # elif doc_decl.search(line): self.entry.identifier = doc_decl.group(1) # Test for data declaration if doc_begin_data.search(line): self.entry.decl_type = doc_begin_data.group(1) self.entry.identifier = doc_begin_data.group(2) # # Look for a function description # elif doc_begin_func.search(line): self.entry.identifier = doc_begin_func.group(1) self.entry.decl_type = "function" # # We struck out. # else: self.emit_msg(ln, f"This comment starts with '/**', but isn't a kernel-doc comment. Refer to Documentation/doc-guide/kernel-doc.rst\n{line}") self.state = state.NORMAL return # # OK, set up for a new kerneldoc entry. # self.state = state.BODY self.entry.identifier = self.entry.identifier.strip(" ") # if there's no @param blocks need to set up default section here self.entry.begin_section(ln + 1) # # Find the description portion, which *should* be there but # isn't always. # (We should be able to capture this from the previous parsing - someday) # r = KernRe("[-:](.*)") if r.search(line): self.entry.declaration_purpose = trim_whitespace(r.group(1)) self.state = state.DECLARATION else: self.entry.declaration_purpose = "" if not self.entry.declaration_purpose and self.config.wshort_desc: self.emit_msg(ln, f"missing initial short description on line:\n{line}") if not self.entry.identifier and self.entry.decl_type != "enum": self.emit_msg(ln, f"wrong kernel-doc identifier on line:\n{line}") self.state = state.NORMAL if self.config.verbose: self.emit_msg(ln, f"Scanning doc for {self.entry.decl_type} {self.entry.identifier}", warning=False) # # Failed to find an identifier. Emit a warning # else: self.emit_msg(ln, f"Cannot find identifier on line:\n{line}") def is_new_section(self, ln, line): """ Helper function to determine if a new section is being started. """ if doc_sect.search(line): self.state = state.BODY # # Pick out the name of our new section, tweaking it if need be. # newsection = doc_sect.group(1) if newsection.lower() == 'description': newsection = 'Description' elif newsection.lower() == 'context': newsection = 'Context' self.state = state.SPECIAL_SECTION elif newsection.lower() in ["@return", "@returns", "return", "returns"]: newsection = "Return" self.state = state.SPECIAL_SECTION elif newsection[0] == '@': self.state = state.SPECIAL_SECTION # # Initialize the contents, and get the new section going. # newcontents = doc_sect.group(2) if not newcontents: newcontents = "" self.dump_section() self.entry.begin_section(ln, newsection) self.entry.leading_space = None self.entry.add_text(newcontents.lstrip()) return True return False def is_comment_end(self, ln, line): """ Helper function to detect (and effect) the end of a kerneldoc comment. """ if doc_end.search(line): self.dump_section() # Look for doc_com + <text> + doc_end: r = KernRe(r'\s*\*\s*[a-zA-Z_0-9:.]+\*/') if r.match(line): self.emit_msg(ln, f"suspicious ending line: {line}") self.entry.prototype = "" self.entry.new_start_line = ln + 1 self.state = state.PROTO return True return False def process_decl(self, ln, line, source): """ STATE_DECLARATION: We've seen the beginning of a declaration. """ if self.is_new_section(ln, line) or self.is_comment_end(ln, line): return # # Look for anything with the " * " line beginning. # if doc_content.search(line): cont = doc_content.group(1) # # A blank line means that we have moved out of the declaration # part of the comment (without any "special section" parameter # descriptions). # if cont == "": self.state = state.BODY # # Otherwise we have more of the declaration section to soak up. # else: self.entry.declaration_purpose = \ trim_whitespace(self.entry.declaration_purpose + ' ' + cont) else: # Unknown line, ignore self.emit_msg(ln, f"bad line: {line}") def process_special(self, ln, line, source): """ STATE_SPECIAL_SECTION: a section ending with a blank line. """ # # If we have hit a blank line (only the " * " marker), then this # section is done. # if KernRe(r"\s*\*\s*$").match(line): self.entry.begin_section(ln, dump = True) self.state = state.BODY return # # Not a blank line, look for the other ways to end the section. # if self.is_new_section(ln, line) or self.is_comment_end(ln, line): return # # OK, we should have a continuation of the text for this section. # if doc_content.search(line): cont = doc_content.group(1) # # If the lines of text after the first in a special section have # leading white space, we need to trim it out or Sphinx will get # confused. For the second line (the None case), see what we # find there and remember it. # if self.entry.leading_space is None: r = KernRe(r'^(\s+)') if r.match(cont): self.entry.leading_space = len(r.group(1)) else: self.entry.leading_space = 0 # # Otherwise, before trimming any leading chars, be *sure* # that they are white space. We should maybe warn if this # isn't the case. # for i in range(0, self.entry.leading_space): if cont[i] != " ": self.entry.leading_space = i break # # Add the trimmed result to the section and we're done. # self.entry.add_text(cont[self.entry.leading_space:]) else: # Unknown line, ignore self.emit_msg(ln, f"bad line: {line}") def process_body(self, ln, line, source): """ STATE_BODY: the bulk of a kerneldoc comment. """ if self.is_new_section(ln, line) or self.is_comment_end(ln, line): return if doc_content.search(line): cont = doc_content.group(1) self.entry.add_text(cont) else: # Unknown line, ignore self.emit_msg(ln, f"bad line: {line}") def process_inline_name(self, ln, line, source): """STATE_INLINE_NAME: beginning of docbook comments within a prototype.""" if doc_inline_sect.search(line): self.entry.begin_section(ln, doc_inline_sect.group(1)) self.entry.add_text(doc_inline_sect.group(2).lstrip()) self.state = state.INLINE_TEXT elif doc_inline_end.search(line): self.dump_section() self.state = state.PROTO elif doc_content.search(line): self.emit_msg(ln, f"Incorrect use of kernel-doc format: {line}") self.state = state.PROTO # # Don't let it add partial comments at the code, as breaks the # logic meant to remove comments from prototypes. # self.process_proto_type(ln, "/**\n" + line, source) # else ... ?? def process_inline_text(self, ln, line, source): """STATE_INLINE_TEXT: docbook comments within a prototype.""" if doc_inline_end.search(line): self.dump_section() self.state = state.PROTO elif doc_content.search(line): self.entry.add_text(doc_content.group(1)) # else ... ?? def syscall_munge(self, ln, proto): # pylint: disable=W0613 """ Handle syscall definitions. """ is_void = False # Strip newlines/CR's proto = re.sub(r'[\r\n]+', ' ', proto) # Check if it's a SYSCALL_DEFINE0 if 'SYSCALL_DEFINE0' in proto: is_void = True # Replace SYSCALL_DEFINE with correct return type & function name proto = KernRe(r'SYSCALL_DEFINE.*\(').sub('long sys_', proto) r = KernRe(r'long\s+(sys_.*?),') if r.search(proto): proto = KernRe(',').sub('(', proto, count=1) elif is_void: proto = KernRe(r'\)').sub('(void)', proto, count=1) # Now delete all of the odd-numbered commas in the proto # so that argument types & names don't have a comma between them count = 0 length = len(proto) if is_void: length = 0 # skip the loop if is_void for ix in range(length): if proto[ix] == ',': count += 1 if count % 2 == 1: proto = proto[:ix] + ' ' + proto[ix + 1:] return proto def tracepoint_munge(self, ln, proto): """ Handle tracepoint definitions. """ tracepointname = None tracepointargs = None # Match tracepoint name based on different patterns r = KernRe(r'TRACE_EVENT\((.*?),') if r.search(proto): tracepointname = r.group(1) r = KernRe(r'DEFINE_SINGLE_EVENT\((.*?),') if r.search(proto): tracepointname = r.group(1) Lines 1001–1500 of 1731. Previous lines Load more
r = KernRe(r'^(\w+)\s+') if r.search(prototype): return_type = '' declaration_name = r.group(1) func_macro = True found = True else: # # Apply the initial transformations. # prototype = self.xforms.apply("func", prototype) # Yes, this truly is vile. We are looking for: # 1. Return type (may be nothing if we're looking at a macro) # 2. Function name # 3. Function parameters. # # All the while we have to watch out for function pointer parameters # (which IIRC is what the two sections are for), C types (these # regexps don't even start to express all the possibilities), and # so on. # # If you mess with these regexps, it's a good idea to check that # the following functions' documentation still comes out right: # - parport_register_device (function pointer parameters) # - atomic_set (macro) # - pci_match_device, __copy_to_user (long return type) name = r'\w+' type1 = r'(?:[\w\s]+)?' type2 = r'(?:[\w\s]+\*+)+' # # Attempt to match first on (args) with no internal parentheses; this # lets us easily filter out __acquires() and other post-args stuff. If # that fails, just grab the rest of the line to the last closing # parenthesis. # proto_args = r'\(([^\(]*|.*)\)' # # (Except for the simple macro case) attempt to split up the prototype # in the various ways we understand. # if not found: patterns = [ rf'^()({name})\s*{proto_args}', rf'^({type1})\s+({name})\s*{proto_args}', rf'^({type2})\s*({name})\s*{proto_args}', ] for p in patterns: r = KernRe(p) if r.match(prototype): return_type = r.group(1) declaration_name = r.group(2) args = r.group(3) self.create_parameter_list(ln, decl_type, args, ',', declaration_name) found = True break # # Parsing done; make sure that things are as we expect. # if not found: self.emit_msg(ln, f"cannot understand function prototype: '{prototype}'") return if self.entry.identifier != declaration_name: self.emit_msg(ln, f"expecting prototype for {self.entry.identifier}(). " f"Prototype was for {declaration_name}() instead") return self.check_sections(ln, declaration_name, "function") self.check_return_section(ln, declaration_name, return_type) # # Store the result. # self.output_declaration(decl_type, declaration_name, source=source, typedef=('typedef' in return_type), functiontype=return_type, purpose=self.entry.declaration_purpose, func_macro=func_macro) def dump_typedef(self, ln, proto, source): """ Store a ``typedef`` inside self.entries array. """ # # We start by looking for function typedefs. # typedef_type = r'typedef((?:\s+[\w*]+\b){0,7}\s+(?:\w+\b|\*+))\s*' typedef_ident = r'\*?\s*(\w\S+)\s*' typedef_args = r'\s*\((.*)\);' source = source typedef1 = KernRe(typedef_type + r'\(' + typedef_ident + r'\)' + typedef_args) typedef2 = KernRe(typedef_type + typedef_ident + typedef_args) # Parse function typedef prototypes for r in [typedef1, typedef2]: if not r.match(proto): continue return_type = r.group(1).strip() declaration_name = r.group(2) args = r.group(3) if self.entry.identifier != declaration_name: self.emit_msg(ln, f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n") return self.create_parameter_list(ln, 'function', args, ',', declaration_name) self.output_declaration('function', declaration_name, source=source, typedef=True, functiontype=return_type, purpose=self.entry.declaration_purpose) return # # Not a function, try to parse a simple typedef. # r = KernRe(r'typedef.*\s+(\w+)\s*;') if r.match(proto): declaration_name = r.group(1) if self.entry.identifier != declaration_name: self.emit_msg(ln, f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n") return self.output_declaration('typedef', declaration_name, source=source, purpose=self.entry.declaration_purpose) return self.emit_msg(ln, "error: Cannot parse typedef!") @staticmethod def process_export(function_set, line): """ process ``EXPORT_SYMBOL*`` tags This method doesn't use any variable from the class, so declare it with a staticmethod decorator. """ # We support documenting some exported symbols with different # names. A horrible hack. suffixes = [ '_noprof' ] # Note: it accepts only one EXPORT_SYMBOL* per line, as having # multiple export lines would violate Kernel coding style. if export_symbol.search(line): symbol = export_symbol.group(2) elif export_symbol_ns.search(line): symbol = export_symbol_ns.group(2) else: return False # # Found an export, trim out any special suffixes # for suffix in suffixes: # Be backward compatible with Python < 3.9 if symbol.endswith(suffix): symbol = symbol[:-len(suffix)] function_set.add(symbol) return True def process_normal(self, ln, line, source): """ STATE_NORMAL: looking for the ``/**`` to begin everything. """ if not doc_start.match(line): return # start a new entry self.reset_state(ln) # next line is always the function name self.state = state.NAME def process_name(self, ln, line, source): """ STATE_NAME: Looking for the "name - description" line """ # # Check for a DOC: block and handle them specially. # if doc_block.search(line): if not doc_block.group(1): self.entry.begin_section(ln, "Introduction") else: self.entry.begin_section(ln, doc_block.group(1)) self.entry.identifier = self.entry.section self.state = state.DOCBLOCK # # Otherwise we're looking for a normal kerneldoc declaration line. # elif doc_decl.search(line): self.entry.identifier = doc_decl.group(1) # Test for data declaration if doc_begin_data.search(line): self.entry.decl_type = doc_begin_data.group(1) self.entry.identifier = doc_begin_data.group(2) # # Look for a function description # elif doc_begin_func.search(line): self.entry.identifier = doc_begin_func.group(1) self.entry.decl_type = "function" # # We struck out. # else: self.emit_msg(ln, f"This comment starts with '/**', but isn't a kernel-doc comment. Refer to Documentation/doc-guide/kernel-doc.rst\n{line}") self.state = state.NORMAL return # # OK, set up for a new kerneldoc entry. # self.state = state.BODY self.entry.identifier = self.entry.identifier.strip(" ") # if there's no @param blocks need to set up default section here self.entry.begin_section(ln + 1) # # Find the description portion, which *should* be there but # isn't always. # (We should be able to capture this from the previous parsing - someday) # r = KernRe("[-:](.*)") if r.search(line): self.entry.declaration_purpose = trim_whitespace(r.group(1)) self.state = state.DECLARATION else: self.entry.declaration_purpose = "" if not self.entry.declaration_purpose and self.config.wshort_desc: self.emit_msg(ln, f"missing initial short description on line:\n{line}") if not self.entry.identifier and self.entry.decl_type != "enum": self.emit_msg(ln, f"wrong kernel-doc identifier on line:\n{line}") self.state = state.NORMAL if self.config.verbose: self.emit_msg(ln, f"Scanning doc for {self.entry.decl_type} {self.entry.identifier}", warning=False) # # Failed to find an identifier. Emit a warning # else: self.emit_msg(ln, f"Cannot find identifier on line:\n{line}") def is_new_section(self, ln, line): """ Helper function to determine if a new section is being started. """ if doc_sect.search(line): self.state = state.BODY # # Pick out the name of our new section, tweaking it if need be. # newsection = doc_sect.group(1) if newsection.lower() == 'description': newsection = 'Description' elif newsection.lower() == 'context': newsection = 'Context' self.state = state.SPECIAL_SECTION elif newsection.lower() in ["@return", "@returns", "return", "returns"]: newsection = "Return" self.state = state.SPECIAL_SECTION elif newsection[0] == '@': self.state = state.SPECIAL_SECTION # # Initialize the contents, and get the new section going. # newcontents = doc_sect.group(2) if not newcontents: newcontents = "" self.dump_section() self.entry.begin_section(ln, newsection) self.entry.leading_space = None self.entry.add_text(newcontents.lstrip()) return True return False def is_comment_end(self, ln, line): """ Helper function to detect (and effect) the end of a kerneldoc comment. """ if doc_end.search(line): self.dump_section() # Look for doc_com + <text> + doc_end: r = KernRe(r'\s*\*\s*[a-zA-Z_0-9:.]+\*/') if r.match(line): self.emit_msg(ln, f"suspicious ending line: {line}") self.entry.prototype = "" self.entry.new_start_line = ln + 1 self.state = state.PROTO return True return False def process_decl(self, ln, line, source): """ STATE_DECLARATION: We've seen the beginning of a declaration. """ if self.is_new_section(ln, line) or self.is_comment_end(ln, line): return # # Look for anything with the " * " line beginning. # if doc_content.search(line): cont = doc_content.group(1) # # A blank line means that we have moved out of the declaration # part of the comment (without any "special section" parameter # descriptions). # if cont == "": self.state = state.BODY # # Otherwise we have more of the declaration section to soak up. # else: self.entry.declaration_purpose = \ trim_whitespace(self.entry.declaration_purpose + ' ' + cont) else: # Unknown line, ignore self.emit_msg(ln, f"bad line: {line}") def process_special(self, ln, line, source): """ STATE_SPECIAL_SECTION: a section ending with a blank line. """ # # If we have hit a blank line (only the " * " marker), then this # section is done. # if KernRe(r"\s*\*\s*$").match(line): self.entry.begin_section(ln, dump = True) self.state = state.BODY return # # Not a blank line, look for the other ways to end the section. # if self.is_new_section(ln, line) or self.is_comment_end(ln, line): return # # OK, we should have a continuation of the text for this section. # if doc_content.search(line): cont = doc_content.group(1) # # If the lines of text after the first in a special section have # leading white space, we need to trim it out or Sphinx will get # confused. For the second line (the None case), see what we # find there and remember it. # if self.entry.leading_space is None: r = KernRe(r'^(\s+)') if r.match(cont): self.entry.leading_space = len(r.group(1)) else: self.entry.leading_space = 0 # # Otherwise, before trimming any leading chars, be *sure* # that they are white space. We should maybe warn if this # isn't the case. # for i in range(0, self.entry.leading_space): if cont[i] != " ": self.entry.leading_space = i break # # Add the trimmed result to the section and we're done. # self.entry.add_text(cont[self.entry.leading_space:]) else: # Unknown line, ignore self.emit_msg(ln, f"bad line: {line}") def process_body(self, ln, line, source): """ STATE_BODY: the bulk of a kerneldoc comment. """ if self.is_new_section(ln, line) or self.is_comment_end(ln, line): return if doc_content.search(line): cont = doc_content.group(1) self.entry.add_text(cont) else: # Unknown line, ignore self.emit_msg(ln, f"bad line: {line}") def process_inline_name(self, ln, line, source): """STATE_INLINE_NAME: beginning of docbook comments within a prototype.""" if doc_inline_sect.search(line): self.entry.begin_section(ln, doc_inline_sect.group(1)) self.entry.add_text(doc_inline_sect.group(2).lstrip()) self.state = state.INLINE_TEXT elif doc_inline_end.search(line): self.dump_section() self.state = state.PROTO elif doc_content.search(line): self.emit_msg(ln, f"Incorrect use of kernel-doc format: {line}") self.state = state.PROTO # # Don't let it add partial comments at the code, as breaks the # logic meant to remove comments from prototypes. # self.process_proto_type(ln, "/**\n" + line, source) # else ... ?? def process_inline_text(self, ln, line, source): """STATE_INLINE_TEXT: docbook comments within a prototype.""" if doc_inline_end.search(line): self.dump_section() self.state = state.PROTO elif doc_content.search(line): self.entry.add_text(doc_content.group(1)) # else ... ?? def syscall_munge(self, ln, proto): # pylint: disable=W0613 """ Handle syscall definitions. """ is_void = False # Strip newlines/CR's proto = re.sub(r'[\r\n]+', ' ', proto) # Check if it's a SYSCALL_DEFINE0 if 'SYSCALL_DEFINE0' in proto: is_void = True # Replace SYSCALL_DEFINE with correct return type & function name proto = KernRe(r'SYSCALL_DEFINE.*\(').sub('long sys_', proto) r = KernRe(r'long\s+(sys_.*?),') if r.search(proto): proto = KernRe(',').sub('(', proto, count=1) elif is_void: proto = KernRe(r'\)').sub('(void)', proto, count=1) # Now delete all of the odd-numbered commas in the proto # so that argument types & names don't have a comma between them count = 0 length = len(proto) if is_void: length = 0 # skip the loop if is_void for ix in range(length): if proto[ix] == ',': count += 1 if count % 2 == 1: proto = proto[:ix] + ' ' + proto[ix + 1:] return proto def tracepoint_munge(self, ln, proto): """ Handle tracepoint definitions. """ tracepointname = None tracepointargs = None # Match tracepoint name based on different patterns r = KernRe(r'TRACE_EVENT\((.*?),') if r.search(proto): tracepointname = r.group(1) r = KernRe(r'DEFINE_SINGLE_EVENT\((.*?),') if r.search(proto): tracepointname = r.group(1)