diff --git a/utils_maintenance/c_struct_clean.py b/utils_maintenance/c_struct_clean.py new file mode 100755 index 0000000000000000000000000000000000000000..e327ad867c7a7ba14130605da79a0db9c203630e --- /dev/null +++ b/utils_maintenance/c_struct_clean.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 + +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program 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 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +""" +When a source file declares a struct which isn't used anywhere else in the file. +Remove it. + +There may be times this is needed, however there can typically be removed. +""" + +import os +import sys +import re + +PWD = os.path.dirname(__file__) +sys.path.append(os.path.join(PWD, "modules")) + +from batch_edit_text import run + +SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", "..", "..")))) + +# TODO, move to config file +SOURCE_DIRS = ( + "source", + "intern/ghost", +) + +SOURCE_EXT = ( + # C/C++ + ".c", ".h", ".cpp", ".hpp", ".cc", ".hh", ".cxx", ".hxx", ".inl", + # Objective C + ".m", ".mm", +) + +re_words = re.compile("[A-Za-z_][A-Za-z_0-9]*") +re_match_struct = re.compile(r"struct\s+([A-Za-z_][A-Za-z_0-9]*)\s*;") + +def clean_structs(fn, data_src): + import re + + word_occurance = {} + for w in re_words.finditer(data_src): + w = w.group(0) + try: + word_occurance[w] += 1 + except KeyError: + word_occurance[w] = 1 + + lines = data_src.splitlines(keepends=True) + + i = 0 + while i < len(lines): + m = re_match_struct.match(lines[i]) + if m is not None: + struct_name = m.group(1) + if word_occurance[struct_name] == 1: + print(struct_name, fn) + del lines[i] + i -= 1 + + i += 1 + + data_dst = "".join(lines) + if data_src != data_dst: + return data_dst + +run( + directories=[os.path.join(SOURCE_DIR, d) for d in SOURCE_DIRS], + is_text=lambda fn: fn.endswith(SOURCE_EXT), + text_operation=clean_structs, + use_multiprocess=False, +)