{"id":17190711,"url":"https://github.com/dyollb/modernize_cpp","last_synced_at":"2025-03-25T05:54:29.110Z","repository":{"id":96260111,"uuid":"310022609","full_name":"dyollb/modernize_cpp","owner":"dyollb","description":"small collection of script to refactor legacy C++ code.","archived":false,"fork":false,"pushed_at":"2022-06-09T06:38:13.000Z","size":48,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-30T05:27:36.167Z","etag":null,"topics":["clang-tidy","cplusplus","cpp","cpp11","cpp14","modernization","refactoring"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dyollb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-04T14:13:47.000Z","updated_at":"2023-10-18T16:17:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"ecf69e1e-91d9-40b8-8d83-2f93d810ef5a","html_url":"https://github.com/dyollb/modernize_cpp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyollb%2Fmodernize_cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyollb%2Fmodernize_cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyollb%2Fmodernize_cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyollb%2Fmodernize_cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dyollb","download_url":"https://codeload.github.com/dyollb/modernize_cpp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245407772,"owners_count":20610234,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clang-tidy","cplusplus","cpp","cpp11","cpp14","modernization","refactoring"],"created_at":"2024-10-15T01:23:41.124Z","updated_at":"2025-03-25T05:54:29.091Z","avatar_url":"https://github.com/dyollb.png","language":"Python","readme":"\r\n# Modernizing legacy C++ code\r\n\r\n## Overview\r\n`clang-tidy` offers a wide range of checks to lint C++ code. In some cases it can generate automatic fixes, e.g. to replace expressions with `typedef` to `using`.\r\n`run-clang-tidy.py` is a tool which runs `clang-tidy` with a set of checks for an entire source code directory. To do this it needs to know how the source is compiled.\r\nCMake can generate this information for `ninja` and `Makefile` generators by specifying the option `CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON`.\r\n\r\n\r\n## Tools\r\n### clang-tidy provides a range of checks with fixits.\r\nFor a list of these checks see https://clang.llvm.org/extra/clang-tidy/. Some warn about bugprone code, improve readability or allow to enforce coding styles. The `modernize-*` checks mostly help to transform pre-c++11 code to c++11 (or c++14) code.\r\nOn Ubuntu you can install it via:\r\n- `apt-get update`\r\n- `apt install clang-tools-10`\r\n- `apt install clang-tidy-10`\r\n\r\n### The run-clang-tidy.py script\r\nThis script is available at [llvm](https://clang.llvm.org/extra/doxygen/run-clang-tidy_8py_source.html). Run it with `-h` to get help.\r\n*Note: I patched the script*, because it did not merge patches correctly (because warnings did not have normalized paths). Due to this bug it would sometimes add keywords multiple times, e.g. `std::string Name() override override`.\r\n\r\n\r\n### The batch-run-clang-tidy.py script\r\nThis script runs `run-clang-tidy.py` for a range of checks. After each check it tries to compile the code. If compilation succeeds, it commits tha patch using `git commit -am \"\u003ccheck_name\u003e\"`.\r\nThe script includes code compiled withing a folder (recursively), so if you want to focus on refactoring e.g. subfolder XYZ then you could run:\r\n\r\n`python ./Modernize/batch-run-clang-tidy.py -b /work/build/debug -s /work/src/YourProject/XYZ -c modernize-use-using -c modernize-use-override`\r\n\r\nIn the call above, the folder `/work/build/debug` is where the build folder in this example. Also note that multiple checks can be queued. If you want the script to cancel if something fails, then add `-stop-on-error`.\r\n\r\n\r\n## clazy\r\n[This is a project](https://github.com/KDE/clazy) I recently stumbled upon. It is built on clang-tidy/llvm tooling to perform static checks on Qt4/Qt5 code.\r\nA nice summary of some of these checks that help to avoid typical issues with Qt signals and slots is given [here](https://www.kdab.com/nailing-13-signal-slot-mistakes-clazy-1-3/).\r\n\r\n\r\n## Other scripts to replace legacy code\r\nSince large parts of our code is only built with msvc14 (VS 20215), and we use precompiled headers, clang-tidy was not always successful at providing fixits. Therefore, I created collection of python scripts to modernize our code, and e.g. reduce depedencies on boost where c++11 provides an alternative. The basic logic is implemented in [replace_expression.py](replace_scripts/replace_expression.py)\r\n\r\n- replace_boost_foreach.py\r\n  - replaces BOOST_FOREACH if on a single line\r\n  - removes header\r\n  - skips removing header in files with `BOOST_REVERSE_FOREACH`\r\n- replace_lexical_cast.py:\r\n  - replaces `boost::lexical_cast\u003cstd::string\u003e` by `std::to_string`\r\n  - removes unused header\r\n- replace_typedef_with_using.py\r\n  - transforms `typedef x::y::z\u003cT\u003e xyz_t` to `using xyz_t = x::y::z\u003cT\u003e`\r\n  - skips multiline typedefs and function pointer-like typedefs\r\n- replace_incorrect_include_capitalization.py\r\n  - tries to fix incorrect spelling of headers (relative paths only)\r\n- replace_assign_list_of.py\r\n  - replaces `boost::assign::list_of(X)(Y)` by `{ X, Y }`\r\n- replace_null.py\r\n  - finds typical context where `NULL` is used and replaces it by `nullptr`\r\n- etc.\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyollb%2Fmodernize_cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdyollb%2Fmodernize_cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyollb%2Fmodernize_cpp/lists"}