2023-02-21 16:39:58 +01:00
|
|
|
#!/usr/bin/env python3
|
2023-08-16 00:20:26 +10:00
|
|
|
# SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-06-14 23:06:58 +10:00
|
|
|
#
|
2023-02-21 16:39:58 +01:00
|
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
2025-01-04 20:27:07 +11:00
|
|
|
__all__ = (
|
|
|
|
|
"main",
|
|
|
|
|
)
|
|
|
|
|
|
2023-02-21 16:39:58 +01:00
|
|
|
import os
|
|
|
|
|
from os.path import join
|
|
|
|
|
|
2025-04-05 20:06:34 +11:00
|
|
|
from collections.abc import (
|
|
|
|
|
Callable,
|
|
|
|
|
Iterator,
|
|
|
|
|
Sequence,
|
|
|
|
|
)
|
|
|
|
|
|
2025-04-16 11:08:40 +10:00
|
|
|
from trailing_space_clean_config import PATHS
|
|
|
|
|
|
2023-02-21 16:39:58 +01:00
|
|
|
SOURCE_EXT = (
|
|
|
|
|
# C/C++
|
|
|
|
|
".c", ".h", ".cpp", ".hpp", ".cc", ".hh", ".cxx", ".hxx", ".inl",
|
|
|
|
|
# Objective C
|
|
|
|
|
".m", ".mm",
|
|
|
|
|
# GLSL
|
|
|
|
|
".glsl",
|
|
|
|
|
# Python
|
|
|
|
|
".py",
|
2025-02-02 13:56:48 +11:00
|
|
|
# TOML.
|
|
|
|
|
".toml",
|
2023-02-21 16:39:58 +01:00
|
|
|
# Text (also CMake)
|
|
|
|
|
".txt", ".cmake", ".rst",
|
|
|
|
|
# MS-Windows Scripts.
|
|
|
|
|
".bat", ".cmd",
|
2025-02-02 13:56:48 +11:00
|
|
|
# HTML, XML.
|
|
|
|
|
".html",
|
|
|
|
|
".xml",
|
2023-02-21 16:39:58 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2025-04-05 20:06:34 +11:00
|
|
|
def is_source(filename: str) -> bool:
|
2023-02-21 16:39:58 +01:00
|
|
|
return filename.endswith(SOURCE_EXT)
|
|
|
|
|
|
|
|
|
|
|
2025-04-05 20:06:34 +11:00
|
|
|
def path_iter(
|
|
|
|
|
path: str,
|
|
|
|
|
filename_check: Callable[[str], bool] | None = None,
|
|
|
|
|
) -> Iterator[str]:
|
2023-02-21 16:39:58 +01:00
|
|
|
for dirpath, dirnames, filenames in os.walk(path):
|
|
|
|
|
# skip ".git"
|
|
|
|
|
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
|
|
|
|
|
|
|
|
|
for filename in filenames:
|
|
|
|
|
if filename.startswith("."):
|
|
|
|
|
continue
|
|
|
|
|
filepath = join(dirpath, filename)
|
|
|
|
|
if filename_check is None or filename_check(filepath):
|
|
|
|
|
yield filepath
|
|
|
|
|
|
|
|
|
|
|
2025-04-05 20:06:34 +11:00
|
|
|
def path_expand(
|
|
|
|
|
paths: Sequence[str],
|
|
|
|
|
filename_check: Callable[[str], bool] | None = None,
|
|
|
|
|
) -> Iterator[str]:
|
2023-02-21 16:39:58 +01:00
|
|
|
for f in paths:
|
|
|
|
|
if not os.path.exists(f):
|
|
|
|
|
print("Missing:", f)
|
|
|
|
|
elif os.path.isdir(f):
|
|
|
|
|
yield from path_iter(f, filename_check)
|
|
|
|
|
else:
|
|
|
|
|
yield f
|
|
|
|
|
|
|
|
|
|
|
2025-04-05 20:06:34 +11:00
|
|
|
def rstrip_file(filename: str) -> tuple[str, ...]:
|
2023-02-21 16:39:58 +01:00
|
|
|
reports = []
|
|
|
|
|
with open(filename, "r", encoding="utf-8") as fh:
|
|
|
|
|
data_src = fh.read()
|
|
|
|
|
|
|
|
|
|
# Strip trailing space.
|
2025-04-05 20:06:34 +11:00
|
|
|
data_dst_list = []
|
2023-02-21 16:39:58 +01:00
|
|
|
for l in data_src.rstrip().splitlines(True):
|
2025-04-05 20:06:34 +11:00
|
|
|
data_dst_list.append(l.rstrip() + "\n")
|
2023-02-21 16:39:58 +01:00
|
|
|
|
2025-04-05 20:06:34 +11:00
|
|
|
data_dst = "".join(data_dst_list)
|
|
|
|
|
del data_dst_list
|
2023-02-21 16:39:58 +01:00
|
|
|
|
|
|
|
|
# Remove BOM.
|
|
|
|
|
if data_dst and (data_dst[0] == '\ufeff'):
|
|
|
|
|
data_dst = data_dst[1:]
|
|
|
|
|
|
|
|
|
|
len_strip = len(data_src) - len(data_dst)
|
|
|
|
|
if len_strip != 0:
|
2024-04-27 16:06:53 +10:00
|
|
|
reports.append("STRIP={:d}".format(len_strip))
|
2023-02-21 16:39:58 +01:00
|
|
|
|
|
|
|
|
if len_strip:
|
|
|
|
|
with open(filename, "w", encoding="utf-8") as fh:
|
|
|
|
|
fh.write(data_dst)
|
|
|
|
|
return tuple(reports)
|
|
|
|
|
|
|
|
|
|
|
2025-04-05 20:06:34 +11:00
|
|
|
def main() -> None:
|
2023-02-21 16:39:58 +01:00
|
|
|
for f in path_expand(PATHS, is_source):
|
|
|
|
|
report = rstrip_file(f)
|
|
|
|
|
if report:
|
2024-04-27 16:06:53 +10:00
|
|
|
print("Strip ({:s}): {:s}".format(', '.join(report), f))
|
2023-02-21 16:39:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|