1#!/usr/bin/env python3 2 3import os 4from . import settings, utils, tag_database, cppcheck_analysis 5 6class ParseTagPhaseError(Exception): 7 pass 8 9class BuildPhaseError(Exception): 10 pass 11 12class CleanPhaseError(Exception): 13 pass 14 15 16def parse_xen_tags(): 17 # Load the database for the Xen tags 18 subs_list = tag_database.load_tag_database( 19 settings.analysis_tool, 20 [settings.repo_dir + "/docs/misra/safe.json"] 21 ) 22 subs_list = tag_database.load_tag_database( 23 settings.analysis_tool, 24 [settings.repo_dir + "/docs/misra/false-positive-{}.json" 25 .format(settings.analysis_tool)], 26 subs_list, 27 "false-positive" 28 ) 29 30 # Create outdir if it doesn't exists 31 os.makedirs(settings.outdir, exist_ok=True) 32 33 # The following lambda function will return a file if it contains lines with 34 # a comment containing "SAF-<number>-{safe|false-positive-<tool>}" on a 35 # single line. 36 grep_action = lambda x: utils.grep(x, 37 tag_database.get_xen_tag_comment_regex( 38 settings.analysis_tool) 39 ) 40 # Look for a list of .h/.c files that matches the condition above 41 parse_file_list = utils.recursive_find_file(settings.xen_dir, r'.*\.[ch]$', 42 grep_action) 43 44 for entry in parse_file_list: 45 file = entry["file"] 46 bkp_file = file + ".safparse" 47 if os.path.isfile(bkp_file): 48 raise ParseTagPhaseError( 49 "Found {}, please check the integrity of {}" 50 .format(bkp_file,file) 51 ) 52 os.rename(file, bkp_file) 53 time_bkp_file = os.stat(bkp_file) 54 # Create <file> from <file>.safparse but with the Xen tag parsed 55 try: 56 tag_database.substitute_tags(settings.analysis_tool, bkp_file, entry, 57 subs_list) 58 except Exception as e: 59 raise ParseTagPhaseError("{}".format(e)) 60 finally: 61 # Set timestamp for file equal to bkp_file, so that if the file is 62 # modified during the process by the user, we can catch it 63 os.utime(file, (time_bkp_file.st_atime, time_bkp_file.st_mtime)) 64 65 66def build_xen(): 67 utils.invoke_command( 68 "make -C {} {} {} build" 69 .format(settings.xen_dir, settings.make_forward_args, 70 cppcheck_analysis.cppcheck_extra_make_args), 71 False, BuildPhaseError, 72 "Build error occured when running:\n{}" 73 ) 74 75 76def clean_analysis_artifacts(): 77 safparse_files = utils.recursive_find_file(settings.xen_dir, 78 r'.*.safparse$') 79 for original_file in safparse_files: 80 # This commands strips the .safparse extension, leaving <file> 81 parsed_file_path = os.path.splitext(original_file)[0] 82 mtime_original_file = os.stat(original_file).st_mtime 83 mtime_parsed_file = os.stat(parsed_file_path).st_mtime 84 if mtime_original_file != mtime_parsed_file: 85 return CleanPhaseError( 86 "The file {} was modified during the analysis " 87 "procedure, it is impossible now to restore from the " 88 "content of {}, please handle it manually" 89 .format(parsed_file_path, original_file) 90 ) 91 # Replace <file>.safparse to <file> 92 os.replace(original_file, parsed_file_path) 93