Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env python32#3# ===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#4#5# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.6# See https://llvm.org/LICENSE.txt for license information.7# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception8#9# ===------------------------------------------------------------------------===#11"""12This script reads input from a unified diff and reformats all the changed13lines. This is useful to reformat all the lines touched by a specific patch.14Example usage for git/svn users:16git diff -U0 --no-color --relative HEAD^ | {clang_format_diff} -p1 -i17svn diff --diff-cmd=diff -x-U0 | {clang_format_diff} -i19It should be noted that the filename contained in the diff is used unmodified20to determine the source file to update. Users calling this script directly21should be careful to ensure that the path in the diff is correct relative to the22current working directory.23"""24from __future__ import absolute_import, division, print_function26import argparse27import difflib28import re29import subprocess30import sys32from io import StringIO35def main():36parser = argparse.ArgumentParser(37description=__doc__.format(clang_format_diff="%(prog)s"),38formatter_class=argparse.RawDescriptionHelpFormatter,39)40parser.add_argument(41"-i",42action="store_true",43default=False,44help="apply edits to files instead of displaying a diff",45)46parser.add_argument(47"-p",48metavar="NUM",49default=0,50help="strip the smallest prefix containing P slashes",51)52parser.add_argument(53"-regex",54metavar="PATTERN",55default=None,56help="custom pattern selecting file paths to reformat "57"(case sensitive, overrides -iregex)",58)59parser.add_argument(60"-iregex",61metavar="PATTERN",62default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"63r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|s?vh?)",64help="custom pattern selecting file paths to reformat "65"(case insensitive, overridden by -regex)",66)67parser.add_argument(68"-sort-includes",69action="store_true",70default=False,71help="let clang-format sort include blocks",72)73parser.add_argument(74"-v",75"--verbose",76action="store_true",77help="be more verbose, ineffective without -i",78)79parser.add_argument(80"-style",81help="formatting style to apply (LLVM, GNU, Google, Chromium, "82"Microsoft, Mozilla, WebKit)",83)84parser.add_argument(85"-fallback-style",86help="The name of the predefined style used as a"87"fallback in case clang-format is invoked with"88"-style=file, but can not find the .clang-format"89"file to use.",90)91parser.add_argument(92"-binary",93default="clang-format",94help="location of binary to use for clang-format",95)96args = parser.parse_args()98# Extract changed lines for each file.99filename = None100lines_by_file = {}101for line in sys.stdin:102match = re.search(r"^\+\+\+\ (.*?/){%s}(\S*)" % args.p, line)103if match:104filename = match.group(2)105if filename is None:106continue108if args.regex is not None:109if not re.match("^%s$" % args.regex, filename):110continue111else:112if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):113continue115match = re.search(r"^@@.*\+(\d+)(?:,(\d+))?", line)116if match:117start_line = int(match.group(1))118line_count = 1119if match.group(2):120line_count = int(match.group(2))121# The input is something like122#123# @@ -1, +0,0 @@124#125# which means no lines were added.126if line_count == 0:127continue128# Also format lines range if line_count is 0 in case of deleting129# surrounding statements.130end_line = start_line131if line_count != 0:132end_line += line_count - 1133lines_by_file.setdefault(filename, []).extend(134["-lines", str(start_line) + ":" + str(end_line)]135)137# Reformat files containing changes in place.138for filename, lines in lines_by_file.items():139if args.i and args.verbose:140print("Formatting {}".format(filename))141command = [args.binary, filename]142if args.i:143command.append("-i")144if args.sort_includes:145command.append("-sort-includes")146command.extend(lines)147if args.style:148command.extend(["-style", args.style])149if args.fallback_style:150command.extend(["-fallback-style", args.fallback_style])152try:153p = subprocess.Popen(154command,155stdout=subprocess.PIPE,156stderr=None,157stdin=subprocess.PIPE,158universal_newlines=True,159)160except OSError as e:161# Give the user more context when clang-format isn't162# found/isn't executable, etc.163raise RuntimeError(164'Failed to run "%s" - %s"' % (" ".join(command), e.strerror)165)167stdout, _stderr = p.communicate()168if p.returncode != 0:169sys.exit(p.returncode)171if not args.i:172with open(filename) as f:173code = f.readlines()174formatted_code = StringIO(stdout).readlines()175diff = difflib.unified_diff(176code,177formatted_code,178filename,179filename,180"(before formatting)",181"(after formatting)",182)183diff_string = "".join(diff)184if len(diff_string) > 0:185sys.stdout.write(diff_string)186sys.exit(1)189if __name__ == "__main__":190main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.