├── clang_html ├── __init__.py ├── __main__.py ├── checks.py └── clang_visualizer.py ├── PyPI.md ├── pyproject.toml ├── .vscode └── launch.json ├── LICENSE ├── setup.py ├── .gitignore ├── examples ├── sample.log ├── clang-tidy-checks.py └── clang.html └── README.md /clang_html/__init__.py: -------------------------------------------------------------------------------- 1 | from .clang_visualizer import clang_tidy_visualizer 2 | -------------------------------------------------------------------------------- /PyPI.md: -------------------------------------------------------------------------------- 1 | # how to upload to PyPI 2 | 1. `rm -r dist` 3 | 2. `python -m build` 4 | 3. `python -m twine upload dist/*` -------------------------------------------------------------------------------- /clang_html/__main__.py: -------------------------------------------------------------------------------- 1 | from clang_html.clang_visualizer import main 2 | 3 | if __name__ == "__main__": 4 | main() 5 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>=42", 4 | "wheel" 5 | ] 6 | build-backend = "setuptools.build_meta" 7 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: Module", 9 | "type": "python", 10 | "request": "launch", 11 | "module": "clang_html", 12 | "justMyCode": true, 13 | "args": [".\\examples\\sample.log", "-d", "http://releases.llvm.org/14.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/list.html"] 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2021 Austin Hale 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Always prefer setuptools over distutils 2 | from setuptools import setup, find_packages 3 | import pathlib 4 | 5 | here = pathlib.Path(__file__).parent.resolve() 6 | long_description = (here / 'README.md').read_text(encoding='utf-8') 7 | 8 | setup( 9 | name='clang-html', 10 | version='1.6.1', 11 | description='Generates an html file that organizes your clang-tidy log output with the latest clang-tidy checks.', 12 | long_description=long_description, 13 | long_description_content_type="text/markdown", 14 | url='https://github.com/austinbhale/Clang-Visualizer', 15 | author='Austin Hale', 16 | author_email='ah@unc.edu', 17 | license='MIT License', 18 | install_requires=[ 19 | "beautifulsoup4", 20 | "certifi", 21 | "lxml", 22 | "requests" 23 | ], 24 | classifiers=[ 25 | 'Programming Language :: Python :: 3', 26 | 'License :: OSI Approved :: MIT License', 27 | 'Operating System :: OS Independent' 28 | ], 29 | keywords='clang, clang-tidy, html', 30 | entry_points={ 31 | 'console_scripts': [ 32 | 'clang-tidy-html=clang_html.clang_visualizer:main', 33 | ], 34 | }, 35 | python_requires='>=3.6, <4', 36 | packages=find_packages() 37 | ) 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | old* 2 | build/ 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | cover/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | .pybuilder/ 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | # For a library or package, you might want to ignore these files since the code is 90 | # intended to run in multiple environments; otherwise, check them in: 91 | # .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 101 | __pypackages__/ 102 | 103 | # Celery stuff 104 | celerybeat-schedule 105 | celerybeat.pid 106 | 107 | # SageMath parsed files 108 | *.sage.py 109 | 110 | # Environments 111 | .env 112 | .venv 113 | env/ 114 | venv/ 115 | ENV/ 116 | env.bak/ 117 | venv.bak/ 118 | 119 | # Spyder project settings 120 | .spyderproject 121 | .spyproject 122 | 123 | # Rope project settings 124 | .ropeproject 125 | 126 | # mkdocs documentation 127 | /site 128 | 129 | # mypy 130 | .mypy_cache/ 131 | .dmypy.json 132 | dmypy.json 133 | 134 | # Pyre type checker 135 | .pyre/ 136 | 137 | # pytype static type analyzer 138 | .pytype/ 139 | 140 | # Cython debug symbols 141 | cython_debug/ -------------------------------------------------------------------------------- /examples/sample.log: -------------------------------------------------------------------------------- 1 | /home/ahale/clangtidy_generator/clang_visualizer.c:6:1: warning: #includes are not sorted properly [llvm-include-order] 2 | #include 3 | ^ ~~~~~~~~~ 4 | 5 | /home/ahale/clangtidy_generator/clang_visualizer.c:27:6: warning: function 'read_log' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name] 6 | void read_log(FILE *log, node_t *head, node_t **next, char line[]); 7 | ^ ~~~~~ 8 | log_line 9 | /home/ahale/clangtidy_generator/clang_visualizer.c:1105:6: note: the definition seen here 10 | void read_log(FILE *log, node_t *head, node_t **next, char log_line[]) 11 | ^ 12 | /home/ahale/clangtidy_generator/clang_visualizer.c:27:6: note: differing parameters are named here: ('line'), in definition: ('log_line') 13 | void read_log(FILE *log, node_t *head, node_t **next, char line[]); 14 | ^ 15 | /home/ahale/clangtidy_generator/clang_visualizer.c:1061:32: warning: use 'fopen' mode 'e' to set O_CLOEXEC [android-cloexec-fopen] 16 | html = fopen("clangtidy.html","w"); 17 | ^~~~ 18 | "we" 19 | /home/ahale/clangtidy_generator/clang_visualizer.c:1062:23: warning: use 'fopen' mode 'e' to set O_CLOEXEC [android-cloexec-fopen] 20 | log = fopen(argv[1], "r"); 21 | ^~~~ 22 | "re" 23 | /home/ahale/clangtidy_generator/clang_visualizer.c:1094:45: warning: statement should be inside braces [hicpp-braces-around-statements] 24 | for (int idx=0; idx < used_checks_amt; idx++) 25 | ^ 26 | { 27 | /home/ahale/clangtidy_generator/clang_visualizer.c:1114:42: warning: statement should be inside braces [hicpp-braces-around-statements] 28 | if (strstr(log_line,checks_list[idx])) 29 | ^ 30 | { 31 | /home/ahale/clangtidy_generator/clang_visualizer.c:1133:4: warning: Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 [clang-analyzer-security.insecureAPI.strcpy] 32 | strcpy(used_checks_list[new_checks_idx].name, checks_list[used_idx]); 33 | ^ 34 | /home/ahale/clangtidy_generator/clang_visualizer.c:1133:4: note: Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 35 | /home/ahale/clangtidy_generator/clang_visualizer.c:1145:31: warning: statement should be inside braces [readability-braces-around-statements] 36 | if (used_checks_list == NULL) 37 | ^ 38 | { 39 | /home/ahale/clangtidy_generator/clang_visualizer.c:1155:25: warning: statement should be inside braces [readability-braces-around-statements] 40 | if (check_details > 3) 41 | ^ 42 | { 43 | /home/ahale/clangtidy_generator/clang_visualizer.c:1231:53: warning: statement should be inside braces [google-readability-braces-around-statements] 44 | for (struct node *ptr = head; ptr; ptr = ptr->next) 45 | ^ 46 | { 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # clang-html 2 | A visualizer for LLVM's linting tool: clang-tidy. 3 | 4 | ## Getting Started with pip 5 | ![test](https://static.pepy.tech/personalized-badge/clang-html?period=total&units=international_system&left_color=black&right_color=blue&left_text=Downloads) 6 | 7 | Install it: 8 | ``` 9 | python -m pip install clang-html 10 | ``` 11 | In your shell: 12 | ``` 13 | # Call it as python module 14 | python -m clang_html [logfile.log] [-o clang.html] [-d list.html] 15 | 16 | # Call it directly 17 | clang-tidy-html [logfile.log] [-o clang.html] [-d list.html] 18 | ``` 19 | 20 | In your python terminal: 21 | ``` 22 | >>> from pathlib import Path 23 | >>> from clang_html import clang_tidy_visualizer 24 | 25 | >>> clang_tidy_visualizer(Path("examples/sample.log")) 26 | 2021-04-23 12:30:40,619 - clang_html.clang_visualizer - INFO - Writing results to clang.html 27 | ``` 28 | 29 | ### Libraries 30 | - [beautifulsoup4](https://pypi.org/project/beautifulsoup4/) 31 | - [certifi](https://pypi.org/project/certifi/) 32 | - [lxml](https://pypi.org/project/lxml/) 33 | - [requests](https://pypi.org/project/requests/) 34 | 35 | ### Prerequisites 36 | 37 | Install [Clang-Tidy](http://clang.llvm.org/extra/clang-tidy/) to use for your C/C++ source files. 38 | 39 | On your local Linux machine, installation is as easy as: 40 | 41 | ``` 42 | sudo apt install clang-tidy 43 | ``` 44 | 45 | You will need bash or some other terminal to execute the script. Download Python 3 or higher [here](https://www.python.org/downloads/). 46 | 47 | When running clang-tidy on your files, be sure to pipe it into a new log file of checks: 48 | 49 | ``` 50 | clang-tidy -checks=* [filename.c] | tee [newfile.log] 51 | ``` 52 | 53 | If you are receiving the following error: 54 | 55 | > Error while trying to load a compilation database: 56 | > Could not auto-detect compilation database for file "your_file.c" 57 | > No compilation database found in /your/directory or any parent directory 58 | 59 | Create a simple json file to be compiled into your project documented [here](http://clang.llvm.org/docs/JSONCompilationDatabase.html). 60 | 61 | ## Running the script locally 62 | 63 | Clone or fork this repository to run the script on your native system. 64 | 65 | The script takes in one file argument of a txt or log file with your outputted clang-tidy checks. 66 | 67 | ``` 68 | python -m clang_html [newfile.log] [-o clang.html] [-d list.html] 69 | ``` 70 | 71 | ## Example Output 72 | 73 | Inside the same directory as clang_visualizer.py, you will find a new html file called 'clang.html'. 74 | 75 | You can also specify your custom file name when calling the script with `[-o, --out] other_name.html` or `clang_tidy_visualizer(Path("sample.log"), Path("clang.html"))`. 76 | 77 | An example html output can be found [here](https://austinbhale.com/clang-tidy-html/examples/clang.html). 78 | 79 | The highlighting functionality uses your local session storage, which will save your changes on exit. 80 | 81 | ## Contributing 82 | 83 | Feel free to create a pull request for any updates or fixes to this repository. 84 | 85 | ## Versioning 86 | 87 | This repository uses [LLVM Clang](http://clang.llvm.org/extra/clang-tidy/index.html) for versioning. By default, the script uses the latest information presented on LLVM's official [checks list](http://clang.llvm.org/extra/clang-tidy/checks/list.html). Earlier versions should have support for the vast majority of checks. 88 | 89 | The `-d --checks_dict_url` command-line option can link to another version (e.g., find v14.0.0 checks with: https://releases.llvm.org/14.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/list.html). 90 | 91 | ## Authors 92 | 93 | - **Austin Hale** 94 | 95 | See also the list of [contributors](https://github.com/austinbhale/Clang-Visualizer/graphs/contributors) who participated in this project. 96 | 97 | ## License 98 | 99 | This project is licensed under the MIT License - see the [LICENSE](https://github.com/austinbhale/Clang-Visualizer/LICENSE) file for details. 100 | -------------------------------------------------------------------------------- /examples/clang-tidy-checks.py: -------------------------------------------------------------------------------- 1 | checks_list = ['abseil-cleanup-ctad','abseil-duration-addition','abseil-duration-comparison','abseil-duration-conversion-cast','abseil-duration-division','abseil-duration-factory-float','abseil-duration-factory-scale','abseil-duration-subtraction','abseil-duration-unnecessary-conversion','abseil-faster-strsplit-delimiter','abseil-no-internal-dependencies','abseil-no-namespace','abseil-redundant-strcat-calls','abseil-str-cat-append','abseil-string-find-startswith','abseil-string-find-str-contains','abseil-time-comparison','abseil-time-subtraction','abseil-upgrade-duration-conversions','altera-id-dependent-backward-branch','altera-kernel-name-restriction','altera-single-work-item-barrier','altera-struct-pack-align','altera-unroll-loops','android-cloexec-accept','android-cloexec-accept4','android-cloexec-creat','android-cloexec-dup','android-cloexec-epoll-create','android-cloexec-epoll-create1','android-cloexec-fopen','android-cloexec-inotify-init','android-cloexec-inotify-init1','android-cloexec-memfd-create','android-cloexec-open','android-cloexec-pipe','android-cloexec-pipe2','android-cloexec-socket','android-comparison-in-temp-failure-retry','boost-use-to-string','bugprone-argument-comment','bugprone-assert-side-effect','bugprone-assignment-in-if-condition','bugprone-bad-signal-to-kill-thread','bugprone-bool-pointer-implicit-conversion','bugprone-branch-clone','bugprone-copy-constructor-init','bugprone-dangling-handle','bugprone-dynamic-static-initializers','bugprone-easily-swappable-parameters','bugprone-exception-escape','bugprone-fold-init-type','bugprone-forward-declaration-namespace','bugprone-forwarding-reference-overload','bugprone-implicit-widening-of-multiplication-result','bugprone-inaccurate-erase','bugprone-incorrect-roundings','bugprone-infinite-loop','bugprone-integer-division','bugprone-lambda-function-name','bugprone-macro-parentheses','bugprone-macro-repeated-side-effects','bugprone-misplaced-operator-in-strlen-in-alloc','bugprone-misplaced-pointer-arithmetic-in-alloc','bugprone-misplaced-widening-cast','bugprone-move-forwarding-reference','bugprone-multiple-statement-macro','bugprone-narrowing-conversions','bugprone-no-escape','bugprone-not-null-terminated-result','bugprone-parent-virtual-call','bugprone-posix-return','bugprone-redundant-branch-condition','bugprone-reserved-identifier','bugprone-shared-ptr-array-mismatch','bugprone-signal-handler','bugprone-signed-char-misuse','bugprone-sizeof-container','bugprone-sizeof-expression','bugprone-spuriously-wake-up-functions','bugprone-string-constructor','bugprone-string-integer-assignment','bugprone-string-literal-with-embedded-nul','bugprone-stringview-nullptr','bugprone-suspicious-enum-usage','bugprone-suspicious-include','bugprone-suspicious-memory-comparison','bugprone-suspicious-memset-usage','bugprone-suspicious-missing-comma','bugprone-suspicious-semicolon','bugprone-suspicious-string-compare','bugprone-swapped-arguments','bugprone-terminating-continue','bugprone-throw-keyword-missing','bugprone-too-small-loop-variable','bugprone-unchecked-optional-access','bugprone-undefined-memory-manipulation','bugprone-undelegated-constructor','bugprone-unhandled-exception-at-new','bugprone-unhandled-self-assignment','bugprone-unused-raii','bugprone-unused-return-value','bugprone-use-after-move','bugprone-virtual-near-miss','cert-con36-c','cert-con54-cpp','cert-dcl03-c','cert-dcl16-c','cert-dcl21-cpp','cert-dcl37-c','cert-dcl50-cpp','cert-dcl51-cpp','cert-dcl54-cpp','cert-dcl58-cpp','cert-dcl59-cpp','cert-env33-c','cert-err09-cpp','cert-err33-c','cert-err34-c','cert-err52-cpp','cert-err58-cpp','cert-err60-cpp','cert-err61-cpp','cert-exp42-c','cert-fio38-c','cert-flp30-c','cert-flp37-c','cert-mem57-cpp','cert-msc30-c','cert-msc32-c','cert-msc50-cpp','cert-msc51-cpp','cert-oop11-cpp','cert-oop54-cpp','cert-oop57-cpp','cert-oop58-cpp','cert-pos44-c','cert-pos47-c','cert-sig30-c','cert-str34-c','clang-analyzer-core.CallAndMessage','clang-analyzer-core.DivideZero','clang-analyzer-core.DynamicTypePropagation','clang-analyzer-core.NonNullParamChecker','clang-analyzer-core.NullDereference','clang-analyzer-core.StackAddressEscape','clang-analyzer-core.UndefinedBinaryOperatorResult','clang-analyzer-core.VLASize','clang-analyzer-core.uninitialized.ArraySubscript','clang-analyzer-core.uninitialized.Assign','clang-analyzer-core.uninitialized.Branch','clang-analyzer-core.uninitialized.CapturedBlockVariable','clang-analyzer-core.uninitialized.UndefReturn','clang-analyzer-cplusplus.InnerPointer','clang-analyzer-cplusplus.Move','clang-analyzer-cplusplus.NewDelete','clang-analyzer-cplusplus.NewDeleteLeaks','clang-analyzer-deadcode.DeadStores','clang-analyzer-nullability.NullPassedToNonnull','clang-analyzer-nullability.NullReturnedFromNonnull','clang-analyzer-nullability.NullableDereferenced','clang-analyzer-nullability.NullablePassedToNonnull','clang-analyzer-nullability.NullableReturnedFromNonnull','clang-analyzer-optin.cplusplus.UninitializedObject','clang-analyzer-optin.cplusplus.VirtualCall','clang-analyzer-optin.mpi.MPI-Checker','clang-analyzer-optin.osx.OSObjectCStyleCast','clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker','clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker','clang-analyzer-optin.performance.GCDAntipattern','clang-analyzer-optin.performance.Padding','clang-analyzer-optin.portability.UnixAPI','clang-analyzer-osx.API','clang-analyzer-osx.MIG','clang-analyzer-osx.NumberObjectConversion','clang-analyzer-osx.OSObjectRetainCount','clang-analyzer-osx.ObjCProperty','clang-analyzer-osx.SecKeychainAPI','clang-analyzer-osx.cocoa.AtSync','clang-analyzer-osx.cocoa.AutoreleaseWrite','clang-analyzer-osx.cocoa.ClassRelease','clang-analyzer-osx.cocoa.Dealloc','clang-analyzer-osx.cocoa.IncompatibleMethodTypes','clang-analyzer-osx.cocoa.Loops','clang-analyzer-osx.cocoa.MissingSuperCall','clang-analyzer-osx.cocoa.NSAutoreleasePool','clang-analyzer-osx.cocoa.NSError','clang-analyzer-osx.cocoa.NilArg','clang-analyzer-osx.cocoa.NonNilReturnValue','clang-analyzer-osx.cocoa.ObjCGenerics','clang-analyzer-osx.cocoa.RetainCount','clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak','clang-analyzer-osx.cocoa.SelfInit','clang-analyzer-osx.cocoa.SuperDealloc','clang-analyzer-osx.cocoa.UnusedIvars','clang-analyzer-osx.cocoa.VariadicMethodTypes','clang-analyzer-osx.coreFoundation.CFError','clang-analyzer-osx.coreFoundation.CFNumber','clang-analyzer-osx.coreFoundation.CFRetainRelease','clang-analyzer-osx.coreFoundation.containers.OutOfBounds','clang-analyzer-osx.coreFoundation.containers.PointerSizedValues','clang-analyzer-security.FloatLoopCounter','clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling','clang-analyzer-security.insecureAPI.UncheckedReturn','clang-analyzer-security.insecureAPI.bcmp','clang-analyzer-security.insecureAPI.bcopy','clang-analyzer-security.insecureAPI.bzero','clang-analyzer-security.insecureAPI.getpw','clang-analyzer-security.insecureAPI.gets','clang-analyzer-security.insecureAPI.mkstemp','clang-analyzer-security.insecureAPI.mktemp','clang-analyzer-security.insecureAPI.rand','clang-analyzer-security.insecureAPI.strcpy','clang-analyzer-security.insecureAPI.vfork','clang-analyzer-unix.API','clang-analyzer-unix.Malloc','clang-analyzer-unix.MallocSizeof','clang-analyzer-unix.MismatchedDeallocator','clang-analyzer-unix.Vfork','clang-analyzer-unix.cstring.BadSizeArg','clang-analyzer-unix.cstring.NullArg','clang-analyzer-valist.CopyToSelf','clang-analyzer-valist.Uninitialized','clang-analyzer-valist.Unterminated','concurrency-mt-unsafe','concurrency-thread-canceltype-asynchronous','cppcoreguidelines-avoid-c-arrays','cppcoreguidelines-avoid-goto','cppcoreguidelines-avoid-magic-numbers','cppcoreguidelines-avoid-non-const-global-variables','cppcoreguidelines-c-copy-assignment-signature','cppcoreguidelines-explicit-virtual-functions','cppcoreguidelines-init-variables','cppcoreguidelines-interfaces-global-init','cppcoreguidelines-macro-to-enum','cppcoreguidelines-macro-usage','cppcoreguidelines-narrowing-conversions','cppcoreguidelines-no-malloc','cppcoreguidelines-non-private-member-variables-in-classes','cppcoreguidelines-owning-memory','cppcoreguidelines-prefer-member-initializer','cppcoreguidelines-pro-bounds-array-to-pointer-decay','cppcoreguidelines-pro-bounds-constant-array-index','cppcoreguidelines-pro-bounds-pointer-arithmetic','cppcoreguidelines-pro-type-const-cast','cppcoreguidelines-pro-type-cstyle-cast','cppcoreguidelines-pro-type-member-init','cppcoreguidelines-pro-type-reinterpret-cast','cppcoreguidelines-pro-type-static-cast-downcast','cppcoreguidelines-pro-type-union-access','cppcoreguidelines-pro-type-vararg','cppcoreguidelines-slicing','cppcoreguidelines-special-member-functions','cppcoreguidelines-virtual-class-destructor','darwin-avoid-spinlock','darwin-dispatch-once-nonstatic','fuchsia-default-arguments-calls','fuchsia-default-arguments-declarations','fuchsia-header-anon-namespaces','fuchsia-multiple-inheritance','fuchsia-overloaded-operator','fuchsia-statically-constructed-objects','fuchsia-trailing-return','fuchsia-virtual-inheritance','google-build-explicit-make-pair','google-build-namespaces','google-build-using-namespace','google-default-arguments','google-explicit-constructor','google-global-names-in-headers','google-objc-avoid-nsobject-new','google-objc-avoid-throwing-exception','google-objc-function-naming','google-objc-global-variable-declaration','google-readability-avoid-underscore-in-googletest-name','google-readability-braces-around-statements','google-readability-casting','google-readability-function-size','google-readability-namespace-comments','google-readability-todo','google-runtime-int','google-runtime-operator','google-upgrade-googletest-case','hicpp-avoid-c-arrays','hicpp-avoid-goto','hicpp-braces-around-statements','hicpp-deprecated-headers','hicpp-exception-baseclass','hicpp-explicit-conversions','hicpp-function-size','hicpp-invalid-access-moved','hicpp-member-init','hicpp-move-const-arg','hicpp-multiway-paths-covered','hicpp-named-parameter','hicpp-new-delete-operators','hicpp-no-array-decay','hicpp-no-assembler','hicpp-no-malloc','hicpp-noexcept-move','hicpp-signed-bitwise','hicpp-special-member-functions','hicpp-static-assert','hicpp-undelegated-constructor','hicpp-uppercase-literal-suffix','hicpp-use-auto','hicpp-use-emplace','hicpp-use-equals-default','hicpp-use-equals-delete','hicpp-use-noexcept','hicpp-use-nullptr','hicpp-use-override','hicpp-vararg','linuxkernel-must-use-errs','llvm-else-after-return','llvm-header-guard','llvm-include-order','llvm-namespace-comment','llvm-prefer-isa-or-dyn-cast-in-conditionals','llvm-prefer-register-over-unsigned','llvm-qualified-auto','llvm-twine-local','llvmlibc-callee-namespace','llvmlibc-implementation-in-namespace','llvmlibc-restrict-system-libc-headers','misc-confusable-identifiers','misc-const-correctness','misc-definitions-in-headers','misc-misleading-bidirectional','misc-misleading-identifier','misc-misplaced-const','misc-new-delete-overloads','misc-no-recursion','misc-non-copyable-objects','misc-non-private-member-variables-in-classes','misc-redundant-expression','misc-static-assert','misc-throw-by-value-catch-by-reference','misc-unconventional-assign-operator','misc-uniqueptr-reset-release','misc-unused-alias-decls','misc-unused-parameters','misc-unused-using-decls','modernize-avoid-bind','modernize-avoid-c-arrays','modernize-concat-nested-namespaces','modernize-deprecated-headers','modernize-deprecated-ios-base-aliases','modernize-loop-convert','modernize-macro-to-enum','modernize-make-shared','modernize-make-unique','modernize-pass-by-value','modernize-raw-string-literal','modernize-redundant-void-arg','modernize-replace-auto-ptr','modernize-replace-disallow-copy-and-assign-macro','modernize-replace-random-shuffle','modernize-return-braced-init-list','modernize-shrink-to-fit','modernize-unary-static-assert','modernize-use-auto','modernize-use-bool-literals','modernize-use-default-member-init','modernize-use-emplace','modernize-use-equals-default','modernize-use-equals-delete','modernize-use-nodiscard','modernize-use-noexcept','modernize-use-nullptr','modernize-use-override','modernize-use-trailing-return-type','modernize-use-transparent-functors','modernize-use-uncaught-exceptions','modernize-use-using','mpi-buffer-deref','mpi-type-mismatch','objc-assert-equals','objc-avoid-nserror-init','objc-dealloc-in-category','objc-forbidden-subclassing','objc-missing-hash','objc-nsinvocation-argument-lifetime','objc-property-declaration','objc-super-self','openmp-exception-escape','openmp-use-default-none','performance-faster-string-find','performance-for-range-copy','performance-implicit-conversion-in-loop','performance-inefficient-algorithm','performance-inefficient-string-concatenation','performance-inefficient-vector-operation','performance-move-const-arg','performance-move-constructor-init','performance-no-automatic-move','performance-no-int-to-ptr','performance-noexcept-move-constructor','performance-trivially-destructible','performance-type-promotion-in-math-fn','performance-unnecessary-copy-initialization','performance-unnecessary-value-param','portability-restrict-system-includes','portability-simd-intrinsics','portability-std-allocator-const','readability-avoid-const-params-in-decls','readability-braces-around-statements','readability-const-return-type','readability-container-contains','readability-container-data-pointer','readability-container-size-empty','readability-convert-member-functions-to-static','readability-delete-null-pointer','readability-duplicate-include','readability-else-after-return','readability-function-cognitive-complexity','readability-function-size','readability-identifier-length','readability-identifier-naming','readability-implicit-bool-conversion','readability-inconsistent-declaration-parameter-name','readability-isolate-declaration','readability-magic-numbers','readability-make-member-function-const','readability-misleading-indentation','readability-misplaced-array-index','readability-named-parameter','readability-non-const-parameter','readability-qualified-auto','readability-redundant-access-specifiers','readability-redundant-control-flow','readability-redundant-declaration','readability-redundant-function-ptr-dereference','readability-redundant-member-init','readability-redundant-preprocessor','readability-redundant-smartptr-get','readability-redundant-string-cstr','readability-redundant-string-init','readability-simplify-boolean-expr','readability-simplify-subscript-expr','readability-static-accessed-through-instance','readability-static-definition-in-anonymous-namespace','readability-string-compare','readability-suspicious-call-argument','readability-uniqueptr-delete-release','readability-uppercase-literal-suffix','readability-use-anyofallof','zircon-temporary-objects'] -------------------------------------------------------------------------------- /clang_html/checks.py: -------------------------------------------------------------------------------- 1 | checks_list = ['[abseil-duration-addition]','[abseil-duration-comparison]','[abseil-duration-conversion-cast]','[abseil-duration-division]','[abseil-duration-factory-float]','[abseil-duration-factory-scale]','[abseil-duration-subtraction]','[abseil-duration-unnecessary-conversion]','[abseil-faster-strsplit-delimiter]','[abseil-no-internal-dependencies]','[abseil-no-namespace]','[abseil-redundant-strcat-calls]','[abseil-str-cat-append]','[abseil-string-find-startswith]','[abseil-string-find-str-contains]','[abseil-time-comparison]','[abseil-time-subtraction]','[abseil-upgrade-duration-conversions]','[altera-kernel-name-restriction]','[altera-single-work-item-barrier]','[altera-struct-pack-align]','[altera-unroll-loops]','[android-cloexec-accept4]','[android-cloexec-accept]','[android-cloexec-creat]','[android-cloexec-dup]','[android-cloexec-epoll-create1]','[android-cloexec-epoll-create]','[android-cloexec-fopen]','[android-cloexec-inotify-init1]','[android-cloexec-inotify-init]','[android-cloexec-memfd-create]','[android-cloexec-open]','[android-cloexec-pipe2]','[android-cloexec-pipe]','[android-cloexec-socket]','[android-comparison-in-temp-failure-retry]','[boost-use-to-string]','[bugprone-argument-comment]','[bugprone-assert-side-effect]','[bugprone-bad-signal-to-kill-thread]','[bugprone-bool-pointer-implicit-conversion]','[bugprone-branch-clone]','[bugprone-copy-constructor-init]','[bugprone-dangling-handle]','[bugprone-dynamic-static-initializers]','[bugprone-exception-escape]','[bugprone-fold-init-type]','[bugprone-forward-declaration-namespace]','[bugprone-forwarding-reference-overload]','[bugprone-implicit-widening-of-multiplication-result]','[bugprone-inaccurate-erase]','[bugprone-incorrect-roundings]','[bugprone-infinite-loop]','[bugprone-integer-division]','[bugprone-lambda-function-name]','[bugprone-macro-parentheses]','[bugprone-macro-repeated-side-effects]','[bugprone-misplaced-operator-in-strlen-in-alloc]','[bugprone-misplaced-pointer-arithmetic-in-alloc]','[bugprone-misplaced-widening-cast]','[bugprone-move-forwarding-reference]','[bugprone-multiple-statement-macro]','[bugprone-no-escape]','[bugprone-not-null-terminated-result]','[bugprone-parent-virtual-call]','[bugprone-posix-return]','[bugprone-redundant-branch-condition]','[bugprone-reserved-identifier]','[bugprone-signal-handler]','[bugprone-signed-char-misuse]','[bugprone-sizeof-container]','[bugprone-sizeof-expression]','[bugprone-spuriously-wake-up-functions]','[bugprone-string-constructor]','[bugprone-string-integer-assignment]','[bugprone-string-literal-with-embedded-nul]','[bugprone-suspicious-enum-usage]','[bugprone-suspicious-include]','[bugprone-suspicious-memset-usage]','[bugprone-suspicious-missing-comma]','[bugprone-suspicious-semicolon]','[bugprone-suspicious-string-compare]','[bugprone-swapped-arguments]','[bugprone-terminating-continue]','[bugprone-throw-keyword-missing]','[bugprone-too-small-loop-variable]','[bugprone-undefined-memory-manipulation]','[bugprone-undelegated-constructor]','[bugprone-unhandled-exception-at-new]','[bugprone-unhandled-self-assignment]','[bugprone-unused-raii]','[bugprone-unused-return-value]','[bugprone-use-after-move]','[bugprone-virtual-near-miss]','[cert-con36-c]','[cert-con54-cpp]','[cert-dcl03-c]','[cert-dcl16-c]','[cert-dcl21-cpp]','[cert-dcl37-c]','[cert-dcl50-cpp]','[cert-dcl51-cpp]','[cert-dcl54-cpp]','[cert-dcl58-cpp]','[cert-dcl59-cpp]','[cert-env33-c]','[cert-err09-cpp]','[cert-err34-c]','[cert-err52-cpp]','[cert-err58-cpp]','[cert-err60-cpp]','[cert-err61-cpp]','[cert-fio38-c]','[cert-flp30-c]','[cert-mem57-cpp]','[cert-msc30-c]','[cert-msc32-c]','[cert-msc50-cpp]','[cert-msc51-cpp]','[cert-oop11-cpp]','[cert-oop54-cpp]','[cert-oop57-cpp]','[cert-oop58-cpp]','[cert-pos44-c]','[cert-pos47-c]','[cert-sig30-c]','[cert-str34-c]','[clang-analyzer-core.CallAndMessage]','[clang-analyzer-core.DivideZero]','[clang-analyzer-core.DynamicTypePropagation]','[clang-analyzer-core.NonNullParamChecker]','[clang-analyzer-core.NullDereference]','[clang-analyzer-core.StackAddressEscape]','[clang-analyzer-core.UndefinedBinaryOperatorResult]','[clang-analyzer-core.VLASize]','[clang-analyzer-core.uninitialized.ArraySubscript]','[clang-analyzer-core.uninitialized.Assign]','[clang-analyzer-core.uninitialized.Branch]','[clang-analyzer-core.uninitialized.CapturedBlockVariable]','[clang-analyzer-core.uninitialized.UndefReturn]','[clang-analyzer-cplusplus.InnerPointer]','[clang-analyzer-cplusplus.Move]','[clang-analyzer-cplusplus.NewDeleteLeaks]','[clang-analyzer-cplusplus.NewDelete]','[clang-analyzer-deadcode.DeadStores]','[clang-analyzer-nullability.NullPassedToNonnull]','[clang-analyzer-nullability.NullReturnedFromNonnull]','[clang-analyzer-nullability.NullableDereferenced]','[clang-analyzer-nullability.NullablePassedToNonnull]','[clang-analyzer-nullability.NullableReturnedFromNonnull]','[clang-analyzer-optin.cplusplus.UninitializedObject]','[clang-analyzer-optin.cplusplus.VirtualCall]','[clang-analyzer-optin.mpi.MPI-Checker]','[clang-analyzer-optin.osx.OSObjectCStyleCast]','[clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker]','[clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker]','[clang-analyzer-optin.performance.GCDAntipattern]','[clang-analyzer-optin.performance.Padding]','[clang-analyzer-optin.portability.UnixAPI]','[clang-analyzer-osx.API]','[clang-analyzer-osx.MIG]','[clang-analyzer-osx.NumberObjectConversion]','[clang-analyzer-osx.OSObjectRetainCount]','[clang-analyzer-osx.ObjCProperty]','[clang-analyzer-osx.SecKeychainAPI]','[clang-analyzer-osx.cocoa.AtSync]','[clang-analyzer-osx.cocoa.AutoreleaseWrite]','[clang-analyzer-osx.cocoa.ClassRelease]','[clang-analyzer-osx.cocoa.Dealloc]','[clang-analyzer-osx.cocoa.IncompatibleMethodTypes]','[clang-analyzer-osx.cocoa.Loops]','[clang-analyzer-osx.cocoa.MissingSuperCall]','[clang-analyzer-osx.cocoa.NSAutoreleasePool]','[clang-analyzer-osx.cocoa.NSError]','[clang-analyzer-osx.cocoa.NilArg]','[clang-analyzer-osx.cocoa.NonNilReturnValue]','[clang-analyzer-osx.cocoa.ObjCGenerics]','[clang-analyzer-osx.cocoa.RetainCount]','[clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak]','[clang-analyzer-osx.cocoa.SelfInit]','[clang-analyzer-osx.cocoa.SuperDealloc]','[clang-analyzer-osx.cocoa.UnusedIvars]','[clang-analyzer-osx.cocoa.VariadicMethodTypes]','[clang-analyzer-osx.coreFoundation.CFError]','[clang-analyzer-osx.coreFoundation.CFNumber]','[clang-analyzer-osx.coreFoundation.CFRetainRelease]','[clang-analyzer-osx.coreFoundation.containers.OutOfBounds]','[clang-analyzer-osx.coreFoundation.containers.PointerSizedValues]','[clang-analyzer-security.FloatLoopCounter]','[clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]','[clang-analyzer-security.insecureAPI.UncheckedReturn]','[clang-analyzer-security.insecureAPI.bcmp]','[clang-analyzer-security.insecureAPI.bcopy]','[clang-analyzer-security.insecureAPI.bzero]','[clang-analyzer-security.insecureAPI.getpw]','[clang-analyzer-security.insecureAPI.gets]','[clang-analyzer-security.insecureAPI.mkstemp]','[clang-analyzer-security.insecureAPI.mktemp]','[clang-analyzer-security.insecureAPI.rand]','[clang-analyzer-security.insecureAPI.strcpy]','[clang-analyzer-security.insecureAPI.vfork]','[clang-analyzer-unix.API]','[clang-analyzer-unix.MallocSizeof]','[clang-analyzer-unix.Malloc]','[clang-analyzer-unix.MismatchedDeallocator]','[clang-analyzer-unix.Vfork]','[clang-analyzer-unix.cstring.BadSizeArg]','[clang-analyzer-unix.cstring.NullArg]','[clang-analyzer-valist.CopyToSelf]','[clang-analyzer-valist.Uninitialized]','[clang-analyzer-valist.Unterminated]','[concurrency-mt-unsafe]','[concurrency-thread-canceltype-asynchronous]','[cppcoreguidelines-avoid-c-arrays]','[cppcoreguidelines-avoid-goto]','[cppcoreguidelines-avoid-magic-numbers]','[cppcoreguidelines-avoid-non-const-global-variables]','[cppcoreguidelines-c-copy-assignment-signature]','[cppcoreguidelines-explicit-virtual-functions]','[cppcoreguidelines-init-variables]','[cppcoreguidelines-interfaces-global-init]','[cppcoreguidelines-macro-usage]','[cppcoreguidelines-narrowing-conversions]','[cppcoreguidelines-no-malloc]','[cppcoreguidelines-non-private-member-variables-in-classes]','[cppcoreguidelines-owning-memory]','[cppcoreguidelines-prefer-member-initializer]','[cppcoreguidelines-pro-bounds-array-to-pointer-decay]','[cppcoreguidelines-pro-bounds-constant-array-index]','[cppcoreguidelines-pro-bounds-pointer-arithmetic]','[cppcoreguidelines-pro-type-const-cast]','[cppcoreguidelines-pro-type-cstyle-cast]','[cppcoreguidelines-pro-type-member-init]','[cppcoreguidelines-pro-type-reinterpret-cast]','[cppcoreguidelines-pro-type-static-cast-downcast]','[cppcoreguidelines-pro-type-union-access]','[cppcoreguidelines-pro-type-vararg]','[cppcoreguidelines-slicing]','[cppcoreguidelines-special-member-functions]','[darwin-avoid-spinlock]','[darwin-dispatch-once-nonstatic]','[fuchsia-default-arguments-calls]','[fuchsia-default-arguments-declarations]','[fuchsia-header-anon-namespaces]','[fuchsia-multiple-inheritance]','[fuchsia-overloaded-operator]','[fuchsia-statically-constructed-objects]','[fuchsia-trailing-return]','[fuchsia-virtual-inheritance]','[google-build-explicit-make-pair]','[google-build-namespaces]','[google-build-using-namespace]','[google-default-arguments]','[google-explicit-constructor]','[google-global-names-in-headers]','[google-objc-avoid-nsobject-new]','[google-objc-avoid-throwing-exception]','[google-objc-function-naming]','[google-objc-global-variable-declaration]','[google-readability-avoid-underscore-in-googletest-name]','[google-readability-braces-around-statements]','[google-readability-casting]','[google-readability-function-size]','[google-readability-namespace-comments]','[google-readability-todo]','[google-runtime-int]','[google-runtime-operator]','[google-upgrade-googletest-case]','[hicpp-avoid-c-arrays]','[hicpp-avoid-goto]','[hicpp-braces-around-statements]','[hicpp-deprecated-headers]','[hicpp-exception-baseclass]','[hicpp-explicit-conversions]','[hicpp-function-size]','[hicpp-invalid-access-moved]','[hicpp-member-init]','[hicpp-move-const-arg]','[hicpp-multiway-paths-covered]','[hicpp-named-parameter]','[hicpp-new-delete-operators]','[hicpp-no-array-decay]','[hicpp-no-assembler]','[hicpp-no-malloc]','[hicpp-noexcept-move]','[hicpp-signed-bitwise]','[hicpp-special-member-functions]','[hicpp-static-assert]','[hicpp-undelegated-constructor]','[hicpp-uppercase-literal-suffix]','[hicpp-use-auto]','[hicpp-use-emplace]','[hicpp-use-equals-default]','[hicpp-use-equals-delete]','[hicpp-use-noexcept]','[hicpp-use-nullptr]','[hicpp-use-override]','[hicpp-vararg]','[https://clang.llvm.org/docs/analyzer/checkers]','[linuxkernel-must-use-errs]','[llvm-else-after-return]','[llvm-header-guard]','[llvm-include-order]','[llvm-namespace-comment]','[llvm-prefer-isa-or-dyn-cast-in-conditionals]','[llvm-prefer-register-over-unsigned]','[llvm-qualified-auto]','[llvm-twine-local]','[llvmlibc-callee-namespace]','[llvmlibc-implementation-in-namespace]','[llvmlibc-restrict-system-libc-headers]','[misc-definitions-in-headers]','[misc-misplaced-const]','[misc-new-delete-overloads]','[misc-no-recursion]','[misc-non-copyable-objects]','[misc-non-private-member-variables-in-classes]','[misc-redundant-expression]','[misc-static-assert]','[misc-throw-by-value-catch-by-reference]','[misc-unconventional-assign-operator]','[misc-uniqueptr-reset-release]','[misc-unused-alias-decls]','[misc-unused-parameters]','[misc-unused-using-decls]','[modernize-avoid-bind]','[modernize-avoid-c-arrays]','[modernize-concat-nested-namespaces]','[modernize-deprecated-headers]','[modernize-deprecated-ios-base-aliases]','[modernize-loop-convert]','[modernize-make-shared]','[modernize-make-unique]','[modernize-pass-by-value]','[modernize-raw-string-literal]','[modernize-redundant-void-arg]','[modernize-replace-auto-ptr]','[modernize-replace-disallow-copy-and-assign-macro]','[modernize-replace-random-shuffle]','[modernize-return-braced-init-list]','[modernize-shrink-to-fit]','[modernize-unary-static-assert]','[modernize-use-auto]','[modernize-use-bool-literals]','[modernize-use-default-member-init]','[modernize-use-emplace]','[modernize-use-equals-default]','[modernize-use-equals-delete]','[modernize-use-nodiscard]','[modernize-use-noexcept]','[modernize-use-nullptr]','[modernize-use-override]','[modernize-use-trailing-return-type]','[modernize-use-transparent-functors]','[modernize-use-uncaught-exceptions]','[modernize-use-using]','[mpi-buffer-deref]','[mpi-type-mismatch]','[objc-avoid-nserror-init]','[objc-dealloc-in-category]','[objc-forbidden-subclassing]','[objc-missing-hash]','[objc-nsinvocation-argument-lifetime]','[objc-property-declaration]','[objc-super-self]','[openmp-exception-escape]','[openmp-use-default-none]','[performance-faster-string-find]','[performance-for-range-copy]','[performance-implicit-conversion-in-loop]','[performance-inefficient-algorithm]','[performance-inefficient-string-concatenation]','[performance-inefficient-vector-operation]','[performance-move-const-arg]','[performance-move-constructor-init]','[performance-no-automatic-move]','[performance-no-int-to-ptr]','[performance-noexcept-move-constructor]','[performance-trivially-destructible]','[performance-type-promotion-in-math-fn]','[performance-unnecessary-copy-initialization]','[performance-unnecessary-value-param]','[portability-restrict-system-includes]','[portability-simd-intrinsics]','[readability-avoid-const-params-in-decls]','[readability-braces-around-statements]','[readability-const-return-type]','[readability-container-size-empty]','[readability-convert-member-functions-to-static]','[readability-delete-null-pointer]','[readability-else-after-return]','[readability-function-cognitive-complexity]','[readability-function-size]','[readability-identifier-naming]','[readability-implicit-bool-conversion]','[readability-inconsistent-declaration-parameter-name]','[readability-isolate-declaration]','[readability-magic-numbers]','[readability-make-member-function-const]','[readability-misleading-indentation]','[readability-misplaced-array-index]','[readability-named-parameter]','[readability-non-const-parameter]','[readability-qualified-auto]','[readability-redundant-access-specifiers]','[readability-redundant-control-flow]','[readability-redundant-declaration]','[readability-redundant-function-ptr-dereference]','[readability-redundant-member-init]','[readability-redundant-preprocessor]','[readability-redundant-smartptr-get]','[readability-redundant-string-cstr]','[readability-redundant-string-init]','[readability-simplify-boolean-expr]','[readability-simplify-subscript-expr]','[readability-static-accessed-through-instance]','[readability-static-definition-in-anonymous-namespace]','[readability-string-compare]','[readability-uniqueptr-delete-release]','[readability-uppercase-literal-suffix]','[readability-use-anyofallof]','[zircon-temporary-objects]'] -------------------------------------------------------------------------------- /clang_html/clang_visualizer.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import logging 3 | import re 4 | import sys 5 | from requests import Session 6 | from requests.adapters import HTTPAdapter 7 | from pathlib import Path 8 | from bs4 import BeautifulSoup 9 | import ssl 10 | import certifi 11 | 12 | log = logging.getLogger(__name__) 13 | handler = logging.StreamHandler() 14 | log_format = '%(asctime)s - %(name)12s - %(levelname)8s - %(message)s' 15 | handler.setFormatter(logging.Formatter(log_format)) 16 | log.addHandler(handler) 17 | log.setLevel(logging.DEBUG) 18 | 19 | COLOR_DICT = { 20 | '0': [(88, 88, 88), (88, 88, 88)], 21 | '30': [(0, 0, 0), (0, 0, 0)], 22 | '31': [(255, 0, 0), (128, 0, 0)], 23 | '32': [(0, 255, 0), (0, 128, 0)], 24 | '33': [(255, 255, 0), (128, 128, 0)], 25 | '34': [(0, 0, 255), (0, 0, 128)], 26 | '35': [(255, 0, 255), (128, 0, 128)], 27 | '36': [(0, 255, 255), (0, 128, 128)], 28 | '37': [(255, 255, 255), (128, 128, 128)], 29 | } 30 | 31 | COLOR_REGEX = re.compile( 32 | r'\[(?P\d+)(;(?P\d+)(;(?P\d+))?)?m') 33 | 34 | BOLD_TEMPLATE = '' 35 | LIGHT_TEMPLATE = '' 36 | 37 | 38 | def ansi_to_html(text): 39 | text = text.replace('[0m', '').replace('\033', '') 40 | 41 | def single_sub(match): 42 | argsdict = match.groupdict() 43 | color = '0' 44 | for arg in argsdict.values(): 45 | if arg is not None: 46 | val = int(str(arg)) 47 | if val == 0: 48 | bold = False 49 | elif val == 1: 50 | bold = True 51 | elif val >= 30 and val <= 37: 52 | color = arg 53 | if bold: 54 | return BOLD_TEMPLATE.format(COLOR_DICT[color][1]) 55 | return LIGHT_TEMPLATE.format(COLOR_DICT[color][0]) 56 | 57 | return COLOR_REGEX.sub(single_sub, text) 58 | 59 | # You can also import custom clang checks from checks.py below. 60 | # from checks import checks_list 61 | 62 | # Each check will have its own node of information. 63 | class checks: 64 | def __init__(self, dataval=None): 65 | self.name = '' 66 | self.count = 0 67 | self.data = '' 68 | 69 | # Begin here. 70 | def main(): 71 | # Process command line arguments. 72 | parser = argparse.ArgumentParser() 73 | parser.add_argument('file', type=Path) 74 | parser.add_argument( 75 | '-o', '--out', help="Generated html file name.", nargs='?', const="clang.html", default="clang.html", type=str) 76 | parser.add_argument( 77 | '-d', '--checks_dict_url', help="Override the latest checks list, (e.g., v14.0.0 uses \ 78 | https://releases.llvm.org/14.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/list.html).", nargs='?', type=str) 79 | 80 | try: 81 | args = parser.parse_args() 82 | except: 83 | parser.print_help() 84 | usage() 85 | sys.exit(-1) 86 | 87 | tidy_log_lines: Path = args.file 88 | output_path: Path = Path(args.out) 89 | clang_tidy_visualizer(tidy_log_lines, output_path, args.checks_dict_url) 90 | 91 | 92 | def clang_tidy_visualizer(tidy_log_file: Path, 93 | output_html_file: Path = Path("clang.html"), 94 | checks_dict_url = None): 95 | tidy_log_lines = tidy_log_file.read_text().splitlines() 96 | clang_base_url = "https://clang.llvm.org/extra/clang-tidy/checks/" 97 | global checks_dict 98 | 99 | if checks_dict_url is None: 100 | checks_dict_url = clang_base_url + 'list.html' 101 | 102 | checks_dict = find_checks_dict(checks_dict_url) 103 | if checks_dict is None or len(checks_dict) == 0: 104 | print("Error! Could not retrieve a dictionary of checks.") 105 | exit(0) 106 | checks_list = list(checks_dict.keys()) 107 | checks_list.sort() 108 | 109 | # Updates the newest clang-tidy checks to your checks.py file. 110 | write_checks_file( 111 | checks_list, to_file=output_html_file.parent / "clang-tidy-checks.py") 112 | 113 | checks_used = [0] * len(checks_list) 114 | 115 | # Increments each occurrence of a check. 116 | for line, content in enumerate(tidy_log_lines): 117 | content = content.replace('<', '<') 118 | content = content.replace('>', '>') 119 | for check_name in checks_list: 120 | if content.find(check_name.replace('/', '-')) != -1: 121 | checks_used[checks_list.index(check_name)] += 1 122 | 123 | # Counts the max number of used checks in the log file. 124 | num_used_checks = 0 125 | for line, check in enumerate(checks_list): 126 | if checks_used[line] != 0: 127 | num_used_checks += 1 128 | 129 | names_of_used = [None] * num_used_checks 130 | names_of_usedL = [None] * num_used_checks 131 | 132 | # Creates new check classes for each used check. 133 | used_line = 0 134 | total_num_checks = 0 135 | for line, check in enumerate(checks_list): 136 | if checks_used[line] != 0: 137 | new_node = checks(check) 138 | new_node.name = check 139 | new_node.count = checks_used[line] 140 | total_num_checks += checks_used[line] 141 | names_of_used[used_line] = new_node 142 | 143 | names_of_usedL[used_line] = checks_list[line] 144 | used_line += 1 145 | 146 | # Adds details for each organized check. 147 | for line, content in enumerate(tidy_log_lines): 148 | # Goes through each used check. 149 | for initial_check in names_of_usedL: 150 | # Adds the lines that detail the warning message. 151 | if content.find(initial_check.replace('/', '-')) != -1: 152 | content = content.replace('<', '<') 153 | content = content.replace('>', '>') 154 | names_of_used[names_of_usedL.index( 155 | initial_check)].data += content + '\n' 156 | details = line + 1 157 | finished = False 158 | while not finished: 159 | # Ensure there is no overflow. 160 | if details >= len(tidy_log_lines): 161 | break 162 | # If the line includes a used Clang-Tidy check name, 163 | # continue to find the next. 164 | for end_check in names_of_usedL: 165 | if tidy_log_lines[details].find(end_check.replace('/', '-')) != -1: 166 | finished = True 167 | break 168 | # Otherwise, add the data to the specific used check 169 | # name for the organization of checks in the HTML file. 170 | if not finished: 171 | names_of_used[names_of_usedL.index( 172 | initial_check)].data += tidy_log_lines[details] + '\n' 173 | details += 1 174 | 175 | with open(output_html_file, "w") as clang_html: 176 | log.info(f"Writing results to {output_html_file}") 177 | # Functions for writing to the clang.html file. 178 | writeHeader(clang_html) 179 | writeList(clang_html, num_used_checks, names_of_used, 180 | clang_base_url, total_num_checks) 181 | writeSortedLogs(clang_html, tidy_log_lines, 182 | num_used_checks, names_of_used, clang_base_url) 183 | writeScript(clang_html, num_used_checks) 184 | 185 | # adapted from https://github.com/psf/requests/issues/4775#issuecomment-478198879 186 | class TLSAdapter(HTTPAdapter): 187 | def init_poolmanager(self, *args, **kwargs): 188 | ctx = ssl.create_default_context(cafile=certifi.where()) 189 | ctx.set_ciphers('DEFAULT@SECLEVEL=1') 190 | kwargs['ssl_context'] = ctx 191 | return super(TLSAdapter, self).init_poolmanager(*args, **kwargs) 192 | 193 | # Scrape data from clang-tidy's official list of current checks. 194 | def find_checks_dict(checks_dict_url: str): 195 | session = Session() 196 | session.mount('https://', TLSAdapter()) 197 | try: 198 | res = session.get(checks_dict_url) 199 | except Exception as e: 200 | print(e) 201 | return None 202 | 203 | soup = BeautifulSoup(res.text, "lxml") 204 | scrape_checks_dict = dict() 205 | clang_check_links = soup.find_all('a', href=True) 206 | 207 | for link in clang_check_links: 208 | match_docs_check_name = re.match( 209 | "^([a-zA-Z0-9].*).html.*$", link['href']) 210 | if match_docs_check_name: 211 | docs_check_name = match_docs_check_name.group(1) 212 | split_docs_check = docs_check_name.split('/') 213 | len_split_docs_check = len(split_docs_check) 214 | if len_split_docs_check > 0 and len_split_docs_check <= 2: 215 | scrape_checks_dict[fromClangDocsName( 216 | docs_check_name)] = split_docs_check[0] 217 | return scrape_checks_dict 218 | 219 | # Optional: Update the checks.py file with the most recent checks. 220 | def write_checks_file(checks_list, to_file): 221 | with open(to_file, 'w') as f: 222 | f.write('checks_list = [') 223 | for check, item in enumerate(checks_list): 224 | if check == len(checks_list) - 1: 225 | f.write("'{}']".format(item)) 226 | else: 227 | f.write("'{}',".format(item)) 228 | 229 | # Helper functions to fix the links of the clang-tidy documentation. 230 | # Referenced in #8 231 | def toClangDocsName(original_check_name): 232 | checks_category = checks_dict[original_check_name] 233 | match_except_first_hyphen = re.compile(rf'^({checks_category})-(.*)$') 234 | clang_docs_name = match_except_first_hyphen.sub( 235 | r'\1/\2', original_check_name) 236 | return clang_docs_name 237 | 238 | def fromClangDocsName(docs_check_name): 239 | return docs_check_name.replace('/', '-', 1) 240 | 241 | # Prints usage information for the script. 242 | def usage(): 243 | print(""" 244 | ***------------------------------------------ Clang HTML Visualizer -----------------------------------------*** 245 | 246 | Generates an html file as a visual for clang-tidy checks. Additionally, it writes a checks.py file that 247 | informs you which checks have been scraped from http://clang.llvm.org/extra/clang-tidy/checks/list.html 248 | 249 | How to use: 250 | - Call the script directly: 251 | 1. clang-tidy-html [logfile.log] 252 | 2. python -m clang_html [logfile.log] 253 | OR 254 | - Import it in your Python terminal: 255 | >>> from pathlib import Path 256 | >>> from clang_html import clang_tidy_visualizer 257 | >>> clang_tidy_visualizer(Path("examples/sample.log")) 258 | 259 | Optional args: 260 | - [-o, --out] or clang_tidy_visualizer(path_to_log: Path, output_path: Path) 261 | - Rename the generated html file. The default filename is stored as "clang.html" in the directory 262 | from where you call the script. 263 | 264 | ***----------------------------------------------------------------------------------------------------------***""") 265 | 266 | # Header of the clang.html file. 267 | def writeHeader(f): 268 | f.write(""" 269 | 270 | 271 | 272 | Clang-Tidy Visualizer 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | """) 282 | 283 | # List the used checks found in the source code. 284 | def writeList(f, num_used_checks, names_of_used, clang_base_url, total_num_checks): 285 | f.write(""" 286 | 287 |
288 | 296 |
297 |
    298 | """) 299 | 300 | # Iterates through each used check's details and organizes them into the given
     sections.
    301 |     f.write("""
    302 |             
    303 |                 {} Original Log
    304 |             
    305 | """.format(total_num_checks))
    306 | 
    307 |     for line in range(0, num_used_checks):
    308 |         f.write("""
    309 |             
    310 |                 {1} {2}
    311 |             
    312 | """.format(line, names_of_used[line].count, names_of_used[line].name.replace('/', '-')))
    313 | 
    314 |     f.write("""
    315 |         
316 | 317 | 350 | """) 351 | 352 | for check_idx in range(0, num_used_checks): 353 | collapse_idx = check_idx + 1 354 | f.write(""" 355 |
356 |
357 | 360 |

361 | {2} 362 |

363 | """.format(check_idx, collapse_idx, names_of_used[check_idx].name)) 364 | 365 | # Attach a button to the specific check's docs in clang. Link opens in a new tab. 366 | docs_check_name = toClangDocsName(names_of_used[check_idx].name) 367 | clang_check_url = clang_base_url.replace( 368 | '/', '\/') + docs_check_name + '.html' 369 | external_name = 'Documentation' 370 | f.write(""" 371 | 376 | """.format(clang_check_url, external_name)) 377 | 378 | f.write(""" 379 |
380 |
381 | """)
382 | 
383 |         names_of_used[check_idx].data = names_of_used[check_idx].data.replace(
384 |             '<', '<')
385 |         names_of_used[check_idx].data = names_of_used[check_idx].data.replace(
386 |             '>', '>')
387 |         names_of_used[check_idx].data = ansi_to_html(
388 |             names_of_used[check_idx].data)
389 |         f.write("""{}
390 |             
391 |
392 | """.format(names_of_used[check_idx].data)) 393 | 394 | f.write(""" 395 |
396 | 397 | """) 398 | 399 | # Writes Javascript and JQuery code to the html file for button and grouping functionalities. 400 | def writeScript(f, num_used_checks): 401 | f.write(""" 402 | 546 | 556 | 557 | 558 | """.format(num_used_checks)) 559 | -------------------------------------------------------------------------------- /examples/clang.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Clang-Tidy Visualizer 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 25 |
26 | 61 | 62 | 125 | 126 | 154 | 155 | 179 | 180 | 204 | 205 | 233 | 234 | 258 | 259 | 291 | 292 | 322 | 323 |
324 | 325 | 326 | 470 | 480 | 481 | 482 | --------------------------------------------------------------------------------