Add Chromium-only Blender WebEngine parity work
This commit is contained in:
192
blender-5.2.0/tools/utils_ide/cmake_qtcreator_project.py
Executable file
192
blender-5.2.0/tools/utils_ide/cmake_qtcreator_project.py
Executable file
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2010-2022 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
r"""
|
||||
Example Linux usage:
|
||||
python ~/blender-git/blender/build_files/cmake/cmake_qtcreator_project.py --build-dir ~/blender-git/cmake
|
||||
|
||||
Example Win32 usage:
|
||||
c:\Python32\python.exe c:\blender_dev\blender\build_files\cmake\cmake_qtcreator_project.py --build-dir c:\blender_dev\cmake_build
|
||||
"""
|
||||
|
||||
__all__ = (
|
||||
"main",
|
||||
)
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
project_name_default = "Unknown"
|
||||
|
||||
|
||||
def quote_define(define: str) -> str:
|
||||
if " " in define.strip():
|
||||
return '"%s"' % define
|
||||
else:
|
||||
return define
|
||||
|
||||
|
||||
def create_qtc_project_main(name: str) -> None:
|
||||
from project_info import (
|
||||
SIMPLE_PROJECTFILE,
|
||||
SOURCE_DIR,
|
||||
# CMAKE_DIR,
|
||||
PROJECT_DIR,
|
||||
source_list,
|
||||
is_project_file,
|
||||
is_c_header,
|
||||
cmake_advanced_info,
|
||||
cmake_compiler_defines,
|
||||
project_name_get,
|
||||
)
|
||||
|
||||
files = list(source_list(SOURCE_DIR, filename_check=is_project_file))
|
||||
files_rel = [os.path.relpath(f, start=PROJECT_DIR) for f in files]
|
||||
files_rel.sort()
|
||||
|
||||
# --- qtcreator specific, simple format
|
||||
if SIMPLE_PROJECTFILE:
|
||||
# --- qtcreator specific, simple format
|
||||
PROJECT_NAME = name or project_name_default
|
||||
FILE_NAME = PROJECT_NAME.lower()
|
||||
with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
|
||||
f.write("\n".join(files_rel))
|
||||
|
||||
with open(os.path.join(PROJECT_DIR, "%s.includes" % FILE_NAME), 'w') as f:
|
||||
f.write("\n".join(sorted(list(set(os.path.dirname(f)
|
||||
for f in files_rel if is_c_header(f))))))
|
||||
|
||||
qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
|
||||
with open(qtc_prj, 'w') as f:
|
||||
f.write("[General]\n")
|
||||
|
||||
qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
|
||||
if not os.path.exists(qtc_cfg):
|
||||
with open(qtc_cfg, 'w') as f:
|
||||
f.write("// ADD PREDEFINED MACROS HERE!\n")
|
||||
else:
|
||||
if (includes_and_defines := cmake_advanced_info()) is None:
|
||||
return
|
||||
includes, defines = includes_and_defines
|
||||
|
||||
# for some reason it doesn't give all internal includes
|
||||
includes = list(
|
||||
set(includes) | {
|
||||
os.path.dirname(f)
|
||||
for f in files_rel if is_c_header(f)
|
||||
}
|
||||
)
|
||||
includes.sort()
|
||||
|
||||
# be tricky, get the project name from CMake if we can!
|
||||
PROJECT_NAME = name or project_name_get() or project_name_default
|
||||
|
||||
FILE_NAME = PROJECT_NAME.lower()
|
||||
with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
|
||||
f.write("\n".join(files_rel))
|
||||
|
||||
with open(os.path.join(PROJECT_DIR, "%s.includes" % FILE_NAME), 'w', encoding='utf-8') as f:
|
||||
f.write("\n".join(sorted(includes)))
|
||||
|
||||
qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
|
||||
with open(qtc_prj, 'w') as f:
|
||||
f.write("[General]\n")
|
||||
|
||||
qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
|
||||
with open(qtc_cfg, 'w') as f:
|
||||
f.write("// ADD PREDEFINED MACROS TO %s_custom.config!\n" % FILE_NAME)
|
||||
|
||||
qtc_custom_cfg = os.path.join(PROJECT_DIR, "%s_custom.config" % FILE_NAME)
|
||||
if os.path.exists(qtc_custom_cfg):
|
||||
with open(qtc_custom_cfg, 'r') as fc:
|
||||
f.write(fc.read())
|
||||
f.write("\n")
|
||||
|
||||
defines_final = [("#define %s %s" % (item[0], quote_define(item[1]))) for item in defines]
|
||||
if os.name != "nt":
|
||||
defines_final.extend(cmake_compiler_defines() or [])
|
||||
f.write("\n".join(defines_final))
|
||||
|
||||
print("Blender project file written to: %r" % qtc_prj)
|
||||
# --- end
|
||||
|
||||
|
||||
def create_qtc_project_python(name: str) -> None:
|
||||
from project_info import (
|
||||
SOURCE_DIR,
|
||||
# CMAKE_DIR,
|
||||
PROJECT_DIR,
|
||||
source_list,
|
||||
is_py,
|
||||
project_name_get,
|
||||
)
|
||||
|
||||
files = list(source_list(SOURCE_DIR, filename_check=is_py))
|
||||
files_rel = [os.path.relpath(f, start=PROJECT_DIR) for f in files]
|
||||
files_rel.sort()
|
||||
|
||||
# --- qtcreator specific, simple format
|
||||
# be tricky, get the project name from git if we can!
|
||||
PROJECT_NAME = (name or project_name_get() or project_name_default) + "_Python"
|
||||
|
||||
FILE_NAME = PROJECT_NAME.lower()
|
||||
with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
|
||||
f.write("\n".join(files_rel))
|
||||
|
||||
qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
|
||||
with open(qtc_prj, 'w') as f:
|
||||
f.write("[General]\n")
|
||||
|
||||
qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
|
||||
if not os.path.exists(qtc_cfg):
|
||||
with open(qtc_cfg, 'w') as f:
|
||||
f.write("// ADD PREDEFINED MACROS HERE!\n")
|
||||
|
||||
print("Python project file written to: %r" % qtc_prj)
|
||||
|
||||
|
||||
def argparse_create() -> argparse.ArgumentParser:
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="This script generates Qt Creator project files for Blender",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-n", "--name",
|
||||
dest="name",
|
||||
metavar='NAME', type=str,
|
||||
help="Override default project name (\"Blender\")",
|
||||
required=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-b", "--build-dir",
|
||||
dest="build_dir",
|
||||
metavar='BUILD_DIR', type=str,
|
||||
help="Specify the build path (or fallback to the $PWD)",
|
||||
required=False,
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse_create()
|
||||
args = parser.parse_args()
|
||||
name = args.name
|
||||
|
||||
import project_info
|
||||
if not project_info.init(args.build_dir):
|
||||
return 1
|
||||
|
||||
create_qtc_project_main(name)
|
||||
create_qtc_project_python(name)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
117
blender-5.2.0/tools/utils_ide/natvis/Blender.natvis
Normal file
117
blender-5.2.0/tools/utils_ide/natvis/Blender.natvis
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="blender::StringRef">
|
||||
<DisplayString>{data_,[size_]s} (size={size_})</DisplayString>
|
||||
</Type>
|
||||
<Type Name="blender::Vector<*>">
|
||||
<DisplayString>{{size={end_ - begin_}}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]" ExcludeView="simple"> end_ - begin_</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">capacity_end_ - begin_</Item>
|
||||
<ArrayItems>
|
||||
<Size>end_ - begin_</Size>
|
||||
<ValuePointer>begin_</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="blender::Span<*>">
|
||||
<DisplayString>{{size={size_ }}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]" ExcludeView="simple"> size_</Item>
|
||||
<ArrayItems>
|
||||
<Size>size_</Size>
|
||||
<ValuePointer>data_</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="blender::VecBase<*,3>">
|
||||
<DisplayString>{{x={x}, y={y}, z={z}}}</DisplayString>
|
||||
</Type>
|
||||
<Type Name="blender::Array<*>">
|
||||
<DisplayString>{{size={size_ }}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]" ExcludeView="simple"> size_</Item>
|
||||
<ArrayItems>
|
||||
<Size>size_</Size>
|
||||
<ValuePointer>data_</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<!-- visualizer for Map with pointer keys (IntrusiveMapSlot slot type) -->
|
||||
<Type Name="blender::Map<*>" Priority="MediumLow">
|
||||
<DisplayString>Size={occupied_and_removed_slots_ - removed_slots_}</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems MaxItemsPerView="5000">
|
||||
<Variable Name="slot" InitialValue="slots_.data_"/>
|
||||
<Variable Name="i" InitialValue="0"/>
|
||||
<Loop>
|
||||
<Break Condition="i >= occupied_and_removed_slots_ - removed_slots_"/>
|
||||
<If Condition="(uint64_t)slot->key_ < 0xfffffffffffffffe">
|
||||
<Item Name="{slot->key_}">slot->value_buffer_</Item>
|
||||
<Exec>++i</Exec>
|
||||
</If>
|
||||
<Exec>++slot</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<!-- visualizer for regular Map (SimpleMapSlot slot type) -->
|
||||
<Type Name="blender::Map<*>">
|
||||
<DisplayString>Size={occupied_and_removed_slots_ - removed_slots_}</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="slot" InitialValue="slots_.data_"/>
|
||||
<Variable Name="i" InitialValue="0"/>
|
||||
<Loop>
|
||||
<Item Condition="slot->state_ == 1" Name="{slot->key_buffer_}">slot->value_buffer_</Item>
|
||||
<Exec>++slot</Exec>
|
||||
<Exec>++i</Exec>
|
||||
<Break Condition="i > slots_.size_"/>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<!-- visualizer for Set with pointer keys (IntrusiveSetSlot slot type) -->
|
||||
<Type Name="blender::Set<*>" Priority="MediumLow">
|
||||
<DisplayString>Size={occupied_and_removed_slots_ - removed_slots_}</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems MaxItemsPerView="5000">
|
||||
<Variable Name="slot" InitialValue="slots_.data_"/>
|
||||
<Variable Name="i" InitialValue="0"/>
|
||||
<Loop>
|
||||
<Break Condition="i >= occupied_and_removed_slots_ - removed_slots_"/>
|
||||
<If Condition="(uint64_t)slot->key_ < 0xfffffffffffffffe">
|
||||
<Item Name="[{i}]">slot->key_</Item>
|
||||
<Exec>++i</Exec>
|
||||
</If>
|
||||
<Exec>++slot</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<!-- visualizer for regular Set (SimpleSetSlot slot type) -->
|
||||
<Type Name="blender::Set<*>">
|
||||
<DisplayString>Size={occupied_and_removed_slots_ - removed_slots_}</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="slot" InitialValue="slots_.data_"/>
|
||||
<Variable Name="i" InitialValue="0"/>
|
||||
<Loop>
|
||||
<Break Condition="i >= occupied_and_removed_slots_ - removed_slots_"/>
|
||||
<If Condition="slot->state_ == 1">
|
||||
<Item Name="[{i}]">slot->key_buffer_</Item>
|
||||
<Exec>++i</Exec>
|
||||
</If>
|
||||
<Exec>++slot</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="blender::TypedBuffer<*,*>">
|
||||
<DisplayString>{*($T1*)buffer_.buffer_.buffer_}</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>*($T1*)buffer_.buffer_.buffer_,nd</ExpandedItem>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
240
blender-5.2.0/tools/utils_ide/project_info.py
Executable file
240
blender-5.2.0/tools/utils_ide/project_info.py
Executable file
@@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2010-2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Module for accessing project file data for Blender.
|
||||
|
||||
Before use, call init(cmake_build_dir).
|
||||
"""
|
||||
|
||||
# TODO: Use CMAKE_EXPORT_COMPILE_COMMANDS (compile_commands.json)
|
||||
# Instead of Eclipse project format.
|
||||
|
||||
__all__ = (
|
||||
"SIMPLE_PROJECTFILE",
|
||||
"SOURCE_DIR",
|
||||
"CMAKE_DIR",
|
||||
"PROJECT_DIR",
|
||||
"source_list",
|
||||
"is_project_file",
|
||||
"is_c_header",
|
||||
"is_py",
|
||||
"cmake_advanced_info",
|
||||
"cmake_compiler_defines",
|
||||
"project_name_get",
|
||||
"init",
|
||||
)
|
||||
|
||||
from collections.abc import (
|
||||
Callable,
|
||||
Iterator,
|
||||
)
|
||||
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
from os.path import (
|
||||
abspath,
|
||||
dirname,
|
||||
exists,
|
||||
join,
|
||||
normpath,
|
||||
splitext,
|
||||
)
|
||||
|
||||
SOURCE_DIR = join(dirname(__file__), "..", "..")
|
||||
SOURCE_DIR = normpath(SOURCE_DIR)
|
||||
SOURCE_DIR = abspath(SOURCE_DIR)
|
||||
|
||||
SIMPLE_PROJECTFILE = False
|
||||
|
||||
# must initialize from 'init'
|
||||
CMAKE_DIR = ""
|
||||
PROJECT_DIR = ""
|
||||
|
||||
|
||||
def init(cmake_path: str) -> bool:
|
||||
global CMAKE_DIR, PROJECT_DIR
|
||||
|
||||
# get cmake path
|
||||
cmake_path = cmake_path or ""
|
||||
|
||||
if (not cmake_path) or (not exists(join(cmake_path, "CMakeCache.txt"))):
|
||||
cmake_path = os.getcwd()
|
||||
if not exists(join(cmake_path, "CMakeCache.txt")):
|
||||
print("CMakeCache.txt not found in %r or %r\n"
|
||||
" Pass CMake build dir as an argument, or run from that dir, aborting" %
|
||||
(cmake_path, os.getcwd()))
|
||||
return False
|
||||
|
||||
PROJECT_DIR = CMAKE_DIR = cmake_path
|
||||
return True
|
||||
|
||||
|
||||
def source_list(
|
||||
path: str,
|
||||
filename_check: Callable[[str], bool] | None = None,
|
||||
) -> Iterator[str]:
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
# skip '.git'
|
||||
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
||||
|
||||
for filename in filenames:
|
||||
filepath = join(dirpath, filename)
|
||||
if filename_check is None or filename_check(filepath):
|
||||
yield filepath
|
||||
|
||||
|
||||
# extension checking
|
||||
def is_cmake(filename: str) -> bool:
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".cmake") or (filename.endswith("CMakeLists.txt"))
|
||||
|
||||
|
||||
def is_c_header(filename: str) -> bool:
|
||||
ext = splitext(filename)[1]
|
||||
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
||||
|
||||
|
||||
def is_py(filename: str) -> bool:
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".py")
|
||||
|
||||
|
||||
def is_glsl(filename: str) -> bool:
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".glsl")
|
||||
|
||||
|
||||
def is_c(filename: str) -> bool:
|
||||
ext = splitext(filename)[1]
|
||||
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"})
|
||||
|
||||
|
||||
def is_c_any(filename: str) -> bool:
|
||||
return is_c(filename) or is_c_header(filename)
|
||||
|
||||
|
||||
def is_project_file(filename: str) -> bool:
|
||||
return (is_c_any(filename) or is_cmake(filename) or is_glsl(filename))
|
||||
|
||||
|
||||
def cmake_advanced_info() -> (
|
||||
tuple[list[str], list[tuple[str, str]]] | None
|
||||
):
|
||||
""" Extract includes and defines from cmake.
|
||||
"""
|
||||
|
||||
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
|
||||
if make_exe is None:
|
||||
print("Make command not found: CMAKE_MAKE_PROGRAM")
|
||||
return None
|
||||
|
||||
make_exe_basename = os.path.basename(make_exe)
|
||||
|
||||
def create_eclipse_project() -> str:
|
||||
print("CMAKE_DIR %r" % CMAKE_DIR)
|
||||
if sys.platform == "win32":
|
||||
raise Exception("Error: win32 is not supported")
|
||||
else:
|
||||
if make_exe_basename.startswith(("make", "gmake")):
|
||||
cmd = ("cmake", CMAKE_DIR, "-GEclipse CDT4 - Unix Makefiles")
|
||||
elif make_exe_basename.startswith("ninja"):
|
||||
cmd = ("cmake", CMAKE_DIR, "-GEclipse CDT4 - Ninja")
|
||||
else:
|
||||
raise Exception("Unknown make program %r" % make_exe)
|
||||
|
||||
subprocess.check_call(cmd)
|
||||
return join(CMAKE_DIR, ".cproject")
|
||||
|
||||
includes = []
|
||||
defines = []
|
||||
|
||||
project_path = create_eclipse_project()
|
||||
|
||||
if not exists(project_path):
|
||||
print("Generating Eclipse Project File Failed: %r not found" % project_path)
|
||||
return None
|
||||
|
||||
from xml.dom.minidom import parse
|
||||
tree = parse(project_path)
|
||||
|
||||
# Enable to check on nicer XML.
|
||||
use_pretty_xml = False
|
||||
if use_pretty_xml:
|
||||
with open(".cproject_pretty", 'w', encoding="utf-8") as fh:
|
||||
fh.write(tree.toprettyxml(indent=" ", newl=""))
|
||||
|
||||
ELEMENT_NODE = tree.ELEMENT_NODE
|
||||
|
||||
cproject, = tree.getElementsByTagName("cproject")
|
||||
for storage in cproject.childNodes:
|
||||
if storage.nodeType != ELEMENT_NODE:
|
||||
continue
|
||||
|
||||
if storage.attributes["moduleId"].value == "org.eclipse.cdt.core.settings":
|
||||
cconfig = storage.getElementsByTagName("cconfiguration")[0]
|
||||
for substorage in cconfig.childNodes:
|
||||
if substorage.nodeType != ELEMENT_NODE:
|
||||
continue
|
||||
|
||||
moduleId = substorage.attributes["moduleId"].value
|
||||
|
||||
if moduleId == "org.eclipse.cdt.core.pathentry":
|
||||
for path in substorage.childNodes:
|
||||
if path.nodeType != ELEMENT_NODE:
|
||||
continue
|
||||
kind = path.attributes["kind"].value
|
||||
|
||||
if kind == "mac":
|
||||
# `<pathentry kind="mac" name="PREFIX" path="" value=""/opt/blender25""/>`
|
||||
defines.append((path.attributes["name"].value, path.attributes["value"].value))
|
||||
elif kind == "inc":
|
||||
# `<pathentry include="/path/to/include" kind="inc" path="" system="true"/>`
|
||||
includes.append(path.attributes["include"].value)
|
||||
else:
|
||||
pass
|
||||
|
||||
return includes, defines
|
||||
|
||||
|
||||
def cmake_cache_var(var: str) -> str | None:
|
||||
with open(os.path.join(CMAKE_DIR, "CMakeCache.txt"), encoding='utf-8') as cache_file:
|
||||
lines = [
|
||||
line_strip for line in cache_file
|
||||
if (line_strip := line.strip())
|
||||
if not line_strip.startswith(("//", "#"))
|
||||
]
|
||||
|
||||
for line in lines:
|
||||
if line.split(":")[0] == var:
|
||||
return line.split("=", 1)[-1]
|
||||
return None
|
||||
|
||||
|
||||
def cmake_compiler_defines() -> list[str] | None:
|
||||
compiler = cmake_cache_var("CMAKE_C_COMPILER") # could do CXX too
|
||||
|
||||
if compiler is None:
|
||||
print("Couldn't find the compiler, os defines will be omitted...")
|
||||
return None
|
||||
|
||||
import tempfile
|
||||
temp_c = tempfile.mkstemp(suffix=".c")[1]
|
||||
temp_def = tempfile.mkstemp(suffix=".def")[1]
|
||||
|
||||
os.system("%s -dM -E %s > %s" % (compiler, temp_c, temp_def))
|
||||
|
||||
with open(temp_def, "r", encoding="utf-8") as temp_def_fh:
|
||||
lines = [line.strip() for line in temp_def_fh if line.strip()]
|
||||
|
||||
os.remove(temp_c)
|
||||
os.remove(temp_def)
|
||||
return lines
|
||||
|
||||
|
||||
def project_name_get() -> str | None:
|
||||
return cmake_cache_var("CMAKE_PROJECT_NAME")
|
||||
195
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_assembler_preview.py
Executable file
195
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_assembler_preview.py
Executable file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Takes 2 args
|
||||
|
||||
qtc_assembler_preview.py <build_dir> <file.c/c++>
|
||||
|
||||
Currently GCC is assumed
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
VERBOSE = os.environ.get("VERBOSE", False)
|
||||
BUILD_DIR = sys.argv[-2]
|
||||
SOURCE_FILE = sys.argv[-1]
|
||||
|
||||
# TODO, support other compilers
|
||||
COMPILER_ID = 'GCC'
|
||||
|
||||
|
||||
def find_arg(source, data):
|
||||
source_base = os.path.basename(source)
|
||||
for l in data:
|
||||
# chances are high that we found the file
|
||||
if source_base in l:
|
||||
# check if this file is in the line
|
||||
l_split = shlex.split(l)
|
||||
for w in l_split:
|
||||
if w.endswith(source_base):
|
||||
if os.path.isabs(w):
|
||||
if os.path.samefile(w, source):
|
||||
# print(l)
|
||||
return l
|
||||
else:
|
||||
# check trailing path (a/b/c/d/e.c == d/e.c)
|
||||
w_sep = os.path.normpath(w).split(os.sep)
|
||||
s_sep = os.path.normpath(source).split(os.sep)
|
||||
m = min(len(w_sep), len(s_sep))
|
||||
if w_sep[-m:] == s_sep[-m:]:
|
||||
# print(l)
|
||||
return l
|
||||
|
||||
|
||||
def find_build_args_ninja(source):
|
||||
make_exe = "ninja"
|
||||
process = subprocess.Popen(
|
||||
[make_exe, "-t", "commands"],
|
||||
stdout=subprocess.PIPE,
|
||||
cwd=BUILD_DIR,
|
||||
)
|
||||
while process.poll():
|
||||
time.sleep(1)
|
||||
|
||||
out = process.stdout.read()
|
||||
process.stdout.close()
|
||||
# print("done!", len(out), "bytes")
|
||||
data = out.decode("utf-8", errors="ignore").split("\n")
|
||||
return find_arg(source, data)
|
||||
|
||||
|
||||
def find_build_args_make(source):
|
||||
make_exe = "make"
|
||||
process = subprocess.Popen(
|
||||
[make_exe, "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"],
|
||||
stdout=subprocess.PIPE,
|
||||
cwd=BUILD_DIR,
|
||||
)
|
||||
while process.poll():
|
||||
time.sleep(1)
|
||||
|
||||
out = process.stdout.read()
|
||||
process.stdout.close()
|
||||
|
||||
# print("done!", len(out), "bytes")
|
||||
data = out.decode("utf-8", errors="ignore").split("\n")
|
||||
return find_arg(source, data)
|
||||
|
||||
|
||||
def main():
|
||||
import re
|
||||
|
||||
# currently only supports ninja or makefiles
|
||||
build_file_ninja = os.path.join(BUILD_DIR, "build.ninja")
|
||||
build_file_make = os.path.join(BUILD_DIR, "Makefile")
|
||||
if os.path.exists(build_file_ninja):
|
||||
if VERBOSE:
|
||||
print("Using Ninja")
|
||||
arg = find_build_args_ninja(SOURCE_FILE)
|
||||
elif os.path.exists(build_file_make):
|
||||
if VERBOSE:
|
||||
print("Using Make")
|
||||
arg = find_build_args_make(SOURCE_FILE)
|
||||
else:
|
||||
sys.stderr.write(f"Can't find Ninja or Makefile ({build_file_ninja!r} or {build_file_make!r}), aborting")
|
||||
return
|
||||
|
||||
if arg is None:
|
||||
sys.stderr.write(f"Can't find file {SOURCE_FILE!r} in build command output of {BUILD_DIR!r}, aborting")
|
||||
return
|
||||
|
||||
# now we need to get arg and modify it to produce assembler
|
||||
arg_split = shlex.split(arg)
|
||||
|
||||
# get rid of: 'cd /a/b/c && ' prefix used by make (ninja doesn't need)
|
||||
try:
|
||||
i = arg_split.index("&&")
|
||||
except ValueError:
|
||||
i = -1
|
||||
if i != -1:
|
||||
del arg_split[:i + 1]
|
||||
|
||||
if COMPILER_ID == 'GCC':
|
||||
# --- Switch debug for optimized ---
|
||||
for arg, n in (
|
||||
# regular flags which prevent asm output
|
||||
("-o", 2),
|
||||
("-MF", 2),
|
||||
("-MT", 2),
|
||||
("-MMD", 1),
|
||||
|
||||
# debug flags
|
||||
("-O0", 1),
|
||||
(re.compile(r"\-g\d*"), 1),
|
||||
(re.compile(r"\-ggdb\d*"), 1),
|
||||
("-fno-inline", 1),
|
||||
("-fno-builtin", 1),
|
||||
("-fno-nonansi-builtins", 1),
|
||||
("-fno-common", 1),
|
||||
("-DDEBUG", 1), ("-D_DEBUG", 1),
|
||||
|
||||
# ASAN flags.
|
||||
(re.compile(r"\-fsanitize=.*"), 1),
|
||||
):
|
||||
if isinstance(arg, str):
|
||||
# exact string compare
|
||||
while arg in arg_split:
|
||||
i = arg_split.index(arg)
|
||||
del arg_split[i: i + n]
|
||||
else:
|
||||
# regex match
|
||||
for i in reversed(range(len(arg_split))):
|
||||
if arg.match(arg_split[i]):
|
||||
del arg_split[i: i + n]
|
||||
|
||||
# add optimized args
|
||||
arg_split += ["-O3", "-fomit-frame-pointer", "-DNDEBUG", "-Wno-error"]
|
||||
|
||||
# not essential but interesting to know
|
||||
arg_split += ["-ftree-vectorizer-verbose=1"]
|
||||
|
||||
arg_split += ["-S"]
|
||||
if False:
|
||||
arg_split += ["-masm=intel"] # Optional.
|
||||
arg_split += ["-fverbose-asm"] # Optional but handy.
|
||||
else:
|
||||
sys.stderr.write(f"Compiler {COMPILER_ID!r} not supported")
|
||||
return
|
||||
|
||||
source_asm = f"{SOURCE_FILE}.asm"
|
||||
|
||||
# Never overwrite existing files
|
||||
i = 1
|
||||
while os.path.exists(source_asm):
|
||||
source_asm = f"{SOURCE_FILE}.asm.{i:d}"
|
||||
i += 1
|
||||
|
||||
arg_split += ["-o", source_asm]
|
||||
|
||||
# print("Executing:", arg_split)
|
||||
kwargs = {}
|
||||
if not VERBOSE:
|
||||
kwargs["stdout"] = subprocess.DEVNULL
|
||||
|
||||
os.chdir(BUILD_DIR)
|
||||
subprocess.call(arg_split, **kwargs)
|
||||
|
||||
del kwargs
|
||||
|
||||
if not os.path.exists(source_asm):
|
||||
sys.stderr.write(f"Did not create {source_asm!r} from calling {arg_split!r}")
|
||||
return
|
||||
if VERBOSE:
|
||||
print(f"Running: {arg_split}")
|
||||
print(f"Created: {source_asm!r}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_assembler_preview">
|
||||
<description>Create an assembler file from source (C/C++)</description>
|
||||
<displayname>Assembler Preview</displayname>
|
||||
<category>Compiler</category>
|
||||
<executable output="showinpane" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_assembler_preview.py</path>
|
||||
<arguments>%{CurrentProject:BuildPath} %{CurrentDocument:FilePath}</arguments>
|
||||
<workingdirectory>%{CurrentProject:BuildPath}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Takes 1 arg
|
||||
|
||||
qtc_blender_diffusion.py <file> <row>
|
||||
|
||||
Currently GCC is assumed
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
SOURCE_FILE = sys.argv[-2]
|
||||
SOURCE_ROW = sys.argv[-1]
|
||||
|
||||
BASE_URL = "https://developer.blender.org/diffusion/B/browse"
|
||||
|
||||
|
||||
def main():
|
||||
dirname, _filename = os.path.split(SOURCE_FILE)
|
||||
|
||||
process = subprocess.Popen(
|
||||
["git", "rev-parse", "--symbolic-full-name", "--abbrev-ref",
|
||||
"@{u}"], stdout=subprocess.PIPE, cwd=dirname, universal_newlines=True)
|
||||
output = process.communicate()[0]
|
||||
branchname = output.rstrip().rsplit('/', 1)[-1]
|
||||
|
||||
process = subprocess.Popen(
|
||||
["git", "rev-parse", "--show-toplevel"],
|
||||
stdout=subprocess.PIPE, cwd=dirname, universal_newlines=True)
|
||||
output = process.communicate()[0]
|
||||
toplevel = output.rstrip()
|
||||
filepath = os.path.relpath(SOURCE_FILE, toplevel)
|
||||
|
||||
url = '/'.join([BASE_URL, branchname, filepath]) + "$" + SOURCE_ROW
|
||||
|
||||
print(url)
|
||||
|
||||
# Maybe handy, but also annoying?
|
||||
if "--browse" in sys.argv:
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_blender_diffusion">
|
||||
<description>Print a URL to Diffusion on developer.blender.org for online reference</description>
|
||||
<displayname>Blender Diffusion</displayname>
|
||||
<category>Documentation</category>
|
||||
<executable output="showinpane" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_blender_diffusion.py</path>
|
||||
<arguments>%{CurrentDocument:FilePath} %{CurrentDocument:Row}</arguments>
|
||||
<workingdirectory>%{CurrentDocument:Path}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Convert C++ Style Comments:
|
||||
|
||||
// hello
|
||||
// world
|
||||
|
||||
To This:
|
||||
|
||||
/* hello
|
||||
* world
|
||||
*/
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
txt = sys.stdin.read()
|
||||
data = txt.split("\n")
|
||||
# TODO. block comments
|
||||
|
||||
|
||||
# first detect blocks
|
||||
def block_data(data, i_start):
|
||||
i_begin = -1
|
||||
i_index = -1
|
||||
i_end = -1
|
||||
i = i_start
|
||||
while i < len(data):
|
||||
l = data[i]
|
||||
if "//" in l:
|
||||
i_begin = i
|
||||
i_index = l.index("//")
|
||||
break
|
||||
i += 1
|
||||
if i_begin != -1:
|
||||
i_end = i_begin
|
||||
for i in range(i_begin + 1, len(data)):
|
||||
l = data[i]
|
||||
if "//" in l and l.lstrip().startswith("//") and l.index("//") == i_index:
|
||||
i_end = i
|
||||
else:
|
||||
break
|
||||
|
||||
if i_begin != i_end:
|
||||
# do a block comment replacement
|
||||
data[i_begin] = data[i_begin].replace("//", "/*", 1)
|
||||
for i in range(i_begin + 1, i_end + 1):
|
||||
data[i] = data[i].replace("//", " *", 1)
|
||||
data[i_end] = "{:s} */".format(data[i_end].rstrip())
|
||||
# done with block comment, still go onto do regular replace
|
||||
return max(i_end, i_start + 1)
|
||||
|
||||
|
||||
i = 0
|
||||
while i < len(data):
|
||||
i = block_data(data, i)
|
||||
|
||||
i = 0
|
||||
while "//" not in data[i] and i > len(data):
|
||||
i += 1
|
||||
|
||||
|
||||
for i, l in enumerate(data):
|
||||
if "//" in l: # should check if it's in a string.
|
||||
|
||||
text, comment = l.split("//", 1)
|
||||
|
||||
l = "{:s}/* {:s} */".format(text, comment.strip())
|
||||
|
||||
data[i] = l
|
||||
|
||||
|
||||
print("\n".join(data), end="")
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_cpp_to_c_comments">
|
||||
<description>Convert blocks of C++ comments into C style comments.</description>
|
||||
<displayname>C++ to C (Comments)</displayname>
|
||||
<category>Formatting</category>
|
||||
<executable output="replaceselection" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_cpp_to_c_comments.py</path>
|
||||
<input>%{CurrentDocument:Selection}</input>
|
||||
<workingdirectory>%{CurrentDocument:Path}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
47
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_doxy_file.py
Executable file
47
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_doxy_file.py
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
This script takes 2-3 args: [--browse] <Doxyfile> <sourcefile>
|
||||
|
||||
Where Doxyfile is a path relative to source root,
|
||||
and the sourcefile as an absolute path.
|
||||
|
||||
--browse will open the resulting docs in a web browser.
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
|
||||
def find_gitroot(filepath_reference):
|
||||
path = filepath_reference
|
||||
path_prev = ""
|
||||
while not os.path.exists(os.path.join(path, ".git")) and path != path_prev:
|
||||
path_prev = path
|
||||
path = os.path.dirname(path)
|
||||
return path
|
||||
|
||||
|
||||
doxyfile, sourcefile = sys.argv[-2:]
|
||||
|
||||
doxyfile = os.path.join(find_gitroot(sourcefile), doxyfile)
|
||||
os.chdir(os.path.dirname(doxyfile))
|
||||
|
||||
tempfile = tempfile.NamedTemporaryFile(mode='w+b')
|
||||
doxyfile_tmp = tempfile.name
|
||||
tempfile.write(open(doxyfile, "r+b").read())
|
||||
tempfile.write(b'\n\n')
|
||||
tempfile.write(b'INPUT=' + os.fsencode(sourcefile) + b'\n')
|
||||
tempfile.flush()
|
||||
|
||||
subprocess.call(("doxygen", doxyfile_tmp))
|
||||
del tempfile
|
||||
|
||||
# Maybe handy, but also annoying?
|
||||
if "--browse" in sys.argv:
|
||||
import webbrowser
|
||||
webbrowser.open("html/files.html")
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_doxygen_file">
|
||||
<description>Doxygen a single file</description>
|
||||
<displayname>Doxygen File</displayname>
|
||||
<category>Documentation</category>
|
||||
<executable output="showinpane" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_doxy_file.py</path>
|
||||
<arguments>--browse doc/doxygen/Doxyfile %{CurrentDocument:FilePath}</arguments>
|
||||
<workingdirectory>%{CurrentProject:BuildPath}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
25
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_expand_tabmix.py
Executable file
25
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_expand_tabmix.py
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
|
||||
# TODO, get from QtCreator
|
||||
TABSIZE = 4
|
||||
|
||||
txt = sys.stdin.read()
|
||||
data = txt.split("\n")
|
||||
|
||||
for i, l in enumerate(data):
|
||||
l_lstrip = l.lstrip("\t")
|
||||
l_lstrip_tot = (len(l) - len(l_lstrip))
|
||||
if l_lstrip_tot:
|
||||
l_pre_ws, l_post_ws = l[:l_lstrip_tot], l[l_lstrip_tot:]
|
||||
else:
|
||||
l_pre_ws, l_post_ws = "", l
|
||||
# expand tabs and remove trailing space
|
||||
data[i] = l_pre_ws + l_post_ws.expandtabs(TABSIZE).rstrip(" \t")
|
||||
|
||||
|
||||
print("\n".join(data), end="")
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_expand_tabmix">
|
||||
<description>Expand non-leading tabs into spaces.</description>
|
||||
<displayname>Expand Tab Mix</displayname>
|
||||
<category>Formatting</category>
|
||||
<executable output="replaceselection" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_expand_tabmix.py</path>
|
||||
<input>%{CurrentDocument:Selection}</input>
|
||||
<workingdirectory>%{CurrentDocument:Path}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
40
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_project_update.py
Executable file
40
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_project_update.py
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
This is just a wrapper to run Blender's QtCreator project file generator,
|
||||
knowing only the CMake build path.
|
||||
|
||||
qtc_project_update.py <project_path>
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
PROJECT_DIR = sys.argv[-1]
|
||||
|
||||
|
||||
def cmake_find_source(path):
|
||||
import re
|
||||
match = re.compile(r"^CMAKE_HOME_DIRECTORY\b")
|
||||
cache = os.path.join(path, "CMakeCache.txt")
|
||||
with open(cache, 'r', encoding='utf-8') as f:
|
||||
for l in f:
|
||||
if re.match(match, l):
|
||||
return l[l.index("=") + 1:].strip()
|
||||
return ""
|
||||
|
||||
|
||||
SOURCE_DIR = cmake_find_source(PROJECT_DIR)
|
||||
|
||||
cmd = (
|
||||
"python",
|
||||
os.path.join(SOURCE_DIR, "tools/utils_ide/cmake_qtcreator_project.py"),
|
||||
"--build-dir",
|
||||
PROJECT_DIR,
|
||||
)
|
||||
|
||||
print(cmd)
|
||||
os.system(" ".join(cmd))
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_project_update">
|
||||
<description>Regenerate the project file</description>
|
||||
<displayname>Project File Regenerate</displayname>
|
||||
<category>Project</category>
|
||||
<executable output="showinpane" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_project_update.py</path>
|
||||
<arguments>%{CurrentProject:BuildPath}</arguments>
|
||||
</executable>
|
||||
</externaltool>
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
|
||||
# TODO, get from QtCreator
|
||||
TABSIZE = 4
|
||||
|
||||
txt = sys.stdin.read()
|
||||
data = txt.split("\n")
|
||||
|
||||
maxlen = 0
|
||||
# tabs -> spaces
|
||||
for i, l in enumerate(data):
|
||||
l = l.replace("\t", " " * TABSIZE)
|
||||
l = l.rstrip()
|
||||
maxlen = max(maxlen, len(l))
|
||||
data[i] = l
|
||||
|
||||
for i, l in enumerate(data):
|
||||
ws = l.rsplit(" ", 1)
|
||||
if len(l.strip().split()) == 1 or len(ws) == 1:
|
||||
pass
|
||||
else:
|
||||
j = 1
|
||||
while len(l) < maxlen:
|
||||
l = (" " * j).join(ws)
|
||||
j += 1
|
||||
data[i] = l
|
||||
|
||||
# add tabs back in
|
||||
for i, l in enumerate(data):
|
||||
ls = l.lstrip()
|
||||
d = len(l) - len(ls)
|
||||
indent = ""
|
||||
while d >= TABSIZE:
|
||||
d -= TABSIZE
|
||||
indent += "\t"
|
||||
if d:
|
||||
indent += (" " * d)
|
||||
data[i] = indent + ls
|
||||
|
||||
|
||||
print("\n".join(data), end="")
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_right_align_trailing_char">
|
||||
<description>Right align the last character of each line to the existing furthermost character (useful for multi-line macros).</description>
|
||||
<displayname>Right Align Trailing Char</displayname>
|
||||
<category>Formatting</category>
|
||||
<executable output="replaceselection" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_right_align_trailing_char.py</path>
|
||||
<input>%{CurrentDocument:Selection}</input>
|
||||
<workingdirectory>%{CurrentDocument:Path}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
13
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_select_surround.py
Executable file
13
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_select_surround.py
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
|
||||
# TODO, accept other characters as args
|
||||
|
||||
txt = sys.stdin.read()
|
||||
print("(", end="")
|
||||
print(txt, end="")
|
||||
print(")", end="")
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_select_surround">
|
||||
<description>Surround selection with parentheses or other optionally other characters.</description>
|
||||
<displayname>Surround selection with parentheses</displayname>
|
||||
<category>Formatting</category>
|
||||
<executable output="replaceselection" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_select_surround.py</path>
|
||||
<input>%{CurrentDocument:Selection}</input>
|
||||
<workingdirectory>%{CurrentDocument:Path}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
42
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_sort_paths.py
Executable file
42
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_sort_paths.py
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
|
||||
txt = sys.stdin.read()
|
||||
data = txt.split("\n")
|
||||
|
||||
|
||||
class PathCMP:
|
||||
|
||||
def __init__(self, path):
|
||||
path = path.strip()
|
||||
|
||||
self.path = path
|
||||
if path.startswith("."):
|
||||
path = path[1:]
|
||||
|
||||
if path.startswith("/"):
|
||||
path = path[1:]
|
||||
if path.endswith("/"):
|
||||
path = path[:-1]
|
||||
|
||||
self.level = self.path.count("..")
|
||||
if self.level == 0:
|
||||
self.level = (self.path.count("/") - 10000)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.path == other.path
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.path < other.path if self.level == other.level else self.level < other.level
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.path > other.path if self.level == other.level else self.level > other.level
|
||||
|
||||
|
||||
data.sort(key=lambda a: PathCMP(a))
|
||||
|
||||
print("\n".join(data), end="")
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_sort_paths">
|
||||
<description>Path sort selection, taking into account path depth.</description>
|
||||
<displayname>Sort (Path Depths)</displayname>
|
||||
<category>Formatting</category>
|
||||
<executable output="replaceselection" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_sort_paths.py</path>
|
||||
<input>%{CurrentDocument:Selection}</input>
|
||||
<workingdirectory>%{CurrentDocument:Path}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
44
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_toggle_if0.py
Executable file
44
blender-5.2.0/tools/utils_ide/qtcreator/externaltools/qtc_toggle_if0.py
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
|
||||
txt = sys.stdin.read()
|
||||
data = txt.split("\n")
|
||||
|
||||
# Check if we're if0
|
||||
is_comment = False
|
||||
for l in data:
|
||||
l_strip = l.strip()
|
||||
if l_strip:
|
||||
if l_strip.startswith("#if 0"):
|
||||
is_comment = True
|
||||
else:
|
||||
is_comment = False
|
||||
break
|
||||
|
||||
if is_comment:
|
||||
pop_a = None
|
||||
pop_b = None
|
||||
for i, l in enumerate(data):
|
||||
l_strip = l.strip()
|
||||
|
||||
if pop_a is None:
|
||||
if l_strip.startswith("#if 0"):
|
||||
pop_a = i
|
||||
|
||||
if l_strip.startswith("#endif"):
|
||||
pop_b = i
|
||||
|
||||
if pop_a is not None and pop_b is not None:
|
||||
del data[pop_b]
|
||||
del data[pop_a]
|
||||
else:
|
||||
while data and not data[-1].strip():
|
||||
data.pop()
|
||||
data = ["#if 0"] + data + ["#endif\n"]
|
||||
|
||||
|
||||
print("\n".join(data), end="")
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<externaltool id="qtc_toggle_if0">
|
||||
<description>Toggle if 0 preprocessor block.</description>
|
||||
<displayname>Toggle #if 0</displayname>
|
||||
<category>Formatting</category>
|
||||
<executable output="replaceselection" error="showinpane" modifiesdocument="no">
|
||||
<path>qtc_toggle_if0.py</path>
|
||||
<input>%{CurrentDocument:Selection}</input>
|
||||
<workingdirectory>%{CurrentDocument:Path}</workingdirectory>
|
||||
</executable>
|
||||
</externaltool>
|
||||
44
blender-5.2.0/tools/utils_ide/qtcreator/readme.rst
Normal file
44
blender-5.2.0/tools/utils_ide/qtcreator/readme.rst
Normal file
@@ -0,0 +1,44 @@
|
||||
This repository contains utilities to perform various editing operations as well as some utilities to integrate
|
||||
Uncrustify and Meld.
|
||||
|
||||
|
||||
This is for my own personal use, but I have tried to make the tools generic (where possible) and useful to others.
|
||||
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
All the scripts install to QtCreators ``externaltools`` path:
|
||||
|
||||
eg:
|
||||
``~/.config/QtProject/qtcreator/externaltools/``
|
||||
|
||||
Currently QtCreator has no way to reference commands relative to this directory so the ``externaltools`` dir **must**
|
||||
be added to the systems ``PATH``.
|
||||
|
||||
|
||||
Tools
|
||||
=====
|
||||
|
||||
Here are a list of the tools with some details on how they work.
|
||||
|
||||
|
||||
Assembler Preview
|
||||
-----------------
|
||||
|
||||
``External Tools -> Compiler -> Assembler Preview``
|
||||
|
||||
This tool generates the assembly for the current open document,
|
||||
saving it to a file in the same path with an ".asm" extension.
|
||||
|
||||
This can be handy for checking if the compiler is really optimizing out code as expected.
|
||||
|
||||
Or if some change really doesn't change any functionality.
|
||||
|
||||
The way it works is to get a list of the build commands that would run, and get those commands for the current file.
|
||||
|
||||
Then this command runs, swapping out object creation args for arguments that create the assembly.
|
||||
|
||||
.. note:: It would be nice to open this file, but currently this isn't supported. It's just created along side the source.
|
||||
|
||||
.. note:: Currently only GCC is supported.
|
||||
Reference in New Issue
Block a user