def lookup(self, path, line): """A line of source code.""" if line <= 0: # line numbers are 1-based logging.info("CodeSnippet lookup: line number not positive: %s", line) return None line -= 1 # list indices are 0-based try: if path not in self.source: with open(os.path.join(self.root, path)) as code: self.source[path] = html.escape(code.read()).splitlines() except FileNotFoundError: if srcloct.is_builtin(path): # <builtin-library-malloc>, etc. return None raise UserWarning( "CodeSnippet lookup: file not found: {}".format(path)) # return the whole statement which may be broken over several lines snippet = ' '.join(self.source[path][line:line + 5]) snippet = re.sub(r'\s+', ' ', snippet).strip() idx = snippet.find(';') # end of statement if idx >= 0: return snippet[:idx + 1] idx = snippet.find('}') # end of block if idx >= 0: return snippet[:idx + 1] return snippet # statement extends over more that 5 lines
def parse_cbmc_json(json_data, root): """Parse json output of goto-analyzer --reachable-functions --json.""" root = srcloct.abspath(root) reachable = {} for function in json_data: func_name = function['function'] if func_name.startswith('__CPROVER'): continue file_name = function.get('file') if file_name is None: logging.error( 'Skipping reachable function with invalid source location: %s', function) continue file_name = srcloct.abspath(file_name) if srcloct.is_builtin(file_name): continue if not file_name.startswith(root): continue path = srcloct.relpath(file_name, root) reachable[path] = reachable.get(path, set()) reachable[path].add(func_name) return reachable
def link_text_to_file(text, to_file, from_file=None): """Link text to a file in the source tree.""" if srcloct.is_builtin(to_file) or srcloct.is_missing(to_file): return html.escape(str(text)) from_file = from_file or '.' path = path_to_file(to_file, from_file) return '<a href="{}.html">{}</a>'.format(path, text)
def link_text_to_line(text, to_file, line, from_file=None): """Link text to a line in a file in the source tree.""" if srcloct.is_builtin(to_file): return html.escape(str(text)) from_file = from_file or '.' line = int(line) path = path_to_file(to_file, from_file) return '<a href="{}.html#{}">{}</a>'.format(path, line, text)
def source_files(goto, wkdir, srcdir=None): """Source files appearing in symbol table. Source file path names in symbol table are absolute or relative to wkdir. If srcdir is given, return only files under srcdir. """ wkdir = srcloct.abspath(wkdir) srcs = [dfn['file'] for dfn in parse_symbol_table(symbol_table(goto), wkdir)] srcs = [src for src in srcs if src and not srcloct.is_builtin(src)] if srcdir: srcdir = srcloct.abspath(srcdir) srcs = [src for src in srcs if src.startswith(srcdir)] return sorted(set(srcs))
def parse_location(loc, wkdir): """Symbol source location from location line.""" if not is_location_line(loc): return None, None # Examples of location lines (may be no location for symbol) # Location....: # Location....: file file_name line line_number match = re.match('.* file (.*) line ([0-9]*)', loc) if match is None: return None, None rel_path, line = match.group(1), int(match.group(2)) abs_path = srcloct.normpath(os.path.join(wkdir, rel_path)) if srcloct.is_builtin(abs_path): return None, None return abs_path, line