From 586da70a5ad7c40398a02a06bcf989752a53d4ff Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Mon, 20 Nov 2023 10:45:32 +0200
Subject: Added the script for adjusting XUI xml format

---
 scripts/code_tools/fix_xml_indentations.py | 82 ++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 scripts/code_tools/fix_xml_indentations.py

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_xml_indentations.py b/scripts/code_tools/fix_xml_indentations.py
new file mode 100644
index 0000000000..03cf980247
--- /dev/null
+++ b/scripts/code_tools/fix_xml_indentations.py
@@ -0,0 +1,82 @@
+import os
+import sys
+import glob
+import io
+import xml.etree.ElementTree as ET
+
+def parse_xml_file(file_path):
+    try:
+        tree = ET.parse(file_path)
+        return tree
+    except ET.ParseError as e:
+        print(f"Error parsing XML file {file_path}: {e}")
+        return None
+
+def indent(elem, level=0, indent_text=False, indent_tab=False):
+    indent_string = "\t" if indent_tab else "  "
+    i = "\n" + level * indent_string
+    if len(elem):
+        if not elem.text or not elem.text.strip():
+            elem.text = i + indent_string
+        if not elem.tail or not elem.tail.strip():
+            elem.tail = i
+        for elem in elem:
+            indent(elem, level + 1, indent_text, indent_tab)
+        if not elem.tail or not elem.tail.strip():
+            elem.tail = i
+    else:
+        if level and (not elem.tail or not elem.tail.strip()):
+            elem.tail = i
+        if indent_text and elem.text and not elem.text.isspace():
+            elem.text = "\n" + (level + 1) * indent_string + elem.text.strip() + "\n" + level * indent_string
+
+def save_xml(tree, file_path, indent_text=False, indent_tab=False, rm_space=False):
+    if tree is not None:
+        root = tree.getroot()
+        indent(root, indent_text=indent_text, indent_tab=indent_tab)
+        xml_string = ET.tostring(root, encoding='unicode')
+        if rm_space:
+            xml_string = xml_string.replace(' />', '/>')
+        try:
+            with io.open(file_path, 'wb') as file:
+                file.write('<?xml version="1.0" encoding="utf-8" standalone="yes"?>\n'.encode('utf-8'))
+                file.write(xml_string.encode('utf-8'))
+        except IOError as e:
+            print(f"Error saving file {file_path}: {e}")
+
+def process_directory(directory_path, indent_text=False, indent_tab=False, rm_space=False):
+    if not os.path.isdir(directory_path):
+        print(f"Directory not found: {directory_path}")
+        return
+
+    xml_files = glob.glob(os.path.join(directory_path, "*.xml"))
+    if not xml_files:
+        print(f"No XML files found in directory: {directory_path}")
+        return
+
+    for file_path in xml_files:
+        tree = parse_xml_file(file_path)
+        if tree is not None:
+            save_xml(tree, file_path, indent_text, indent_tab, rm_space)
+
+
+if __name__ == "__main__":
+    if len(sys.argv) < 2 or '--help' in sys.argv:
+        print("XML Formatter Script")
+        print("This script formats XML files in a given directory with options for indentation and space removal.")
+        print("\nUsage:")
+        print("  python script_name.py <path/to/directory> [options]")
+        print("\nOptions:")
+        print("  --indent-text    Indents text within XML tags.")
+        print("  --indent-tab     Uses tabs instead of spaces for indentation.")
+        print("  --rm-space       Removes spaces in self-closing tags.")
+        print("\nCommon Usage:")
+        print("  To format XML files with text indentation, tab indentation, and removal of spaces in self-closing tags:")
+        print("  python script_name.py /path/to/xmls --indent-text --indent-tab --rm-space")
+        sys.exit(1)
+
+    directory_path = sys.argv[1]
+    indent_text = '--indent-text' in sys.argv
+    indent_tab = '--indent-tab' in sys.argv
+    rm_space = '--rm-space' in sys.argv
+    process_directory(directory_path, indent_text, indent_tab, rm_space)
-- 
cgit v1.2.3


From 2c93819d27f56a6628e20d959828b7afdf510782 Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Tue, 21 Nov 2023 00:16:33 +0200
Subject: XML formatter script - added license

---
 scripts/code_tools/fix_xml_indentations.py | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_xml_indentations.py b/scripts/code_tools/fix_xml_indentations.py
index 03cf980247..46f7931589 100644
--- a/scripts/code_tools/fix_xml_indentations.py
+++ b/scripts/code_tools/fix_xml_indentations.py
@@ -1,3 +1,31 @@
+#!/usr/bin/env python3
+"""\
+
+This script formats XML files in a given directory with options for indentation and space removal.
+
+$LicenseInfo:firstyear=2023&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2023, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
+
+
 import os
 import sys
 import glob
-- 
cgit v1.2.3


From 6e63fe32efd4336995720f43de4ba7110f69c09f Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Fri, 24 Nov 2023 09:40:27 +0200
Subject: XML formatter script - added control for the declaration tag

---
 scripts/code_tools/fix_xml_indentations.py | 39 +++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 11 deletions(-)

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_xml_indentations.py b/scripts/code_tools/fix_xml_indentations.py
index 46f7931589..c0661dd975 100644
--- a/scripts/code_tools/fix_xml_indentations.py
+++ b/scripts/code_tools/fix_xml_indentations.py
@@ -25,13 +25,19 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 $/LicenseInfo$
 """
 
-
 import os
 import sys
 import glob
 import io
 import xml.etree.ElementTree as ET
 
+def get_xml_declaration(file_path):
+    with open(file_path, 'r', encoding='utf-8') as file:
+        first_line = file.readline().strip()
+        if first_line.startswith('<?xml'):
+            return first_line
+    return None
+
 def parse_xml_file(file_path):
     try:
         tree = ET.parse(file_path)
@@ -58,21 +64,31 @@ def indent(elem, level=0, indent_text=False, indent_tab=False):
         if indent_text and elem.text and not elem.text.isspace():
             elem.text = "\n" + (level + 1) * indent_string + elem.text.strip() + "\n" + level * indent_string
 
-def save_xml(tree, file_path, indent_text=False, indent_tab=False, rm_space=False):
+def save_xml(tree, file_path, xml_decl, indent_text=False, indent_tab=False, rm_space=False, rewrite_decl=False):
     if tree is not None:
         root = tree.getroot()
         indent(root, indent_text=indent_text, indent_tab=indent_tab)
         xml_string = ET.tostring(root, encoding='unicode')
         if rm_space:
             xml_string = xml_string.replace(' />', '/>')
+
+        xml_decl = (
+            xml_decl if (xml_decl and not rewrite_decl) else (
+                '<?xml version="1.0" encoding="utf-8" standalone="yes"?>'
+                if rm_space else
+                '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>'
+            )
+        )
+
         try:
             with io.open(file_path, 'wb') as file:
-                file.write('<?xml version="1.0" encoding="utf-8" standalone="yes"?>\n'.encode('utf-8'))
+                file.write(xml_decl.encode('utf-8'))
+                file.write('\n'.encode('utf-8'))
                 file.write(xml_string.encode('utf-8'))
         except IOError as e:
             print(f"Error saving file {file_path}: {e}")
 
-def process_directory(directory_path, indent_text=False, indent_tab=False, rm_space=False):
+def process_directory(directory_path, indent_text=False, indent_tab=False, rm_space=False, rewrite_decl=False):
     if not os.path.isdir(directory_path):
         print(f"Directory not found: {directory_path}")
         return
@@ -83,28 +99,29 @@ def process_directory(directory_path, indent_text=False, indent_tab=False, rm_sp
         return
 
     for file_path in xml_files:
+        xml_decl = get_xml_declaration(file_path)
         tree = parse_xml_file(file_path)
         if tree is not None:
-            save_xml(tree, file_path, indent_text, indent_tab, rm_space)
-
+            save_xml(tree, file_path, xml_decl, indent_text, indent_tab, rm_space, rewrite_decl)
 
 if __name__ == "__main__":
     if len(sys.argv) < 2 or '--help' in sys.argv:
-        print("XML Formatter Script")
-        print("This script formats XML files in a given directory with options for indentation and space removal.")
+        print("This script formats XML files in a given directory. Useful to fix XUI XMLs after processing by other tools.")
         print("\nUsage:")
-        print("  python script_name.py <path/to/directory> [options]")
+        print("  python fix_xml_indentations.py <path/to/directory> [options]")
         print("\nOptions:")
         print("  --indent-text    Indents text within XML tags.")
         print("  --indent-tab     Uses tabs instead of spaces for indentation.")
         print("  --rm-space       Removes spaces in self-closing tags.")
+        print("  --rewrite_decl   Replaces the XML declaration line.")
         print("\nCommon Usage:")
         print("  To format XML files with text indentation, tab indentation, and removal of spaces in self-closing tags:")
-        print("  python script_name.py /path/to/xmls --indent-text --indent-tab --rm-space")
+        print("  python fix_xml_indentations.py /path/to/xmls --indent-text --indent-tab --rm-space")
         sys.exit(1)
 
     directory_path = sys.argv[1]
     indent_text = '--indent-text' in sys.argv
     indent_tab = '--indent-tab' in sys.argv
     rm_space = '--rm-space' in sys.argv
-    process_directory(directory_path, indent_text, indent_tab, rm_space)
+    rewrite_decl = '--rewrite_decl' in sys.argv
+    process_directory(directory_path, indent_text, indent_tab, rm_space, rewrite_decl)
-- 
cgit v1.2.3


From 9bf5ad98e508690efd334806885b6d1666bee602 Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Fri, 24 Nov 2023 09:49:19 +0200
Subject: XML formatter script - simplify the default declaration

---
 scripts/code_tools/fix_xml_indentations.py | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_xml_indentations.py b/scripts/code_tools/fix_xml_indentations.py
index c0661dd975..019f6db23c 100644
--- a/scripts/code_tools/fix_xml_indentations.py
+++ b/scripts/code_tools/fix_xml_indentations.py
@@ -72,13 +72,8 @@ def save_xml(tree, file_path, xml_decl, indent_text=False, indent_tab=False, rm_
         if rm_space:
             xml_string = xml_string.replace(' />', '/>')
 
-        xml_decl = (
-            xml_decl if (xml_decl and not rewrite_decl) else (
-                '<?xml version="1.0" encoding="utf-8" standalone="yes"?>'
-                if rm_space else
-                '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>'
-            )
-        )
+        xml_decl = (xml_decl if (xml_decl and not rewrite_decl) 
+                    else '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>')
 
         try:
             with io.open(file_path, 'wb') as file:
-- 
cgit v1.2.3


From 65eec6d2172845de81a3da7ec0fdf63d2ec1897f Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Thu, 18 Jan 2024 23:30:43 +0200
Subject: XML formatting tool - add LF before EOF

---
 scripts/code_tools/fix_xml_indentations.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_xml_indentations.py b/scripts/code_tools/fix_xml_indentations.py
index 019f6db23c..9c8a1fc04b 100644
--- a/scripts/code_tools/fix_xml_indentations.py
+++ b/scripts/code_tools/fix_xml_indentations.py
@@ -79,7 +79,10 @@ def save_xml(tree, file_path, xml_decl, indent_text=False, indent_tab=False, rm_
             with io.open(file_path, 'wb') as file:
                 file.write(xml_decl.encode('utf-8'))
                 file.write('\n'.encode('utf-8'))
-                file.write(xml_string.encode('utf-8'))
+                if xml_string:
+                    file.write(xml_string.encode('utf-8'))
+                    if not xml_string.endswith('\n'):
+                        file.write('\n'.encode('utf-8'))
         except IOError as e:
             print(f"Error saving file {file_path}: {e}")
 
-- 
cgit v1.2.3


From af4ea94efc1999f3b19fd8d643d0331f0b77e265 Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Mon, 29 Apr 2024 06:59:10 +0300
Subject: #824 Add a script to convert tabs to spaces in the code files

---
 scripts/code_tools/fix_whitespace.py | 83 ++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 scripts/code_tools/fix_whitespace.py

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_whitespace.py b/scripts/code_tools/fix_whitespace.py
new file mode 100644
index 0000000000..1c2ba00bb3
--- /dev/null
+++ b/scripts/code_tools/fix_whitespace.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+"""\
+
+This script replaces tab characters with spaces in source code files.
+
+$LicenseInfo:firstyear=2024&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2024, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
+
+import argparse
+import os
+
+def convert_tabs_to_spaces(file_path, tab_stop):
+    """Convert tabs in a file to spaces, considering tab stops."""
+    with open(file_path, 'r') as file:
+        lines = file.readlines()
+
+    new_lines = []
+    for line in lines:
+        # Remove trailing spaces
+        line = line.rstrip()
+        new_line = ''
+        column = 0  # Track the column index for calculating tab stops
+        for char in line:
+            if char == '\t':
+                # Calculate spaces needed to reach the next tab stop
+                spaces_needed = tab_stop - (column % tab_stop)
+                new_line += ' ' * spaces_needed
+                column += spaces_needed
+            else:
+                new_line += char
+                column += 1
+
+        new_lines.append(new_line + '\n')
+
+    with open(file_path, 'w') as file:
+        file.writelines(new_lines)
+
+def process_directory(directory, extensions, tab_stop):
+    """Recursively process files in directory, considering tab stops."""
+    extensions = tuple(extensions)
+    for root, dirs, files in os.walk(directory):
+        for file in files:
+            if file.endswith(extensions):
+                file_path = os.path.join(root, file)
+                print(f"Processing {file_path}")
+                convert_tabs_to_spaces(file_path, tab_stop)
+
+def main():
+    parser = argparse.ArgumentParser(description='Convert tabs to spaces in files, considering tab stops.')
+    parser.add_argument('-e', '--extensions', type=str, default='cpp,h,hpp,inl,cmake', help='Comma-separated list of file extensions to process (default: "cpp,h,hpp,inl,cmake")')
+    parser.add_argument('-t', '--tabstop', type=int, default=4, help='Tab stop size (default: 4)')
+    parser.add_argument('-d', '--directory', type=str, required=True, help='Directory to process')
+
+    args = parser.parse_args()
+
+    extensions = args.extensions.split(',')
+    # Add a dot prefix to each extension if not present
+    extensions = [ext if ext.startswith('.') else f".{ext}" for ext in extensions]
+
+    process_directory(args.directory, extensions, args.tabstop)
+    print("Processing completed.")
+
+if __name__ == "__main__":
+    main()
-- 
cgit v1.2.3


From d48497268eef5738e2af8549d8962b281c6b4c71 Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Wed, 1 May 2024 07:37:52 +0300
Subject: #824 Add c,py,glsl to the script's default file types

---
 scripts/code_tools/fix_whitespace.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_whitespace.py b/scripts/code_tools/fix_whitespace.py
index 1c2ba00bb3..37e15c6d10 100644
--- a/scripts/code_tools/fix_whitespace.py
+++ b/scripts/code_tools/fix_whitespace.py
@@ -66,7 +66,7 @@ def process_directory(directory, extensions, tab_stop):
 
 def main():
     parser = argparse.ArgumentParser(description='Convert tabs to spaces in files, considering tab stops.')
-    parser.add_argument('-e', '--extensions', type=str, default='cpp,h,hpp,inl,cmake', help='Comma-separated list of file extensions to process (default: "cpp,h,hpp,inl,cmake")')
+    parser.add_argument('-e', '--extensions', type=str, default='c,cpp,h,hpp,inl,py,glsl,cmake', help='Comma-separated list of file extensions to process (default: "c,cpp,h,hpp,inl,py,glsl,cmake")')
     parser.add_argument('-t', '--tabstop', type=int, default=4, help='Tab stop size (default: 4)')
     parser.add_argument('-d', '--directory', type=str, required=True, help='Directory to process')
 
-- 
cgit v1.2.3


From e7eced3c87310b15ac20cc3cd470d67686104a14 Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Wed, 1 May 2024 07:58:22 +0300
Subject: #824 Don't fix tabs in files with no tabs

---
 scripts/code_tools/fix_whitespace.py | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'scripts')

diff --git a/scripts/code_tools/fix_whitespace.py b/scripts/code_tools/fix_whitespace.py
index 37e15c6d10..91e82f26f4 100644
--- a/scripts/code_tools/fix_whitespace.py
+++ b/scripts/code_tools/fix_whitespace.py
@@ -33,6 +33,10 @@ def convert_tabs_to_spaces(file_path, tab_stop):
     with open(file_path, 'r') as file:
         lines = file.readlines()
 
+    # Skip files with no tabs
+    if not any('\t' in line for line in lines):
+        return
+
     new_lines = []
     for line in lines:
         # Remove trailing spaces
-- 
cgit v1.2.3