The 2nd option I listed won't work. That will fail UncrustifyCheck as well because EDK II CI will insert missing file/function headers and the files will not match.
We will need to comment out these 2 lines and submit an extra commit to re-enable. Mike > -----Original Message----- > From: Kinney, Michael D <michael.d.kin...@intel.com> > Sent: Wednesday, November 24, 2021 4:08 PM > To: devel@edk2.groups.io; mikub...@linux.microsoft.com; Kinney, Michael D > <michael.d.kin...@intel.com> > Cc: Liming Gao <gaolim...@byosoft.com.cn>; Sean Brogan > <sean.bro...@microsoft.com>; Bret Barkelew > <bret.barke...@microsoft.com> > Subject: RE: [edk2-devel] [PATCH v4 1/1] .pytool/Plugin/UncrustifyCheck: Add > Uncrustify CI plugin > > Hi Michael, > > Unfortunately, enabling the templates in the uncrustify.cfg files modifies > 340 files with missing > file/function headers that will now fail UncrustifyCheck. > > cmt_insert_file_header = default_file_header.txt > cmt_insert_func_header = default_function_header.txt > > Perhaps we should leave this feature off to get the uncrustify format changes > committed and > enable this feature immediately after so patch reviews after that will slowly > fix these missing > file/function headers. > > Or I can comment these two lines out when I generate the final version of the > patch series so > we don’t have to do an extra commit to re-enable. > > Mike > > > -----Original Message----- > > From: Kinney, Michael D <michael.d.kin...@intel.com> > > Sent: Wednesday, November 24, 2021 3:06 PM > > To: devel@edk2.groups.io; mikub...@linux.microsoft.com; Kinney, Michael D > > <michael.d.kin...@intel.com> > > Cc: Liming Gao <gaolim...@byosoft.com.cn>; Sean Brogan > > <sean.bro...@microsoft.com>; Bret Barkelew > > <bret.barke...@microsoft.com> > > Subject: RE: [edk2-devel] [PATCH v4 1/1] .pytool/Plugin/UncrustifyCheck: > > Add Uncrustify CI plugin > > > > Thanks. That makes sense. > > > > Mike > > > > > -----Original Message----- > > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael > > > Kubacki > > > Sent: Wednesday, November 24, 2021 2:55 PM > > > To: devel@edk2.groups.io; Kinney, Michael D <michael.d.kin...@intel.com> > > > Cc: Liming Gao <gaolim...@byosoft.com.cn>; Sean Brogan > > > <sean.bro...@microsoft.com>; Bret Barkelew > > > <bret.barke...@microsoft.com> > > > Subject: Re: [edk2-devel] [PATCH v4 1/1] .pytool/Plugin/UncrustifyCheck: > > > Add Uncrustify CI plugin > > > > > > Yes. Those were redundant and detected by the Python configparser module > > > when I used it to parse the config file. > > > > > > Thanks, > > > Michael > > > > > > On 11/24/2021 5:45 PM, Michael D Kinney wrote: > > > > Hi Michael, > > > > > > > > I see a couple settings deleted from the uncrustify.cfg. Was that in > > > > purpose? Does it change the format? > > > > > > > > > > > > -nl_func_call_start_multi_line = true # Whether to add a newline > > > > after '(' in a function call if '(' and ')' > > are > > > > - # in different lines. > > > > > > > > > > > > -nl_func_call_args_multi_line = true > > > > -nl_func_call_args_multi_line_ignore_closures = false > > > > > > > > > > > > Thanks, > > > > > > > > Mike > > > > > > > >> -----Original Message----- > > > >> From: mikub...@linux.microsoft.com <mikub...@linux.microsoft.com> > > > >> Sent: Wednesday, November 24, 2021 1:42 PM > > > >> To: devel@edk2.groups.io > > > >> Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Liming Gao > > > >> <gaolim...@byosoft.com.cn>; Sean Brogan > > > >> <sean.bro...@microsoft.com>; Bret Barkelew > > > >> <bret.barke...@microsoft.com> > > > >> Subject: [PATCH v4 1/1] .pytool/Plugin/UncrustifyCheck: Add Uncrustify > > > >> CI plugin > > > >> > > > >> From: Michael Kubacki <michael.kuba...@microsoft.com> > > > >> > > > >> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3748 > > > >> > > > >> Adds a new CI plugin for Uncrustify. This is used to check > > > >> coding standard compliance of source code to the EDK II C Coding > > > >> Standards Specification. > > > >> > > > >> An external dependency is added in the plugin directory to retrieve > > > >> the Uncrustify executable. Currently, the executable is from an edk2 > > > >> fork of the application host in this repository: > > > >> > > > >> https://dev.azure.com/projectmu/Uncrustify/ > > > >> > > > >> Note that the Uncrustify application outputs the commit ID that the > > > >> application was built from when given the --version parameter. > > > >> > > > >> This ID can be mapped to the version specified in the Uncrustify CI > > > >> plugin external dependency file (uncrustify_ext_dep.yaml) such as > > > >> 73.0.3 by visiting the Uncrustify edk2 fork release pipeline page > > > >> which associates the NuGet package version with the commit ID it was > > > >> built from: > > > >> > > > >> https://dev.azure.com/projectmu/Uncrustify/_build > > > >> > > > >> The default Uncrustify configuration files are added in the plugin > > > >> directory. Additional details are in the Readme.md file added in > > > >> the Uncrustify plugin directory. > > > >> > > > >> Cc: Michael D Kinney <michael.d.kin...@intel.com> > > > >> Cc: Liming Gao <gaolim...@byosoft.com.cn> > > > >> Cc: Sean Brogan <sean.bro...@microsoft.com> > > > >> Cc: Bret Barkelew <bret.barke...@microsoft.com> > > > >> Signed-off-by: Michael Kubacki <michael.kuba...@microsoft.com> > > > >> --- > > > >> > > > >> Notes: > > > >> V4 changes: > > > >> > > > >> 1. Updated commit subject to use the new plugin name. > > > >> 2. Enabled file and function header templates to be placed in > > > >> files missing a file or function header (comment block). > > > >> 3. Added support to detect whether a file header or function > > > >> header is missing in a file by searching files modified by > > > >> Uncrustify for the template file text. > > > >> 4. Updated the plugin name displayed in some log output messages. > > > >> > > > >> V3 changes: > > > >> > > > >> 1. Renamed the CI plugin to "UncrustifyCheck" from "Uncrustify" > > > >> to follow similar naming conventions used in other plugins > > > >> that check files > > > >> 2. Added a clarifying paragraph to the beginning of the Uncrustify > > > >> CI plugin Readme.md file that the plugin is enabled by default > > > >> and test results can be ignored by enabling "AuditOnly" mode. > > > >> 3. Added instructions in the commit message on how to map the > > > >> version reported by the Uncrustify application (--version) to > > > >> the version specified in the CI plugin external dependency > > > >> YAML file. > > > >> > > > >> V2 changes: > > > >> > > > >> 1. Changed plugin temp directory to > > > >> Build/.pytool/Plugin/Uncrustify > > > >> 2. Added TCBZ REF in patch commit message > > > >> > > > >> .pytool/Plugin/UncrustifyCheck/Readme.md | 120 ++++ > > > >> .pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py | 617 > > > >> ++++++++++++++++++++ > > > >> .pytool/Plugin/UncrustifyCheck/default_file_header.txt | 9 + > > > >> .pytool/Plugin/UncrustifyCheck/default_function_header.txt | 15 + > > > >> .pytool/Plugin/UncrustifyCheck/uncrustify.cfg | 462 > > > >> +++++++++++++++ > > > >> .pytool/Plugin/UncrustifyCheck/uncrustify_ext_dep.yaml | 16 + > > > >> .pytool/Plugin/UncrustifyCheck/uncrustify_plug_in.yaml | 11 + > > > >> .pytool/Readme.md | 4 + > > > >> 8 files changed, 1254 insertions(+) > > > >> > > > >> diff --git a/.pytool/Plugin/UncrustifyCheck/Readme.md > > > >> b/.pytool/Plugin/UncrustifyCheck/Readme.md > > > >> new file mode 100644 > > > >> index 000000000000..bb263bcc87d7 > > > >> --- /dev/null > > > >> +++ b/.pytool/Plugin/UncrustifyCheck/Readme.md > > > >> @@ -0,0 +1,120 @@ > > > >> +# UncrustifyCheck Plugin > > > >> + > > > >> +This CiBuildPlugin scans all the files in a given package and checks > > > >> for coding standard compliance issues. > > > >> + > > > >> +This plugin is enabled by default. If a package would like to prevent > > > >> the plugin from reporting errors, it can do > > > >> +so by enabling [`AuditOnly`](#auditonly) mode. > > > >> + > > > >> +This plugin requires the directory containing the Uncrustify > > > >> executable that should be used for this plugin to > > > >> +be specified in an environment variable named `UNCRUSTIFY_CI_PATH`. > > > >> This unique variable name is used to avoid > > > confusion > > > >> +with other paths to Uncrustify which might not be the expected build > > > >> for use by this plugin. > > > >> + > > > >> +By default, an Uncrustify configuration file named "uncrustify.cfg" > > > >> located in the same directory as the plugin is > > > >> +used. The value can be overridden to a package-specific path with the > > > >> `ConfigFilePath` configuration file option. > > > >> + > > > >> +* Uncrustify source code and documentation: > > > >> https://github.com/uncrustify/uncrustify > > > >> +* Project Mu Uncrustify fork source code and documentation: > > > >> https://dev.azure.com/projectmu/Uncrustify > > > >> + > > > >> +## Files Checked in a Package > > > >> + > > > >> +By default, this plugin will discover all files in the package with > > > >> the following default paths: > > > >> + > > > >> +```python > > > >> +[ > > > >> +# C source > > > >> +"*.c", > > > >> +"*.h" > > > >> +] > > > >> +``` > > > >> + > > > >> +From this list of files, any files ignored by Git or residing in a > > > >> Git submodule will be removed. If Git is not > > > >> +found, submodules are not found, or ignored files are not found no > > > >> changes are made to the list of discovered > files. > > > >> + > > > >> +To control the paths checked in a given package, review the > > > >> configuration options described in this file. > > > >> + > > > >> +## Configuration > > > >> + > > > >> +The plugin can be configured with a few optional configuration > > > >> options. > > > >> + > > > >> +``` yaml > > > >> + "UncrustifyCheck": { > > > >> + "AdditionalIncludePaths": [], # Additional paths to check > > > >> formatting (wildcards supported). > > > >> + "AuditOnly": False, # Don't fail the build if there > > > >> are errors. Just log them. > > > >> + "ConfigFilePath": "", # Custom path to an Uncrustify > > > >> config file. > > > >> + "IgnoreStandardPaths": [], # Standard Plugin defined paths > > > >> that should be ignored. > > > >> + "OutputFileDiffs": False, # Output chunks of formatting > > > >> diffs in the test case log. > > > >> + # This can significantly slow > > > >> down the plugin on very large packages. > > > >> + "SkipGitExclusions": False # Don't exclude git ignored files > > > >> and files in git submodules. > > > >> + } > > > >> +``` > > > >> + > > > >> +### `AdditionalIncludePaths` > > > >> + > > > >> +A package configuration file can specify any additional paths to be > > > >> included with this option. > > > >> + > > > >> +At this time, it is recommended all files run against the plugin be > > > >> written in the C or C++ language. > > > >> + > > > >> +### `AuditOnly` > > > >> + > > > >> +`Boolean` - Default is `False`. > > > >> + > > > >> +If `True`, run the test in an "audit only mode" which will log all > > > >> errors but instead of failing the build, it > will > > > set > > > >> +the test as skipped. This allows visibility into the failures without > > > >> breaking the build. > > > >> + > > > >> +### `ConfigFilePath` > > > >> + > > > >> +`String` - Default is `"uncrustify.cfg"` > > > >> + > > > >> +When specified in the config file, this is a package relative path to > > > >> the Uncrustify configuration file. > > > >> + > > > >> +### `IgnoreStandardPaths` > > > >> + > > > >> +This plugin by default will check the below standard paths. A package > > > >> configuration file can specify any of these > > > paths > > > >> +to be ignored. > > > >> + > > > >> +```python > > > >> +[ > > > >> +# C source > > > >> +"*.c", > > > >> +"*.h" > > > >> +] > > > >> +``` > > > >> + > > > >> +### `OutputFileDiffs` > > > >> + > > > >> +`Boolean` - Default is `False`. > > > >> + > > > >> +If `True`, output diffs of formatting changes into the test case log. > > > >> This is helpful to exactly understand what > > > changes > > > >> +need to be made to the source code in order to fix a coding standard > > > >> compliance issue. > > > >> + > > > >> +Note that calculating the file diffs on a very large set of of > > > >> results (e.g. >100 files) can significantly slow > down > > > >> +plugin execution. > > > >> + > > > >> +### `SkipGitExclusions` > > > >> + > > > >> +`Boolean` - Default is `False`. > > > >> + > > > >> +By default, files in paths matched in a .gitignore file or a > > > >> recognized git submodule are excluded. If this option > > > >> +is `True`, the plugin will not attempt to recognize these files and > > > >> exclude them. > > > >> + > > > >> +## High-Level Plugin Operation > > > >> + > > > >> +This plugin generates two main sets of temporary files: > > > >> + > > > >> + 1. A working directory in the directory > > > >> `Build/.pytool/Plugin/Uncrustify` > > > >> + 2. For each source file with formatting errors, a sibling file with > > > >> the `.uncrustify_plugin` extension > > > >> + > > > >> +The working directory contains temporary files unique to operation of > > > >> the plugin. All of these files are removed > on > > > >> +exit of the plugin including successful or unsuccessful execution > > > >> (such as a Python exception occurring). If for > any > > > >> +reason, any files in the package exist prior to running the plugin > > > >> with the `.uncrustify_plugin` extension, the > > plugin > > > >> +will inform the user to remove these files and exit before running > > > >> Uncrustify. This is to ensure the accuracy of > the > > > >> +results reported from each execution instance of the plugin. > > > >> + > > > >> +The plugin determines the list of relevant files to check with > > > >> Uncrustify and then invokes Uncrustify with that > file > > > >> +list. For any files not compliant to the configuration file provided, > > > >> Uncrustify will generate a corresponding > file > > > >> +with the `.uncrustify_plugin` extension. The plugin discovers all of > > > >> these files. If any such files are present, > > this > > > >> +indicates a formatting issue was found and the test is marked failed > > > >> (unless `AuditOnly` mode is enabled). > > > >> + > > > >> +The test case log will contain a report of which files failed to > > > >> format properly, allowing the user to run > > Uncrustify > > > >> +against the file locally to fix the issue. If the `OutputFileDiffs` > > > >> configuration option is set to `True`, the > > plugin > > > >> +will output diff chunks for all code formatting issues in the test > > > >> case log. > > > >> diff --git a/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py > > > >> b/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py > > > >> new file mode 100644 > > > >> index 000000000000..59534469a2d3 > > > >> --- /dev/null > > > >> +++ b/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py > > > >> @@ -0,0 +1,617 @@ > > > >> +# @file UncrustifyCheck.py > > > >> +# > > > >> +# An edk2-pytool based plugin wrapper for Uncrustify > > > >> +# > > > >> +# Copyright (c) Microsoft Corporation. > > > >> +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > >> +## > > > >> +import configparser > > > >> +import difflib > > > >> +import errno > > > >> +import logging > > > >> +import os > > > >> +import pathlib > > > >> +import shutil > > > >> +import timeit > > > >> +from edk2toolext.environment import version_aggregator > > > >> +from edk2toolext.environment.plugin_manager import PluginManager > > > >> +from edk2toolext.environment.plugintypes.ci_build_plugin import > > > >> ICiBuildPlugin > > > >> +from edk2toolext.environment.plugintypes.uefi_helper_plugin import > > > >> HelperFunctions > > > >> +from edk2toolext.environment.var_dict import VarDict > > > >> +from edk2toollib.log.junit_report_format import JunitReportTestCase > > > >> +from edk2toollib.uefi.edk2.path_utilities import Edk2Path > > > >> +from edk2toollib.utility_functions import RunCmd > > > >> +from io import StringIO > > > >> +from typing import Any, Dict, List, Tuple > > > >> + > > > >> +# > > > >> +# Provide more user friendly messages for certain scenarios > > > >> +# > > > >> +class UncrustifyException(Exception): > > > >> + def __init__(self, message, exit_code): > > > >> + super().__init__(message) > > > >> + self.exit_code = exit_code > > > >> + > > > >> + > > > >> +class UncrustifyAppEnvVarNotFoundException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -101) > > > >> + > > > >> + > > > >> +class UncrustifyAppVersionErrorException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -102) > > > >> + > > > >> + > > > >> +class UncrustifyAppExecutionException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -103) > > > >> + > > > >> + > > > >> +class > > > >> UncrustifyStalePluginFormattedFilesException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -120) > > > >> + > > > >> + > > > >> +class UncrustifyInputFileCreationErrorException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -121) > > > >> + > > > >> +class > > > >> UncrustifyInvalidIgnoreStandardPathsException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -122) > > > >> + > > > >> +class UncrustifyGitIgnoreFileException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -140) > > > >> + > > > >> + > > > >> +class UncrustifyGitSubmoduleException(UncrustifyException): > > > >> + def __init__(self, message): > > > >> + super().__init__(message, -141) > > > >> + > > > >> + > > > >> +class UncrustifyCheck(ICiBuildPlugin): > > > >> + """ > > > >> + A CiBuildPlugin that uses Uncrustify to check the source files in > > > >> the > > > >> + package being tested for coding standard issues. > > > >> + > > > >> + By default, the plugin runs against standard C source file > > > >> extensions but > > > >> + its configuration can be modified through its configuration file. > > > >> + > > > >> + Configuration options: > > > >> + "UncrustifyCheck": { > > > >> + "AdditionalIncludePaths": [], # Additional paths to check > > > >> formatting (wildcards supported). > > > >> + "AuditOnly": False, # Don't fail the build if there > > > >> are errors. Just log them. > > > >> + "ConfigFilePath": "", # Custom path to an Uncrustify > > > >> config file. > > > >> + "IgnoreStandardPaths": [], # Standard Plugin defined paths > > > >> that should be ignored. > > > >> + "OutputFileDiffs": False, # Output chunks of formatting > > > >> diffs in the test case log. > > > >> + # This can significantly slow > > > >> down the plugin on very large packages. > > > >> + "SkipGitExclusions": False # Don't exclude git ignored > > > >> files and files in git submodules. > > > >> + } > > > >> + """ > > > >> + > > > >> + # > > > >> + # By default, use an "uncrustify.cfg" config file in the plugin > > > >> directory > > > >> + # A package can override this path via "ConfigFilePath" > > > >> + # > > > >> + # Note: Values specified via "ConfigFilePath" are relative to the > > > >> package > > > >> + # > > > >> + DEFAULT_CONFIG_FILE_PATH = os.path.join( > > > >> + pathlib.Path(__file__).parent.resolve(), "uncrustify.cfg") > > > >> + > > > >> + # > > > >> + # The extension used for formatted files produced by this plugin > > > >> + # > > > >> + FORMATTED_FILE_EXTENSION = ".uncrustify_plugin" > > > >> + > > > >> + # > > > >> + # A package can add any additional paths with > > > >> "AdditionalIncludePaths" > > > >> + # A package can remove any of these paths with > > > >> "IgnoreStandardPaths" > > > >> + # > > > >> + STANDARD_PLUGIN_DEFINED_PATHS = ("*.c", "*.h") > > > >> + > > > >> + # > > > >> + # The Uncrustify application path should set in this environment > > > >> variable > > > >> + # > > > >> + UNCRUSTIFY_PATH_ENV_KEY = "UNCRUSTIFY_CI_PATH" > > > >> + > > > >> + def GetTestName(self, packagename: str, environment: VarDict) -> > > > >> Tuple: > > > >> + """ Provide the testcase name and classname for use in > > > >> reporting > > > >> + > > > >> + Args: > > > >> + packagename: string containing name of package to build > > > >> + environment: The VarDict for the test to run in > > > >> + Returns: > > > >> + A tuple containing the testcase name and the classname > > > >> + (testcasename, classname) > > > >> + testclassname: a descriptive string for the testcase > > > >> can include whitespace > > > >> + classname: should be patterned > > > >> <packagename>.<plugin>.<optionally any unique condition> > > > >> + """ > > > >> + return ("Check file coding standard compliance in " + > > > >> packagename, packagename + ".UncrustifyCheck") > > > >> + > > > >> + def RunBuildPlugin(self, package_rel_path: str, edk2_path: > > > >> Edk2Path, package_config: Dict[str, List[str]], > > > >> environment_config: Any, plugin_manager: PluginManager, > > > >> plugin_manager_helper: HelperFunctions, tc: > > > JunitReportTestCase, > > > >> output_stream=None) -> int: > > > >> + """ > > > >> + External function of plugin. This function is used to perform > > > >> the task of the CiBuild Plugin. > > > >> + > > > >> + Args: > > > >> + - package_rel_path: edk2 workspace relative path to the > > > >> package > > > >> + - edk2_path: Edk2Path object with workspace and packages > > > >> paths > > > >> + - package_config: Dictionary with the package configuration > > > >> + - environment_config: Environment configuration > > > >> + - plugin_manager: Plugin Manager Instance > > > >> + - plugin_manager_helper: Plugin Manager Helper Instance > > > >> + - tc: JUnit test case > > > >> + - output_stream: The StringIO output stream from this > > > >> plugin (logging) > > > >> + > > > >> + Returns > > > >> + >0 : Number of errors found > > > >> + 0 : Passed successfully > > > >> + -1 : Skipped for missing prereq > > > >> + """ > > > >> + try: > > > >> + # Initialize plugin and check pre-requisites. > > > >> + self._initialize_environment_info( > > > >> + package_rel_path, edk2_path, package_config, tc) > > > >> + self._initialize_configuration() > > > >> + self._check_for_preexisting_formatted_files() > > > >> + > > > >> + # Log important context information. > > > >> + self._log_uncrustify_app_info() > > > >> + > > > >> + # Get template file contents if specified > > > >> + self._get_template_file_contents() > > > >> + > > > >> + # Create meta input files & directories > > > >> + self._create_temp_working_directory() > > > >> + self._create_uncrustify_file_list_file() > > > >> + > > > >> + self._run_uncrustify() > > > >> + > > > >> + # Post-execution actions. > > > >> + self._process_uncrustify_results() > > > >> + > > > >> + except UncrustifyException as e: > > > >> + self._tc.LogStdError( > > > >> + f"Uncrustify error {e.exit_code}. > > > >> Details:\n\n{str(e)}") > > > >> + logging.warning( > > > >> + f"Uncrustify error {e.exit_code}. > > > >> Details:\n\n{str(e)}") > > > >> + return -1 > > > >> + else: > > > >> + if self._formatted_file_error_count > 0: > > > >> + if self._audit_only_mode: > > > >> + logging.info( > > > >> + "Setting test as skipped since AuditOnly is > > > >> enabled") > > > >> + self._tc.SetSkipped() > > > >> + return -1 > > > >> + else: > > > >> + self._tc.SetFailed( > > > >> + f"{self._plugin_name} failed due to > > > >> {self._formatted_file_error_count} incorrectly > formatted > > > >> files.", "CHECK_FAILED") > > > >> + else: > > > >> + self._tc.SetSuccess() > > > >> + return self._formatted_file_error_count > > > >> + finally: > > > >> + self._cleanup_temporary_formatted_files() > > > >> + self._cleanup_temporary_directory() > > > >> + > > > >> + def _initialize_configuration(self) -> None: > > > >> + """ > > > >> + Initializes plugin configuration. > > > >> + """ > > > >> + self._initialize_app_info() > > > >> + self._initialize_config_file_info() > > > >> + self._initialize_file_to_format_info() > > > >> + self._initialize_test_case_output_options() > > > >> + > > > >> + def _check_for_preexisting_formatted_files(self) -> None: > > > >> + """ > > > >> + Checks if any formatted files from prior execution are > > > >> present. > > > >> + > > > >> + Existence of such files is an unexpected condition. This > > > >> might result > > > >> + from an error that occurred during a previous run or a > > > >> premature exit from a debug scenario. In any case, > > the > > > >> package should be clean before starting a new run. > > > >> + """ > > > >> + pre_existing_formatted_file_count = len( > > > >> + [str(path.resolve()) for path in > > > >> pathlib.Path(self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')]) > > > >> + > > > >> + if pre_existing_formatted_file_count > 0: > > > >> + raise UncrustifyStalePluginFormattedFilesException( > > > >> + f"{pre_existing_formatted_file_count} formatted files > > > >> already exist. To prevent overwriting these > > > files, > > > >> please remove them before running this plugin.") > > > >> + > > > >> + def _cleanup_temporary_directory(self) -> None: > > > >> + """ > > > >> + Cleans up the temporary directory used for this execution > > > >> instance. > > > >> + > > > >> + This removes the directory and all files created during this > > > >> instance. > > > >> + """ > > > >> + if hasattr(self, '_working_dir'): > > > >> + self._remove_tree(self._working_dir) > > > >> + > > > >> + def _cleanup_temporary_formatted_files(self) -> None: > > > >> + """ > > > >> + Cleans up the temporary formmatted files produced by > > > >> Uncrustify. > > > >> + > > > >> + This will recursively remove all formatted files generated by > > > >> Uncrustify > > > >> + during this execution instance. > > > >> + """ > > > >> + if hasattr(self, '_abs_package_path'): > > > >> + formatted_files = [str(path.resolve()) for path in > > > >> pathlib.Path( > > > >> + > > > >> self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')] > > > >> + > > > >> + for formatted_file in formatted_files: > > > >> + os.remove(formatted_file) > > > >> + > > > >> + def _create_temp_working_directory(self) -> None: > > > >> + """ > > > >> + Creates the temporary directory used for this execution > > > >> instance. > > > >> + """ > > > >> + self._working_dir = os.path.join( > > > >> + self._abs_workspace_path, "Build", ".pytool", "Plugin", > > > >> f"{self._plugin_name}") > > > >> + > > > >> + try: > > > >> + pathlib.Path(self._working_dir).mkdir(parents=True, > > > >> exist_ok=True) > > > >> + except OSError as e: > > > >> + raise UncrustifyInputFileCreationErrorException( > > > >> + f"Error creating plugin directory > > > >> {self._working_dir}.\n\n{repr(e)}.") > > > >> + > > > >> + def _create_uncrustify_file_list_file(self) -> None: > > > >> + """ > > > >> + Creates the file with the list of source files for Uncrustify > > > >> to process. > > > >> + """ > > > >> + self._app_input_file_path = os.path.join( > > > >> + self._working_dir, "uncrustify_file_list.txt") > > > >> + > > > >> + with open(self._app_input_file_path, 'w', encoding='utf8') as > > > >> f: > > > >> + f.writelines(f"\n".join(self._abs_file_paths_to_format)) > > > >> + > > > >> + def _execute_uncrustify(self) -> None: > > > >> + """ > > > >> + Executes Uncrustify with the initialized configuration. > > > >> + """ > > > >> + output = StringIO() > > > >> + self._app_exit_code = RunCmd( > > > >> + self._app_path, > > > >> + f"-c {self._app_config_file} -F > > > >> {self._app_input_file_path} --if-changed --suffix > > > >> {UncrustifyCheck.FORMATTED_FILE_EXTENSION}", outstream=output) > > > >> + self._app_output = output.getvalue().strip().splitlines() > > > >> + > > > >> + def _get_git_ignored_paths(self) -> List[str]: > > > >> + """" > > > >> + Returns a list of file absolute path strings to all files > > > >> ignored in this git repository. > > > >> + > > > >> + If git is not found, an empty list will be returned. > > > >> + """ > > > >> + if not shutil.which("git"): > > > >> + logging.warn( > > > >> + "Git is not found on this system. Git submodule paths > > > >> will not be considered.") > > > >> + return [] > > > >> + > > > >> + outstream_buffer = StringIO() > > > >> + exit_code = RunCmd("git", "ls-files --other", > > > >> + workingdir=self._abs_workspace_path, > > > >> outstream=outstream_buffer, > > > logging_level=logging.NOTSET) > > > >> + if (exit_code != 0): > > > >> + raise UncrustifyGitIgnoreFileException( > > > >> + f"An error occurred reading git ignore settings. This > > > >> will prevent Uncrustify from running against > > the > > > >> expected set of files.") > > > >> + > > > >> + # Note: This will potentially be a large list, but at least > > > >> sorted > > > >> + return outstream_buffer.getvalue().strip().splitlines() > > > >> + > > > >> + def _get_git_submodule_paths(self) -> List[str]: > > > >> + """ > > > >> + Returns a list of directory absolute path strings to the root > > > >> of each submodule in the workspace > repository. > > > >> + > > > >> + If git is not found, an empty list will be returned. > > > >> + """ > > > >> + if not shutil.which("git"): > > > >> + logging.warn( > > > >> + "Git is not found on this system. Git submodule paths > > > >> will not be considered.") > > > >> + return [] > > > >> + > > > >> + if os.path.isfile(os.path.join(self._abs_workspace_path, > > > >> ".gitmodules")): > > > >> + logging.info( > > > >> + f".gitmodules file found. Excluding submodules in > > > >> {self._package_name}.") > > > >> + > > > >> + outstream_buffer = StringIO() > > > >> + exit_code = RunCmd("git", "config --file .gitmodules > > > >> --get-regexp path", > > > workingdir=self._abs_workspace_path, > > > >> outstream=outstream_buffer, logging_level=logging.NOTSET) > > > >> + if (exit_code != 0): > > > >> + raise UncrustifyGitSubmoduleException( > > > >> + f".gitmodule file detected but an error occurred > > > >> reading the file. Cannot proceed with unknown > > > >> submodule paths.") > > > >> + > > > >> + submodule_paths = [] > > > >> + for line in > > > >> outstream_buffer.getvalue().strip().splitlines(): > > > >> + submodule_paths.append( > > > >> + > > > >> os.path.normpath(os.path.join(self._abs_workspace_path, > > > >> line.split()[1]))) > > > >> + > > > >> + return submodule_paths > > > >> + else: > > > >> + return [] > > > >> + > > > >> + def _get_template_file_contents(self) -> None: > > > >> + """ > > > >> + Gets the contents of Uncrustify template files if they are > > > >> specified > > > >> + in the Uncrustify configuration file. > > > >> + """ > > > >> + > > > >> + self._file_template_contents = None > > > >> + self._func_template_contents = None > > > >> + > > > >> + # Allow no value to allow "set" statements in the config file > > > >> which do > > > >> + # not specify value assignment > > > >> + parser = configparser.ConfigParser(allow_no_value=True) > > > >> + with open(self._app_config_file, 'r') as cf: > > > >> + parser.read_string("[dummy_section]\n" + cf.read()) > > > >> + > > > >> + try: > > > >> + file_template_name = > > > >> parser["dummy_section"]["cmt_insert_file_header"] > > > >> + > > > >> + file_template_path = pathlib.Path(file_template_name) > > > >> + > > > >> + if not file_template_path.is_file(): > > > >> + file_template_path = > > > >> pathlib.Path(os.path.join(self._plugin_path, file_template_name)) > > > >> + self._file_template_contents = > > > >> file_template_path.read_text() > > > >> + except KeyError: > > > >> + logging.warn("A file header template is not specified in > > > >> the config file.") > > > >> + except FileNotFoundError: > > > >> + logging.warn("The specified file header template file was > > > >> not found.") > > > >> + try: > > > >> + func_template_name = > > > >> parser["dummy_section"]["cmt_insert_func_header"] > > > >> + > > > >> + func_template_path = pathlib.Path(func_template_name) > > > >> + > > > >> + if not func_template_path.is_file(): > > > >> + func_template_path = > > > >> pathlib.Path(os.path.join(self._plugin_path, func_template_name)) > > > >> + self._func_template_contents = > > > >> func_template_path.read_text() > > > >> + except KeyError: > > > >> + logging.warn("A function header template is not specified > > > >> in the config file.") > > > >> + except FileNotFoundError: > > > >> + logging.warn("The specified function header template file > > > >> was not found.") > > > >> + > > > >> + def _initialize_app_info(self) -> None: > > > >> + """ > > > >> + Initialize Uncrustify application information. > > > >> + > > > >> + This function will determine the application path and version. > > > >> + """ > > > >> + # Verify Uncrustify is specified in the environment. > > > >> + if UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY not in os.environ: > > > >> + raise UncrustifyAppEnvVarNotFoundException( > > > >> + f"Uncrustify environment variable > > > >> {UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY} is not present.") > > > >> + > > > >> + self._app_path = shutil.which('uncrustify', > > > >> path=os.environ[UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY]) > > > >> + > > > >> + if self._app_path is None: > > > >> + raise FileNotFoundError( > > > >> + errno.ENOENT, os.strerror(errno.ENOENT), > > > >> self._app_path) > > > >> + > > > >> + self._app_path = > > > >> os.path.normcase(os.path.normpath(self._app_path)) > > > >> + > > > >> + if not os.path.isfile(self._app_path): > > > >> + raise FileNotFoundError( > > > >> + errno.ENOENT, os.strerror(errno.ENOENT), > > > >> self._app_path) > > > >> + > > > >> + # Verify Uncrustify is present at the expected path. > > > >> + return_buffer = StringIO() > > > >> + ret = RunCmd(self._app_path, "--version", > > > >> outstream=return_buffer) > > > >> + if (ret != 0): > > > >> + raise UncrustifyAppVersionErrorException( > > > >> + f"Error occurred executing --version: {ret}.") > > > >> + > > > >> + # Log Uncrustify version information. > > > >> + self._app_version = return_buffer.getvalue().strip() > > > >> + self._tc.LogStdOut(f"Uncrustify version: {self._app_version}") > > > >> + version_aggregator.GetVersionAggregator().ReportVersion( > > > >> + "Uncrustify", self._app_version, > > > >> version_aggregator.VersionTypes.INFO) > > > >> + > > > >> + def _initialize_config_file_info(self) -> None: > > > >> + """ > > > >> + Initialize Uncrustify configuration file info. > > > >> + > > > >> + The config file path is relative to the package root. > > > >> + """ > > > >> + self._app_config_file = > > > >> UncrustifyCheck.DEFAULT_CONFIG_FILE_PATH > > > >> + if "ConfigFilePath" in self._package_config: > > > >> + self._app_config_file = > > > >> self._package_config["ConfigFilePath"].strip() > > > >> + > > > >> + self._app_config_file = os.path.normpath( > > > >> + os.path.join(self._abs_package_path, > > > >> self._app_config_file)) > > > >> + > > > >> + if not os.path.isfile(self._app_config_file): > > > >> + raise FileNotFoundError( > > > >> + errno.ENOENT, os.strerror(errno.ENOENT), > > > >> self._app_config_file) > > > >> + > > > >> + def _initialize_environment_info(self, package_rel_path: str, > > > >> edk2_path: Edk2Path, package_config: Dict[str, > > > >> List[str]], tc: JunitReportTestCase) -> None: > > > >> + """ > > > >> + Initializes plugin environment information. > > > >> + """ > > > >> + self._abs_package_path = > > > >> edk2_path.GetAbsolutePathOnThisSytemFromEdk2RelativePath( > > > >> + package_rel_path) > > > >> + self._abs_workspace_path = edk2_path.WorkspacePath > > > >> + self._package_config = package_config > > > >> + self._package_name = os.path.basename( > > > >> + os.path.normpath(package_rel_path)) > > > >> + self._plugin_name = self.__class__.__name__ > > > >> + self._plugin_path = > > > >> os.path.dirname(os.path.realpath(__file__)) > > > >> + self._rel_package_path = package_rel_path > > > >> + self._tc = tc > > > >> + > > > >> + def _initialize_file_to_format_info(self) -> None: > > > >> + """ > > > >> + Forms the list of source files for Uncrustify to process. > > > >> + """ > > > >> + # Create a list of all the package relative file paths in the > > > >> package to run against Uncrustify. > > > >> + rel_file_paths_to_format = list( > > > >> + UncrustifyCheck.STANDARD_PLUGIN_DEFINED_PATHS) > > > >> + > > > >> + # Allow the ci.yaml to remove any of the pre-defined standard > > > >> paths > > > >> + if "IgnoreStandardPaths" in self._package_config: > > > >> + for a in self._package_config["IgnoreStandardPaths"]: > > > >> + if a.strip() in rel_file_paths_to_format: > > > >> + self._tc.LogStdOut( > > > >> + f"Ignoring standard path due to ci.yaml > > > >> ignore: {a}") > > > >> + rel_file_paths_to_format.remove(a.strip()) > > > >> + else: > > > >> + raise > > > >> UncrustifyInvalidIgnoreStandardPathsException(f"Invalid > > > >> IgnoreStandardPaths value: {a}") > > > >> + > > > >> + # Allow the ci.yaml to specify additional include paths for > > > >> this package > > > >> + if "AdditionalIncludePaths" in self._package_config: > > > >> + rel_file_paths_to_format.extend( > > > >> + self._package_config["AdditionalIncludePaths"]) > > > >> + > > > >> + self._abs_file_paths_to_format = [] > > > >> + for path in rel_file_paths_to_format: > > > >> + self._abs_file_paths_to_format.extend( > > > >> + [str(path.resolve()) for path in > > > >> pathlib.Path(self._abs_package_path).rglob(path)]) > > > >> + > > > >> + if not "SkipGitExclusions" in self._package_config or not > > > >> self._package_config["SkipGitExclusions"]: > > > >> + # Remove files ignored by git > > > >> + logging.info( > > > >> + f"{self._package_name} file count before git ignore > > > >> file exclusion: > > > >> {len(self._abs_file_paths_to_format)}") > > > >> + > > > >> + ignored_paths = self._get_git_ignored_paths() > > > >> + self._abs_file_paths_to_format = list( > > > >> + > > > >> set(self._abs_file_paths_to_format).difference(ignored_paths)) > > > >> + > > > >> + logging.info( > > > >> + f"{self._package_name} file count after git ignore > > > >> file exclusion: > > > >> {len(self._abs_file_paths_to_format)}") > > > >> + > > > >> + # Remove files in submodules > > > >> + logging.info( > > > >> + f"{self._package_name} file count before submodule > > > >> exclusion: > > {len(self._abs_file_paths_to_format)}") > > > >> + > > > >> + submodule_paths = tuple(self._get_git_submodule_paths()) > > > >> + for path in submodule_paths: > > > >> + logging.info(f" submodule path: {path}") > > > >> + > > > >> + self._abs_file_paths_to_format = [ > > > >> + f for f in self._abs_file_paths_to_format if not > > > >> f.startswith(submodule_paths)] > > > >> + > > > >> + logging.info( > > > >> + f"{self._package_name} file count after submodule > > > >> exclusion: > {len(self._abs_file_paths_to_format)}") > > > >> + > > > >> + # Sort the files for more consistent results > > > >> + self._abs_file_paths_to_format.sort() > > > >> + > > > >> + def _initialize_test_case_output_options(self) -> None: > > > >> + """ > > > >> + Initializes options that influence test case output. > > > >> + """ > > > >> + self._audit_only_mode = False > > > >> + self._output_file_diffs = False > > > >> + > > > >> + if "AuditOnly" in self._package_config and > > > >> self._package_config["AuditOnly"]: > > > >> + self._audit_only_mode = True > > > >> + > > > >> + if "OutputFileDiffs" in self._package_config and > > > >> self._package_config["OutputFileDiffs"]: > > > >> + self._output_file_diffs = True > > > >> + > > > >> + def _log_uncrustify_app_info(self) -> None: > > > >> + """ > > > >> + Logs Uncrustify application information. > > > >> + """ > > > >> + self._tc.LogStdOut(f"Found Uncrustify at {self._app_path}") > > > >> + self._tc.LogStdOut(f"Uncrustify version: {self._app_version}") > > > >> + self._tc.LogStdOut('\n') > > > >> + logging.info(f"Found Uncrustify at {self._app_path}") > > > >> + logging.info(f"Uncrustify version: {self._app_version}") > > > >> + logging.info('\n') > > > >> + > > > >> + def _process_uncrustify_results(self) -> None: > > > >> + """ > > > >> + Process the results from Uncrustify. > > > >> + > > > >> + Determines whether formatting errors are present and logs > > > >> failures. > > > >> + """ > > > >> + formatted_files = [str(path.resolve()) for path in > > > >> pathlib.Path( > > > >> + > > > >> self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')] > > > >> + > > > >> + self._formatted_file_error_count = len(formatted_files) > > > >> + > > > >> + if self._formatted_file_error_count > 0: > > > >> + self._tc.LogStdError("Files with formatting errors:\n") > > > >> + > > > >> + if self._output_file_diffs: > > > >> + logging.info("Calculating file diffs. This might take > > > >> a while...") > > > >> + > > > >> + for formatted_file in formatted_files: > > > >> + pre_formatted_file = formatted_file[:- > > > >> + > > > >> len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)] > > > >> + > > > >> + if (self._output_file_diffs or > > > >> + self._file_template_contents is not None or > > > >> + self._func_template_contents is not None): > > > >> + self._tc.LogStdError( > > > >> + f"Formatting errors in > > > >> {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n") > > > >> + > > > >> + with open(formatted_file) as ff: > > > >> + formatted_file_text = ff.read() > > > >> + > > > >> + if (self._file_template_contents is not None and > > > >> + self._file_template_contents in > > > >> formatted_file_text): > > > >> + self._tc.LogStdError(f"File header is missing > > > >> in {os.path.relpath(pre_formatted_file, > > > >> self._abs_package_path)}\n") > > > >> + > > > >> + if (self._func_template_contents is not None and > > > >> + self._func_template_contents in > > > >> formatted_file_text): > > > >> + self._tc.LogStdError(f"A function header is > > > >> missing in > {os.path.relpath(pre_formatted_file, > > > >> self._abs_package_path)}\n") > > > >> + > > > >> + if self._output_file_diffs: > > > >> + with open(pre_formatted_file) as pf: > > > >> + pre_formatted_file_text = pf.read() > > > >> + > > > >> + for line in > > > >> difflib.unified_diff(pre_formatted_file_text.split('\n'), > > > >> formatted_file_text.split('\n'), fromfile=pre_formatted_file, > > > >> tofile=formatted_file, n=3): > > > >> + self._tc.LogStdError(line) > > > >> + > > > >> + self._tc.LogStdError('\n') > > > >> + else: > > > >> + self._tc.LogStdError(pre_formatted_file) > > > >> + > > > >> + def _remove_tree(self, dir_path: str, ignore_errors: bool = > > > >> False) -> None: > > > >> + """ > > > >> + Helper for removing a directory. Over time there have been > > > >> + many private implementations of this due to reliability > > > >> issues in the > > > >> + shutil implementations. To consolidate on a single function > > > >> this helper is added. > > > >> + > > > >> + On error try to change file attributes. Also add retry logic. > > > >> + > > > >> + This function is temporarily borrowed from > > > >> edk2toollib.utility_functions > > > >> + since the version used in edk2 is not recent enough to > > > >> include the > > > >> + function. > > > >> + > > > >> + This function should be replaced by "RemoveTree" when it is > > > >> available. > > > >> + > > > >> + Args: > > > >> + - dir_path: Path to directory to remove. > > > >> + - ignore_errors: Whether to ignore errors during removal > > > >> + """ > > > >> + > > > >> + def _remove_readonly(func, path, _): > > > >> + """ > > > >> + Private function to attempt to change permissions on > > > >> file/folder being deleted. > > > >> + """ > > > >> + os.chmod(path, os.stat.S_IWRITE) > > > >> + func(path) > > > >> + > > > >> + for _ in range(3): # retry up to 3 times > > > >> + try: > > > >> + shutil.rmtree(dir_path, ignore_errors=ignore_errors, > > > >> onerror=_remove_readonly) > > > >> + except OSError as err: > > > >> + logging.warning(f"Failed to fully remove {dir_path}: > > > >> {err}") > > > >> + else: > > > >> + break > > > >> + else: > > > >> + raise RuntimeError(f"Failed to remove {dir_path}") > > > >> + > > > >> + def _run_uncrustify(self) -> None: > > > >> + """ > > > >> + Runs Uncrustify for this instance of plugin execution. > > > >> + """ > > > >> + logging.info("Executing Uncrustify. This might take a > > > >> while...") > > > >> + start_time = timeit.default_timer() > > > >> + self._execute_uncrustify() > > > >> + end_time = timeit.default_timer() - start_time > > > >> + > > > >> + execution_summary = f"Uncrustify executed against > > > >> {len(self._abs_file_paths_to_format)} files in > > > >> {self._package_name} in {end_time:.2f} seconds.\n" > > > >> + > > > >> + self._tc.LogStdOut(execution_summary) > > > >> + logging.info(execution_summary) > > > >> + > > > >> + if self._app_exit_code != 0 and self._app_exit_code != 1: > > > >> + raise UncrustifyAppExecutionException( > > > >> + f"Error {str(self._app_exit_code)} returned from > > > >> Uncrustify:\n\n{str(self._app_output)}") > > > >> diff --git a/.pytool/Plugin/UncrustifyCheck/default_file_header.txt > > > >> b/.pytool/Plugin/UncrustifyCheck/default_file_header.txt > > > >> new file mode 100644 > > > >> index 000000000000..2955a734dfe1 > > > >> --- /dev/null > > > >> +++ b/.pytool/Plugin/UncrustifyCheck/default_file_header.txt > > > >> @@ -0,0 +1,9 @@ > > > >> +/** @file > > > >> + Brief description of the file's purpose. > > > >> + > > > >> + Detailed description of the file's contents and other useful > > > >> + information for a person viewing the file for the first time. > > > >> + > > > >> + <<Copyright>> > > > >> + SPDX-License-Identifier: BSD-2-Clause-Patent > > > >> +**/ > > > >> diff --git a/.pytool/Plugin/UncrustifyCheck/default_function_header.txt > > > >> b/.pytool/Plugin/UncrustifyCheck/default_function_header.txt > > > >> new file mode 100644 > > > >> index 000000000000..66edc72e6731 > > > >> --- /dev/null > > > >> +++ b/.pytool/Plugin/UncrustifyCheck/default_function_header.txt > > > >> @@ -0,0 +1,15 @@ > > > >> +/** > > > >> + Brief description of this function's purpose. > > > >> + > > > >> + Follow it immediately with the detailed description. > > > >> + > > > >> + @param[in] Arg1 Description of Arg1. > > > >> + @param[in] Arg2 Description of Arg2 This is complicated and > > > >> requires > > > >> + multiple lines to describe. > > > >> + @param[out] Arg3 Description of Arg3. > > > >> + @param[in, out] Arg4 Description of Arg4. > > > >> + > > > >> + @retval VAL_ONE Description of what VAL_ONE signifies. > > > >> + @retval OTHER This is the only other return value. If there were > > > >> other > > > >> + return values, they would be listed. > > > >> +**/ > > > >> diff --git a/.pytool/Plugin/UncrustifyCheck/uncrustify.cfg > > > >> b/.pytool/Plugin/UncrustifyCheck/uncrustify.cfg > > > >> new file mode 100644 > > > >> index 000000000000..1a87295ec9f9 > > > >> --- /dev/null > > > >> +++ b/.pytool/Plugin/UncrustifyCheck/uncrustify.cfg > > > >> @@ -0,0 +1,462 @@ > > > >> +## @file > > > >> +# Uncrustify Configuration File for EDK II C Code > > > >> +# > > > >> +# Coding Standard: > > > >> https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/ > > > >> +# > > > >> +# This configuration file is meant to be a "best attempt" to align > > > >> with the > > > >> +# definitions in the EDK II C Coding Standards Specification. > > > >> +# > > > >> +# Copyright (c) Microsoft Corporation. > > > >> +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > >> +## > > > >> + > > > >> +# Force UTF-8 encoding (no UTF-16) > > > >> +enable_digraphs = false > > > >> +utf8_byte = false > > > >> +utf8_force = true > > > >> + > > > >> +# Code width / line splitting > > > >> +#code_width =120 # TODO: This causes > > > >> non-deterministic behaviour in some cases when code > > > wraps > > > >> +ls_code_width =false > > > >> +ls_for_split_full =true > > > >> +ls_func_split_full =true > > > >> +pos_comma =trail > > > >> + > > > >> +# 5.1.7 All files must end with CRLF > > > >> +newlines = crlf > > > >> + > > > >> +# 5.1.2 Do not use tab characters > > > >> + > > > >> +cmt_convert_tab_to_spaces = true # Whether to convert all > > > >> tabs to spaces in comments. If false, tabs in > > > >> + # comments are left > > > >> alone, unless used for indenting. > > > >> +indent_columns = 2 # Number of spaces for > > > >> indentation > > > >> +indent_with_tabs = 0 # Do not use TAB > > > >> characters > > > >> +string_replace_tab_chars = true # Replace TAB with SPACE > > > >> + # Note: This will break > > > >> .robot files but is needed for edk2 style > > > >> + > > > >> +# 5.2.1.1 There shall be only one statement on a line (statement ends > > > >> with ;) > > > >> +nl_multi_line_cond = true # Add a newline between > > > >> ')' and '{' if the ')' is on a different line > > than > > > >> + # the if/for/etc. > > > >> +nl_after_semicolon = true # Whether to add a > > > >> newline after semicolons, except in 'for' > statements. > > > >> + > > > >> +# 5.2.1.3 An open brace '{' goes on the same line as the closing > > > >> parenthesis ')' of simple predicate expressions > > > >> +mod_full_brace_do = add # Add or remove braces on > > > >> a single-line 'do' statement. > > > >> +mod_full_brace_for = add > > > >> +mod_full_brace_function = add # Add or remove braces on > > > >> a single-line function definition. > > > >> +mod_full_brace_if = add # Add or remove braces on > > > >> a single-line 'if' statement. Braces will > not > > be > > > >> + # removed if the braced > > > >> statement contains an 'else'. > > > >> +mod_full_brace_if_chain = false > > > >> +mod_full_brace_while = add > > > >> + > > > >> +# 5.2.1.4 A close brace '}' always goes at the beginning of the last > > > >> line of the body > > > >> +eat_blanks_after_open_brace = true > > > >> +eat_blanks_before_close_brace = true # Whether to remove blank > > > >> lines before '}'. > > > >> + > > > >> +# 5.2.2.2 Always put space before and after binary operators. > > > >> +sp_assign = add # Add or remove space > > > >> around assignment operator '=', '+=', etc. > > > >> +sp_assign_default = add > > > >> +sp_bool = add # Add or remove space > > > >> around boolean operators '&&' and '||'. > > > >> +sp_compare = add # Add or remove space > > > >> around compare operator '<', '>', '==', etc. > > > >> + > > > >> +# 5.2.2.3 Do not put space between unary operators and their object > > > >> +sp_addr = remove # A or remove space after > > > >> the '&' (address-of) unary operator. > > > >> +sp_incdec = remove # Add or remove space > > > >> between '++' and '--' the word to which it is > > being > > > >> + # applied, as in '(--x)' > > > >> or 'y++;'. > > > >> +sp_inv = remove # Add or remove space > > > >> after the '~' (invert) unary operator. > > > >> +sp_not = remove # Add or remove space > > > >> after the '!' (not) unary operator. > > > >> +sp_sign = remove # Add or remove space > > > >> after '+' or '-', as in 'x = -5' or 'y = +7'. > > > >> + > > > >> +# 5.2.2.4 Subsequent lines of multi-line function calls should line > > > >> up two spaces from the beginning of the > function > > > >> +# name > > > >> +nl_func_call_args_multi_line = true # Whether to add a > > > >> newline after each ',' in a function call if '(' > and > > > ')' > > > >> + # are in different lines. > > > >> +nl_func_call_args_multi_line_ignore_closures = false > > > >> + > > > >> +# - Indent each argument 2 spaces from the start of the function > > > >> name. If a > > > >> +# function is called through a structure or union member, of type > > > >> +# pointer-to-function, then indent each argument 2 spaces from the > > > >> start of the > > > >> +# member name. > > > >> +indent_func_call_edk2_style = true # Use EDK2 indentation > > > >> style for function calls (**CUSTOM SETTING**) > > > >> +indent_paren_after_func_call = true # Whether to indent the > > > >> open parenthesis of a function call, if the > > > >> + # parenthesis is on its > > > >> own line. > > > >> + > > > >> +# - Align the close parenthesis with the start of the last argument > > > >> +indent_paren_close = 0 # How to indent a close > > > >> parenthesis after a newline. > > > >> + # (0: Body, 1: > > > >> Openparenthesis, 2: Brace level) > > > >> + > > > >> + > > > >> +# 5.2.2.5 Always put space after commas or semicolons that separate > > > >> items > > > >> +sp_after_comma = force # Add or remove space > > > >> after ',', i.e. 'a,b' vs. 'a, b'. > > > >> +sp_before_comma = remove # Add or remove space > > > >> before ','. > > > >> + > > > >> +# 5.2.2.6 Always put space before an open parenthesis > > > >> +sp_after_sparen = add # Add or remove space > > > >> after ')' of control statements. > > > >> +sp_attribute_paren = add # Add or remove space > > > >> between '__attribute__' and '('. > > > >> +sp_before_sparen = force # Add or remove space > > > >> before '(' of control statements > > > >> + # ('if', 'for', 'switch', > > > >> 'while', etc.). > > > >> +sp_defined_paren = force # Add or remove space > > > >> between 'defined' and '(' in '#if defined > (FOO)'. > > > >> +sp_func_call_paren = force # Add or remove space > > > >> between function name and '(' on function calls. > > > >> +sp_func_call_paren_empty = force # Add or remove space > > > >> between function name and '()' on function calls > > > >> + # without parameters. If > > > >> set to ignore (the default), > sp_func_call_paren > > > is > > > >> + # used. > > > >> +sp_func_def_paren = add # Add or remove space > > > >> between alias name and '(' of a non-pointer > > function > > > >> + # type typedef. > > > >> +sp_func_proto_paren = add # Add or remove space > > > >> between function name and '()' on function > > > declaration > > > >> +sp_sizeof_paren = force # Add or remove space > > > >> between 'sizeof' and '('. > > > >> +sp_type_func = add # Add or remove space > > > >> between return type and function name. A minimum > > of > > > 1 > > > >> + # is forced except for > > > >> pointer return types. > > > >> + > > > >> +# Not specified, but also good style to remove spaces inside > > > >> parentheses (Optional) > > > >> +sp_cparen_oparen = remove # Add or remove space > > > >> between back-to-back parentheses, i.e. ')(' vs. > ') > > > ('. > > > >> +sp_inside_fparen = remove # Add or remove space > > > >> inside function '(' and ')'. > > > >> +sp_inside_fparens = remove # Add or remove space > > > >> inside empty function '()'. > > > >> +sp_inside_paren = remove # Add or remove space > > > >> inside '(' and ')'. > > > >> +sp_inside_paren_cast = remove # Add or remove spaces > > > >> inside cast parentheses. '(int)x' > > > >> +sp_inside_square = remove # Add or remove space > > > >> inside a non-empty '[' and ']'. > > > >> +sp_paren_paren = remove # Add or remove space > > > >> between nested parentheses, i.e. '((' vs. ') )'. > > > >> +sp_square_fparen = remove # Add or remove space > > > >> between ']' and '(' when part of a function > call. > > > >> + > > > >> +# 5.2.2.7 Put a space before an open brace if it is not on its own > > > >> line > > > >> +sp_do_brace_open = force # Add or remove space > > > >> between 'do' and '{'. > > > >> +sp_paren_brace = force # Add or remove space > > > >> between ')' and '{'. > > > >> +sp_sparen_brace = force # Add or remove space > > > >> between ')' and '{' of of control statements. > > > >> + > > > >> +# 5.2.2.8 Do not put spaces around structure member and pointer > > > >> operators > > > >> +sp_after_byref = remove # Add or remove space > > > >> after reference sign '&', if followed by a word. > > > >> +sp_before_byref = add # Add or remove space > > > >> before a reference sign '&'. > > > >> +sp_deref = remove # Add or remove space > > > >> after the '*' (dereference) unary operator. This > > > does > > > >> + # not affect the spacing > > > >> after a '*' that is part of a type. > > > >> +sp_member = remove # Add or remove space > > > >> around the '.' or '->' operators. > > > >> + > > > >> +# 5.2.2.9 Do not put spaces before open brackets of array subscripts > > > >> +sp_before_square = remove # Add or remove space > > > >> before '[' (except '[]'). > > > >> +sp_before_squares = remove # Add or remove space > > > >> before '[]'. > > > >> +sp_before_vardef_square = remove # Add or remove space > > > >> before '[' for a variable definition. > > > >> + > > > >> +# 5.2.2.10 Use extra parentheses rather than depending on in-depth > > > >> knowledge of the order of precedence of C > > > >> +mod_full_paren_if_bool = true # Whether to fully > > > >> parenthesize Boolean expressions in 'while' and > 'if' > > > >> + # statement, as in 'if (a > > > >> && b > c)' => 'if (a && (b > c))'. > > > >> + > > > >> +# 5.2.2.11 Align a continuation line with the part of the line that > > > >> it continues. > > > >> +use_indent_continue_only_once = true > > > >> + > > > >> +# Additional '{}' bracing rules (Optional) > > > >> +# NOTE - The style guide specifies two different styles for braces, > > > >> +# so these are ignored for now to allow developers some flexibility. > > > >> +nl_after_brace_close = true # Whether to add a > > > >> newline after '}'. Does not apply if followed by a > > > >> + # necessary ';'. > > > >> +nl_brace_else = remove # Add or remove newline > > > >> between '}' and 'else'. > > > >> +nl_brace_while = remove # Add or remove newline > > > >> between '}' and 'while' of 'do' statement. > > > >> +nl_do_brace = remove # Add or remove newline > > > >> between 'do' and '{'. > > > >> +nl_else_brace = remove # Add or remove newline > > > >> between 'else' and '{'. > > > >> +nl_else_if = remove # Add or remove newline > > > >> between 'else' and 'if'. > > > >> +nl_elseif_brace = remove # Add or remove newline > > > >> between 'else if' and '{'. > > > >> +nl_enum_brace = remove # Add or remove newline > > > >> between 'enum' and '{'. > > > >> +nl_fcall_brace = remove # Add or remove newline > > > >> between a function call's ')' and '{', > > > >> + # as in > > > >> 'list_for_each(item, &list) { }'. > > > >> +nl_for_brace = remove # Add or remove newline > > > >> between 'for' and '{'. > > > >> +nl_if_brace = remove # Add or remove newline > > > >> between 'if' and '{'. > > > >> +nl_struct_brace = remove # Add or remove newline > > > >> between 'struct and '{'. > > > >> +nl_switch_brace = remove # Add or remove newline > > > >> between 'switch' and '{'. > > > >> +nl_union_brace = remove # Add or remove newline > > > >> between 'union' and '{'. > > > >> +nl_while_brace = remove # Add or remove newline > > > >> between 'while' and '{'. > > > >> + > > > >> +# Additional whitespace rules (Optional) > > > >> +sp_after_ptr_star = remove # Add or remove space > > > >> after pointer star '*', if followed by a word. > > > >> + # Useful when paired with > > > >> align_var_def_star_style==2 > > > >> +sp_after_ptr_star_func = remove # Add or remove space > > > >> after a pointer star '*', if followed by a > > function > > > >> + # prototype or function > > > >> definition. > > > >> +sp_after_semi = remove # Add or remove space > > > >> after ';', except when followed by a comment. > > > >> +sp_before_case_colon = remove # Add or remove space > > > >> before case ':'. > > > >> +sp_before_ptr_star = add # Add or remove space > > > >> before pointer star '*'. > > > >> +sp_before_ptr_star_func = add # Add or remove space > > > >> before a pointer star '*', if followed by a > > function > > > >> + # prototype or function > > > >> definition. > > > >> +sp_before_semi = remove # Add or remove space > > > >> before ';' > > > >> +sp_before_semi_for = remove # Add or remove space > > > >> before ';' in non-empty 'for' statements. > > > >> +sp_before_semi_for_empty = add # Add or remove space > > > >> before a semicolon of an empty part of a for > > > statement > > > >> +sp_between_ptr_star = remove # Add or remove space > > > >> between pointer stars '*'. (ie, 'VOID **') > > > >> +sp_brace_close_while = force # Add or remove space > > > >> between '}' and 'while'. > > > >> + > > > >> +sp_after_cast = remove > > > >> +sp_after_type = add > > > >> +sp_balance_nested_parens = false > > > >> +sp_before_nl_cont = add > > > >> +sp_before_square_asm_block = ignore > > > >> +sp_before_unnamed_byref = add > > > >> +sp_brace_brace = ignore > > > >> +sp_brace_else = force > > > >> +sp_brace_typedef = add > > > >> +sp_case_label = force > > > >> +sp_cmt_cpp_doxygen = true > > > >> +sp_cond_colon = add > > > >> +sp_cond_question = add > > > >> +sp_cpp_cast_paren = force > > > >> +sp_else_brace = force > > > >> +sp_endif_cmt = force > > > >> +sp_enum_assign = add > > > >> +sp_inside_braces = force > > > >> +sp_inside_braces_empty = force > > > >> +sp_inside_braces_enum = force > > > >> +sp_inside_braces_struct = force > > > >> +sp_pp_concat = add > > > >> +sp_pp_stringify = add > > > >> +sp_return_paren = add > > > >> +sp_special_semi = force > > > >> +sp_while_paren_open = force > > > >> + > > > >> +# Additional Indentation Rules > > > >> +indent_access_spec = 1 > > > >> +indent_access_spec_body = false > > > >> +indent_align_assign = true > > > >> +indent_align_string = true > > > >> +indent_bool_paren = true > > > >> +indent_brace_parent = false > > > >> +indent_braces = false > > > >> +indent_braces_no_class = false > > > >> +indent_braces_no_func = true > > > >> +indent_braces_no_struct = false > > > >> +indent_class = false > > > >> +indent_class_colon = false > > > >> +indent_cmt_with_tabs = false # Whether to indent > > > >> comments that are not at a brace level with > tabs > > > on > > > >> + # a tabstop. Requires > > > >> indent_with_tabs=2. If false, will use > spaces. > > > >> +indent_col1_comment = true > > > >> +indent_col1_multi_string_literal= true > > > >> +indent_comma_paren = true > > > >> +indent_else_if = true > > > >> +indent_extern = false > > > >> +indent_first_bool_expr = true > > > >> + > > > >> +indent_func_def_param_paren_pos_threshold = 0 > > > >> +indent_func_param_double = false > > > >> +indent_func_proto_param = true > > > >> +indent_ignore_asm_block = true > > > >> +indent_label = 1 > > > >> +indent_member = 2 > > > >> +indent_namespace = false > > > >> +indent_param = 2 > > > >> +indent_paren_nl = false > > > >> +indent_paren_open_brace = false > > > >> +indent_preserve_sql = false > > > >> +indent_relative_single_line_comments = false > > > >> +indent_sing_line_comments = 0 > > > >> +indent_single_newlines = false > > > >> +indent_square_nl = false > > > >> +indent_switch_case = 2 > > > >> +indent_template_param = true > > > >> +indent_var_def_blk = 0 > > > >> +indent_var_def_cont = false > > > >> + > > > >> +# Tidy-up rules (Optional) > > > >> +mod_move_case_break = true # Whether to move a > > > >> 'break' that appears after a fully braced 'case' > > > >> + # before the close brace, > > > >> as in 'case X: { ... } break;' => > > > >> + # 'case X: { ... break; > > > >> }'. > > > >> +mod_pawn_semicolon = false > > > >> +mod_remove_empty_return = false # Whether to remove a > > > >> void 'return;' that appears as the last > statement > > > >> + # in a function. > > > >> +mod_remove_extra_semicolon = true > > > >> +mod_sort_import = false > > > >> +mod_sort_include = false > > > >> +mod_sort_using = false > > > >> +nl_after_case = false # Whether to add a > > > >> newline after a 'case' statement. > > > >> +nl_end_of_file = force # Add or remove newline > > > >> at the end of the file. > > > >> +nl_end_of_file_min = 1 # The minimum number of > > > >> newlines at the end of the file > > > >> +nl_max = 2 # The maximum number of > > > >> consecutive newlines (3 = 2 blank lines). > > > >> +nl_start_of_file = remove # Add or remove newlines > > > >> at the start of the file. > > > >> + > > > >> +# Code alignment rules (Optional) > > > >> +align_asm_colon = false > > > >> +align_assign_span = 1 # The span for aligning > > > >> on '=' in assignments. > > > >> +align_assign_thresh = 4 > > > >> +align_edk2_style = true # Whether to apply > > > >> edk2-specific alignment formatting > > > >> +align_enum_equ_span = 1 # The span for aligning > > > >> on '=' in enums. > > > >> +align_func_params = true # Whether to align > > > >> variable definitions in prototypes and functions. > > > >> +align_func_params_gap = 2 > > > >> +align_func_params_span = 2 # The span for aligning > > > >> parameter definitions in function on parameter > > > name. > > > >> +align_func_params_thresh = 0 > > > >> +align_func_proto_span = 0 > > > >> +align_keep_tabs = false > > > >> +align_left_shift = false > > > >> +align_mix_var_proto = false > > > >> +align_nl_cont = false > > > >> +align_oc_decl_colon = false > > > >> +align_on_operator = false > > > >> +align_on_tabstop = false > > > >> +align_pp_define_gap = 2 > > > >> +align_pp_define_span = 1 > > > >> +align_right_cmt_at_col = 0 # Align trailing comment > > > >> at or beyond column N; 'pulls in' comments as > > > >> + # a bonus side effect > > > >> (0=ignore) > > > >> +align_right_cmt_gap = 0 # If a trailing comment > > > >> is more than this number of columns away from > > the > > > >> + # text it follows, > > > >> + # it will qualify for > > > >> being aligned. This has to be > 0 to do > anything. > > > >> +align_right_cmt_mix = false # If aligning comments, > > > >> mix with comments after '}' and #endif with > less > > > >> + # than 3 spaces before > > > >> the comment > > > >> +align_right_cmt_same_level = true # Whether to only align > > > >> trailing comments that are at the same brace > > > level. > > > >> +align_right_cmt_span = 2 # The span for aligning > > > >> comments that end lines. > > > >> +align_same_func_call_params = false > > > >> +align_single_line_brace = true > > > >> +align_single_line_func = true > > > >> +align_struct_init_span = 1 # The span for aligning > > > >> struct initializer values. > > > >> +align_typedef_amp_style = 1 > > > >> +align_typedef_func = 1 # How to align typedef'd > > > >> functions with other typedefs. > > > >> + # (0: No align, 1: Align > > > >> open paranthesis, 2: Align function type > name) > > > >> +align_typedef_gap = 2 > > > >> +align_typedef_span = 1 # The span for aligning > > > >> single-line typedefs. > > > >> +align_typedef_star_style = 1 > > > >> +align_var_def_amp_style = 1 > > > >> +align_var_def_attribute = true > > > >> +align_var_def_colon = true # Whether to align the > > > >> colon in struct bit fields. > > > >> +align_var_def_gap = 2 # The gap (minimum > > > >> spacing for aligned items) for variable > definitions. > > > >> +align_var_def_inline = false > > > >> +align_var_def_span = 1 # The span (lines needed > > > >> to align) for aligning variable definitions. > > > >> +align_var_def_star_style = 1 # How to consider (or > > > >> treat) the '*' in the alignment of variable > > > >> + # definitions. > > > >> + # 0: Part of the type > > > >> 'void * foo;' (default) > > > >> + # 1: Part of the variable > > > >> 'void *foo;' > > > >> + # 2: Dangling > > > >> 'void *foo;' > > > >> + # (Note - should also set > > > >> sp_after_ptr_star=remove) > > > >> +align_var_struct_gap = 4 > > > >> +align_var_struct_span = 8 # The span for aligning > > > >> struct/union member definitions. > > > >> +align_var_struct_thresh = 0 > > > >> +align_with_tabs = false > > > >> + > > > >> +# Comment formatting > > > >> +cmt_align_doxygen_javadoc_tags = true # Whether to align > > > >> doxygen javadoc-style tags ('@param', '@return', > > etc.) > > > >> + # TODO: Eats '[' in '[in]' > > > >> +cmt_c_group = false > > > >> +cmt_c_nl_end = true # Whether to add a > > > >> newline before the closing '*/' of the combined c- > > > comment. > > > >> +cmt_c_nl_start = true > > > >> +cmt_cpp_group = false > > > >> +cmt_cpp_nl_end = true > > > >> +cmt_cpp_nl_start = true > > > >> +cmt_cpp_to_c = false > > > >> +cmt_indent_multi = false # Whether to apply > > > >> changes to multi-line comments, including > cmt_width, > > > >> + # keyword substitution > > > >> and leading chars. > > > >> +cmt_insert_before_preproc = false > > > >> +cmt_insert_file_header = default_file_header.txt > > > >> +cmt_insert_func_header = default_function_header.txt > > > >> +cmt_multi_check_last = false > > > >> +cmt_multi_first_len_minimum = 2 > > > >> +cmt_reflow_mode = 1 # How to reflow comments. > > > >> + # (0:No reflow, 1:No > > > >> touching at all, 2: Full reflow) > > > >> +cmt_sp_after_star_cont = 0 # The number of spaces to > > > >> insert after the star on subsequent comment > > > lines. > > > >> +cmt_sp_before_star_cont = 0 # The number of spaces to > > > >> insert at the start of subsequent comment > > lines. > > > >> +cmt_star_cont = false # Whether to put a star > > > >> on subsequent comment lines. > > > >> +cmt_width = 120 # Try to wrap comments at > > > >> N columns. > > > >> +sp_cmt_cpp_start = add # Add or remove space > > > >> after the opening of a C++ comment, as in > > > >> + # '// <here> A'. NOTE: > > > >> Breaks indentation within comments. > > > >> + > > > >> +# Function definitions / declarations > > > >> +indent_func_call_param = false # Whether to indent > > > >> continued function call parameters one indent > level, > > > >> + # rather than aligning > > > >> parameters under the open parenthesis. > > > >> +indent_func_class_param = false # Whether to indent > > > >> continued function call declaration one indent > > level, > > > >> + # rather than aligning > > > >> parameters under the open parenthesis. > > > >> +indent_func_ctor_var_param = false # Whether to indent > > > >> continued class variable constructors one indent > > > level, > > > >> + # rather than aligning > > > >> parameters under the open parenthesis. > > > >> +indent_func_def_param = true # Whether to indent > > > >> continued function definition parameters one > indent > > > >> + # level, rather than > > > >> aligning parameters under the open parenthesis. > > > >> +nl_fdef_brace = add # Add or remove newline > > > >> between function signature and '{'. > > > >> +nl_func_call_end_multi_line = true # Whether to add a > > > >> newline before ')' in a function call if '(' and > ')' > > > are > > > >> + # in different lines. > > > >> +nl_func_call_paren = remove # Add or remove newline > > > >> between a function name and the opening '(' in > > the > > > >> + # call. > > > >> +nl_func_call_start_multi_line = true # Whether to add a > > > >> newline after '(' in a function call if '(' and ')' > > are > > > >> + # in different lines. > > > >> +nl_func_decl_args = force # Add or remove newline > > > >> after each ',' in a function declaration. > > > >> +nl_func_decl_empty = add # Add or remove newline > > > >> between '()' in a function declaration. > > > >> +nl_func_def_args = force # Add or remove newline > > > >> after each ',' in a function definition. > > > >> +nl_func_def_empty = add # Add or remove newline > > > >> between '()' in a function definition. > > > >> +nl_func_def_paren = remove # Add or remove newline > > > >> between a function name and the opening '(' > > > >> + # in the definition. > > > >> +nl_func_paren = remove # Add or remove newline > > > >> between a function name and the opening '(' in > > > >> + # the declaration. > > > >> +nl_func_type_name = add # Add or remove newline > > > >> between return type and function name in a > > > function > > > >> + # definition. > > > >> +sp_fparen_brace = force # Add or remove space > > > >> between ')' and '{' of function. > > > >> +use_indent_func_call_param = true # indent_func_call_param > > > >> will be used > > > >> + > > > >> +# Additional Newline Rules > > > >> +nl_after_brace_open = true # Whether to > > > >> add a newline after '{'. This also adds a > > newline > > > >> + # before the > > > >> matching '}'. > > > >> +nl_after_brace_open_cmt = true # Whether to > > > >> add a newline between the open brace and a > > > >> + # trailing > > > >> single-line comment. > > > >> + # Requires > > > >> nl_after_brace_open = true. > > > >> +nl_after_do = add # Add or > > > >> remove blank line after 'do/while' statement. > > > >> +nl_after_for = add # Add or > > > >> remove blank line after 'for' statement. > > > >> +nl_after_func_body = 2 # The number > > > >> of newlines after '}' of a multi-line > function > > > body > > > >> +nl_after_func_body_one_liner = 2 > > > >> +nl_after_func_proto = 2 > > > >> +nl_after_func_proto_group = 2 > > > >> +nl_after_if = add > > > >> +nl_after_multiline_comment = false > > > >> +nl_after_return = false > > > >> +nl_after_struct = 2 > > > >> +nl_after_switch = add > > > >> +nl_after_vbrace_close = true > > > >> +nl_after_vbrace_open = true > > > >> +nl_after_vbrace_open_empty = true > > > >> +nl_after_while = add > > > >> +nl_assign_leave_one_liners = true > > > >> +nl_before_block_comment = 2 > > > >> +nl_before_case = false > > > >> +nl_before_do = ignore > > > >> +nl_before_for = ignore > > > >> +nl_before_if = ignore > > > >> +nl_before_switch = ignore > > > >> +nl_before_while = ignore > > > >> +nl_before_whole_file_ifdef = 2 > > > >> +nl_brace_brace = force > > > >> +nl_brace_struct_var = remove > > > >> +nl_case_colon_brace = add > > > >> +nl_class_leave_one_liners = false > > > >> +nl_collapse_empty_body = false > > > >> +nl_comment_func_def = 1 > > > >> +nl_create_for_one_liner = false > > > >> +nl_create_if_one_liner = false > > > >> +nl_create_while_one_liner = false > > > >> +nl_define_macro = false > > > >> +nl_ds_struct_enum_close_brace = true > > > >> +nl_ds_struct_enum_cmt = false > > > >> +nl_enum_leave_one_liners = false > > > >> +nl_func_decl_end = add > > > >> +nl_func_decl_start = add > > > >> +nl_func_def_end = add > > > >> +nl_func_def_start = add > > > >> +nl_func_leave_one_liners = false > > > >> +nl_func_proto_type_name = add > > > >> +nl_func_var_def_blk = 1 > > > >> +nl_getset_leave_one_liners = false > > > >> +nl_if_leave_one_liners = false > > > >> +nl_multi_line_define = false > > > >> +nl_squeeze_ifdef = false > > > >> +nl_var_def_blk_end = 0 > > > >> +nl_var_def_blk_start = 0 > > > >> + > > > >> +# Preprocessor Rules > > > >> +pp_define_at_level = true > > > >> +pp_if_indent_code = false > > > >> +pp_indent_func_def = false > > > >> +pp_indent_extern = false > > > >> +pp_ignore_define_body = true # Workaround: Turn off > > > >> processing for #define body > > > >> + # (current rules do not > > > >> work for some defines) > > > >> +pp_indent = add > > > >> +pp_indent_at_level = true > > > >> +pp_indent_count = 2 > > > >> +pp_indent_if = 2 > > > >> +pp_indent_region = 2 > > > >> +pp_region_indent_code = false > > > >> +pp_space = remove > > > >> + > > > >> +# > > > >> +# The tokens below are assigned specific types so they are always > > > >> recognized properly. > > > >> +# > > > >> + > > > >> +# Explicitly define EDK II qualifiers > > > >> +set QUALIFIER CONST > > > >> +set QUALIFIER EFIAPI > > > >> +set QUALIFIER IN > > > >> +set QUALIFIER OPTIONAL > > > >> +set QUALIFIER OUT > > > >> + > > > >> +# Explicitly define EDK II types > > > >> +set TYPE EFI_STATUS > > > >> +set TYPE VOID > > > >> diff --git a/.pytool/Plugin/UncrustifyCheck/uncrustify_ext_dep.yaml > > > >> b/.pytool/Plugin/UncrustifyCheck/uncrustify_ext_dep.yaml > > > >> new file mode 100644 > > > >> index 000000000000..d8c22403b4b1 > > > >> --- /dev/null > > > >> +++ b/.pytool/Plugin/UncrustifyCheck/uncrustify_ext_dep.yaml > > > >> @@ -0,0 +1,16 @@ > > > >> +## @file > > > >> +# Downloads the Uncrustify application from a Project Mu NuGet > > > >> package. > > > >> +# > > > >> +# Copyright (c) Microsoft Corporation. > > > >> +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > >> +## > > > >> +{ > > > >> + "id": "uncrustify-ci-1", > > > >> + "scope": "cibuild", > > > >> + "type": "nuget", > > > >> + "name": "mu-uncrustify-release", > > > >> + "source": > > > >> "https://pkgs.dev.azure.com/projectmu/Uncrustify/_packaging/mu_uncrustify/nuget/v3/index.json", > > > >> + "version": "73.0.3", > > > >> + "flags": ["set_shell_var", "host_specific"], > > > >> + "var_name": "UNCRUSTIFY_CI_PATH" > > > >> +} > > > >> diff --git a/.pytool/Plugin/UncrustifyCheck/uncrustify_plug_in.yaml > > > >> b/.pytool/Plugin/UncrustifyCheck/uncrustify_plug_in.yaml > > > >> new file mode 100644 > > > >> index 000000000000..06c76af02759 > > > >> --- /dev/null > > > >> +++ b/.pytool/Plugin/UncrustifyCheck/uncrustify_plug_in.yaml > > > >> @@ -0,0 +1,11 @@ > > > >> +## @file > > > >> +# CiBuildPlugin used to check coding standard compliance of EDK II > > > >> style C source code > > > >> +# > > > >> +# Copyright (c) Microsoft Corporation. > > > >> +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > >> +## > > > >> +{ > > > >> + "scope": "cibuild", > > > >> + "name": "Uncrustify Coding Standard Test", > > > >> + "module": "UncrustifyCheck" > > > >> +} > > > >> diff --git a/.pytool/Readme.md b/.pytool/Readme.md > > > >> index f6505507966a..e0d07f317049 100644 > > > >> --- a/.pytool/Readme.md > > > >> +++ b/.pytool/Readme.md > > > >> @@ -264,6 +264,10 @@ BSD-2-Clause-Patent. > > > >> Run the Ecc tool on the package. The Ecc tool is available in the > > > >> BaseTools > > > >> package. It checks that the code complies to the EDKII coding > > > >> standard. > > > >> > > > >> +### Coding Standard Compliance - UncrustifyCheck > > > >> + > > > >> +Runs the Uncrustify application to check for coding standard > > > >> compliance issues. > > > >> + > > > >> ## PyTool Scopes > > > >> > > > >> Scopes are how the PyTool ext_dep, path_env, and plugins are > > > >> activated. Meaning > > > >> -- > > > >> 2.28.0.windows.1 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#84066): https://edk2.groups.io/g/devel/message/84066 Mute This Topic: https://groups.io/mt/87290954/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-