mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
29abd09a74
These Python scripts have "*/" at the end of the license header comment blocks, presumably copy&pasted from C files. contrib/ChangeLog: * analyze_brprob.py: Remove stray text at end of comment. * analyze_brprob_spec.py: Likewise. * check-params-in-docs.py: Likewise. * check_GNU_style.py: Likewise. * check_GNU_style_lib.py: Likewise. * filter-clang-warnings.py: Likewise. * gcc-changelog/git_check_commit.py: Likewise. * gcc-changelog/git_commit.py: Likewise. * gcc-changelog/git_email.py: Likewise. * gcc-changelog/git_repository.py: Likewise. * gcc-changelog/git_update_version.py: Likewise. * gcc-changelog/test_email.py: Likewise. * gen_autofdo_event.py: Likewise. * mark_spam.py: Likewise. * unicode/gen-box-drawing-chars.py: Likewise. * unicode/gen-combining-chars.py: Likewise. * unicode/gen-printable-chars.py: Likewise. * unicode/gen_wcwidth.py: Likewise.
145 lines
4.7 KiB
Python
Executable File
145 lines
4.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright (C) 2020-2024 Free Software Foundation, Inc.
|
|
#
|
|
# This file is part of GCC.
|
|
#
|
|
# GCC is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free
|
|
# Software Foundation; either version 3, or (at your option) any later
|
|
# version.
|
|
#
|
|
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
# for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with GCC; see the file COPYING3. If not see
|
|
# <http://www.gnu.org/licenses/>.
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
from itertools import takewhile
|
|
|
|
from dateutil.parser import parse
|
|
|
|
from git_commit import GitCommit, GitInfo, decode_path
|
|
|
|
from unidiff import PatchSet, PatchedFile
|
|
|
|
DATE_PREFIX = 'Date: '
|
|
FROM_PREFIX = 'From: '
|
|
SUBJECT_PREFIX = 'Subject: '
|
|
subject_patch_regex = re.compile(r'^\[PATCH( \d+/\d+)?\] ')
|
|
unidiff_supports_renaming = hasattr(PatchedFile(), 'is_rename')
|
|
|
|
|
|
class GitEmail(GitCommit):
|
|
def __init__(self, filename):
|
|
self.filename = filename
|
|
date = None
|
|
author = None
|
|
subject = ''
|
|
|
|
subject_last = False
|
|
with open(self.filename, newline='\n') as f:
|
|
data = f.read()
|
|
diff = PatchSet(data)
|
|
lines = data.splitlines()
|
|
lines = list(takewhile(lambda line: line != '---', lines))
|
|
for line in lines:
|
|
if line.startswith(DATE_PREFIX):
|
|
date = parse(line[len(DATE_PREFIX):])
|
|
elif line.startswith(FROM_PREFIX):
|
|
author = GitCommit.format_git_author(line[len(FROM_PREFIX):])
|
|
elif line.startswith(SUBJECT_PREFIX):
|
|
subject = line[len(SUBJECT_PREFIX):]
|
|
subject_last = True
|
|
elif subject_last and line.startswith(' '):
|
|
subject += line
|
|
elif line == '':
|
|
break
|
|
else:
|
|
subject_last = False
|
|
|
|
if subject:
|
|
subject = subject_patch_regex.sub('', subject)
|
|
header = list(takewhile(lambda line: line != '', lines))
|
|
# Note: commit message consists of email subject, empty line, email body
|
|
message = [subject] + lines[len(header):]
|
|
|
|
modified_files = []
|
|
for f in diff:
|
|
# Strip "a/" and "b/" prefixes
|
|
source = decode_path(f.source_file)[2:]
|
|
target = decode_path(f.target_file)[2:]
|
|
|
|
if f.is_added_file:
|
|
t = 'A'
|
|
elif f.is_removed_file:
|
|
t = 'D'
|
|
elif unidiff_supports_renaming and f.is_rename:
|
|
# Consider that renamed files are two operations: the deletion
|
|
# of the original name and the addition of the new one.
|
|
modified_files.append((source, 'D'))
|
|
t = 'A'
|
|
else:
|
|
t = 'M'
|
|
modified_files.append((target if t != 'D' else source, t))
|
|
git_info = GitInfo(None, date, author, message, modified_files)
|
|
super().__init__(git_info, commit_to_info_hook=None)
|
|
|
|
|
|
def show_help():
|
|
print("""usage: git_email.py [--help] [patch file ...]
|
|
|
|
Check git ChangeLog format of a patch
|
|
|
|
With zero arguments, process every patch file in the
|
|
./patches directory.
|
|
With one argument, process the named patch file.
|
|
|
|
Patch files must be in 'git format-patch' format.""")
|
|
sys.exit(0)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) == 2 and (sys.argv[1] == '-h' or sys.argv[1] == '--help'):
|
|
show_help()
|
|
|
|
if len(sys.argv) == 1:
|
|
allfiles = []
|
|
for root, _dirs, files in os.walk('patches'):
|
|
for f in files:
|
|
full = os.path.join(root, f)
|
|
allfiles.append(full)
|
|
|
|
success = 0
|
|
for full in sorted(allfiles):
|
|
email = GitEmail(full)
|
|
print(email.filename)
|
|
if email.success:
|
|
success += 1
|
|
print(' OK')
|
|
for warning in email.warnings:
|
|
print(' WARN: %s' % warning)
|
|
else:
|
|
for error in email.errors:
|
|
print(' ERR: %s' % error)
|
|
|
|
print()
|
|
print('Successfully parsed: %d/%d' % (success, len(allfiles)))
|
|
else:
|
|
email = GitEmail(sys.argv[1])
|
|
if email.success:
|
|
print('OK')
|
|
email.print_output()
|
|
email.print_warnings()
|
|
else:
|
|
if not email.info.lines:
|
|
print('Error: patch contains no parsed lines', file=sys.stderr)
|
|
email.print_errors()
|
|
sys.exit(1)
|