def check_file(self): """Perform all necessary checks on our file (including rulific ones). Raise FileCheckerError if an error is detected. :return: None. :rtype: None """ log_info("Checking style of `%s' (%s)" % (self.filename, self.file_type)) # Build the error message into a list. And then, at the end of # this function, if it turns out we got at least one issue, # raise it via FileCheckerError. err_msgs = [] # First, run the external checker... external_checker_err_msg = self.run_external_checker() if external_checker_err_msg is not None: # Stop immediately if the external checker detected some # errors. We could continue, and run the rest of the # tests, but cvs_check, the previous style checker, # wasn't doing that, so we don't either so as to be # consistent with the traditional behavior. raise FileCheckerError(external_checker_err_msg) # First, feed line-by-line the contents of the file to each # rulific checker. with open(self.filename) as f: for lineno, line in enumerate(f, 1): eol = get_eol(line) line = line[:-len(eol or '')] for rulific_checker in self.my_rulific_checkers: rulific_checker.process_line(lineno, line, eol) # Merge all the result of the line-by-line checking, currently # stored in each rulific checker, into a combined dictionary, # where keys are still line numbers, but the value is a list # of error messages applying to that line number. all_linenos = sorted( set().union(*(rulific_checker.errors_found.keys() for rulific_checker in self.my_rulific_checkers))) for lineno in all_linenos: for rulific_checker in self.my_rulific_checkers: if lineno in rulific_checker.errors_found: err_msgs.append('%s:%d: %s' % (self.filename, lineno, rulific_checker.errors_found[lineno])) for rulific_checker in self.my_rulific_checkers: global_check_err_msg = rulific_checker.global_check() if global_check_err_msg: err_msgs.append(global_check_err_msg) if err_msgs: raise FileCheckerError(*err_msgs)
def run_external_checker(self): file_type = self.file_type cmd = [ 'gcc', '-c', '-gnats', '-gnatm20', # Set "-x ada" so that we can style check Ada sources even # if their extension is not automatically identified by GCC. '-x', 'ada', ] # Base options: use GNAT style if file_type in (RT_SPEC, RT_BODY): # Set GNAT mode for runtime files only (changes legality and # semantics, and sets more restrictive style rules). # Note: This also enables language extensions. cmd.append('-gnatg') else: # Enable GNAT style checks, GNAT warnings, and treat warnings # and style messages as errors. cmd.extend(['-gnatyg', '-gnatw.g', '-gnatwe']) if 'gnatx' in self.config.style_checks_options: cmd.append('-gnatX') # Set language version: by default enable Ada 2012, except for # compiler units (which must be Ada 95 for bootstrap). Can be # overridden using flags gnat95 and gnat05. (Note that flag # "gnat12" has no effect since this is now the default). if file_type in (RT_SPEC, RT_BODY): # Language version already set by -gnatg for runtime units pass elif 'gnatx' in self.config.style_checks_options: # Language version already set by -gnatX pass elif file_type == COMPILER_CORE or \ 'gnat95' in self.config.style_checks_options: cmd.append('-gnat95') elif 'gnat05' in self.config.style_checks_options: cmd.append('-gnat05') else: cmd.append('-gnat12') # Set preprocessing data file. cmd.append('-gnatep=' + self.config.ada_preprocessing_filename) cmd.append(self.filename) # Run GCC with some some critical environment variables unset. BANNED_ENV_VARS = ('GCC_EXEC_PREFIX', 'GCC_INSTALL_DIRECTORY', 'GCC_INCLUDE_DIR', 'GCC_ROOT', 'GNAT_ROOT', 'BINUTILS_ROOT') gcc_env = { var_name: value for var_name, value in os.environ.items() if var_name not in BANNED_ENV_VARS } try: log_info('Running: %s' % command_line_image(cmd), 2) p = Run(cmd, env=gcc_env) if p.status != 0 or p.out: return p.out except OSError as e: return 'Failed to run %s: %s' % (cmd[0], e)
def run_external_checker(self): file_type = self.file_type cmd = [ "gcc", "-c", "-gnats", "-gnatm20", # Set "-x ada" so that we can style check Ada sources even # if their extension is not automatically identified by GCC. "-x", "ada", ] # Base options: use GNAT style if file_type in (RT_SPEC, RT_BODY): # Set GNAT mode for runtime files only (changes legality and # semantics, and sets more restrictive style rules). # # Note: -gnatg normally also enables language extensions # (i.e. -gnatX), but it only does so when it recognizes # the unit's filename. Since we also store implementation # variations of the same runtime unit inside files whose name # do not always match the normal filename naming scheme # (e.g. "a-except__zfp.adb"), we force -gnatX to ensure # extensions are consistently used across all GNAT runtime # sources. # # Note also that the compiler hardcodes the language version # it uses when compiling the runtime units, so there is no point # in trying to force a different version with a command-line # switch, the compiler just ignores them (see T618-047 for # confirmation of that). cmd.extend(["-gnatg", "-gnatX"]) else: # Enable GNAT style checks, GNAT warnings, and treat warnings # and style messages as errors. cmd.extend(["-gnatyg", "-gnatw.g", "-gnatwe"]) # The "gnat" repository needs specific treatment because we want # to allow building GNAT without requiring too recent a compiler. if file_type in (RT_SPEC, RT_BODY): # Language version already set by -gnatg for runtime units pass elif file_type == COMPILER_CORE: cmd.append("-gnat12") # For all other repositories, allow Ada 2012 by default, except # explicity overriden by the repository. elif "gnatx" in self.config.style_checks_options: cmd.append("-gnatX") elif "gnat95" in self.config.style_checks_options: cmd.append("-gnat95") elif "gnat05" in self.config.style_checks_options: cmd.append("-gnat05") elif "gnat12" in self.config.style_checks_options: cmd.append("-gnat12") elif "gnat2020" in self.config.style_checks_options: cmd.append("-gnat2020") else: cmd.append("-gnat2020") # Set preprocessing data file. cmd.append("-gnatep=" + self.config.ada_preprocessing_filename) cmd.append(self.filename) # Run GCC with some some critical environment variables unset. BANNED_ENV_VARS = ( "GCC_EXEC_PREFIX", "GCC_INSTALL_DIRECTORY", "GCC_INCLUDE_DIR", "GCC_ROOT", "GNAT_ROOT", "BINUTILS_ROOT", ) gcc_env = { var_name: value for var_name, value in os.environ.items() if var_name not in BANNED_ENV_VARS } try: log_info("Running: %s" % command_line_image(cmd), 2) p = Run(cmd, env=gcc_env) if p.status != 0 or p.out: return p.out except OSError as e: return "Failed to run %s: %s" % (cmd[0], e)