From 6dfe1bf58ccd451af1ba1c96efbc8792a88cc4ba Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 27 Nov 2023 10:24:53 +0100 Subject: [PATCH] Documentation: port warnings_filter Sphinx extension from Zephyr ignore known warnings: /home/raiden00/git/RTOS/nuttx/nuttx/Documentation/reference/os/netdev.rst:61: WARNING: Duplicate C declaration, also defined at reference/os/netdev:39. Declaration is '.. c:struct:: net_driver_s'. /home/raiden00/git/RTOS/nuttx/nuttx/Documentation/reference/user/07_signals.rst:180: WARNING: Duplicate C declaration, also defined at reference/user/structures:112. Declaration is '.. c:struct:: sigaction'. --- .gitignore | 1 + Documentation/_extensions/__init__.py | 19 +++ Documentation/_extensions/warnings_filter.py | 157 +++++++++++++++++++ Documentation/conf.py | 12 +- Documentation/known-warnings.txt | 6 + LICENSE | 5 + 6 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 Documentation/_extensions/__init__.py create mode 100644 Documentation/_extensions/warnings_filter.py create mode 100644 Documentation/known-warnings.txt diff --git a/.gitignore b/.gitignore index 7314e2736a..34e29b2264 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ *.ddc *.dds *.su +*.pyc *~ .depend /.config diff --git a/Documentation/_extensions/__init__.py b/Documentation/_extensions/__init__.py new file mode 100644 index 0000000000..d7cd7010e4 --- /dev/null +++ b/Documentation/_extensions/__init__.py @@ -0,0 +1,19 @@ +############################################################################## +# Documentation/_extensions/__init__.py +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################## diff --git a/Documentation/_extensions/warnings_filter.py b/Documentation/_extensions/warnings_filter.py new file mode 100644 index 0000000000..40fb96cb2d --- /dev/null +++ b/Documentation/_extensions/warnings_filter.py @@ -0,0 +1,157 @@ +############################################################################## +# Documentation/_extenstions/warnings_filter.py +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################## + +# This extension was ported from Zephyr. Original file can be found at: +# +# https://github.com/zephyrproject-rtos/zephyr/blob/main/doc/_extensions/zephyr/warnings_filter.py + + +""" +Warnings filter extension +######################### + +Copyright (c) 2021 Nordic Semiconductor ASA +SPDX-License-Identifier: Apache-2.0 + +Introduction +============ + +This Sphinx plugin can be used to filter out warnings that are known to be false +positives. The warnings are filtered out based on a set of regular expressions +given via an configuration file. The format of the configuration file is a +plain-text file where each line consists of a regular expression. Any lines +starting with ``#`` will be ignored. + +Configuration options +===================== + +- ``warnings_filter_config``: Configuration file. +- ``warnings_filter_silent``: Silent flag. If True, warning is hidden. If False + the warning is converted to an information message and displayed. +""" + +import logging +import re +from typing import Any, Dict, List, Optional + +from sphinx.application import Sphinx +from sphinx.util.logging import NAMESPACE + +__version__ = "0.1.0" + + +class WarningsFilter(logging.Filter): + """Warnings filter. + + Args: + expressions: List of regular expressions. + silent: If true, warning is hidden, otherwise it is shown as INFO. + name: Filter name. + """ + + def __init__(self, expressions: List[str], silent: bool, name: str = "") -> None: + super().__init__(name) + + self._expressions = expressions + self._silent = silent + + def filter(self, record: logging.LogRecord) -> bool: + if record.levelno != logging.WARNING: + return True + + for expression in self._expressions: + # The message isn't always a string so we convert it before regexing as we can only regex strings + if expression.match(str(record.msg)): + if self._silent: + return False + else: + record.levelno = logging.INFO + record.msg = f"Filtered warning: {record.msg}" + return True + + return True + + +class Expression: + """ + Encapsulate a log filter pattern and track if it ever matches a log line. + """ + + def __init__(self, pattern): + self.pattern = pattern + self.matched = False + + def match(self, str): + matches = bool(re.match(self.pattern, str)) + self.matched = matches or self.matched + return matches + + +def configure(app: Sphinx) -> None: + """Entry point. + + Args: + app: Sphinx application instance. + """ + + # load expressions from configuration file + with open(app.config.warnings_filter_config) as f: + expressions = list() + for line in f.readlines(): + if line.strip() and not line.startswith("#"): + expressions.append(Expression(line.rstrip())) + + app.env.warnings_filter_expressions = expressions + + # install warnings filter to all the Sphinx logger handlers + filter = WarningsFilter(expressions, app.config.warnings_filter_silent) + logger = logging.getLogger(NAMESPACE) + for handler in logger.handlers: + handler.filters.insert(0, filter) + + +def finished(app: Sphinx, exception: Optional[Exception]): + """ + Prints out any patterns that have not matched a log line to allow us to clean up any that are not used. + """ + if exception: + # Early exit if there has been an exception as matching data is only + # valid for complete builds + return + + expressions = app.env.warnings_filter_expressions + + for expression in expressions: + if not expression.matched: + logging.warning(f"Unused expression: {expression.pattern}") + + +def setup(app: Sphinx) -> Dict[str, Any]: + app.add_config_value("warnings_filter_config", "", "") + app.add_config_value("warnings_filter_silent", True, "") + + app.connect("builder-inited", configure) + app.connect("build-finished", finished) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/Documentation/conf.py b/Documentation/conf.py index 3edc99c5db..ffffcfe8a0 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -31,9 +31,12 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) +import sys + +# Add the '_extensions' directory to sys.path, to enable finding Sphinx +# extensions within. +sys.path.insert(0, "_extensions") # -- Project information ----------------------------------------------------- @@ -55,6 +58,7 @@ extensions = [ "sphinx.ext.todo", "sphinx_tabs.tabs", "sphinx_copybutton", + "warnings_filter", ] source_suffix = [".rst", ".md"] @@ -124,3 +128,7 @@ linkcheck_ignore = [ latex_engine = "lualatex" copybutton_exclude = ".linenos, .gp, .go" + +# -- Options for warnings_filter ------------------------------------------ + +warnings_filter_config = "known-warnings.txt" diff --git a/Documentation/known-warnings.txt b/Documentation/known-warnings.txt new file mode 100644 index 0000000000..4688c74d49 --- /dev/null +++ b/Documentation/known-warnings.txt @@ -0,0 +1,6 @@ +# Each line should contain the regular expression of a known Sphinx warning +# that should be filtered out + +# Function and (enum or struct) name +.*Duplicate C declaration.*\n.*'\.\. c:.*:: net_driver_s'.* +.*Duplicate C declaration.*\n.*'\.\. c:.*:: sigaction'.* diff --git a/LICENSE b/LICENSE index ae678e7e39..03bd548b5d 100644 --- a/LICENSE +++ b/LICENSE @@ -8497,3 +8497,8 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Documentation/_extensions/warnings_filter.py +============================================ +Copyright (c) 2021 Nordic Semiconductor ASA +SPDX-License-Identifier: Apache-2.0