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 (#84062): https://edk2.groups.io/g/devel/message/84062
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]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to