From cd60bb8f2dff9df169526ed8fab80eb90106083e Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 29 Aug 2024 08:55:43 +1000 Subject: [PATCH] Port doxygen_space to python --- scripts/astyle.sh | 2 +- scripts/doxygen_space.py | 156 ++++++++++++++++++ ...{doxygen_space.pl => old_doxygen_space.pl} | 0 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100755 scripts/doxygen_space.py rename scripts/{doxygen_space.pl => old_doxygen_space.pl} (100%) diff --git a/scripts/astyle.sh b/scripts/astyle.sh index 602428c7354..414a7f4fb3f 100755 --- a/scripts/astyle.sh +++ b/scripts/astyle.sh @@ -102,7 +102,7 @@ astyleit() { modified=$1.unify_includes_modified cp "$1" "$modified" perl -i.sortinc -n scripts/unify_includes.pl "$modified" - scripts/doxygen_space.pl "$modified" + scripts/doxygen_space.py "$modified" diff "$1" "$modified" >/dev/null || mv "$modified" "$1" rm -f "$modified" } diff --git a/scripts/doxygen_space.py b/scripts/doxygen_space.py new file mode 100755 index 00000000000..d7e92fbf31d --- /dev/null +++ b/scripts/doxygen_space.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 + +########################################################################### +# doxygen_space.pl +# --------------------- +# begin : October 2016 +# copyright : (C) 2016 by Nyall Dawson +# email : nyall dot dawson at gmail dot com +# +########################################################################### +# # +# 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. # +# # +########################################################################### +import sys +import re + + +def process_file(file_path): + with open(file_path, 'r') as file: + input_lines = file.readlines() + + output = [] + inside_dox_block = False + inside_dox_list = False + previous_was_blankline = False + previous_was_dox_blankline = False + just_finished_a_list = False + buffered_line = '' + + i = 0 + while i < len(input_lines): + line = input_lines[i].rstrip() + is_blank_line = not line.strip() + + if re.match(r'^\s*(?:#ifdef|#ifndef|#else|#endif)', line): + output.append(line) + elif match := re.match(r'^(\s*)//!\s*(.*?)$', line): + indentation, comment = match.groups() + # found a //! comment + # check next line to see if it also begins with //! + if i + 1 < len(input_lines) and re.match(r'^\s*//!\s*(.*?)$', + input_lines[i + 1]): + # we are in a multiline //! comment block, convert to /** block + if not previous_was_blankline: + output.append('') + output.append(f"{indentation}/**") + output.append(f"{indentation} * {comment}") + while i + 1 < len(input_lines) and ( + next_match := re.match(r'^\s*//!\s*(.*?)$', + input_lines[i + 1])): + next_comment = next_match.group(1) + if next_comment: + output.append(f"{indentation} * {next_comment}") + else: + output.append(f"{indentation} *") + i += 1 + output.append(f"{indentation} */") + else: + output.append(line) + elif inside_dox_block: + # replace "* abc" style doxygen lists with correct "- abc" formatting + line = re.sub(r'^(\s+)\*\s{1,10}\*', r'\1* -', line) + + if re.match(r'^\s*\*\s*$', line): + previous_was_dox_blankline = True + if inside_dox_list: + inside_dox_list = False + just_finished_a_list = True + buffered_line = line + # print("end list") + else: + output.append(line) + elif match := re.match(r'^(\s*)\*\s*-(?![-\d>]) *(.*)$', + line): + indent, content = match.groups() + if not inside_dox_list and not previous_was_dox_blankline: + output.append(f"{indent}*") + if just_finished_a_list: + # print("just finished a list, continuing the same one!!") + buffered_line = "" + # print("start list") + output.append(f"{indent}* - {content}") + inside_dox_list = True + just_finished_a_list = False + elif inside_dox_list and ( + match := re.match(r'^(\s*)\*\s{2,}(.*)$', line)): + # print("list continuation") + indent, content = match.groups() + output.append(f"{indent}* {content}") + elif inside_dox_list and (match := re.match(r'^(\s*)\*(?!/)', line)): + inside_dox_list = False + indent = match.group(1) + # print("end list without line break") + output.append(f"{indent}*") + output.append(line) + just_finished_a_list = True + elif re.match(r'^(\s*)\*/\s*$', line): + inside_dox_block = False + inside_dox_list = False + just_finished_a_list = False + if buffered_line: + output.append(buffered_line) + buffered_line = '' + output.append(line) + # print("end_block") + else: + if buffered_line: + output.append(buffered_line) + buffered_line = '' + + if not re.match(r'^\s*[#*]', line) and ( + match := re.match(r'^(\s*?)(\s?)(.+?)$', line)): + indent, space, content = match.groups() + line = f"{indent}* {content}" + + output.append(line) + # print("normal dox") + previous_was_dox_blankline = False + just_finished_a_list = False + elif (match := re.match(r'^(\s*)/\*\*(?!\*)\s*(.*)$', line)): + indent, content = match.groups() + # Space around doxygen start blocks (force blank line before /**) + if not previous_was_blankline: + output.append('') + if content: + # new line after /** begin block + output.append(f"{indent}/**") + output.append(f"{indent} * {content}") + else: + output.append(line) + inside_dox_block = True + # print("start_block") + else: + if buffered_line: + output.append(buffered_line) + buffered_line = '' + output.append(line) + + i += 1 + previous_was_blankline = is_blank_line + + with open(file_path, 'w') as file: + file.write('\n'.join(output) + '\n') + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python doxygen_space.py ") + sys.exit(1) + + file_path = sys.argv[1] + process_file(file_path) diff --git a/scripts/doxygen_space.pl b/scripts/old_doxygen_space.pl similarity index 100% rename from scripts/doxygen_space.pl rename to scripts/old_doxygen_space.pl