diff --git a/BeefBoot/BeefBoot.vcxproj b/BeefBoot/BeefBoot.vcxproj
index 5a13fb11..f88b55fa 100644
--- a/BeefBoot/BeefBoot.vcxproj
+++ b/BeefBoot/BeefBoot.vcxproj
@@ -93,6 +93,7 @@
Level3
Disabled
WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
Console
@@ -112,6 +113,7 @@
MultiThreadedDebug
false
ProgramDatabase
+ true
Console
@@ -128,6 +130,7 @@
true
true
WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
Console
@@ -149,6 +152,7 @@
../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm\tools\clang\include
MultiThreaded
false
+ true
Console
diff --git a/BeefBoot/CMakeLists.txt b/BeefBoot/CMakeLists.txt
index e0a3ce14..3848b33c 100644
--- a/BeefBoot/CMakeLists.txt
+++ b/BeefBoot/CMakeLists.txt
@@ -27,9 +27,9 @@ if(NOT CMAKE_BUILD_TYPE)
endif(NOT CMAKE_BUILD_TYPE)
# Definition of Macros
-add_definitions(
- -DIDEHELPER_EXPORTS
- -DBFSYSLIB_DYNAMIC
+add_definitions(
+ -DIDEHELPER_EXPORTS
+ -DBFSYSLIB_DYNAMIC
-DUNICODE
-D_UNICODE
-DBF_NO_FBX
@@ -41,10 +41,10 @@ if (${APPLE})
include_directories(
.
../
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
- ../BeefySysLib/third_party/freetype/include
- ../extern/llvm-project_13_0_1/llvm/include
+ ../BeefySysLib/third_party/freetype/include
+ ../extern/llvm-project_13_0_1/llvm/include
../extern/llvm-project_13_0_1/llvm/lib/Target
../IDEHelper
@@ -54,14 +54,14 @@ else()
include_directories(
.
../
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
- ../BeefySysLib/third_party/freetype/include
- ../extern/llvm-project_13_0_1/llvm/include
+ ../BeefySysLib/third_party/freetype/include
+ ../extern/llvm-project_13_0_1/llvm/include
../extern/llvm-project_13_0_1/llvm/lib/Target
../IDEHelper
- ../BeefySysLib/platform/linux
+ ../BeefySysLib/platform/linux
)
endif()
@@ -69,7 +69,7 @@ endif()
# Defines outputs , depending Debug or Release. #
#################################################
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(
-D_DEBUG
)
@@ -85,23 +85,23 @@ else()
../extern/llvm_linux_rel_13_0_1/lib/Target/X86
)
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}")
- set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_rel_13_0_1/lib")
+ set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_rel_13_0_1/lib")
endif()
################### Dependencies ##################
# Add Dependencies to project. #
###################################################
-option(BUILD_DEPENDS
- "Build other CMake project."
- ON
+option(BUILD_DEPENDS
+ "Build other CMake project."
+ ON
)
# Dependencies : disable BUILD_DEPENDS to link with lib already build.
if(BUILD_DEPENDS)
-
+
else()
-
+
endif()
################# Flags ################
@@ -113,7 +113,7 @@ if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
endif(MSVC)
if(NOT MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wno-multichar -Wno-invalid-offsetof")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wno-multichar -Wno-invalid-offsetof")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
@@ -137,8 +137,17 @@ execute_process(
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_13_0_1/bin/llvm-config --system-libs --link-static
OUTPUT_VARIABLE LLVM_SYSTEM_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE EXEC_RESULT
)
+if (EXEC_RESULT AND NOT EXEC_RESULT EQUAL 0)
+ if (EXEC_RESULT MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "llvm-config exited with code ${EXEC_RESULT}.")
+ else()
+ message(FATAL_ERROR "llvm-config couldn't be executed: ${EXEC_RESULT}")
+ endif()
+endif()
+
if (${APPLE})
set(TARGET_LIBS_OS "")
else()
@@ -152,10 +161,10 @@ endif()
if(MSVC)
target_link_libraries(${PROJECT_NAME} BeefySysLib IDEHelper kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib)
else()
- target_link_libraries(${PROJECT_NAME} BeefySysLib
- IDEHelper
+ target_link_libraries(${PROJECT_NAME} BeefySysLib
+ IDEHelper
${TARGET_LIBS_OS}
-
- #${LLVM_LIB}/libLLVMSupport.a
- )
+
+ #${LLVM_LIB}/libLLVMSupport.a
+ )
endif()
diff --git a/BeefBuild/BeefProj.toml b/BeefBuild/BeefProj.toml
index 0d636f30..88591bcd 100644
--- a/BeefBuild/BeefProj.toml
+++ b/BeefBuild/BeefProj.toml
@@ -7,7 +7,7 @@ StartupObject = "BeefBuild.Program"
[Platform.Windows]
Description = "BeefBuild"
-FileVersion = "0.43.3"
+FileVersion = "0.43.4"
[Configs.Debug.Win32]
TargetName = ""
@@ -19,7 +19,7 @@ TargetName = "$(ProjectName)_d"
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib Rpcrt4.lib Ole32.lib"
CLibType = "Dynamic"
BeefLibType = "DynamicDebug"
-DebugCommandArguments = "-proddir=c:\\Beef\\IDEHelper\\Tests -test"
+DebugCommandArguments = "-proddir=c:\\Beef\\IDE -config=Debug2"
DebugWorkingDirectory = "c:\\beef\\ide"
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
PreprocessorMacros = ["DEBUG", "CLI"]
@@ -75,9 +75,6 @@ DebugWorkingDirectory = "$(ProjectDir)\\dist"
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
PreprocessorMacros = ["RELEASE", "CLI"]
-[Configs.Release.Win64z]
-BuildKind = "StaticLib"
-
[Configs.Debug2.Win32]
TargetName = ""
OtherLinkFlags = ""
diff --git a/BeefFuzz/BeefFuzz.cpp b/BeefFuzz/BeefFuzz.cpp
new file mode 100644
index 00000000..df405bbf
--- /dev/null
+++ b/BeefFuzz/BeefFuzz.cpp
@@ -0,0 +1,87 @@
+#pragma warning(disable:4996)
+
+#include
+#include "BeefySysLib/Common.h"
+#include "BeefySysLib/util/Array.h"
+#include "BeefySysLib/util/SizedArray.h"
+#include "BeefySysLib/util/Dictionary.h"
+#include "BeefySysLib/util/CabUtil.h"
+#include "BeefySysLib/util/BeefPerf.h"
+#include "BeefySysLib/util/Deque.h"
+#include "BeefySysLib/util/HashSet.h"
+#include "BeefySysLib/util/MultiHashSet.h"
+
+#define BF_DBG_64
+#include "IDEHelper/StrHashMap.h"
+
+using namespace Beefy;
+
+#include "FuzzApp.h"
+
+BF_IMPORT void BF_CALLTYPE IDEHelper_ProgramStart();
+BF_IMPORT void BF_CALLTYPE IDEHelper_ProgramDone();
+
+static void FuzzInit()
+{
+ BfpSystem_SetCommandLine(0, NULL);
+
+ BfpThread_SetName(NULL, "MainThread", NULL);
+
+ BfpSystem_Init(BFP_VERSION, BfpSystemInitFlag_None);
+
+ IDEHelper_ProgramStart();
+
+ gApp = new FuzzApp();
+ gApp->SetTargetPath("fuzz_testd");
+ gApp->AddDefine("CLI");
+ gApp->AddDefine("DEBUG");
+ gApp->SetStartupObject("fuzz_test.Program");
+ gApp->SetLinkParams("./libBeefRT_d.a ./libBeefySysLib_d.so -ldl -lpthread -Wl,-rpath -Wl,$ORIGIN");
+
+ BF_ASSERT(gApp->Init());
+}
+
+void trimwhitespace(const uint8_t*& str, size_t& len)
+{
+ while (len > 0 && isspace(*str))
+ {
+ str++;
+ len--;
+ }
+
+ const uint8_t* end = str + len - 1;
+ while (len > 0 && isspace(*end))
+ {
+ end--;
+ len--;
+ }
+}
+
+static bool init = false;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
+{
+ if (!init)
+ {
+ init = true;
+ FuzzInit();
+ }
+
+ trimwhitespace(Data, Size);
+ if (Size == 0)
+ return 0;
+
+ gApp->PrepareCompiler();
+
+ bool ready = gApp->QueueFile((char*)Data, Size);
+
+ //if (ready)
+ // ready = gApp->QueuePath("./corlib/src");
+
+ //if (ready)
+ // gApp->Compile();
+
+ gApp->ReleaseCompiler();
+
+ return 0;
+}
\ No newline at end of file
diff --git a/BeefFuzz/BeefFuzz.h b/BeefFuzz/BeefFuzz.h
new file mode 100644
index 00000000..724d73cc
--- /dev/null
+++ b/BeefFuzz/BeefFuzz.h
@@ -0,0 +1,180 @@
+#pragma once
+
+#include "BeefySysLib/Common.h"
+#include "BeefySysLib/util/Array.h"
+#include "BeefySysLib/util/String.h"
+#include
+//#include
+
+#pragma warning(disable:4996)
+
+NS_BF_BEGIN
+
+#define APPEND2(VAL1, VAL2) VAL1##VAL2
+#define APPEND(VAL1, VAL2) APPEND2(VAL1, VAL2)
+#define ENUM_VAL_GENERATE(ENUM_ENTRY) APPEND(ENUM_TYPE, _##ENUM_ENTRY),
+#define ENUM_NAME_GENERATE(ENUM_ENTRY) #ENUM_ENTRY,
+#define ENUM_CREATE_DO2(EnumName) \
+ static const char* EnumName##_Names[] = { ENUM_DECLARE(ENUM_NAME_GENERATE) }; \
+ enum EnumName { ENUM_DECLARE(ENUM_VAL_GENERATE) }; \
+ static bool EnumParse(const String& name, EnumName& result) \
+ { \
+ for (int i = 0; i < sizeof(EnumName##_Names)/sizeof(const char*); i++) \
+ if (name == EnumName##_Names[i]) { result = (EnumName)i; return true; } \
+ return false; \
+ } \
+ static const char* EnumToString(EnumName enumVal) \
+ { \
+ return EnumName##_Names[(int)enumVal]; \
+ }
+#define ENUM_CREATE_DO(EnumType) ENUM_CREATE_DO2(EnumType)
+#define ENUM_CREATE ENUM_CREATE_DO(ENUM_TYPE)
+
+class IDEUtils
+{
+public:
+ static bool FixFilePath(String& filePath)
+ {
+ if (filePath.length() == 0)
+ return false;
+
+ if (filePath[0] == '<')
+ return false;
+
+ if ((filePath.length() > 1) && (filePath[1] == ':'))
+ filePath[0] = tolower(filePath[0]);
+
+ bool prevWasSlash = false;
+ for (int i = 0; i < filePath.length(); i++)
+ {
+ //if ((filePath[i] == '/') && (filePath[i - 1])
+
+ if (filePath[i] == DIR_SEP_CHAR_ALT)
+ filePath[i] = DIR_SEP_CHAR;
+
+ if (filePath[i] == DIR_SEP_CHAR)
+ {
+ if ((prevWasSlash) && (i > 1))
+ {
+ filePath.Remove(i, 1);
+ i--;
+ continue;
+ }
+
+ prevWasSlash = true;
+ }
+ else
+ prevWasSlash = false;
+
+ if ((i >= 4) && (filePath[i - 3] == DIR_SEP_CHAR) && (filePath[i - 2] == '.') && (filePath[i - 1] == '.') && (filePath[i] == DIR_SEP_CHAR))
+ {
+ int prevSlash = (int)filePath.LastIndexOf(DIR_SEP_CHAR, i - 4);
+ if (prevSlash != -1)
+ {
+ filePath.Remove(prevSlash, i - prevSlash);
+ i = prevSlash;
+ }
+ }
+ }
+ return true;
+ }
+
+ static void GetDirWithSlash(String& dirName)
+ {
+ if (dirName.length() == 0)
+ return;
+ char lastC = dirName[dirName.length() - 1];
+ if ((lastC != '\\') && (lastC != '/'))
+ dirName += DIR_SEP_CHAR;
+ }
+
+ static FILE* CreateFileWithDir(const String& fileName, const char* options)
+ {
+ FILE* fp = fopen(fileName.c_str(), options);
+ if (fp == NULL)
+ {
+ String fileDir = GetFileDir(fileName);
+ if (!fileDir.empty())
+ {
+ RecursiveCreateDirectory(fileDir);
+ fp = fopen(fileName.c_str(), "w");
+ }
+ }
+ return fp;
+ }
+
+ static bool WriteAllText(const String& fileName, const String& data)
+ {
+ FILE* fp = CreateFileWithDir(fileName, "w");
+ if (fp == NULL)
+ return false;
+ fwrite(data.c_str(), 1, data.length(), fp);
+ fclose(fp);
+ return true;
+ }
+
+ static void GetFileNameWithoutExtension(const String& filePath, String& outFileName)
+ {
+ outFileName += GetFileName(filePath);
+ int dot = (int)outFileName.LastIndexOf('.');
+ if (dot != -1)
+ outFileName.RemoveToEnd(dot);
+ }
+
+ static void GetExtension(const String& filePath, String& ext)
+ {
+ int idx = (int)filePath.LastIndexOf('.');
+ if (idx != -1)
+ ext = filePath.Substring(idx);
+ }
+
+ static void AppendWithOptionalQuotes(String& targetStr, const String& srcFileName)
+ {
+ if ((int)srcFileName.IndexOf(' ') == -1)
+ targetStr += srcFileName;
+ else
+ targetStr += "\"" + srcFileName + "\"";
+ }
+};
+
+class ArgBuilder
+{
+public:
+ String* mTarget;
+ bool mDoLongBreak;
+ int mLastBreak;
+ std::multiset mLinkPaths;
+
+public:
+ ArgBuilder(String& target, bool doLongBreak)
+ {
+ mTarget = ⌖
+ mDoLongBreak = doLongBreak;
+ if (mDoLongBreak)
+ mLastBreak = (int)mTarget->LastIndexOf('\n');
+ else
+ mLastBreak = 0;
+ }
+
+ void AddSep()
+ {
+ if (mDoLongBreak)
+ {
+ if (mTarget->length() - mLastBreak > 0x1F000)
+ {
+ mLastBreak = (int)mTarget->length();
+ mTarget->Append('\n');
+ return;
+ }
+ }
+ mTarget->Append(' ');
+ }
+
+ void AddFileName(const String& filePath)
+ {
+ IDEUtils::AppendWithOptionalQuotes(*mTarget, filePath);
+ }
+};
+
+NS_BF_END
+
diff --git a/BeefFuzz/BeefFuzz.vcxproj b/BeefFuzz/BeefFuzz.vcxproj
new file mode 100644
index 00000000..adb08cb8
--- /dev/null
+++ b/BeefFuzz/BeefFuzz.vcxproj
@@ -0,0 +1,182 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {F5FD6845-BBAE-47B6-AE4E-2C1D30F6E145}
+ Win32Proj
+ BeefFuzz
+ 10.0.17763.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\ide\dist\
+
+
+ true
+ $(ProjectName)_d
+ $(SolutionDir)\ide\dist\
+
+
+ false
+ $(SolutionDir)\ide\dist\
+
+
+ false
+ $(SolutionDir)\ide\dist\
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include
+ true
+ false
+ MultiThreadedDebug
+ false
+ ProgramDatabase
+
+
+ Console
+ DebugFull
+ $(SolutionDir)\ide\dist\$(TargetName).exe
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm\tools\clang\include
+ MultiThreaded
+ false
+
+
+ Console
+ true
+ true
+ DebugFull
+ $(SolutionDir)\ide\dist\$(TargetName).exe
+ Default
+
+
+
+
+
+
+
+
+ {eceab68d-2f15-495f-a29c-5ea9548aa23d}
+
+
+ {f8d29c38-d37c-4af2-8540-2f6e543264f1}
+ false
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BeefFuzz/BeefFuzz.vcxproj.filters b/BeefFuzz/BeefFuzz.vcxproj.filters
new file mode 100644
index 00000000..bd3cc797
--- /dev/null
+++ b/BeefFuzz/BeefFuzz.vcxproj.filters
@@ -0,0 +1,33 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/BeefFuzz/CMakeLists.txt b/BeefFuzz/CMakeLists.txt
new file mode 100644
index 00000000..d1b85ae8
--- /dev/null
+++ b/BeefFuzz/CMakeLists.txt
@@ -0,0 +1,169 @@
+cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+
+################### Variables. ####################
+# Change if you want modify path or other values. #
+###################################################
+
+set(PROJECT_NAME BeefFuzz)
+# Output Variables
+set(OUTPUT_DEBUG Debug/bin)
+set(OUTPUT_RELEASE Release/bin)
+
+############## CMake Project ################
+# The main options of project #
+#############################################
+
+project(${PROJECT_NAME} CXX C)
+
+set (CMAKE_CXX_STANDARD 14)
+add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1)
+
+#set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+# Define Release by default.
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "Debug")
+ message(STATUS "Build type not specified: Use Debug by default.")
+endif(NOT CMAKE_BUILD_TYPE)
+
+# Definition of Macros
+add_definitions(
+ -DIDEHELPER_EXPORTS
+ -DBFSYSLIB_DYNAMIC
+ -DUNICODE
+ -D_UNICODE
+ -DBF_NO_FBX
+ -DFT2_BUILD_LIBRARY
+ -DBFSYSLIB_DYNAMIC
+)
+
+if (${APPLE})
+ include_directories(
+ .
+ ../
+ ../BeefySysLib/
+ ../BeefySysLib/third_party
+ ../BeefySysLib/third_party/freetype/include
+ ../extern/llvm-project_13_0_1/llvm/include
+ ../extern/llvm-project_13_0_1/llvm/lib/Target
+ ../IDEHelper
+
+ ../BeefySysLib/platform/osx
+ )
+else()
+ include_directories(
+ .
+ ../
+ ../BeefySysLib/
+ ../BeefySysLib/third_party
+ ../BeefySysLib/third_party/freetype/include
+ ../extern/llvm-project_13_0_1/llvm/include
+ ../extern/llvm-project_13_0_1/llvm/lib/Target
+ ../IDEHelper
+
+ ../BeefySysLib/platform/linux
+ )
+endif()
+
+############## Artefacts Output #################
+# Defines outputs , depending Debug or Release. #
+#################################################
+
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ add_definitions(
+ -D_DEBUG
+ )
+ include_directories(
+ ../extern/llvm_linux_13_0_1/include
+ ../extern/llvm_linux_13_0_1/lib/Target/X86
+ )
+ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_DEBUG}")
+ set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_13_0_1/lib")
+else()
+ include_directories(
+ ../extern/llvm_linux_rel_13_0_1/include
+ ../extern/llvm_linux_rel_13_0_1/lib/Target/X86
+ )
+ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}")
+ set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_rel_13_0_1/lib")
+endif()
+
+################### Dependencies ##################
+# Add Dependencies to project. #
+###################################################
+
+option(BUILD_DEPENDS
+ "Build other CMake project."
+ ON
+)
+
+# Dependencies : disable BUILD_DEPENDS to link with lib already build.
+if(BUILD_DEPENDS)
+
+else()
+
+endif()
+
+################# Flags ################
+# Defines Flags for Windows and Linux. #
+########################################
+
+if(MSVC)
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /MD /MDd /Od /EHsc")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
+else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wno-multichar -Wno-invalid-offsetof -fno-omit-frame-pointer -fsanitize=fuzzer")
+ if (BF_ENABLE_ASAN)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
+ endif()
+endif()
+
+################ Files ################
+# -- Add files to project. -- #
+#######################################
+
+file(GLOB SRC_FILES
+ BeefFuzz.cpp
+ FuzzApp.cpp
+)
+
+# Add executable to build.
+add_executable(${PROJECT_NAME}
+ ${SRC_FILES}
+)
+
+execute_process(
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_13_0_1/bin/llvm-config --system-libs --link-static
+ OUTPUT_VARIABLE LLVM_SYSTEM_LIBS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE EXEC_RESULT
+)
+
+if (EXEC_RESULT AND NOT EXEC_RESULT EQUAL 0)
+ if (EXEC_RESULT MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "llvm-config exited with code ${EXEC_RESULT}.")
+ else()
+ message(FATAL_ERROR "llvm-config couldn't be executed: ${EXEC_RESULT}")
+ endif()
+endif()
+
+if (${APPLE})
+ set(TARGET_LIBS_OS "")
+else()
+ #set(TARGET_LIBS_OS "curses")
+ #set(TARGET_LIBS_OS "-Xlinker --no-demangle -v")
+
+ set(TARGET_LIBS_OS "${LLVM_SYSTEM_LIBS}")
+endif()
+
+# Link with other dependencies.
+if(MSVC)
+ target_link_libraries(${PROJECT_NAME} BeefySysLib IDEHelper kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib)
+else()
+ target_link_libraries(${PROJECT_NAME} BeefySysLib
+ IDEHelper
+ ${TARGET_LIBS_OS}
+
+ #${LLVM_LIB}/libLLVMSupport.a
+ )
+endif()
diff --git a/BeefFuzz/FuzzApp.cpp b/BeefFuzz/FuzzApp.cpp
new file mode 100644
index 00000000..ff919a5d
--- /dev/null
+++ b/BeefFuzz/FuzzApp.cpp
@@ -0,0 +1,300 @@
+#pragma warning(disable:4996)
+
+#include "FuzzApp.h"
+#include
+#include "BeefySysLib/util/String.h"
+#include "BeefySysLib/util/FileEnumerator.h"
+#include "BeefySysLib/util/WorkThread.h"
+#include "BeefySysLib/platform/PlatformHelper.h"
+#include "Compiler/BfSystem.h"
+
+#ifdef BF_PLATFORM_WINDOWS
+#include
+#endif
+
+BF_IMPORT void BF_CALLTYPE Targets_Create();
+BF_IMPORT void BF_CALLTYPE Targets_Delete();
+
+BF_IMPORT void BF_CALLTYPE BfSystem_ReportMemory(void* bfSystem);
+BF_EXPORT void BF_CALLTYPE BfCompiler_ProgramDone();
+
+BF_IMPORT void BF_CALLTYPE Debugger_FullReportMemory();
+
+//////////////////////////////////////////////////////////////////////////
+
+BF_IMPORT void BF_CALLTYPE BfCompiler_Delete(void* bfCompiler);
+BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(void* bfCompiler, void* hotProject, int hotIdx,
+ const char* targetTriple, const char* targetCPU, int toolsetType, int simdSetting, int allocStackCount, int maxWorkerThreads,
+ Beefy::BfCompilerOptionFlags optionFlags, const char* mallocLinkName, const char* freeLinkName);
+BF_IMPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(void* bfCompiler);
+BF_IMPORT bool BF_CALLTYPE BfCompiler_Compile(void* bfCompiler, void* bfPassInstance, const char* outputPath);
+BF_IMPORT float BF_CALLTYPE BfCompiler_GetCompletionPercentage(void* bfCompiler);
+BF_IMPORT const char* BF_CALLTYPE BfCompiler_GetUsedOutputFileNames(void* bfCompiler, void* bfProject, bool flushQueuedHotFiles, bool* hadOutputChanges);
+
+BF_IMPORT void* BF_CALLTYPE BfSystem_CreateParser(void* bfSystem, void* bfProject);
+BF_IMPORT void BF_CALLTYPE BfParser_SetSource(void* bfParser, const char* data, int length, const char* fileName);
+BF_IMPORT void BF_CALLTYPE BfParser_SetCharIdData(void* bfParser, uint8* data, int length);
+BF_IMPORT bool BF_CALLTYPE BfParser_Parse(void* bfParser, void* bfPassInstance, bool compatMode);
+BF_IMPORT bool BF_CALLTYPE BfParser_Reduce(void* bfParser, void* bfPassInstance);
+BF_IMPORT bool BF_CALLTYPE BfParser_BuildDefs(void* bfParser, void* bfPassInstance, void* resolvePassData, bool fullRefresh);
+
+//////////////////////////////////////////////////////////////////////////
+
+BF_IMPORT void* BF_CALLTYPE BfSystem_Create();
+BF_EXPORT void BF_CALLTYPE BfSystem_Lock(void* bfSystem, int priority);
+BF_EXPORT void BF_CALLTYPE BfSystem_Unlock(void* bfSystem);
+BF_IMPORT void BF_CALLTYPE BfSystem_ReportMemory(void* bfSystem);
+BF_IMPORT void BF_CALLTYPE BfSystem_Delete(void* bfSystem);
+BF_IMPORT void* BF_CALLTYPE BfSystem_CreatePassInstance(void* bfSystem);
+BF_IMPORT void* BF_CALLTYPE BfSystem_CreateCompiler(void* bfSystem, bool isResolveOnly);
+BF_IMPORT void* BF_CALLTYPE BfSystem_CreateProject(void* bfSystem, const char* projectName, const char* projectDir);
+BF_IMPORT void BF_CALLTYPE BfParser_Delete(void* bfParser);
+BF_IMPORT void BF_CALLTYPE BfSystem_AddTypeOptions(void* bfSystem, const char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 arrayBoundsCheck,
+ int32 initLocalVariables, int32 emitDynamicCastCheck, int32 emitObjectAccessCheck, int32 allocStackTraceDepth);
+
+//////////////////////////////////////////////////////////////////////////
+
+BF_IMPORT void BF_CALLTYPE BfProject_SetDisabled(void* bfProject, bool disabled);
+BF_IMPORT void BF_CALLTYPE BfProject_SetOptions(void* bfProject, int targetType, const char* startupObject, const char* preprocessorMacros,
+ int optLevel, int ltoType, int relocType, int picLevel, int32 flags);
+BF_IMPORT void BF_CALLTYPE BfProject_ClearDependencies(void* bfProject);
+BF_IMPORT void BF_CALLTYPE BfProject_AddDependency(void* bfProject, void* depProject);
+
+//////////////////////////////////////////////////////////////////////////
+
+BF_IMPORT const char* BF_CALLTYPE BfPassInstance_PopOutString(void* bfPassInstance);
+BF_IMPORT void BF_CALLTYPE BfPassInstance_Delete(void* bfPassInstance);
+
+//////////////////////////////////////////////////////////////////////////
+
+BF_IMPORT const char* BF_CALLTYPE VSSupport_Find();
+
+//////////////////////////////////////////////////////////////////////////
+
+USING_NS_BF;
+
+FuzzApp* Beefy::gApp = NULL;
+
+
+FuzzApp::FuzzApp()
+{
+ Targets_Create();
+
+ mTargetType = BfTargetType_BeefConsoleApplication;
+
+ mSystem = NULL;
+ mCompiler = NULL;
+ mProject = NULL;
+ mCELibProject = NULL;
+ mIsCERun = false;
+ mStartupObject = "Program";
+
+#ifdef BF_PLATFORM_WINDOWS
+ mOptLevel = BfOptLevel_OgPlus;
+ mToolset = BfToolsetType_Microsoft;
+#else
+ mOptLevel = BfOptLevel_O0;
+ mToolset = BfToolsetType_GNU;
+#endif
+
+#ifdef BF_PLATFORM_WINDOWS
+ mTargetTriple = "x86_64-pc-windows-msvc";
+#elif defined BF_PLATFORM_MACOS
+ mTargetTriple = "x86_64-apple-macosx10.8.0";
+#else
+ mTargetTriple = "x86_64-unknown-linux-gnu";
+#endif
+}
+
+FuzzApp::~FuzzApp()
+{
+ Targets_Delete();
+}
+
+bool FuzzApp::Init()
+{
+ char* cwdPtr = getcwd(NULL, 0);
+ mWorkingDir = cwdPtr;
+ free(cwdPtr);
+
+ if (mTargetPath.IsEmpty())
+ return false;
+
+ return true;
+}
+
+bool FuzzApp::QueueFile(const char* data, size_t len)
+{
+ bool worked = true;
+ void* bfParser = BfSystem_CreateParser(mSystem, (mCELibProject != NULL) ? mCELibProject : mProject);
+ BfParser_SetSource(bfParser, data, len, "Fuzz.bf");
+ //bfParser.SetCharIdData(charIdData);
+ worked &= BfParser_Parse(bfParser, mPassInstance, false);
+ worked &= BfParser_Reduce(bfParser, mPassInstance);
+ worked &= BfParser_BuildDefs(bfParser, mPassInstance, NULL, false);
+ return worked;
+}
+
+bool FuzzApp::QueuePath(const StringImpl& path)
+{
+ if (DirectoryExists(path))
+ {
+ for (auto& fileEntry : FileEnumerator(path, FileEnumerator::Flags_Files))
+ {
+ String filePath = fileEntry.GetFilePath();
+
+ String fileName;
+ fileName = GetFileName(filePath);
+
+ String ext;
+ ext = GetFileExtension(filePath);
+
+ if ((ext.Equals(".bf", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
+ (ext.Equals(".cs", StringImpl::CompareKind_OrdinalIgnoreCase)))
+ {
+ int len;
+ const char* data = LoadTextData(filePath, &len);
+ if (data != NULL)
+ {
+ bool success = QueueFile(data, len);
+ delete[] data;
+
+ if (!success)
+ return false;
+ }
+ }
+ }
+
+ for (auto& fileEntry : FileEnumerator(path, FileEnumerator::Flags_Directories))
+ {
+ String childPath = fileEntry.GetFilePath();
+ String dirName;
+ dirName = GetFileName(childPath);
+
+ if (dirName == "build")
+ continue;
+
+ if (!QueuePath(childPath))
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool FuzzApp::CopyFile(const StringImpl& srcPath, const StringImpl& destPath)
+{
+ BfpFileResult result = BfpFileResult_Ok;
+ for (int i = 0; i < 20; i++)
+ {
+ BfpFile_Copy(srcPath.c_str(), destPath.c_str(), BfpFileCopyKind_Always, &result);
+ if (result == BfpFileResult_Ok)
+ return true;
+ BfpThread_Sleep(100);
+ }
+ return false;
+}
+
+void FuzzApp::PrepareCompiler()
+{
+ mSystem = BfSystem_Create();
+
+ mCompiler = BfSystem_CreateCompiler(mSystem, false);
+
+ String projectName = GetFileName(mTargetPath);
+ int dotPos = (int)projectName.IndexOf('.');
+ if (dotPos != -1)
+ projectName.RemoveToEnd(dotPos);
+ if (projectName.IsEmpty())
+ projectName.Append("BeefProject");
+
+ mProject = BfSystem_CreateProject(mSystem, projectName.c_str(), GetFileDir(mTargetPath).c_str());
+
+ if (mIsCERun)
+ {
+ mCELibProject = BfSystem_CreateProject(mSystem, "BeefLib", GetFileDir(mTargetPath).c_str());
+ BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, BfProjectFlags_None);
+ }
+
+ String defines = mDefines;
+ if (!defines.IsEmpty())
+ defines.Append("\n");
+ defines.Append("BF_64_BIT");
+ defines.Append("\nBF_LITTLE_ENDIAN");
+ defines.Append("\n");
+ defines.Append(BF_PLATFORM_NAME);
+
+ int ltoType = 0;
+ BfProject_SetOptions(mProject, mTargetType, mStartupObject.c_str(), defines.c_str(), BfOptLevel_O0, ltoType, 0, 0, BfProjectFlags_None);
+
+ if (mCELibProject != NULL)
+ BfProject_AddDependency(mProject, mCELibProject);
+
+ mPassInstance = BfSystem_CreatePassInstance(mSystem);
+
+ Beefy::String exePath;
+ BfpGetStrHelper(exePath, [](char* outStr, int* inOutStrSize, BfpResult* result)
+ {
+ BfpSystem_GetExecutablePath(outStr, inOutStrSize, (BfpSystemResult*)result);
+ });
+ mBuildDir = GetFileDir(exePath) + "/build";
+
+ RecursiveCreateDirectory(mBuildDir + "/" + projectName);
+ if (mIsCERun)
+ RecursiveCreateDirectory(mBuildDir + "/BeefLib");
+
+ BfCompilerOptionFlags optionFlags = (BfCompilerOptionFlags)(BfCompilerOptionFlag_EmitDebugInfo | BfCompilerOptionFlag_EmitLineInfo | BfCompilerOptionFlag_GenerateOBJ | BfCompilerOptionFlag_OmitDebugHelpers);
+
+ //int maxWorkerThreads = BfpSystem_GetNumLogicalCPUs(NULL);
+ //if (maxWorkerThreads <= 1)
+ // maxWorkerThreads = 6;
+
+ BfCompiler_SetOptions(mCompiler, NULL, 0, mTargetTriple.c_str(), "", mToolset, BfSIMDSetting_SSE2, 1, 1, optionFlags, "malloc", "free");
+}
+
+
+bool FuzzApp::Compile()
+{
+ BfCompiler_ClearBuildCache(mCompiler);
+
+ if (!BfCompiler_Compile(mCompiler, mPassInstance, mBuildDir.c_str()))
+ return false;
+
+ if (!mCEDest.IsEmpty())
+ {
+ String ext;
+ String srcResult = mBuildDir + "/BeefProject/BeefProject";
+ srcResult += BF_OBJ_EXT;
+
+ if (!CopyFile(srcResult, mCEDest))
+ return false;
+ }
+
+ while (true)
+ {
+ const char* msg = BfPassInstance_PopOutString(mPassInstance);
+ if (msg == NULL)
+ break;
+
+ if ((strncmp(msg, ":error ", 7) == 0) ||
+ (strncmp(msg, "ERROR(", 6) == 0) ||
+ (strncmp(msg, "ERROR:", 6) == 0))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void FuzzApp::ReleaseCompiler()
+{
+ BfPassInstance_Delete(mPassInstance);
+ BfCompiler_Delete(mCompiler);
+
+ BfSystem_Delete(mSystem);
+}
+
+
diff --git a/BeefFuzz/FuzzApp.h b/BeefFuzz/FuzzApp.h
new file mode 100644
index 00000000..b491e256
--- /dev/null
+++ b/BeefFuzz/FuzzApp.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include "BeefFuzz.h"
+#include "BeefySysLib/FileStream.h"
+#include "BeefySysLib/util/CritSect.h"
+#include "BeefySysLib/util/String.h"
+#include "BeefySysLib/util/Array.h"
+#include "Compiler/BfSystem.h"
+
+NS_BF_BEGIN
+
+class FuzzApp
+{
+public:
+ BfTargetType mTargetType;
+ String mTargetTriple;
+ BfOptLevel mOptLevel;
+ BfToolsetType mToolset;
+ String mBuildDir;
+ String mWorkingDir;
+ String mDefines;
+ String mStartupObject;
+ String mTargetPath;
+ String mLinkParams;
+
+ void* mSystem;
+ void* mCompiler;
+ void* mProject;
+ void* mPassInstance;
+
+ bool mIsCERun;
+ void* mCELibProject;
+ String mCEDest;
+
+public:
+ bool CopyFile(const StringImpl& srcPath, const StringImpl& destPath);
+
+ bool QueueFile(const char* data, size_t len);
+ bool QueuePath(const StringImpl& path);
+
+public:
+ FuzzApp();
+ ~FuzzApp();
+
+ void SetTargetType(BfTargetType value) { mTargetType = value; }
+ void SetTargetTriple(const String& value) { mTargetTriple = value; }
+ void SetOptLevel(BfOptLevel value) { mOptLevel = value; }
+ void SetToolset(BfToolsetType value) { mToolset = value; }
+ void SetBuildDir(const String& value) { mBuildDir = value; }
+ void SetWorkingDir(const String& value) { mWorkingDir = value; }
+ void AddDefine(const String& value) { mDefines += mDefines.IsEmpty() ? value : "\n" + value; }
+ void SetStartupObject(const String& value) { mStartupObject = value; }
+ void SetTargetPath(const String& value) { mTargetPath = value; }
+ void SetLinkParams(const String& value) { mLinkParams = value; }
+ void SetCEDest(const String& value) { mCEDest = value; }
+
+ bool Init();
+
+ void PrepareCompiler();
+ bool Compile();
+ void ReleaseCompiler();
+};
+
+extern FuzzApp* gApp;
+
+NS_BF_END
diff --git a/BeefLibs/Beefy2D/src/BFApp.bf b/BeefLibs/Beefy2D/src/BFApp.bf
index 9159aeef..f1f1aefa 100644
--- a/BeefLibs/Beefy2D/src/BFApp.bf
+++ b/BeefLibs/Beefy2D/src/BFApp.bf
@@ -792,9 +792,23 @@ namespace Beefy
BFApp_SetCursor((int32)cursor);
}
- public virtual void* GetClipboardData(String format, out int32 size)
+ public virtual void* GetClipboardData(String format, out int32 size, int waitTime = 500)
{
- return BFApp_GetClipboardData(format, out size);
+ Stopwatch sw = null;
+ repeat
+ {
+ if (sw != null)
+ Thread.Sleep(1);
+ void* result = BFApp_GetClipboardData(format, out size);
+ if (size != -1)
+ return result;
+ if (waitTime == 0)
+ return null;
+ if (sw == null)
+ sw = scope:: .()..Start();
+ }
+ while (waitTime < sw.ElapsedMilliseconds);
+ return null;
}
public virtual void ReleaseClipboardData(void* ptr)
@@ -802,9 +816,9 @@ namespace Beefy
BFApp_ReleaseClipboardData(ptr);
}
- public virtual bool GetClipboardText(String outStr)
+ public virtual bool GetClipboardText(String outStr, int waitTime = 500)
{
- return GetClipboardTextData("text", outStr);
+ return GetClipboardTextData("text", outStr, waitTime);
}
public virtual bool GetClipboardText(String outStr, String extra)
@@ -813,10 +827,10 @@ namespace Beefy
return GetClipboardTextData("text", outStr);
}
- public bool GetClipboardTextData(String format, String outStr)
+ public bool GetClipboardTextData(String format, String outStr, int waitTime = 500)
{
int32 aSize;
- void* clipboardData = GetClipboardData(format, out aSize);
+ void* clipboardData = GetClipboardData(format, out aSize, waitTime);
if (clipboardData == null)
return false;
diff --git a/BeefLibs/Beefy2D/src/Utils.bf b/BeefLibs/Beefy2D/src/Utils.bf
index 9ff8fb2e..f2eaecb0 100644
--- a/BeefLibs/Beefy2D/src/Utils.bf
+++ b/BeefLibs/Beefy2D/src/Utils.bf
@@ -170,7 +170,7 @@ namespace Beefy
if (autoRetry)
{
if (fileOpenErr == .SharingViolation)
- retry = true;
+ retry = i != 99;
}
if (!retry)
return .Err(.OpenError(fileOpenErr));
diff --git a/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf b/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf
index 8a1d7975..0e2dc3d8 100644
--- a/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf
+++ b/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf
@@ -33,7 +33,7 @@ namespace Beefy.theme.dark
}
- public virtual void MouseDown(float x, float y, int btn, int btnCount)
+ public virtual void MouseDown(Rect rect, float x, float y, int btn, int btnCount)
{
}
@@ -63,6 +63,7 @@ namespace Beefy.theme.dark
public bool mScrollToStartOnLostFocus;
public bool mHiliteCurrentLine;
public Dictionary mEmbeds = new .() ~ DeleteDictionaryAndValues!(_);
+ public Embed mEmbedSelected;
public Range? mLineRange;
protected static uint32[] sDefaultColors = new uint32[] ( Color.White ) ~ delete _;
@@ -457,6 +458,12 @@ namespace Beefy.theme.dark
LineStartsChanged();
}
+ public override void ClearText()
+ {
+ mLineRange = null;
+ base.ClearText();
+ }
+
public virtual float DrawText(Graphics g, String str, float x, float y, uint16 typeIdAndFlags)
{
using (g.PushColor(mTextColors[typeIdAndFlags & 0xFF]))
diff --git a/BeefLibs/MiniZ/src/Zip.bf b/BeefLibs/MiniZ/src/Zip.bf
index cc740203..d9ff58b4 100644
--- a/BeefLibs/MiniZ/src/Zip.bf
+++ b/BeefLibs/MiniZ/src/Zip.bf
@@ -2781,6 +2781,11 @@ namespace MiniZ
array_ptr.m_element_size = element_size;
}
+ static mixin ZIP_ARRAY_ELEMENT_PTR(var array_ptr, int index)
+ {
+ &((T*)(array_ptr.m_p))[index]
+ }
+
static mixin ZIP_ARRAY_ELEMENT(var array_ptr, int index)
{
((T*)(array_ptr.m_p))[index]
@@ -2929,9 +2934,9 @@ namespace MiniZ
static bool zip_reader_filename_less(ZipArray* pCentral_dir_array, ZipArray* pCentral_dir_offsets, uint32 l_index, uint32 r_index)
{
- uint8* pL = &ZIP_ARRAY_ELEMENT!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index));
+ uint8* pL = ZIP_ARRAY_ELEMENT_PTR!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index));
uint8* pE;
- uint8* pR = &ZIP_ARRAY_ELEMENT!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, r_index));
+ uint8* pR = ZIP_ARRAY_ELEMENT_PTR!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, r_index));
uint32 l_len = ReadLE16!(pL + ZIP_CDH_FILENAME_LEN_OFS), r_len = ReadLE16!(pR + ZIP_CDH_FILENAME_LEN_OFS);
char8 l = 0, r = 0;
pL += ZIP_CENTRAL_DIR_HEADER_SIZE; pR += ZIP_CENTRAL_DIR_HEADER_SIZE;
@@ -2951,7 +2956,7 @@ namespace MiniZ
ZipInternalState* pState = pZip.m_pState;
ZipArray* pCentral_dir_offsets = &pState.m_central_dir_offsets;
ZipArray* pCentral_dir = &pState.m_central_dir;
- uint32* pIndices = &ZIP_ARRAY_ELEMENT!(&pState.m_sorted_central_dir_offsets, 0);
+ uint32* pIndices = ZIP_ARRAY_ELEMENT_PTR!(&pState.m_sorted_central_dir_offsets, 0);
int size = (int)pZip.m_total_files;
int start = (size - 2) >> 1, end;
while (start >= 0)
@@ -3063,9 +3068,9 @@ namespace MiniZ
int32 total_header_size, comp_size, decomp_size, disk_index;
if ((n < ZIP_CENTRAL_DIR_HEADER_SIZE) || (ReadLE32!(p) != ZIP_CENTRAL_DIR_HEADER_SIG))
return false;
- ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, i) = (uint32)(p - (uint8*)pZip.m_pState.m_central_dir.m_p);
+ *ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_central_dir_offsets, i) = (uint32)(p - (uint8*)pZip.m_pState.m_central_dir.m_p);
if (sort_central_dir)
- ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_sorted_central_dir_offsets, i) = (uint32)i;
+ *ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_sorted_central_dir_offsets, i) = (uint32)i;
comp_size = (int32)ReadLE32!(p + ZIP_CDH_COMPRESSED_SIZE_OFS);
decomp_size = (int32)ReadLE32!(p + ZIP_CDH_DECOMPRESSED_SIZE_OFS);
if (((ReadLE32!(p + ZIP_CDH_METHOD_OFS) == 0) && (decomp_size != comp_size)) || ((decomp_size != 0) && (comp_size == 0)) || (decomp_size == -1) || (comp_size == -1))
@@ -3210,7 +3215,7 @@ namespace MiniZ
{
if ((pZip == null) || (pZip.m_pState == null) || (file_index >= pZip.m_total_files) || (pZip.m_zip_mode != .Reading))
return null;
- return &ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index));
+ return ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index));
}
static bool zip_reader_is_file_encrypted(ZipArchive* pZip, int32 file_index)
@@ -3313,7 +3318,7 @@ namespace MiniZ
{
char8* pR = pR_in;
- uint8* pL = &ZIP_ARRAY_ELEMENT!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index));
+ uint8* pL = ZIP_ARRAY_ELEMENT_PTR!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index));
uint8* pE;
int32 l_len = ReadLE16!(pL + ZIP_CDH_FILENAME_LEN_OFS);
char8 l = 0, r = 0;
@@ -3334,7 +3339,7 @@ namespace MiniZ
ZipInternalState* pState = pZip.m_pState;
ZipArray* pCentral_dir_offsets = &pState.m_central_dir_offsets;
ZipArray* pCentral_dir = &pState.m_central_dir;
- uint32* pIndices = &ZIP_ARRAY_ELEMENT!(&pState.m_sorted_central_dir_offsets, 0);
+ uint32* pIndices = ZIP_ARRAY_ELEMENT_PTR!(&pState.m_sorted_central_dir_offsets, 0);
int32 size = pZip.m_total_files;
int32 filename_len = (int32)Internal.CStrLen(pFilename);
int32 l = 0, h = size - 1;
@@ -3363,7 +3368,7 @@ namespace MiniZ
comment_len = (pComment != null) ? Internal.CStrLen(pComment) : 0; if (comment_len > 0xFFFF) return -1;
for (file_index = 0; file_index < pZip.m_total_files; file_index++)
{
- uint8* pHeader = &ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index));
+ uint8* pHeader = ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index));
int32 filename_len = ReadLE16!(pHeader + ZIP_CDH_FILENAME_LEN_OFS);
char8* pFilename = (char8*)pHeader + ZIP_CENTRAL_DIR_HEADER_SIZE;
if (filename_len < name_len)
diff --git a/BeefLibs/corlib/src/Allocator.bf b/BeefLibs/corlib/src/Allocator.bf
index 10a9c7dd..9f2fab0d 100644
--- a/BeefLibs/corlib/src/Allocator.bf
+++ b/BeefLibs/corlib/src/Allocator.bf
@@ -5,8 +5,13 @@ namespace System
{
interface IRawAllocator
{
- void* Alloc(int size, int align);
- void Free(void* ptr);
+ void* Alloc(int size, int align) mut;
+ void Free(void* ptr) mut;
+ }
+
+ interface ITypedAllocator : IRawAllocator
+ {
+ void* AllocTyped(Type type, int size, int align) mut;
}
struct StdAllocator : IRawAllocator
@@ -22,6 +27,76 @@ namespace System
}
}
+ class SingleAllocator : ITypedAllocator
+ {
+ void* mPtr;
+ int mSize;
+ Type mType;
+
+ [AllowAppend]
+ public this(int size)
+ {
+ void* ptr = append uint8[size]*(?);
+ mPtr = ptr;
+ mSize = size;
+ }
+
+ public ~this()
+ {
+ if ((mType != null) && (mType.IsObject))
+ {
+ Object obj = Internal.UnsafeCastToObject(mPtr);
+ delete:null obj;
+ }
+
+ if (mSize < 0)
+ delete mPtr;
+ }
+
+ protected virtual void* AllocLarge(int size, int align)
+ {
+ return new uint8[size]*;
+ }
+
+ protected virtual void FreeLarge(void* ptr)
+ {
+ delete ptr;
+ }
+
+ public void* Alloc(int size, int align)
+ {
+ return AllocTyped(typeof(void), size, align);
+ }
+
+ public void Free(void* ptr)
+ {
+ Runtime.Assert(ptr == mPtr);
+ mType = typeof(void);
+ }
+
+ [Optimize]
+ public void* AllocTyped(Type type, int size, int align)
+ {
+ Runtime.Assert(mType == null, "SingleAllocator has been used for multiple allocations");
+
+ mType = type;
+ do
+ {
+ if (size > size)
+ break;
+ void* usePtr = (void*)(int)Math.Align((int)mPtr, align);
+ if ((uint8*)usePtr + size > (uint8*)mPtr + mSize)
+ break;
+ mPtr = usePtr;
+ mSize = 0;
+ return mPtr;
+ }
+ mSize = -1;
+ mPtr = AllocLarge(size, align);
+ return mPtr;
+ }
+ }
+
struct AllocWrapper where T : new, delete
{
alloctype(T) mVal;
diff --git a/BeefLibs/corlib/src/Attribute.bf b/BeefLibs/corlib/src/Attribute.bf
index e0eb24ae..795eda52 100644
--- a/BeefLibs/corlib/src/Attribute.bf
+++ b/BeefLibs/corlib/src/Attribute.bf
@@ -425,10 +425,18 @@ namespace System
}
}
- [AttributeUsage(.Field | .StaticField | .Method | .Property /*2*/)]
+ [AttributeUsage(.Field | .StaticField | .Method | .Property | .Types)]
public struct NoShowAttribute : Attribute
{
+ public this()
+ {
+ }
+
+ public this(bool allowDirect)
+ {
+
+ }
}
[AttributeUsage(.Parameter)]
diff --git a/BeefLibs/corlib/src/Collections/List.bf b/BeefLibs/corlib/src/Collections/List.bf
index fd86b82d..f712e655 100644
--- a/BeefLibs/corlib/src/Collections/List.bf
+++ b/BeefLibs/corlib/src/Collections/List.bf
@@ -71,6 +71,12 @@ namespace System.Collections
Add(item);
}
+ [AllowAppend]
+ public this(Span span) : this(span.Length)
+ {
+ AddRange(span);
+ }
+
[AllowAppend]
public this(int capacity)
{
diff --git a/BeefLibs/corlib/src/Collections/SplitList.bf b/BeefLibs/corlib/src/Collections/SplitList.bf
new file mode 100644
index 00000000..b3fec014
--- /dev/null
+++ b/BeefLibs/corlib/src/Collections/SplitList.bf
@@ -0,0 +1,626 @@
+using System;
+using System.Reflection;
+using System.Diagnostics;
+
+namespace System.Collections
+{
+ class SplitList : IEnumerable, IList, ICollection where T : struct
+ {
+ private const int_cosize cDefaultCapacity = 4;
+
+ private void* mItems;
+ private int_cosize mSize;
+ private int_cosize mAllocSize;
+#if VERSION_LIST
+ private int32 mVersion;
+ const String cVersionError = "List changed during enumeration";
+#endif
+
+ [Inline] public int AllocSize => mAllocSize;
+
+ static void GetFields(List fieldList)
+ {
+ if (typeof(T).IsUnion)
+ return;
+ for (var field in typeof(T).GetFields())
+ {
+ if (field.IsStatic)
+ continue;
+ fieldList.Add(field);
+ }
+ }
+
+ [Comptime, OnCompile(.TypeInit)]
+ static void Init()
+ {
+ var fields = GetFields(.. scope .());
+ String code = scope $"""
+ int_cosize[{Math.Max(0, fields.Count - 1)}] mOffsets;
+ """;
+ Compiler.EmitTypeBody(typeof(Self), code);
+
+ if (typeof(T).IsUnion)
+ Runtime.FatalError("Cannot use SplitList on a union");
+ }
+
+ public struct Data
+ {
+ SelfOuter mList;
+
+ public this(SelfOuter list)
+ {
+ mList = list;
+ }
+
+ [Comptime, OnCompile(.TypeInit)]
+ static void Init()
+ {
+ var fields = GetFields(.. scope .());
+ String code = scope .();
+ for (var field in fields)
+ {
+ code.AppendF($"[Inline] public Span<{field.FieldType}> {field.Name} => .((.)((uint8*)mList.mItems");
+ if (@field.Index > 0)
+ code.AppendF($" + mList.mOffsets[{@field.Index - 1}]");
+ code.AppendF($"), mList.mSize);\n");
+ }
+ Compiler.EmitTypeBody(typeof(Self), code);
+ }
+ }
+
+ [Comptime]
+ static void Emit_Get(String prefix, String idx, String item)
+ {
+ var fields = GetFields(.. scope .());
+ String code = scope .();
+ for (var field in fields)
+ {
+ code.AppendF($"{item}.[Friend]{field.Name} = (({field.FieldType}*)((uint8*){prefix}mItems");
+ if (@field.Index > 0)
+ code.AppendF($" + {prefix}mOffsets[{@field.Index - 1}]");
+ code.AppendF($"))[{idx}];\n");
+ }
+
+ Compiler.MixinRoot(code);
+ }
+
+ [Comptime]
+ static void Emit_Set(String prefix, String idx, String item)
+ {
+ String code = scope .();
+ var fields = GetFields(.. scope .());
+ for (var field in fields)
+ {
+ if (field.IsStatic)
+ continue;
+ code.AppendF($"(({field.FieldType}*)((uint8*){prefix}mItems");
+ if (@field.Index > 0)
+ code.AppendF($" + {prefix}mOffsets[{@field.Index - 1}]");
+ code.AppendF($"))[{idx}] = {item}.[Friend]{field.Name};\n");
+ }
+
+ Compiler.MixinRoot(code);
+ }
+
+ [Comptime]
+ static void Emit_Copy(String destOfs, String srcOfs, String length)
+ {
+ var fields = GetFields(.. scope .());
+ String code = scope .();
+ for (var field in fields)
+ {
+ if (@field.Index > 0)
+ code.AppendF($"Internal.MemMove((uint8*)mItems + mOffsets[{@field.Index - 1}] + {destOfs} * {field.FieldType.Stride}, (uint8*)mItems + mOffsets[{@field.Index - 1}] + {srcOfs} * {field.FieldType.Stride}, mSize * {field.FieldType.Stride});\n");
+ else
+ code.AppendF($"Internal.MemMove((uint8*)mItems + {destOfs} * {field.FieldType.Stride}, (uint8*)mItems + {srcOfs} * {field.FieldType.Stride}, {length} * {field.FieldType.Stride});\n");
+ }
+ Compiler.MixinRoot(code);
+ }
+
+ public struct Entry
+ {
+ SelfOuter mList;
+ int_cosize mIdx;
+
+ [Inline]
+ public this(SelfOuter list, int idx)
+ {
+ mList = list;
+ mIdx = (.)idx;
+ }
+
+ [Comptime, OnCompile(.TypeInit)]
+ static void Init()
+ {
+ var fields = GetFields(.. scope .());
+ String code = scope .();
+ for (var field in fields)
+ {
+ code.AppendF($"[Inline] public ref {field.FieldType} {field.Name} => ref (({field.FieldType}*)((uint8*)mList.mItems");
+ if (@field.Index > 0)
+ code.AppendF($" + mList.mOffsets[{@field.Index - 1}]");
+ code.AppendF($"))[mIdx];\n");
+ }
+
+ Compiler.EmitTypeBody(typeof(Self), code);
+ }
+
+ public T Value
+ {
+ get
+ {
+ T value = ?;
+ Emit_Get("mList.", "mIdx", "value");
+ return value;
+ }
+
+ set
+ {
+ Emit_Set("mList.", "mIdx", "value");
+ }
+ }
+
+ public static T operator implicit(Self self) => self.[Inline]Value;
+ }
+
+ public ~this()
+ {
+ Free(mItems);
+ }
+
+ public Entry this[int index]
+ {
+ [Checked]
+ get
+ {
+ Runtime.Assert((uint)index < (uint)mSize);
+ return .(this, index);
+ }
+
+ [Unchecked, Inline]
+ get
+ {
+ return .(this, index);
+ }
+ }
+
+ public int Count => mSize;
+
+ [Inline] public Data Data => .(this);
+
+ protected virtual void* Alloc(int byteSize)
+ {
+ return new uint8[byteSize]*;
+ }
+
+ protected virtual void Free(void* val)
+ {
+ delete val;
+ }
+
+ void* Realloc(int newSize, bool autoFree)
+ {
+ [Comptime]
+ void Emit_Start()
+ {
+ var fields = GetFields(.. scope .());
+ String code = scope $"int_cosize[{Math.Max(0, fields.Count - 1)}] newOffsets;\n";
+ FieldInfo prevFieldInfo = default;
+ for (var field in fields)
+ {
+ if (@field.Index > 0)
+ {
+ code.AppendF($"newOffsets[{@field.Index - 1}] = (.)Math.Align(");
+ if (@field.Index > 1)
+ code.AppendF($"newOffsets[{@field.Index - 2}] + ");
+ code.AppendF($"newSize * {prevFieldInfo.FieldType.Stride}, {field.FieldType.Align});\n");
+ }
+ prevFieldInfo = field;
+ }
+
+ if (fields.Count == 0)
+ code.AppendF("int newSizeBytes = 0;\n");
+ else if (fields.Count == 1)
+ code.AppendF($"int newSizeBytes = newSize * {typeof(T).Stride};\n");
+ else
+ code.AppendF($"int newSizeBytes = newOffsets[{fields.Count - 2}] + newSize * {fields[fields.Count - 1].FieldType.Stride};\n");
+
+ Compiler.MixinRoot(code);
+ }
+
+ [Comptime]
+ void Emit_Copy()
+ {
+ var fields = GetFields(.. scope .());
+ String code = scope .();
+ for (var field in fields)
+ {
+ if (@field.Index > 0)
+ code.AppendF($"Internal.MemCpy((uint8*)newItems + newOffsets[{@field.Index - 1}], (uint8*)mItems + mOffsets[{@field.Index - 1}], mSize * {field.FieldType.Stride});\n");
+ else
+ code.AppendF($"Internal.MemCpy(newItems, mItems, mSize * {field.FieldType.Stride});\n");
+ }
+ Compiler.MixinRoot(code);
+ }
+
+ void* oldAlloc = null;
+ if (newSize > 0)
+ {
+ Emit_Start();
+ void* newItems = Alloc(newSizeBytes);
+ if (mSize > 0)
+ {
+ Emit_Copy();
+ }
+ oldAlloc = mItems;
+ mItems = newItems;
+ mOffsets = newOffsets;
+ mAllocSize = (.)newSize;
+ }
+ else
+ {
+ oldAlloc = mItems;
+ mItems = null;
+ mAllocSize = 0;
+ }
+
+ if ((autoFree) && (oldAlloc != null))
+ {
+ Free(oldAlloc);
+ return null;
+ }
+
+ return oldAlloc;
+ }
+
+ public void* EnsureCapacity(int min, bool autoFree)
+ {
+ int allocSize = AllocSize;
+ if (allocSize >= min)
+ return null;
+
+ int_cosize newCapacity = (int_cosize)(allocSize == 0 ? cDefaultCapacity : allocSize * 2);
+ // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
+ // Note that this check works even when mItems.Length overflowed thanks to the (uint) cast
+ //if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
+ if (newCapacity < min) newCapacity = (int_cosize)min;
+ return Realloc(newCapacity, autoFree);
+ }
+
+ public void Reserve(int size)
+ {
+ EnsureCapacity(size, true);
+ }
+
+ /// Adds an item to the back of the list.
+ public void Add(T item)
+ {
+ if (mSize == AllocSize)
+ {
+ // We free after the insert to allow for inserting a ref to another list element
+ let oldPtr = EnsureCapacity(mSize + 1, false);
+ Emit_Set("", "mSize", "item");
+ mSize++;
+ Free(oldPtr);
+ return;
+ }
+
+ Emit_Set("", "mSize", "item");
+ mSize++;
+#if VERSION_LIST
+ mVersion++;
+#endif
+ }
+
+ protected override void GCMarkMembers()
+ {
+ [Comptime]
+ void Emit()
+ {
+ String code = scope .();
+ var fields = GetFields(.. scope .());
+ for (var field in fields)
+ {
+ if (!field.FieldType.WantsMark)
+ continue;
+ code.AppendF($"for (int i < mSize) {{ GC.Mark!((({field.FieldType}*)((uint8*)mItems");
+ if (@field.Index > 0)
+ code.AppendF($" + mOffsets[{@field.Index - 1}]");
+ code.Append("))[i]); }\n");
+ }
+ Compiler.MixinRoot(code);
+ }
+
+ if (mItems == null)
+ return;
+ let type = typeof(T);
+ if ((type.[Friend]mTypeFlags & .WantsMark) == 0)
+ return;
+ Emit();
+ }
+
+ public void Clear()
+ {
+ if (mSize > 0)
+ {
+ mSize = 0;
+#if VERSION_LIST
+ mVersion++;
+#endif
+ }
+ }
+
+ public bool Contains(T item)
+ {
+ for (int i < mSize)
+ if (this[i].Value == item)
+ return true;
+ return false;
+ }
+
+ public void CopyTo(Span span)
+ {
+ for (int i < span.Length)
+ span[i] = this[i].Value;
+ }
+
+ public bool Remove(T item)
+ {
+ int index = IndexOf(item);
+ if (index >= 0)
+ {
+ RemoveAt(index);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void RemoveAt(int index)
+ {
+ Debug.Assert((uint)index < (uint)mSize);
+ if (index < mSize - 1)
+ {
+ int copySize = mSize - index - 1;
+ (void)copySize;
+ Emit_Copy("index", "(index + 1)", "copySize");
+ }
+ mSize--;
+#if VERSION_LIST
+ mVersion++;
+#endif
+ }
+
+ public void RemoveRange(int index, int count)
+ {
+ Debug.Assert((uint)index + (uint)count <= (uint)mSize);
+ if (index + count <= mSize - 1)
+ {
+ for (int i = index; i < mSize - count; i++)
+ mItems[i] = mItems[i + count];
+ }
+ mSize -= (.)count;
+#if VERSION_LIST
+ mVersion++;
+#endif
+ }
+
+ /// Will change the order of items in the list
+ public void RemoveAtFast(int index)
+ {
+ Debug.Assert((uint32)index < (uint32)mSize);
+ if (mSize > 1)
+ this[index].Value = this[mSize - 1].Value;
+ mSize--;
+#if VERSION_LIST
+ mVersion++;
+#endif
+ }
+
+ Variant IList.this[int index]
+ {
+ get
+ {
+ return [Unbound]Variant.Create(this[index]);
+ }
+
+ set
+ {
+ ThrowUnimplemented();
+ }
+ }
+
+ public Enumerator GetEnumerator()
+ {
+ return .(this);
+ }
+
+ public int FindIndex(Predicate match)
+ {
+ for (int i = 0; i < mSize; i++)
+ if (match(this[i].Value))
+ return i;
+ return -1;
+ }
+
+ public int IndexOf(T item)
+ {
+ for (int i = 0; i < mSize; i++)
+ if (this[i].Value == item)
+ return i;
+ return -1;
+ }
+
+ public int IndexOf(T item, int index)
+ {
+ for (int i = index; i < mSize; i++)
+ if (this[i].Value == item)
+ return i;
+ return -1;
+ }
+
+ public int IndexOf(T item, int index, int count)
+ {
+ for (int i = index; i < index + count; i++)
+ if (this[i].Value == item)
+ return i;
+ return -1;
+ }
+
+ public int IndexOfStrict(T item)
+ {
+ for (int i = 0; i < mSize; i++)
+ if (this[i].Value === item)
+ return i;
+ return -1;
+ }
+
+ public int IndexOfStrict(T item, int index)
+ {
+ for (int i = index; i < mSize; i++)
+ if (this[i].Value === item)
+ return i;
+ return -1;
+ }
+
+ public int IndexOfStrict(T item, int index, int count)
+ {
+ for (int i = index; i < index + count; i++)
+ if (this[i].Value === item)
+ return i;
+ return -1;
+ }
+
+ public int IndexOfAlt(TAlt item) where TAlt : IHashable where bool : operator T == TAlt
+ {
+ for (int i = 0; i < mSize; i++)
+ if (this[i].Value == item)
+ return i;
+ return -1;
+ }
+
+ public int LastIndexOf(T item)
+ {
+ for (int i = mSize - 1; i >= 0; i--)
+ if (this[i].Value == item)
+ return i;
+ return -1;
+ }
+
+ public int LastIndexOfStrict(T item)
+ {
+ for (int i = mSize - 1; i >= 0; i--)
+ if (this[i].Value === item)
+ return i;
+ return -1;
+ }
+
+ public struct Enumerator : IEnumerator, IResettable
+ {
+ private SplitList mList;
+ private int mIndex;
+#if VERSION_LIST
+ private int32 mVersion;
+#endif
+ public this(SplitList list)
+ {
+ mList = list;
+ mIndex = 0;
+#if VERSION_LIST
+ mVersion = list.mVersion;
+#endif
+ }
+
+#if VERSION_LIST
+ void CheckVersion()
+ {
+ if (mVersion != mList.mVersion)
+ Runtime.FatalError(cVersionError);
+ }
+#endif
+
+ public void Dispose()
+ {
+ }
+
+ public bool MoveNext() mut
+ {
+ var localList = mList;
+ if ((uint(mIndex) < uint(localList.mSize)))
+ {
+ mIndex++;
+ return true;
+ }
+ return MoveNextRare();
+ }
+
+ private bool MoveNextRare() mut
+ {
+#if VERSION_LIST
+ CheckVersion();
+#endif
+ mIndex = mList.mSize + 1;
+ return false;
+ }
+
+ public Entry Current
+ {
+ get
+ {
+ return mList[mIndex - 1];
+ }
+ }
+
+ public int Index
+ {
+ get
+ {
+ return mIndex - 1;
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ return mList.Count;
+ }
+ }
+
+ public void Remove() mut
+ {
+ int curIdx = mIndex - 1;
+ mList.RemoveAt(curIdx);
+#if VERSION_LIST
+ mVersion = mList.mVersion;
+#endif
+ mIndex = curIdx;
+ }
+
+ public void RemoveFast() mut
+ {
+ int curIdx = mIndex - 1;
+ int lastIdx = mList.Count - 1;
+ if (curIdx < lastIdx)
+ mList[curIdx].Value = mList[lastIdx].Value;
+ mList.RemoveAt(lastIdx);
+#if VERSION_LIST
+ mVersion = mList.mVersion;
+#endif
+ mIndex = curIdx;
+ }
+
+ public void Reset() mut
+ {
+ mIndex = 0;
+ }
+
+ public Result GetNext() mut
+ {
+ if (!MoveNext())
+ return .Err;
+ return Current;
+ }
+ }
+ }
+}
diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf
index 17d7a8bf..1be6d59d 100644
--- a/BeefLibs/corlib/src/Compiler.bf
+++ b/BeefLibs/corlib/src/Compiler.bf
@@ -259,6 +259,9 @@ namespace System
[LinkName("#CallerExpression")]
public static extern String[0x00FFFFFF] CallerExpression;
+ [LinkName("#OrigCalleeType")]
+ public static extern Type OrigCalleeType;
+
[LinkName("#ProjectName")]
public static extern String ProjectName;
@@ -280,6 +283,9 @@ namespace System
[LinkName("#CompileRev")]
public static extern int32 CompileRev;
+ [LinkName("#NextId")]
+ public static extern int64 NextId;
+
[Comptime(ConstEval=true)]
public static void Assert(bool cond)
{
@@ -287,6 +293,7 @@ namespace System
Runtime.FatalError("Assert failed");
}
+ static extern void Comptime_SetReturnType(int32 typeId);
static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str);
static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags);
static extern void Comptime_EmitTypeBody(int32 typeId, StringView text);
@@ -309,6 +316,12 @@ namespace System
Comptime_EmitTypeBody((.)owner.TypeId, text);
}
+ [Comptime(OnlyFromComptime=true)]
+ public static void SetReturnType(Type type)
+ {
+ Comptime_SetReturnType((.)type.TypeId);
+ }
+
[Comptime(OnlyFromComptime=true)]
public static void EmitAddInterface(Type owner, Type iface)
{
diff --git a/BeefLibs/corlib/src/Enum.bf b/BeefLibs/corlib/src/Enum.bf
index d334bb17..08326d01 100644
--- a/BeefLibs/corlib/src/Enum.bf
+++ b/BeefLibs/corlib/src/Enum.bf
@@ -5,6 +5,62 @@ namespace System
{
struct Enum
{
+ [NoShow(true)]
+ [Comptime(ConstEval=true)]
+ public static int GetCount() where T : Enum
+ {
+ int count = 0;
+ for (var field in typeof(T).GetFields())
+ {
+ if (field.IsEnumCase)
+ count++;
+ }
+ return count;
+ }
+
+ [NoShow(true)]
+ [Comptime(ConstEval=true)]
+ public static var GetMinValue() where T : Enum
+ {
+ Compiler.SetReturnType(typeof(T));
+
+ int? minValue = null;
+ for (var field in typeof(T).GetFields())
+ {
+ if (field.IsEnumCase)
+ {
+ if (minValue == null)
+ minValue = field.[Friend]mFieldData.mData;
+ else
+ minValue = Math.Min(minValue.Value, field.[Friend]mFieldData.mData);
+ }
+ }
+ return minValue.ValueOrDefault;
+ }
+
+ [NoShow(true)]
+ [Comptime(ConstEval=true)]
+ public static var GetMaxValue() where T : Enum
+ {
+ Compiler.SetReturnType(typeof(T));
+
+ int? maxValue = null;
+ for (var field in typeof(T).GetFields())
+ {
+ if (field.IsEnumCase)
+ {
+ if (maxValue == null)
+ maxValue = field.[Friend]mFieldData.mData;
+ else
+ maxValue = Math.Max(maxValue.Value, field.[Friend]mFieldData.mData);
+ }
+ }
+ if (maxValue == null)
+ return -1;
+ return maxValue.ValueOrDefault;
+ }
+
+ [NoShow(true)]
public static void EnumToString(Type type, String strBuffer, int64 iVal)
{
for (var field in type.GetFields())
@@ -19,6 +75,7 @@ namespace System
iVal.ToString(strBuffer);
}
+ [NoShow(true)]
public static Result Parse(StringView str, bool ignoreCase = false) where T : enum
{
for (var (name, data) in GetEnumerator())
@@ -32,7 +89,8 @@ namespace System
return .Err;
}
- public static bool IsDefined(T value)
+ [NoShow(true)]
+ public static bool IsDefined(T value) where T : Enum
where T : enum
{
for (var data in GetValues())
@@ -44,24 +102,28 @@ namespace System
return false;
}
+ [NoShow(true)]
public static EnumEnumerator GetEnumerator()
where TEnum : enum
{
return .();
}
+ [NoShow(true)]
public static EnumValuesEnumerator GetValues()
where TEnum : enum
{
return .();
}
-
+
+ [NoShow(true)]
public static EnumNamesEnumerator GetNames()
where TEnum : enum
{
return .();
}
+ [NoShow(true)]
private struct EnumFieldsEnumerator
where TEnum : enum
{
@@ -127,6 +189,7 @@ namespace System
}
}
+ [NoShow(true)]
public struct EnumEnumerator : EnumFieldsEnumerator, IEnumerator<(StringView name, TEnum value)>
where TEnum : enum
{
@@ -146,6 +209,7 @@ namespace System
}
}
+ [NoShow(true)]
public struct EnumValuesEnumerator : EnumFieldsEnumerator, IEnumerator
where TEnum : enum
{
@@ -165,6 +229,7 @@ namespace System
}
}
+ [NoShow(true)]
public struct EnumNamesEnumerator : EnumFieldsEnumerator, IEnumerator
where TEnum : enum
{
diff --git a/BeefLibs/corlib/src/Event.bf b/BeefLibs/corlib/src/Event.bf
index 9e760c0d..51b71299 100644
--- a/BeefLibs/corlib/src/Event.bf
+++ b/BeefLibs/corlib/src/Event.bf
@@ -13,10 +13,17 @@ namespace System
// If we are enumerating then mData points to the enumerator.
int mData;
+#if BF_64_BIT
+ const int sIsEnumerating = (.)0x8000'0000'0000'0000;
+ const int sHadEnumRemoves = 0x4000'0000'0000'0000;
+ const int sFlagsMask = (.)0xC000'0000'0000'0000;
+ const int sDataMask = ~sFlagsMask;
+#else
const int sIsEnumerating = 1;
const int sHadEnumRemoves = 2;
const int sFlagsMask = 3;
const int sDataMask = ~sFlagsMask;
+#endif
public bool HasListeners
{
diff --git a/BeefLibs/corlib/src/GC.bf b/BeefLibs/corlib/src/GC.bf
index f8c0e176..04153c0c 100644
--- a/BeefLibs/corlib/src/GC.bf
+++ b/BeefLibs/corlib/src/GC.bf
@@ -149,6 +149,22 @@ namespace System
public static void ExcludeThreadId(int thereadId) {}
#endif
+ [DisableObjectAccessChecks]
+ static void MarkAppendedObject(Object obj)
+ {
+#if BF_ENABLE_REALTIME_LEAK_CHECK
+#if BF_ENABLE_OBJECT_DEBUG_FLAGS
+ ClassVData* maskedVData = (ClassVData*)(void*)(obj.[Friend]mClassVData & ~(int)0xFF);
+ if (maskedVData == null)
+ return;
+#else
+ if (obj.[Friend]mClassVData == null)
+ return;
+#endif
+ obj.[Friend]GCMarkMembers();
+#endif
+ }
+
static void MarkDerefedObject(Object* obj)
{
#if BF_ENABLE_REALTIME_LEAK_CHECK
diff --git a/BeefLibs/corlib/src/IO/File.bf b/BeefLibs/corlib/src/IO/File.bf
index bfae4061..2926569c 100644
--- a/BeefLibs/corlib/src/IO/File.bf
+++ b/BeefLibs/corlib/src/IO/File.bf
@@ -31,7 +31,7 @@ namespace System.IO
public static Result ReadAll(StringView path, List outData)
{
FileStream fs = scope FileStream();
- var result = fs.Open(path, .Open, .Read);
+ var result = fs.Open(path, .Open, .Read, .ReadWrite);
if (result case .Err(let err))
return .Err(.OpenError(err));
diff --git a/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf b/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf
index 420757ac..1a73b017 100644
--- a/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf
+++ b/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf
@@ -110,7 +110,7 @@ namespace System.IO
Windows.SHCreateItemFromParsingName(mSelectedPath.ToScopedNativeWChar!(), null, Windows.COM_IShellItem.sIID, (void**)&folderShellItem);
if (folderShellItem != null)
{
- fileDialog.VT.SetDefaultFolder(fileDialog, folderShellItem);
+ fileDialog.VT.SetFolder(fileDialog, folderShellItem);
folderShellItem.VT.Release(folderShellItem);
}
}
diff --git a/BeefLibs/corlib/src/IO/MemoryStream.bf b/BeefLibs/corlib/src/IO/MemoryStream.bf
index 53dbe501..1522dad0 100644
--- a/BeefLibs/corlib/src/IO/MemoryStream.bf
+++ b/BeefLibs/corlib/src/IO/MemoryStream.bf
@@ -4,7 +4,8 @@ namespace System.IO
{
class MemoryStream : Stream
{
- List mMemory ~ delete _;
+ bool mOwns;
+ List mMemory ~ { if (mOwns) delete _; }
int mPosition = 0;
public override int64 Position
@@ -46,14 +47,18 @@ namespace System.IO
public this()
{
+ mOwns = true;
mMemory = new List();
}
- public this(List memory)
+ public this(List memory, bool owns = true)
{
+ mOwns = owns;
mMemory = memory;
}
+ public List Memory => mMemory;
+
public override Result TryRead(Span data)
{
let count = data.Length;
diff --git a/BeefLibs/corlib/src/IRefCounted.bf b/BeefLibs/corlib/src/IRefCounted.bf
index 1a0b7ca3..a62a01d0 100644
--- a/BeefLibs/corlib/src/IRefCounted.bf
+++ b/BeefLibs/corlib/src/IRefCounted.bf
@@ -6,7 +6,7 @@ namespace System
interface IRefCounted
{
void AddRef();
- void ReleaseRef();
+ void Release();
}
class RefCounted : IRefCounted
@@ -63,5 +63,167 @@ namespace System
Debug.Assert(refCount >= 0);
return refCount;
}
+
+ void IRefCounted.Release()
+ {
+ ReleaseRef();
+ }
+
+ struct Alloc
+ {
+ public void* Alloc(Type type, int size, int align)
+ {
+ int sizeAdd = size + Math.Max(align, sizeof(int));
+
+ void* data = Internal.Malloc(sizeAdd);
+ return (uint8*)data + sizeAdd;
+ }
+ }
+ }
+
+ class RefCounted : IRefCounted where T : class, delete
+ {
+ public T mVal;
+ public int mRefCount = 1;
+
+ public int RefCount => mRefCount;
+ public T Value => mVal;
+
+ protected this()
+ {
+
+ }
+
+ protected ~this()
+ {
+ Debug.Assert(mRefCount == 0);
+ delete mVal;
+ }
+
+ [OnCompile(.TypeInit), Comptime]
+ static void Init()
+ {
+ String emitStr = scope .();
+
+ for (var methodInfo in typeof(T).GetMethods(.Public))
+ {
+ if (methodInfo.IsStatic)
+ continue;
+ if (!methodInfo.IsConstructor)
+ continue;
+
+ emitStr.AppendF("public static RefCounted Create(");
+ methodInfo.GetParamsDecl(emitStr);
+ emitStr.AppendF(")\n");
+ emitStr.AppendF("{{\n");
+ emitStr.AppendF("\treturn new [Friend] RefCountedAppend(");
+ methodInfo.GetArgsList(emitStr);
+ emitStr.AppendF(");\n}}\n");
+ }
+
+ Compiler.EmitTypeBody(typeof(Self), emitStr);
+ }
+
+ public static RefCounted Attach(T val)
+ {
+ return new Self() { mVal = val };
+ }
+
+ public virtual void DeleteSelf()
+ {
+ delete this;
+ }
+
+ public void DeleteUnchecked()
+ {
+ mRefCount = 0;
+ DeleteSelf();
+ }
+
+ public void AddRef()
+ {
+ Interlocked.Increment(ref mRefCount);
+ }
+
+ public void Release()
+ {
+ int refCount = Interlocked.Decrement(ref mRefCount);
+ Debug.Assert(refCount >= 0);
+ if (refCount == 0)
+ DeleteSelf();
+ }
+
+ public void ReleaseLastRef()
+ {
+ int refCount = Interlocked.Decrement(ref mRefCount);
+ Debug.Assert(refCount == 0);
+ if (refCount == 0)
+ DeleteSelf();
+ }
+
+ public int ReleaseRefNoDelete()
+ {
+ int refCount = Interlocked.Decrement(ref mRefCount);
+ Debug.Assert(refCount >= 0);
+ return refCount;
+ }
+
+ public virtual T Detach()
+ {
+ var val = mVal;
+ mVal = null;
+ return val;
+ }
+
+ public static T operator->(Self self)
+ {
+ return self.mVal;
+ }
+
+ public static T operator implicit(Self self)
+ {
+ return self.mVal;
+ }
+ }
+
+ class RefCountedAppend : RefCounted where T : class, new, delete
+ {
+ protected ~this()
+ {
+ Debug.Assert(mRefCount == 0);
+ delete:append mVal;
+ mVal = null;
+ }
+
+ [OnCompile(.TypeInit), Comptime]
+ static void Init()
+ {
+ String emitStr = scope .();
+
+ for (var methodInfo in typeof(T).GetMethods(.Public))
+ {
+ if (methodInfo.IsStatic)
+ continue;
+ if (!methodInfo.IsConstructor)
+ continue;
+
+ emitStr.AppendF("[AllowAppend]\nprotected this(");
+ methodInfo.GetParamsDecl(emitStr);
+ emitStr.AppendF(")\n");
+ emitStr.AppendF("{{\n");
+ emitStr.AppendF("\tvar val = append T(");
+ methodInfo.GetArgsList(emitStr);
+ emitStr.AppendF(");\n");
+ emitStr.AppendF("\tmVal = val;\n");
+ emitStr.AppendF("}}\n");
+ }
+
+ Compiler.EmitTypeBody(typeof(Self), emitStr);
+ }
+
+ public override T Detach()
+ {
+ Runtime.FatalError("Can only detach from objects created via RefCounted.Attach");
+ }
}
}
diff --git a/BeefLibs/corlib/src/Internal.bf b/BeefLibs/corlib/src/Internal.bf
index 26b1f49a..0ecbd02a 100644
--- a/BeefLibs/corlib/src/Internal.bf
+++ b/BeefLibs/corlib/src/Internal.bf
@@ -72,11 +72,6 @@ namespace System
return &mVAList;
#endif
}
-
- public void* ToVAListPtr() mut
- {
- return &mVAList;
- }
}
[AlwaysInclude]
@@ -89,6 +84,8 @@ namespace System
[CallingConvention(.Cdecl), NoReturn]
public static extern void ThrowIndexOutOfRange(int stackOffset = 0);
[CallingConvention(.Cdecl), NoReturn]
+ public static extern void ThrowObjectNotInitialized(int stackOffset = 0);
+ [CallingConvention(.Cdecl), NoReturn]
public static extern void FatalError(String error, int stackOffset = 0);
[Intrinsic("memcpy")]
public static extern void MemCpy(void* dest, void* src, int length, int32 align = 1, bool isVolatile = false);
diff --git a/BeefLibs/corlib/src/Lazy.bf b/BeefLibs/corlib/src/Lazy.bf
new file mode 100644
index 00000000..f33470c1
--- /dev/null
+++ b/BeefLibs/corlib/src/Lazy.bf
@@ -0,0 +1,288 @@
+using System.Threading;
+
+namespace System
+{
+ enum LazyThreadMode
+ {
+ None,
+ Lock,
+ Lockless
+ }
+
+ class Lazy
+ {
+ protected struct Entry
+ {
+ public SelfOuter mSingleton;
+ public T mValue;
+ }
+
+ protected Monitor mMonitor ~ delete _;
+ protected LazyThreadMode mThreadMode;
+ protected volatile int mInitId;
+ protected T mValue;
+ delegate T() mCreateDlg ~ delete _;
+ delegate void(T value) mReleaseDlg ~ delete _;
+
+ public this()
+ {
+
+ }
+
+ public this(LazyThreadMode threadMode)
+ {
+ mThreadMode = threadMode;
+ Init();
+ }
+
+ public this(LazyThreadMode threadMode, delegate T() createDlg = null, delegate void(T value) releaseDlg = null)
+ {
+ mThreadMode = threadMode;
+ mCreateDlg = createDlg;
+ mReleaseDlg = releaseDlg;
+ Init();
+ }
+
+ public this(delegate void(T value) releaseDlg) : this()
+ {
+ mReleaseDlg = releaseDlg;
+ }
+
+ void Init()
+ {
+ switch (mThreadMode)
+ {
+ case .None:
+ case .Lock:
+ mMonitor = new Monitor();
+ case .Lockless:
+ }
+
+ }
+
+ public ~this()
+ {
+ ReleaseValue(mut mValue);
+ }
+
+ protected T DefaultCreateValue()
+ {
+ return default;
+ }
+
+ protected T DefaultCreateValue() where T : struct, new
+ {
+ return T();
+ }
+
+ protected T DefaultCreateValue() where T : class
+ {
+ Runtime.FatalError("No create delegate specified and no public default constructor is available");
+ }
+
+ protected T DefaultCreateValue() where T : class, new
+ {
+ return new T();
+ }
+
+ protected virtual T CreateValue()
+ {
+ return DefaultCreateValue();
+ }
+
+ protected void DefaultReleaseValue(mut T val)
+ {
+
+ }
+
+ protected void DefaultReleaseValue(mut T val) where T : struct, IDisposable
+ {
+ val.Dispose();
+ }
+
+ protected void DefaultReleaseValue(mut T val) where T : class
+ {
+ delete (Object)val;
+ }
+
+ protected virtual void ReleaseValue(mut T val)
+ {
+ DefaultReleaseValue(mut val);
+ }
+
+ public ref T Value
+ {
+ get
+ {
+ if (mInitId == -1)
+ return ref mValue;
+
+ switch (mThreadMode)
+ {
+ case .None:
+ mValue = CreateValue();
+ case .Lock:
+ using (mMonitor.Enter())
+ {
+ if (mInitId != -1)
+ {
+ mValue = CreateValue();
+ Interlocked.Fence();
+ mInitId = -1;
+ }
+ }
+ case .Lockless:
+ int threadId = Thread.CurrentThreadId;
+ while (true)
+ {
+ int initId = Interlocked.CompareExchange(ref mInitId, 0, threadId);
+ if (initId == -1)
+ break;
+
+ if (initId == 0)
+ {
+ Interlocked.Fence();
+ mValue = CreateValue();
+ Interlocked.Fence();
+ mInitId = -1;
+ break;
+ }
+ }
+ }
+ return ref mValue;
+ }
+ }
+
+ public bool IsValueCreated => mInitId != 0;
+
+ public static ref T operator->(Self self) => ref self.[Inline]Value;
+
+ public override void ToString(String strBuffer)
+ {
+ if (IsValueCreated)
+ strBuffer.AppendF($"Value: {Value}");
+ else
+ strBuffer.AppendF($"No Value");
+ }
+ }
+
+ class LazyTLS
+ {
+ protected struct Entry
+ {
+ public SelfOuter mSingleton;
+ public T mValue;
+ }
+
+ void* mData;
+ delegate T() mCreateDlg ~ delete _;
+ delegate void(T value) mReleaseDlg ~ delete _;
+
+ public this()
+ {
+ InitTLS();
+ }
+
+ public this(delegate T() createDlg = null, delegate void(T value) releaseDlg = null)
+ {
+ mCreateDlg = createDlg;
+ mReleaseDlg = releaseDlg;
+ InitTLS();
+ }
+
+ void InitTLS()
+ {
+ mData = Platform.BfpTLS_Create((ptr) =>
+ {
+ var entry = (Entry*)ptr;
+ if (entry.mSingleton.mReleaseDlg != null)
+ entry.mSingleton.mReleaseDlg(entry.mValue);
+ else
+ entry.mSingleton.ReleaseValue(mut entry.mValue);
+ delete entry;
+ });
+ }
+
+ public ~this()
+ {
+ Platform.BfpTLS_Release((.)mData);
+ }
+
+ protected T DefaultCreateValue()
+ {
+ return default;
+ }
+
+ protected T DefaultCreateValue() where T : struct, new
+ {
+ return T();
+ }
+
+ protected T DefaultCreateValue() where T : class
+ {
+ Runtime.FatalError("No create delegate specified and no public default constructor is available");
+ }
+
+ protected T DefaultCreateValue() where T : class, new
+ {
+ return new T();
+ }
+
+ protected virtual T CreateValue()
+ {
+ return DefaultCreateValue();
+ }
+
+ protected void DefaultReleaseValue(mut T val)
+ {
+
+ }
+
+ protected void DefaultReleaseValue(mut T val) where T : struct, IDisposable
+ {
+ val.Dispose();
+ }
+
+
+ protected void DefaultReleaseValue(mut T val) where T : class
+ {
+ delete (Object)val;
+ }
+
+ protected virtual void ReleaseValue(mut T val)
+ {
+ DefaultReleaseValue(mut val);
+ }
+
+ public ref T Value
+ {
+ get
+ {
+ void* ptr = Platform.BfpTLS_GetValue((.)mData);
+ if (ptr != null)
+ return ref ((Entry*)ptr).mValue;
+
+ Entry* entry = new Entry();
+ entry.mSingleton = this;
+ if (mCreateDlg != null)
+ entry.mValue = mCreateDlg();
+ else
+ entry.mValue = CreateValue();
+ Platform.BfpTLS_SetValue((.)mData, entry);
+ return ref entry.mValue;
+ }
+ }
+
+ public bool IsValueCreated => Platform.BfpTLS_GetValue((.)mData) != null;
+
+ public static ref T operator->(Self self) => ref self.[Inline]Value;
+
+ public override void ToString(String strBuffer)
+ {
+ if (IsValueCreated)
+ strBuffer.AppendF($"Value: {Value}");
+ else
+ strBuffer.AppendF($"No Value");
+ }
+ }
+}
diff --git a/BeefLibs/corlib/src/Math.bf b/BeefLibs/corlib/src/Math.bf
index ccd1aab0..3777f47b 100644
--- a/BeefLibs/corlib/src/Math.bf
+++ b/BeefLibs/corlib/src/Math.bf
@@ -192,8 +192,18 @@ namespace System
[CLink]
private static extern double modf(double x, out double intpart);
+
+#if BF_PLATFORM_WINDOWS && BF_64_BIT
[CLink]
private static extern float modff(float x, out float intpart);
+#else
+ private static float modff(float x, out float intpart)
+ {
+ var f = modf(x, var i);
+ intpart = (.)i;
+ return (.)f;
+ }
+#endif
public static float Truncate(float f)
{
diff --git a/BeefLibs/corlib/src/Nullable.bf b/BeefLibs/corlib/src/Nullable.bf
index 1e195af7..6830b790 100644
--- a/BeefLibs/corlib/src/Nullable.bf
+++ b/BeefLibs/corlib/src/Nullable.bf
@@ -35,6 +35,15 @@ namespace System
}
}
+ public T ValueOrDefault
+ {
+ [Inline]
+ get
+ {
+ return mValue;
+ }
+ }
+
public ref T ValueRef
{
[Inline]
@@ -96,9 +105,19 @@ namespace System
[Inline]
public static explicit operator T(Nullable value)
{
+ if (!value.mHasValue)
+ Debug.FatalError("Value requested for null nullable.");
return value.mValue;
}
+ [Inline]
+ public static ref T operator->(ref Nullable value)
+ {
+ if (!value.mHasValue)
+ Debug.FatalError("Value requested for null nullable.");
+ return ref value.mValue;
+ }
+
[Inline, Commutable]
public static bool operator==(Nullable lhs, T rhs)
{
@@ -401,31 +420,6 @@ namespace System
return Nullable(lhs.mValue | rhs.mValue);
}
- //
-
- public static T operator??(Nullable lhs, T rhs)
- {
- return (lhs.mHasValue) ? lhs.mValue : rhs;
- }
-
- public static TResult? operator??(TOther lhs, Nullable rhs) where TResult : operator TOther ?? T where TResult : struct
- {
- if (!rhs.mHasValue) return null;
- return Nullable(lhs ?? rhs.mValue);
- }
-
- public static TResult? operator??(Nullable lhs, TOther rhs) where TResult : operator T ?? TOther where TResult : struct
- {
- if (!lhs.mHasValue) return null;
- return Nullable(lhs.mValue ?? rhs);
- }
-
- public static TResult? operator??(Nullable lhs, Nullable rhs) where TOther : struct where TResult : operator T ?? TOther where TResult : struct
- {
- if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
- return Nullable(lhs.mValue ?? rhs.mValue);
- }
-
//
public static TResult? operator<< (TOther lhs, Nullable rhs) where TResult : operator TOther << T where TResult : struct
diff --git a/BeefLibs/corlib/src/Platform.bf b/BeefLibs/corlib/src/Platform.bf
index b23c378f..7fc94710 100644
--- a/BeefLibs/corlib/src/Platform.bf
+++ b/BeefLibs/corlib/src/Platform.bf
@@ -42,6 +42,7 @@ namespace System
public struct BfpEvent {};
public struct BfpFileWatcher {}
public struct BfpProcess {}
+ public struct BfpTLS;
public enum BfpSystemResult : int32
{
@@ -95,6 +96,18 @@ namespace System
[CallingConvention(.Stdcall), CLink]
public static extern void BfpSystem_GetComputerName(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult);
+ [CallingConvention(.Stdcall), CLink]
+ public static extern int BfpThread_GetCurrentId();
+
+ [CallingConvention(.Stdcall), CLink]
+ public static extern BfpTLS* BfpTLS_Create(function [CallingConvention(.Stdcall)] void(void*) exitProc);
+ [CallingConvention(.Stdcall), CLink]
+ public static extern void BfpTLS_Release(BfpTLS* tls);
+ [CallingConvention(.Stdcall), CLink]
+ public static extern void BfpTLS_SetValue(BfpTLS* tls, void* value);
+ [CallingConvention(.Stdcall), CLink]
+ public static extern void* BfpTLS_GetValue(BfpTLS* tls);
+
public enum BfpFileWatcherFlags : int32
{
None = 0,
diff --git a/BeefLibs/corlib/src/Range.bf b/BeefLibs/corlib/src/Range.bf
index 7614d3c6..2ff245fc 100644
--- a/BeefLibs/corlib/src/Range.bf
+++ b/BeefLibs/corlib/src/Range.bf
@@ -225,6 +225,187 @@ namespace System
}
}
+ struct Range where T : operator T + int where int : operator T - T where bool : operator T >= T
+ {
+ protected T mStart;
+ protected T mEnd;
+
+ public this()
+ {
+ mStart = default;
+ mEnd = default;
+ }
+
+ [Inline]
+ public this(T start, T end)
+ {
+ Debug.Assert(end >= start);
+ mStart = start;
+ mEnd = end;
+ }
+
+ public int Length
+ {
+ [Inline]
+ get
+ {
+ return mEnd - mStart;
+ }
+
+ [Inline]
+ set mut
+ {
+ mEnd = mStart + value;
+ }
+ }
+
+ public T Start
+ {
+ [Inline]
+ get
+ {
+ return mStart;
+ }
+
+ [Inline]
+ set mut
+ {
+ mStart = value;
+ }
+ }
+
+ public T End
+ {
+ [Inline]
+ get
+ {
+ return mEnd;
+ }
+
+ set mut
+ {
+ mEnd = value;
+ }
+ }
+
+ public bool IsEmpty
+ {
+ [Inline]
+ get
+ {
+ return mEnd == mStart;
+ }
+ }
+
+ public ReverseEnumerator Reversed
+ {
+ [Inline]
+ get
+ {
+ return ReverseEnumerator(mEnd + -1, mStart);
+ }
+ }
+
+ public bool Contains(T idx)
+ {
+ return (idx >= mStart) && !(idx >= mEnd);
+ }
+
+ public bool Contains(Range val)
+ {
+ return (val.[Friend]mStart >= mStart) && (val.[Friend]mEnd <= mEnd);
+ }
+
+ public void Clear() mut
+ {
+ mStart = default;
+ mEnd = default;
+ }
+
+ [Inline]
+ public Enumerator GetEnumerator()
+ {
+ return Enumerator(this);
+ }
+
+ public override void ToString(String strBuffer)
+ {
+ strBuffer.AppendF($"{mStart}..<{mEnd}");
+ }
+
+ public struct Enumerator : IEnumerator
+ {
+ private T mEnd;
+ private T mIndex;
+
+ [Inline]
+ public this(Range range)
+ {
+ mIndex = range.mStart + -1;
+ mEnd = range.mEnd;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public ref T Index
+ {
+ get mut
+ {
+ return ref mIndex;
+ }
+ }
+
+ public T End => mEnd;
+
+ [Inline]
+ public Result GetNext() mut
+ {
+ if (mIndex + 1 >= mEnd)
+ return .Err;
+ mIndex += 1;
+ return mIndex;
+ }
+ }
+
+ public struct ReverseEnumerator : IEnumerator
+ {
+ private T mEnd;
+ private T mIndex;
+
+ [Inline]
+ public this(T start, T end)
+ {
+ mIndex = start + 1;
+ mEnd = end;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public ref T Index
+ {
+ get mut
+ {
+ return ref mIndex;
+ }
+ }
+
+ public T End => mEnd;
+
+ [Inline]
+ public Result GetNext() mut
+ {
+ if (mIndex <= mEnd)
+ return .Err;
+ mIndex += -1;
+ return mIndex;
+ }
+ }
+ }
+
struct IndexRange : RangeExpression
{
protected Index mStart;
diff --git a/BeefLibs/corlib/src/Reflection/FieldInfo.bf b/BeefLibs/corlib/src/Reflection/FieldInfo.bf
index e75d8f57..e3066926 100644
--- a/BeefLibs/corlib/src/Reflection/FieldInfo.bf
+++ b/BeefLibs/corlib/src/Reflection/FieldInfo.bf
@@ -8,7 +8,8 @@ namespace System.Reflection
public enum Error
{
InvalidTargetType,
- InvalidValueType
+ InvalidValueType,
+ AppendedField
}
TypeInstance mTypeInstance;
@@ -24,6 +25,8 @@ namespace System.Reflection
public int32 MemberOffset => (int32)mFieldData.mData;
public Type FieldType => Type.[Friend]GetType(mFieldData.mFieldTypeId);
public bool IsConst => mFieldData.mFlags.HasFlag(.Const);
+ public bool IsAppended => mFieldData.mFlags.HasFlag(.Appended);
+ public bool IsEnumCase => mFieldData.mFlags.HasFlag(.EnumCase);
public bool IsReadOnly => mFieldData.mFlags.HasFlag(.ReadOnly);
public bool IsStatic => mFieldData.mFlags.HasFlag(.Static);
public bool IsPublic => (mFieldData.mFlags & .FieldAccessMask) == .Public;
@@ -85,7 +88,12 @@ namespace System.Reflection
if (valueType == fieldType)
{
if (valueType.IsObject)
+ {
+ if (mFieldData.mFlags.HasFlag(.Appended))
+ return .Err(.AppendedField);
+
*((void**)dataAddr) = Internal.UnsafeCastToPtr(value);
+ }
else
Internal.MemCpy(dataAddr, valueDataAddr, fieldType.[Friend]mSize);
}
@@ -384,7 +392,10 @@ namespace System.Reflection
if (typeCode == TypeCode.Object)
{
value.[Friend]mStructType = 0;
- value.[Friend]mData = *(int*)targetDataAddr;
+ if (mFieldData.mFlags.HasFlag(.Appended))
+ value.[Friend]mData = (int)targetDataAddr;
+ else
+ value.[Friend]mData = *(int*)targetDataAddr;
}
else
{
diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf
index cf814559..8ec9dd4f 100644
--- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf
+++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf
@@ -50,6 +50,9 @@ namespace System.Reflection
public bool IsReadOnly => Compiler.IsComptime ?
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.ReadOnly) :
mData.mMethodData.[Friend]mFlags.HasFlag(.ReadOnly);
+ public bool IsStatic => Compiler.IsComptime ?
+ Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.Static) :
+ mData.mMethodData.[Friend]mFlags.HasFlag(.Static);
public StringView Name => Compiler.IsComptime ?
Type.[Friend]Comptime_Method_GetName(mData.mComptimeMethodInstance) :
@@ -112,6 +115,19 @@ namespace System.Reflection
}
}
+ public TypeInstance.ParamFlags GetParamFlags(int paramIdx)
+ {
+ if (Compiler.IsComptime)
+ {
+ return Type.[Friend]Comptime_Method_GetParamInfo(mData.mComptimeMethodInstance, (.)paramIdx).mParamFlags;
+ }
+ else
+ {
+ Debug.Assert((uint)paramIdx < (uint)mData.mMethodData.mParamCount);
+ return mData.mMethodData.mParamData[paramIdx].mParamFlags;
+ }
+ }
+
public Result GetParamCustomAttribute(int paramIdx) where T : Attribute
{
if (Compiler.IsComptime)
@@ -967,19 +983,60 @@ namespace System.Reflection
strBuffer.Append(' ');
strBuffer.Append(mData.mMethodData.mName);
strBuffer.Append('(');
+
+ int useParamIdx = 0;
for (int paramIdx < mData.mMethodData.mParamCount)
{
- if (paramIdx > 0)
- strBuffer.Append(", ");
let paramData = mData.mMethodData.mParamData[paramIdx];
let paramType = Type.[Friend]GetType(paramData.mType);
+ if (paramData.mParamFlags.HasFlag(.Implicit))
+ continue;
+ if (useParamIdx > 0)
+ strBuffer.Append(", ");
paramType.ToString(strBuffer);
strBuffer.Append(' ');
strBuffer.Append(paramData.mName);
+ useParamIdx++;
}
strBuffer.Append(')');
}
+ public void GetParamsDecl(String strBuffer)
+ {
+ int useParamIdx = 0;
+ for (int paramIdx < ParamCount)
+ {
+ var flag = GetParamFlags(paramIdx);
+ if (flag.HasFlag(.Implicit))
+ continue;
+ if (useParamIdx > 0)
+ strBuffer.Append(", ");
+ if (flag.HasFlag(.Params))
+ strBuffer.Append("params ");
+ strBuffer.Append(GetParamType(paramIdx));
+ strBuffer.Append(" ");
+ strBuffer.Append(GetParamName(paramIdx));
+ useParamIdx++;
+ }
+ }
+
+ public void GetArgsList(String strBuffer)
+ {
+ int useParamIdx = 0;
+ for (int paramIdx < ParamCount)
+ {
+ var flag = GetParamFlags(paramIdx);
+ if (flag.HasFlag(.Implicit))
+ continue;
+ if (useParamIdx > 0)
+ strBuffer.Append(", ");
+ if (flag.HasFlag(.Params))
+ strBuffer.Append("params ");
+ strBuffer.Append(GetParamName(paramIdx));
+ useParamIdx++;
+ }
+ }
+
public struct Enumerator : IEnumerator
{
BindingFlags mBindingFlags;
diff --git a/BeefLibs/corlib/src/Result.bf b/BeefLibs/corlib/src/Result.bf
index a4aa719c..2b6fe451 100644
--- a/BeefLibs/corlib/src/Result.bf
+++ b/BeefLibs/corlib/src/Result.bf
@@ -27,6 +27,22 @@ namespace System
}
}
+ public ref T ValueRef
+ {
+ [Inline]
+ get mut
+ {
+ switch (this)
+ {
+ case .Ok(var ref val): return ref val;
+ case .Err:
+ {
+ Internal.FatalError("Unhandled error in result", 2);
+ }
+ }
+ }
+ }
+
[Inline]
public static implicit operator Result(T value)
{
@@ -39,6 +55,19 @@ namespace System
return result.Unwrap();
}
+ [Inline]
+ public static mut T operator->(ref Result result)
+ {
+ switch (result)
+ {
+ case .Ok(var mut val): return mut val;
+ case .Err:
+ {
+ Internal.FatalError("Unhandled error in result", 2);
+ }
+ }
+ }
+
[Inline]
public void IgnoreError()
{
@@ -99,7 +128,7 @@ namespace System
extension Result where T : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Ok(var val))
val.Dispose();
@@ -116,9 +145,9 @@ namespace System
switch (this)
{
case .Ok(var val): return val;
- case .Err(var err):
+ case .Err:
{
- Internal.FatalError(scope String()..AppendF("Unhandled error in result:\n {}", err), 2);
+ Internal.FatalError("Unhandled error in result", 2);
}
}
}
@@ -131,16 +160,47 @@ namespace System
}
}
+ public ref T ValueRef
+ {
+ [Inline]
+ get mut
+ {
+ switch (this)
+ {
+ case .Ok(var ref val): return ref val;
+ case .Err:
+ {
+ Internal.FatalError("Unhandled error in result", 2);
+ }
+ }
+ }
+ }
+
+ [Inline]
public static implicit operator Result(T value)
{
return .Ok(value);
}
+ [Inline]
public static implicit operator T(Result result)
{
return result.Unwrap();
}
+ [Inline]
+ public static mut T operator->(ref Result result)
+ {
+ switch (result)
+ {
+ case .Ok(var mut val): return mut val;
+ case .Err:
+ {
+ Internal.FatalError("Unhandled error in result", 2);
+ }
+ }
+ }
+
public void IgnoreError()
{
}
@@ -203,7 +263,7 @@ namespace System
extension Result where T : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Ok(var val))
val.Dispose();
@@ -212,7 +272,7 @@ namespace System
extension Result where TErr : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Err(var err))
err.Dispose();
@@ -221,7 +281,7 @@ namespace System
extension Result where T : IDisposable where TErr : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Ok(var val))
val.Dispose();
diff --git a/BeefLibs/corlib/src/Runtime.bf b/BeefLibs/corlib/src/Runtime.bf
index b2861236..528a672c 100644
--- a/BeefLibs/corlib/src/Runtime.bf
+++ b/BeefLibs/corlib/src/Runtime.bf
@@ -9,7 +9,7 @@ namespace System
[StaticInitPriority(101)]
static class Runtime
{
- const int32 cVersion = 9;
+ const int32 cVersion = 10;
[CRepr, AlwaysInclude]
struct BfDebugMessageData
@@ -118,6 +118,7 @@ namespace System
function bool (Object thread) mThread_IsAutoDelete;
function void (Object thread) mThread_AutoDelete;
function int32 (Object thread) mThread_GetMaxStackSize;
+ function void () mThread_Exiting;
function void () mGC_MarkAllStaticMembers;
function bool () mGC_CallRootCallbacks;
function void () mGC_Shutdown;
@@ -146,7 +147,7 @@ namespace System
static Type Object_GetType(Object obj)
{
#if BF_DBG_RUNTIME
- return obj.[Friend]RawGetType();
+ return obj.[Friend, DisableObjectAccessChecks]RawGetType();
#else
return null;
#endif
diff --git a/BeefLibs/corlib/src/Span.bf b/BeefLibs/corlib/src/Span.bf
index 4931bbaf..758f6e89 100644
--- a/BeefLibs/corlib/src/Span.bf
+++ b/BeefLibs/corlib/src/Span.bf
@@ -276,6 +276,7 @@ namespace System
public void RemoveFromEnd(int length) mut
{
+ Debug.Assert((uint)length <= (uint)mLength);
mLength -= length;
}
diff --git a/BeefLibs/corlib/src/String.bf b/BeefLibs/corlib/src/String.bf
index 514981be..5b93082a 100644
--- a/BeefLibs/corlib/src/String.bf
+++ b/BeefLibs/corlib/src/String.bf
@@ -40,7 +40,7 @@ namespace System
[Ordered]
class String : IHashable, IFormattable, IPrintable
{
- enum CreateFlags
+ public enum CreateFlags
{
None = 0,
NullTerminate = 1
@@ -48,7 +48,7 @@ namespace System
int_strsize mLength;
uint_strsize mAllocSizeAndFlags;
- char8* mPtr = null;
+ char8* mPtrOrBuffer = null;
extern const String* sStringLiterals;
extern const String* sIdStringLiterals;
@@ -210,8 +210,8 @@ namespace System
[AllowAppend]
public this(StringView strView)
{
- let tryBufferSize = strView.Length - sizeof(char8*);
- let bufferSize = (tryBufferSize >= 0) ? tryBufferSize : 0;
+ let count = strView.Length;
+ int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
#unwarn
char8* addlPtr = append char8[bufferSize]*(?);
Init(bufferSize);
@@ -326,7 +326,7 @@ namespace System
public ~this()
{
if (IsDynAlloc)
- delete:this mPtr;
+ delete:this mPtrOrBuffer;
}
void FakeMethod ()
@@ -390,7 +390,7 @@ namespace System
//[Optimize]
get
{
- return ((mAllocSizeAndFlags & cStrPtrFlag) != 0) ? mPtr : (char8*)&mPtr;
+ return ((mAllocSizeAndFlags & cStrPtrFlag) != 0) ? mPtrOrBuffer : (char8*)&mPtrOrBuffer;
}
}
@@ -660,10 +660,10 @@ namespace System
{
if (str.IsDynAlloc)
{
- delete str.mPtr;
+ delete str.mPtrOrBuffer;
}
- str.mPtr = mPtr;
+ str.mPtrOrBuffer = mPtrOrBuffer;
str.mAllocSizeAndFlags = mAllocSizeAndFlags;
str.mLength = mLength;
@@ -673,7 +673,7 @@ namespace System
}
else
{
- mPtr = null;
+ mPtrOrBuffer = null;
mAllocSizeAndFlags = (int_strsize)sizeof(char8*);
mLength = 0;
}
@@ -689,8 +689,8 @@ namespace System
public void Reference(String str)
{
if (IsDynAlloc)
- delete:this mPtr;
- mPtr = str.Ptr;
+ delete:this mPtrOrBuffer;
+ mPtrOrBuffer = str.Ptr;
mLength = str.mLength;
mAllocSizeAndFlags = cStrPtrFlag;
}
@@ -698,8 +698,8 @@ namespace System
public void Reference(char8* ptr, int length, int allocSize)
{
if (IsDynAlloc)
- delete:this mPtr;
- mPtr = ptr;
+ delete:this mPtrOrBuffer;
+ mPtrOrBuffer = ptr;
mLength = (int_strsize)length;
mAllocSizeAndFlags = cStrPtrFlag;
}
@@ -707,8 +707,8 @@ namespace System
public void Reference(char8* ptr, int length)
{
if (IsDynAlloc)
- delete:this mPtr;
- mPtr = ptr;
+ delete:this mPtrOrBuffer;
+ mPtrOrBuffer = ptr;
mLength = (int_strsize)length;
mAllocSizeAndFlags = cStrPtrFlag;
}
@@ -721,8 +721,8 @@ namespace System
public void Reference(char8* ptr)
{
if (IsDynAlloc)
- delete:this mPtr;
- mPtr = ptr;
+ delete:this mPtrOrBuffer;
+ mPtrOrBuffer = ptr;
mLength = StrLen(ptr);
mAllocSizeAndFlags = cStrPtrFlag;
}
@@ -734,7 +734,7 @@ namespace System
Debug.Assert(!IsDynAlloc);
Debug.Assert(AllocSize == 0); // Assert is reference
Debug.Assert((uint)mLength >= (uint)adjBytes);
- mPtr += adjBytes;
+ mPtrOrBuffer += adjBytes;
mLength -= (int_strsize)adjBytes;
}
@@ -763,8 +763,8 @@ namespace System
Internal.MemSet(newPtr + mLength, 0, newSize - mLength);
#endif
if (IsDynAlloc)
- delete:this mPtr;
- mPtr = newPtr;
+ delete:this mPtrOrBuffer;
+ mPtrOrBuffer = newPtr;
mAllocSizeAndFlags = (uint_strsize)newSize | cDynAllocFlag | cStrPtrFlag;
}
@@ -780,8 +780,8 @@ namespace System
Debug.Assert((uint)newSize <= cSizeFlags);
Internal.MemCpy(newPtr, Ptr, mLength);
if (IsDynAlloc)
- delete:this mPtr;
- mPtr = newPtr;
+ delete:this mPtrOrBuffer;
+ mPtrOrBuffer = newPtr;
mAllocSizeAndFlags = (uint_strsize)newSize | cDynAllocFlag | cStrPtrFlag;
}
@@ -1313,7 +1313,7 @@ namespace System
if (pos == len || (ch = format[pos]) < '0' || ch > '9')
{
if ((pos < len) &&
- ((ch == '}') || (ch == ':')))
+ ((ch == '}') || (ch == ':') || (ch == ',')))
index = autoArgIdx++;
else
return FormatError();
@@ -1603,8 +1603,8 @@ namespace System
newPtr[outIdx] = '\0';
if (IsDynAlloc)
- delete mPtr;
- mPtr = newPtr;
+ delete mPtrOrBuffer;
+ mPtrOrBuffer = newPtr;
mAllocSizeAndFlags = (uint_strsize)newSize | cDynAllocFlag | cStrPtrFlag;
}
}
@@ -1633,8 +1633,8 @@ namespace System
int newLen = UTF8Map(Ptr, mLength, newStr, allocSize, (int32)unicodeNormalizationOptions);
if (IsDynAlloc)
- delete:this mPtr;
- mPtr = newStr;
+ delete:this mPtrOrBuffer;
+ mPtrOrBuffer = newStr;
mLength = (int_strsize)newLen;
mAllocSizeAndFlags = (uint32)(allocSize) | cDynAllocFlag | cStrPtrFlag;
return .Ok;
@@ -1656,8 +1656,8 @@ namespace System
int newLen = UTF8Map(Ptr, mLength, newStr, allocSize, (int32)unicodeNormalizationOptions);
if (destStr.IsDynAlloc)
- delete:destStr destStr.mPtr;
- destStr.mPtr = newStr;
+ delete:destStr destStr.mPtrOrBuffer;
+ destStr.mPtrOrBuffer = newStr;
destStr.mLength = (int_strsize)newLen;
destStr.mAllocSizeAndFlags = (uint_strsize)(newLen + 1) | cDynAllocFlag | cStrPtrFlag;
return .Ok;
@@ -2059,7 +2059,7 @@ namespace System
{
if (mLength != str.[Friend]mLength)
return false;
- return EqualsHelper(str.Ptr, mPtr, mLength);
+ return EqualsHelper(str.Ptr, Ptr, mLength);
}
public bool Equals(StringView str, StringComparison comparisonType = StringComparison.Ordinal)
@@ -2067,8 +2067,8 @@ namespace System
if (mLength != str.[Friend]mLength)
return false;
if (comparisonType == StringComparison.OrdinalIgnoreCase)
- return EqualsIgnoreCaseHelper(str.Ptr, mPtr, mLength);
- return EqualsHelper(str.Ptr, mPtr, mLength);
+ return EqualsIgnoreCaseHelper(str.Ptr, Ptr, mLength);
+ return EqualsHelper(str.Ptr, Ptr, mLength);
}
public bool StartsWith(StringView b, StringComparison comparisonType = StringComparison.Ordinal)
@@ -2488,6 +2488,56 @@ namespace System
return StringSplitEnumerator(Ptr, Length, separators, count, options);
}
+ public StringSplitEnumerator Split(char8[] separators, StringSplitOptions options)
+ {
+ return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options);
+ }
+
+ public StringStringSplitEnumerator Split(StringView sv)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, sv, Int32.MaxValue, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView separator, int count)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separator, count, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView separator, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separator, Int32.MaxValue, options);
+ }
+
+ public StringStringSplitEnumerator Split(StringView separator, int count, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separator, count, options);
+ }
+
+ public StringStringSplitEnumerator Split(params StringView[] separators)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators, int count)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, count, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators, int count, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, count, options);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options);
+ }
+
public static mixin NewOrSet(var target, var source)
{
if (target == null)
@@ -2914,11 +2964,11 @@ namespace System
RemoveEmptyEntries = 1
}
- struct StringSplitEnumerator : IEnumerator
+ public struct StringSplitEnumerator : IEnumerator
{
StringSplitOptions mSplitOptions;
- char8 mSplitChar0;
- char8[] mSplitChars;
+ char8 mFirstSeparator;
+ char8[] mSeparators;
char8* mPtr;
int_strsize mStrLen;
int32 mCurCount;
@@ -2926,15 +2976,15 @@ namespace System
int_strsize mPos;
int_strsize mMatchPos;
- public this(char8* ptr, int strLength, char8[] splitChars, int count, StringSplitOptions splitOptions)
+ public this(char8* ptr, int strLength, char8[] separators, int count, StringSplitOptions splitOptions)
{
mPtr = ptr;
mStrLen = (int_strsize)strLength;
- if (splitChars.Count > 0)
- mSplitChar0 = splitChars[0];
+ if (separators?.Count > 0)
+ mFirstSeparator = separators[0];
else
- mSplitChar0 = '\0';
- mSplitChars = splitChars;
+ mFirstSeparator = '\0';
+ mSeparators = separators;
mCurCount = 0;
mMaxCount = (int32)count;
mPos = 0;
@@ -2942,12 +2992,12 @@ namespace System
mSplitOptions = splitOptions;
}
- public this(char8* ptr, int strLength, char8 splitChar, int count, StringSplitOptions splitOptions)
+ public this(char8* ptr, int strLength, char8 separator, int count, StringSplitOptions splitOptions)
{
mPtr = ptr;
mStrLen = (int_strsize)strLength;
- mSplitChar0 = splitChar;
- mSplitChars = null;
+ mFirstSeparator = separator;
+ mSeparators = null;
mCurCount = 0;
mMaxCount = (int32)count;
mPos = 0;
@@ -3028,14 +3078,18 @@ namespace System
else
{
char8 c = mPtr[mMatchPos];
- if (c == mSplitChar0)
+ if (c.IsWhiteSpace && mFirstSeparator == '\0' && (mSeparators == null || mSeparators.IsEmpty))
{
foundMatch = true;
}
- else if (mSplitChars != null)
+ else if (c == mFirstSeparator)
{
- for (int i = 1; i < mSplitChars.Count; i++)
- if (c == mSplitChars[i])
+ foundMatch = true;
+ }
+ else if (mSeparators != null)
+ {
+ for (int i = 1; i < mSeparators.Count; i++)
+ if (c == mSeparators[i])
foundMatch = true;
}
}
@@ -3070,6 +3124,179 @@ namespace System
}
}
+ public struct StringStringSplitEnumerator : IEnumerator
+ {
+ StringSplitOptions mSplitOptions;
+ StringView mFirstSeparator;
+ StringView[] mSeparators;
+ char8* mPtr;
+ int_strsize mStrLen;
+ int32 mCurCount;
+ int32 mMaxCount;
+ int_strsize mPos;
+ int_strsize mMatchPos;
+ int_strsize mMatchLen;
+
+ public this(char8* ptr, int strLength, StringView[] separators, int count, StringSplitOptions splitOptions)
+ {
+ mPtr = ptr;
+ mStrLen = (int_strsize)strLength;
+ if (separators?.Count > 0)
+ mFirstSeparator = separators[0];
+ else
+ mFirstSeparator = .();
+ mSeparators = separators;
+ mCurCount = 0;
+ mMaxCount = (int32)count;
+ mPos = 0;
+ mMatchPos = -1;
+ mMatchLen = 1;
+ mSplitOptions = splitOptions;
+ }
+
+ public this(char8* ptr, int strLength, StringView separator, int count, StringSplitOptions splitOptions)
+ {
+ mPtr = ptr;
+ mStrLen = (int_strsize)strLength;
+ mFirstSeparator = separator;
+ mSeparators = null;
+ mCurCount = 0;
+ mMaxCount = (int32)count;
+ mPos = 0;
+ mMatchPos = -1;
+ mMatchLen = 1;
+ mSplitOptions = splitOptions;
+ }
+
+ public StringView Current
+ {
+ get
+ {
+ return StringView(mPtr + mPos, mMatchPos - mPos);
+ }
+ }
+
+ public int_strsize Pos
+ {
+ get
+ {
+ return mPos;
+ }
+ }
+
+ public int_strsize MatchPos
+ {
+ get
+ {
+ return mMatchPos;
+ }
+ }
+
+ public int32 MatchIndex
+ {
+ get
+ {
+ return mCurCount - 1;
+ }
+ }
+
+ public bool HasMore
+ {
+ get
+ {
+ return mMatchPos < mStrLen;
+ }
+ }
+
+ public bool MoveNext() mut
+ {
+ if (mCurCount >= mMaxCount)
+ return false;
+
+ mPos = mMatchPos + mMatchLen;
+
+ mCurCount++;
+ if (mCurCount == mMaxCount)
+ {
+ mMatchPos = (int_strsize)mStrLen;
+ if (mPos > mMatchPos)
+ return false;
+ if ((mMatchPos == mPos) && (mSplitOptions.HasFlag(.RemoveEmptyEntries)))
+ return false;
+ return true;
+ }
+
+ int endDiff = mStrLen - mMatchPos;
+ if (endDiff == 0)
+ return false;
+ while (true)
+ {
+ mMatchPos++;
+ endDiff--;
+ bool foundMatch = false;
+ if (endDiff == 0)
+ {
+ foundMatch = true;
+ }
+ else
+ {
+ if (mFirstSeparator.IsNull && (mSeparators == null || mSeparators.IsEmpty) && mPtr[mMatchPos].IsWhiteSpace)
+ {
+ foundMatch = true;
+ mMatchLen = 1;
+ }
+ else if (mFirstSeparator.Length <= mStrLen - mMatchPos && StringView(&mPtr[mMatchPos], mFirstSeparator.Length) == mFirstSeparator)
+ {
+ foundMatch = true;
+ mMatchLen = (int_strsize)mFirstSeparator.Length;
+ }
+ else if (mSeparators != null)
+ {
+ for (int i = 1; i < mSeparators.Count; i++)
+ {
+ if (mSeparators[i].Length <= mStrLen - mMatchPos && StringView(&mPtr[mMatchPos], mSeparators[i].Length) == mSeparators[i])
+ {
+ foundMatch = true;
+ mMatchLen = (int_strsize)mSeparators[i].Length;
+ }
+ }
+ }
+ }
+
+ if (foundMatch)
+ {
+ if ((mMatchPos >= mPos + 1) || (!mSplitOptions.HasFlag(StringSplitOptions.RemoveEmptyEntries)))
+ return true;
+ mPos = mMatchPos + mMatchLen;
+ if (mPos >= mStrLen)
+ return false;
+ }
+ else
+ {
+ mMatchLen = 1;
+ }
+ }
+ }
+
+ public void Reset() mut
+ {
+ mPos = 0;
+ mMatchPos = -1;
+ }
+
+ public void Dispose()
+ {
+
+ }
+
+ public Result GetNext() mut
+ {
+ if (!MoveNext())
+ return .Err;
+ return Current;
+ }
+ }
+
public struct StringView : Span, IFormattable, IPrintable, IHashable
{
public this()
@@ -3080,12 +3307,23 @@ namespace System
public this(String string)
{
+ if (string == null)
+ {
+ this = default;
+ return;
+ }
mPtr = string.Ptr;
mLength = string.Length;
}
public this(String string, int offset)
{
+ if (string == null)
+ {
+ Debug.Assert(offset == 0);
+ this = default;
+ return;
+ }
Debug.Assert((uint)offset <= (uint)string.Length);
mPtr = string.Ptr + offset;
mLength = string.Length - offset;
@@ -3093,6 +3331,12 @@ namespace System
public this(String string, int offset, int length)
{
+ if (string == null)
+ {
+ Debug.Assert(offset == 0 && length == 0);
+ this = default;
+ return;
+ }
Debug.Assert((uint)offset + (uint)length <= (uint)string.Length);
mPtr = string.Ptr + offset;
mLength = length;
@@ -3120,6 +3364,12 @@ namespace System
public this(char8[] arr, int offset, int length)
{
+ if (arr == null)
+ {
+ Debug.Assert(offset == 0 && length == 0);
+ this = default;
+ return;
+ }
Debug.Assert((uint)offset + (uint)length <= (uint)arr.Count);
mPtr = arr.CArray() + offset;
mLength = length;
@@ -3127,13 +3377,23 @@ namespace System
public this(char8* ptr)
{
+ if (ptr == null)
+ {
+ this = default;
+ return;
+ }
mPtr = ptr;
mLength = String.StrLen(ptr);
}
public this(char8* ptr, int length)
-
{
+ if (ptr == null)
+ {
+ Debug.Assert(length == 0);
+ this = default;
+ return;
+ }
mPtr = ptr;
mLength = length;
}
@@ -3749,11 +4009,71 @@ namespace System
return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None);
}
- public StringSplitEnumerator Split(char8[] separators, int count = Int32.MaxValue, StringSplitOptions options = .None)
+ public StringSplitEnumerator Split(char8[] separators)
+ {
+ return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None);
+ }
+
+ public StringSplitEnumerator Split(char8[] separators, int count)
+ {
+ return StringSplitEnumerator(Ptr, Length, separators, count, StringSplitOptions.None);
+ }
+
+ public StringSplitEnumerator Split(char8[] separators, int count, StringSplitOptions options)
{
return StringSplitEnumerator(Ptr, Length, separators, count, options);
}
+ public StringSplitEnumerator Split(char8[] separators, StringSplitOptions options)
+ {
+ return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options);
+ }
+
+ public StringStringSplitEnumerator Split(StringView c)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, c, Int32.MaxValue, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView separator, int count)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separator, count, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView separator, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separator, Int32.MaxValue, options);
+ }
+
+ public StringStringSplitEnumerator Split(StringView separator, int count, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separator, count, options);
+ }
+
+ public StringStringSplitEnumerator Split(params StringView[] separators)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators, int count)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, count, StringSplitOptions.None);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators, int count, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, count, options);
+ }
+
+ public StringStringSplitEnumerator Split(StringView[] separators, StringSplitOptions options)
+ {
+ return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options);
+ }
+
public String Intern()
{
using (String.[Friend]sMonitor.Enter())
@@ -3820,18 +4140,21 @@ namespace System
public mixin ToScopedNativeWChar()
{
int encodedLen = UTF16.GetEncodedLen(this);
- char16* buf;
+ c_wchar* buf;
if (encodedLen < 128)
{
- buf = scope:mixin char16[encodedLen+1]* ( ? );
+ buf = scope:mixin c_wchar[encodedLen+1]* ( ? );
}
else
{
- buf = new char16[encodedLen+1]* ( ? );
+ buf = new c_wchar[encodedLen+1]* ( ? );
defer:mixin delete buf;
}
- UTF16.Encode(this, buf, encodedLen);
+ if (sizeof(c_wchar) == 2)
+ UTF16.Encode(this, (.)buf, encodedLen);
+ else
+ UTF32.Encode(this, (.)buf, encodedLen);
buf[encodedLen] = 0;
buf
}
diff --git a/BeefLibs/corlib/src/Threading/Thread.bf b/BeefLibs/corlib/src/Threading/Thread.bf
index 4fb76c2e..ed529803 100644
--- a/BeefLibs/corlib/src/Threading/Thread.bf
+++ b/BeefLibs/corlib/src/Threading/Thread.bf
@@ -20,8 +20,13 @@ namespace System.Threading
private Object mThreadStartArg;
bool mAutoDelete;
- public static Thread sMainThread = new Thread() ~ delete _;
-
+
+ static Monitor sMonitor = new .() ~ delete _;
+ static Event sOnExit ~ _.Dispose();
+ Event mOnExit ~ _.Dispose();
+
+ public static Thread sMainThread = new Thread() ~ delete _;
+
[StaticInitPriority(102)]
struct RuntimeThreadInit
{
@@ -62,6 +67,14 @@ namespace System.Threading
return ((Thread)thread).mMaxStackSize;
}
+ static void Thread_Exiting()
+ {
+ using (sMonitor.Enter())
+ {
+ sOnExit();
+ }
+ }
+
static void Thread_StartProc(Object threadObj)
{
Thread thread = (Thread)threadObj;
@@ -103,6 +116,7 @@ namespace System.Threading
cb.[Friend]mThread_IsAutoDelete = => Thread_IsAutoDelete;
cb.[Friend]mThread_AutoDelete = => Thread_AutoDelete;
cb.[Friend]mThread_GetMaxStackSize = => Thread_GetMaxStackSize;
+ cb.[Friend]mThread_Exiting = => Thread_Exiting;
}
}
@@ -178,6 +192,38 @@ namespace System.Threading
}
}
+ public void AddExitNotify(delegate void() dlg)
+ {
+ using (sMonitor.Enter())
+ {
+ mOnExit.Add(dlg);
+ }
+ }
+
+ public Result RemovedExitNotify(delegate void() dlg, bool delegateDelegate = false)
+ {
+ using (sMonitor.Enter())
+ {
+ return mOnExit.Remove(dlg, delegateDelegate);
+ }
+ }
+
+ public static void AddGlobalExitNotify(delegate void() dlg)
+ {
+ using (sMonitor.Enter())
+ {
+ sOnExit.Add(dlg);
+ }
+ }
+
+ public static Result RemoveGlobalExitNotify(delegate void() dlg, bool delegateDelegate = false)
+ {
+ using (sMonitor.Enter())
+ {
+ return sOnExit.Remove(dlg, delegateDelegate);
+ }
+ }
+
extern void ManualThreadInit();
extern void StartInternal();
extern void SetStackStart(void* ptr);
@@ -217,6 +263,7 @@ namespace System.Threading
}
}
+ public static extern void RequestExitNotify();
public extern void Suspend();
public extern void Resume();
@@ -316,9 +363,10 @@ namespace System.Threading
}
}
- extern int32 GetThreadId();
+ [CallingConvention(.Cdecl)]
+ extern int GetThreadId();
- public int32 Id
+ public int Id
{
get
{
@@ -326,6 +374,8 @@ namespace System.Threading
}
}
+ public static int CurrentThreadId => Platform.BfpThread_GetCurrentId();
+
[CallingConvention(.Cdecl)]
private static extern Thread GetCurrentThreadNative();
@@ -337,6 +387,12 @@ namespace System.Threading
public ~this()
{
+ using (sMonitor.Enter())
+ {
+ mOnExit();
+ sOnExit();
+ }
+
// Make sure we're not deleting manually if mAutoDelete is set
Debug.Assert((!mAutoDelete) || (CurrentThread == this));
// Delegate to the unmanaged portion.
diff --git a/BeefLibs/corlib/src/TimeSpan.bf b/BeefLibs/corlib/src/TimeSpan.bf
index fb92c0c4..34bb6b92 100644
--- a/BeefLibs/corlib/src/TimeSpan.bf
+++ b/BeefLibs/corlib/src/TimeSpan.bf
@@ -196,5 +196,7 @@ namespace System
{
TimeSpanFormat.[Friend]Format(this, format, formatProvider, outStr);
}
+
+ public static TimeSpan operator-(Self lhs, Self rhs) => .((int64)lhs - (int64)rhs);
}
}
diff --git a/BeefLibs/corlib/src/TimeZoneInfo.bf b/BeefLibs/corlib/src/TimeZoneInfo.bf
index a14a4127..cda8c21d 100644
--- a/BeefLibs/corlib/src/TimeZoneInfo.bf
+++ b/BeefLibs/corlib/src/TimeZoneInfo.bf
@@ -1942,7 +1942,8 @@ namespace System {
}
// the data returned from the PAL is completely bogus; return a dummy entry
return CreateCustomTimeZone(c_localId, TimeSpan.Zero, c_localId, c_localId);*/
- Runtime.NotImplemented();
+ // TODO: Not implemented.
+ return Utc;
}
#endif // !FEATURE_WIN32_REGISTRY
diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf
index f4159dfa..0420a43d 100644
--- a/BeefLibs/corlib/src/Type.bf
+++ b/BeefLibs/corlib/src/Type.bf
@@ -852,7 +852,8 @@ namespace System.Reflection
None = 0,
Splat = 1,
Implicit = 2,
- AppendIdx = 4
+ AppendIdx = 4,
+ Params = 8
}
[CRepr, AlwaysInclude]
@@ -1479,6 +1480,7 @@ namespace System.Reflection
EnumDiscriminator = 0x0200,
EnumCase = 0x0400,
ReadOnly = 0x0800,
+ Appended = 0x1000,
}
public enum MethodFlags : uint16
diff --git a/BeefLibs/corlib/src/ValueType.bf b/BeefLibs/corlib/src/ValueType.bf
index 52005fbe..86c7d0ec 100644
--- a/BeefLibs/corlib/src/ValueType.bf
+++ b/BeefLibs/corlib/src/ValueType.bf
@@ -2,6 +2,7 @@ namespace System
{
struct ValueType
{
+ [NoShow(true)]
public static extern bool Equals(T val1, T val2);
}
}
diff --git a/BeefLink/BeefLink.vcxproj b/BeefLink/BeefLink.vcxproj
index f9ae5447..6bc21290 100644
--- a/BeefLink/BeefLink.vcxproj
+++ b/BeefLink/BeefLink.vcxproj
@@ -94,6 +94,7 @@
Level3
Disabled
WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
Console
@@ -112,6 +113,7 @@
false
MultiThreadedDebug
false
+ true
Console
@@ -128,6 +130,7 @@
true
true
WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
Console
@@ -149,6 +152,7 @@
../;../BeefySysLib;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm\include;..\extern\llvm_win64\include;..\extern\llvm\lib\Target;..\extern\llvm_win64\lib\Target\X86;..\extern\llvm\tools\clang\include
MultiThreaded
false
+ true
Console
diff --git a/BeefRT/BeefDbg/BeefDbg.vcxproj b/BeefRT/BeefDbg/BeefDbg.vcxproj
index f8702896..1b36a3ba 100644
--- a/BeefRT/BeefDbg/BeefDbg.vcxproj
+++ b/BeefRT/BeefDbg/BeefDbg.vcxproj
@@ -140,6 +140,7 @@
+
@@ -356,6 +357,7 @@
+
@@ -526,6 +528,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreadedDebug
ProgramDatabase
+ true
Windows
@@ -589,6 +592,7 @@
false
MultiThreadedDebug
ProgramDatabase
+ true
Windows
@@ -664,6 +668,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreaded
false
+ true
Windows
@@ -724,6 +729,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
false
MultiThreaded
+ true
Windows
diff --git a/BeefRT/BeefDbg/BeefDbg.vcxproj.filters b/BeefRT/BeefDbg/BeefDbg.vcxproj.filters
index 05028bff..a3a371a5 100644
--- a/BeefRT/BeefDbg/BeefDbg.vcxproj.filters
+++ b/BeefRT/BeefDbg/BeefDbg.vcxproj.filters
@@ -25,6 +25,9 @@
{0027c869-120a-44d3-80e6-e2ab12ce83bc}
+
+ {59aee039-211d-47df-abb4-ca95d75d2c56}
+
{8e5503bc-1b01-46f1-be03-bb504d93f05d}
@@ -105,6 +108,9 @@
BeefySysLib\third_party\utf8proc
+
+ BeefySysLib\third_party\putty
+
BeefySysLib\util
@@ -326,6 +332,9 @@
BeefySysLib\third_party\utf8proc
+
+ BeefySysLib\third_party\putty
+
BeefySysLib\util
diff --git a/BeefRT/BeefRT.vcxproj b/BeefRT/BeefRT.vcxproj
index f4e02f8c..47794e20 100644
--- a/BeefRT/BeefRT.vcxproj
+++ b/BeefRT/BeefRT.vcxproj
@@ -252,6 +252,7 @@
TurnOffAllWarnings
+
@@ -271,6 +272,7 @@
+
@@ -479,6 +481,7 @@
false
false
ProgramDatabase
+ true
Windows
@@ -541,6 +544,7 @@
stdcpp17
false
ProgramDatabase
+ true
Windows
@@ -612,6 +616,7 @@
stdcpp17
MultiThreaded
false
+ true
Windows
@@ -681,6 +686,7 @@
false
false
stdcpp17
+ true
Windows
diff --git a/BeefRT/BeefRT.vcxproj.filters b/BeefRT/BeefRT.vcxproj.filters
index 2c8d57e8..b911d04f 100644
--- a/BeefRT/BeefRT.vcxproj.filters
+++ b/BeefRT/BeefRT.vcxproj.filters
@@ -28,6 +28,9 @@
{f94ea9c5-428b-4925-a59e-b7688752d7d7}
+
+ {e790c845-8b10-4edd-b2c0-71e35b0d80b2}
+
@@ -87,6 +90,9 @@
BeefySysLib\third_party\libffi
+
+ BeefySysLib\third_party\putty
+
rt
@@ -148,6 +154,9 @@
BeefySysLib\third_party\libffi\x86
+
+ BeefySysLib\third_party\putty
+
diff --git a/BeefRT/CMakeLists.txt b/BeefRT/CMakeLists.txt
index ed65705b..83703bab 100644
--- a/BeefRT/CMakeLists.txt
+++ b/BeefRT/CMakeLists.txt
@@ -25,9 +25,9 @@ if(NOT CMAKE_BUILD_TYPE)
endif(NOT CMAKE_BUILD_TYPE)
# Definition of Macros
-add_definitions(
- -DIDEHELPER_EXPORTS
- -DBFSYSLIB_DYNAMIC
+add_definitions(
+ -DIDEHELPER_EXPORTS
+ -DBFSYSLIB_DYNAMIC
-DUNICODE
-D_UNICODE
-DBF_NO_FBX
@@ -45,16 +45,16 @@ if (HAVE_BACKTRACE_HEADERS)
add_definitions(-DBFP_HAS_BACKTRACE)
endif ()
-if (${IOS})
+if (${IOS})
include_directories(
.
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/build_iphoneos-arm64/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
@@ -63,13 +63,13 @@ if (${IOS})
elseif (${APPLE})
include_directories(
.
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/x86_64-apple-darwin${CMAKE_HOST_SYSTEM_VERSION}/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
@@ -79,13 +79,13 @@ elseif (${ANDROID})
if (ANDROID_ABI STREQUAL "x86")
include_directories(
.
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/i686-pc-linux-gnu/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
@@ -94,13 +94,13 @@ elseif (${ANDROID})
elseif (ANDROID_ABI STREQUAL "x86_64")
include_directories(
.
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/x86_64-pc-linux-gnu/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
@@ -109,28 +109,28 @@ elseif (${ANDROID})
elseif (ANDROID_ABI STREQUAL "armeabi-v7a")
include_directories(
.
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/arm-unknown-linux-gnu/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
../BeefySysLib/platform/android
)
- else()
+ else()
include_directories(
.
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/aarch64-unknown-linux-gnu/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
@@ -140,13 +140,13 @@ elseif (${ANDROID})
else()
include_directories(
.
- ../BeefySysLib/
+ ../BeefySysLib/
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
@@ -175,16 +175,16 @@ endif()
# Add Dependencies to project. #
###################################################
-option(BUILD_DEPENDS
- "Build other CMake project."
- ON
+option(BUILD_DEPENDS
+ "Build other CMake project."
+ ON
)
# Dependencies : disable BUILD_DEPENDS to link with lib already build.
if(BUILD_DEPENDS)
-
+
else()
-
+
endif()
################# Flags ################
@@ -196,14 +196,14 @@ if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
endif(MSVC)
if(NOT MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof")
endif(NOT MSVC)
################ Files ################
# -- Add files to project. -- #
#######################################
-file(GLOB SRC_FILES
+file(GLOB SRC_FILES
rt/Internal.cpp
rt/Chars.cpp
rt/Object.cpp
@@ -219,8 +219,9 @@ file(GLOB SRC_FILES
../BeefySysLib/util/BeefPerf.cpp
../BeefySysLib/util/String.cpp
../BeefySysLib/util/UTF8.cpp
- ../BeefySysLib/util/Hash.cpp
- ../BeefySysLib/third_party/utf8proc/utf8proc.c
+ ../BeefySysLib/util/Hash.cpp
+ ../BeefySysLib/third_party/utf8proc/utf8proc.c
+ ../BeefySysLib/third_party/putty/wildcard.c
)
if (${IOS})
@@ -282,10 +283,10 @@ endif()
if (${APPLE})
target_link_libraries(${PROJECT_NAME} pthread ffi)
-elseif (${ANDROID})
+elseif (${ANDROID})
#target_link_libraries(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/../BeefySysLib/third_party/libffi/aarch64-unknown-linux-gnu/.libs/libffi.a)
#target_link_libraries(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/../BeefySysLib/third_party/libffi/i686-pc-linux-gnu/.libs/libffi.a)
-else()
+else()
target_link_libraries(${PROJECT_NAME} pthread ffi ${TARGET_LIBS_OS})
endif()
diff --git a/BeefRT/JEMalloc/jemalloc.vcxproj b/BeefRT/JEMalloc/jemalloc.vcxproj
index 561f2802..394b0f98 100644
--- a/BeefRT/JEMalloc/jemalloc.vcxproj
+++ b/BeefRT/JEMalloc/jemalloc.vcxproj
@@ -275,6 +275,9 @@
include;include\msvc_compat;%(AdditionalIncludeDirectories)
4090;4146;4267;4334
$(OutputPath)$(TargetName).pdb
+ true
+ true
+ true
Windows
@@ -292,6 +295,7 @@
MultiThreadedDebug
4090;4146;4267;4334
$(OutputPath)$(TargetName).pdb
+ true
Windows
@@ -310,6 +314,7 @@
$(OutputPath)$(TargetName).pdb
false
MultiThreadedDebug
+ true
Windows
@@ -329,6 +334,7 @@
OldStyle
false
false
+ true
Windows
@@ -348,6 +354,7 @@
OldStyle
false
false
+ true
Windows
@@ -366,6 +373,7 @@
include;include\msvc_compat;%(AdditionalIncludeDirectories)
4090;4146;4267;4334
$(OutputPath)$(TargetName).pdb
+ true
Windows
@@ -387,6 +395,7 @@
MultiThreaded
4090;4146;4267;4334
$(OutputPath)$(TargetName).pdb
+ true
Windows
@@ -408,6 +417,7 @@
4090;4146;4267;4334
$(OutputPath)$(TargetName).pdb
MultiThreaded
+ true
Windows
@@ -429,6 +439,7 @@
MultiThreadedDLL
4090;4146;4267;4334
OldStyle
+ true
Windows
@@ -450,6 +461,7 @@
MultiThreaded
4090;4146;4267;4334
OldStyle
+ true
Windows
diff --git a/BeefRT/MinRT/MinRT.vcxproj b/BeefRT/MinRT/MinRT.vcxproj
index 2281fe91..95c25711 100644
--- a/BeefRT/MinRT/MinRT.vcxproj
+++ b/BeefRT/MinRT/MinRT.vcxproj
@@ -173,6 +173,7 @@
MINRT_CONSOLE;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
.;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime
false
+ true
Windows
@@ -188,6 +189,7 @@
MINRT_GUI;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
.;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime
false
+ true
Windows
@@ -208,6 +210,7 @@
Default
false
/Zc:threadSafeInit- %(AdditionalOptions)
+ true
Windows
@@ -233,6 +236,7 @@
Default
false
/Zc:threadSafeInit- %(AdditionalOptions)
+ true
Windows
@@ -254,6 +258,7 @@
true
MINRT_CONSOLE;BF_SMALL;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
.;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime
+ true
Windows
@@ -272,6 +277,7 @@
true
MINRT_GUI;BF_SMALL;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
.;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime
+ true
Windows
@@ -291,6 +297,7 @@
MINRT_CONSOLE;BF_SMALL;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
.;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime
/Zc:threadSafeInit- %(AdditionalOptions)
+ true
Windows
@@ -316,6 +323,7 @@
.;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime
/Zc:threadSafeInit- %(AdditionalOptions)
false
+ true
Windows
diff --git a/BeefRT/TCMalloc/TCMalloc.vcxproj b/BeefRT/TCMalloc/TCMalloc.vcxproj
index 9f889ff5..ba9202e5 100644
--- a/BeefRT/TCMalloc/TCMalloc.vcxproj
+++ b/BeefRT/TCMalloc/TCMalloc.vcxproj
@@ -502,6 +502,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreadedDebug
ProgramDatabase
+ true
Windows
@@ -522,6 +523,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreadedDebug
ProgramDatabase
+ true
Windows
@@ -542,6 +544,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreadedDebug
ProgramDatabase
+ true
Windows
@@ -565,6 +568,7 @@
false
MultiThreadedDebug
ProgramDatabase
+ true
Windows
@@ -591,6 +595,7 @@
MultiThreadedDebug
ProgramDatabase
false
+ true
Windows
@@ -616,6 +621,7 @@
false
MultiThreadedDebugDLL
ProgramDatabase
+ true
Windows
@@ -640,6 +646,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreaded
false
+ true
Windows
@@ -660,6 +667,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreaded
false
+ true
Windows
@@ -680,6 +688,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
MultiThreadedDLL
false
+ true
Windows
@@ -700,6 +709,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
false
MultiThreaded
+ true
Windows
@@ -722,6 +732,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
false
MultiThreaded
+ true
Windows
@@ -744,6 +755,7 @@
.;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows
false
MultiThreadedDLL
+ true
Windows
diff --git a/BeefRT/rt/BfObjects.h b/BeefRT/rt/BfObjects.h
index 237d69c9..d8573e58 100644
--- a/BeefRT/rt/BfObjects.h
+++ b/BeefRT/rt/BfObjects.h
@@ -3,7 +3,7 @@
#include "BeefySysLib/Common.h"
#include "BeefySysLib/util/String.h"
-#define BFRT_VERSION 9
+#define BFRT_VERSION 10
#ifdef BFRT_DYNAMIC
#define BFRT_EXPORT __declspec(dllexport)
@@ -99,6 +99,7 @@ namespace bf
bool(*Thread_IsAutoDelete)(bf::System::Threading::Thread* thread);
void(*Thread_AutoDelete)(bf::System::Threading::Thread* thread);
int32(*Thread_GetMaxStackSize)(bf::System::Threading::Thread* thread);
+ void(*Thread_Exiting)();
void(*GC_MarkAllStaticMembers)();
bool(*GC_CallRootCallbacks)();
void(*GC_Shutdown)();
@@ -107,7 +108,7 @@ namespace bf
void(*DebugMessageData_SetupProfilerCmd)(const char* str);
void(*DebugMessageData_Fatal)();
void(*DebugMessageData_Clear)();
- int(*CheckErrorHandler)(const char* kind, const char* arg1, const char* arg2, intptr arg3);
+ int(*CheckErrorHandler)(const char* kind, const char* arg1, const char* arg2, intptr arg3);
};
public:
diff --git a/BeefRT/rt/Internal.cpp b/BeefRT/rt/Internal.cpp
index 4bcc49a4..ba90fc5c 100644
--- a/BeefRT/rt/Internal.cpp
+++ b/BeefRT/rt/Internal.cpp
@@ -55,6 +55,12 @@ static Beefy::StringT<0> gCmdLineString;
bf::System::Runtime::BfRtCallbacks gBfRtCallbacks;
BfRtFlags gBfRtFlags = (BfRtFlags)0;
+#ifdef BF_PLATFORM_WINDOWS
+DWORD gBfTLSKey = 0;
+#else
+pthread_key_t gBfTLSKey = 0;
+#endif
+
static int gTestMethodIdx = -1;
static uint32 gTestStartTick = 0;
static bool gTestBreakOnFailure = false;
@@ -86,6 +92,7 @@ namespace bf
BFRT_EXPORT static void ObjectDynCheck(Object* object, int typeId, bool allowNull);
BFRT_EXPORT static void ObjectDynCheckFailed(Object* object, int typeId);
BFRT_EXPORT static void ThrowIndexOutOfRange(intptr stackOffset);
+ BFRT_EXPORT static void ThrowObjectNotInitialized(intptr stackOffset);
BFRT_EXPORT static void FatalError(String* error, intptr stackOffset = 0);
BFRT_EXPORT static void MemCpy(void* dest, void* src, intptr length);
BFRT_EXPORT static void MemMove(void* dest, void* src, intptr length);
@@ -286,6 +293,11 @@ static void GetCrashInfo()
}
}
+static void NTAPI TlsFreeFunc(void* ptr)
+{
+ gBfRtCallbacks.Thread_Exiting();
+}
+
void bf::System::Runtime::Init(int version, int flags, BfRtCallbacks* callbacks)
{
BfpSystemInitFlags sysInitFlags = BfpSystemInitFlag_InstallCrashCatcher;
@@ -342,6 +354,12 @@ void bf::System::Runtime::Init(int version, int flags, BfRtCallbacks* callbacks)
useCmdLineStr++;
}
gCmdLineString = useCmdLineStr;
+
+#ifdef BF_PLATFORM_WINDOWS
+ gBfTLSKey = FlsAlloc(TlsFreeFunc);
+#else
+ pthread_key_create(&gBfTLSKey, TlsFreeFunc);
+#endif
}
void bf::System::Runtime::SetErrorString(char* errorStr)
@@ -423,6 +441,30 @@ void Internal::ThrowIndexOutOfRange(intptr stackOffset)
Internal_FatalError("Index out of range");
}
+void Internal::ThrowObjectNotInitialized(intptr stackOffset)
+{
+ if (gClientPipe != NULL)
+ {
+ if (gTestBreakOnFailure)
+ {
+ SETUP_ERROR("Object not initialized", (int)(2 + stackOffset));
+ BF_DEBUG_BREAK();
+ }
+
+ Beefy::String str = ":TestFail\tObject not initialized\n";
+ TestString(str);
+ exit(1);
+ }
+
+ if ((stackOffset != -1) && (::IsDebuggerPresent()))
+ {
+ SETUP_ERROR("Object not initialized", (int)(2 + stackOffset));
+ BF_DEBUG_BREAK();
+ }
+
+ Internal_FatalError("Object not initialized");
+}
+
void Internal::FatalError(bf::System::String* error, intptr stackOffset)
{
if (gClientPipe != NULL)
diff --git a/BeefRT/rt/Thread.cpp b/BeefRT/rt/Thread.cpp
index 0e79e8a3..37114d63 100644
--- a/BeefRT/rt/Thread.cpp
+++ b/BeefRT/rt/Thread.cpp
@@ -19,6 +19,12 @@ BF_TLS_DECLSPEC Thread* Thread::sCurrentThread;
static volatile int gLiveThreadCount;
static Beefy::SyncEvent gThreadsDoneEvent;
+#ifdef BF_PLATFORM_WINDOWS
+extern DWORD gBfTLSKey;
+#else
+extern pthread_key_t gBfTLSKey;
+#endif
+
bf::System::Threading::Thread* BfGetCurrentThread()
{
#ifdef BF_THREAD_TLS
@@ -133,7 +139,8 @@ static void BF_CALLTYPE CStartProc(void* threadParam)
bool wantsDelete = false;
//
{
- internalThread->ThreadStopped();
+ internalThread->ThreadStopped();
+
Beefy::AutoCrit autoCrit(internalThread->mCritSect);
if (isAutoDelete)
gBfRtCallbacks.Thread_AutoDelete(thread);
@@ -207,15 +214,28 @@ void Thread::StartInternal()
#endif
}
+void Thread::RequestExitNotify()
+{
+ // Do we already have implicit exiting notification?
+ if (BfGetCurrentThread() != NULL)
+ return;
+
+#ifdef BF_PLATFORM_WINDOWS
+ FlsSetValue(gBfTLSKey, (void*)&gBfRtCallbacks);
+#else
+ pthread_setspecific(gBfTLSKey, (void*)&gBfRtCallbacks);
+#endif
+}
+
void Thread::ThreadStarted()
{
auto internalThread = GetInternalThread();
internalThread->mCritSect.Unlock();
}
-int Thread::GetThreadId()
+intptr Thread::GetThreadId()
{
- return (int)GetInternalThread()->mThreadId;
+ return GetInternalThread()->mThreadId;
}
void Thread::SetStackStart(void* ptr)
diff --git a/BeefRT/rt/Thread.h b/BeefRT/rt/Thread.h
index 17bfec7e..22ea4d93 100644
--- a/BeefRT/rt/Thread.h
+++ b/BeefRT/rt/Thread.h
@@ -39,7 +39,7 @@ namespace bf
private:
BfInternalThread* SetupInternalThread();
- BFRT_EXPORT void ManualThreadInit();
+ BFRT_EXPORT void ManualThreadInit();
BFRT_EXPORT int GetPriorityNative();
BFRT_EXPORT void SetPriorityNative(int priority);
BFRT_EXPORT void SetJoinOnDelete(bool joinOnDelete);
@@ -59,7 +59,7 @@ namespace bf
BFRT_EXPORT void SetBackgroundNative(bool isBackground);
BFRT_EXPORT int GetThreadStateNative();
BFRT_EXPORT void InformThreadNameChange(String* name);
- BFRT_EXPORT int GetThreadId();
+ BFRT_EXPORT intptr GetThreadId();
BFRT_EXPORT void Dbg_CreateInternal();
@@ -68,6 +68,7 @@ namespace bf
BFRT_EXPORT void Resume();
BFRT_EXPORT void Abort();
+ BFRT_EXPORT static void RequestExitNotify();
BFRT_EXPORT static void MemoryBarrier();
static Thread* Alloc()
diff --git a/BeefRT/rt/ThreadLocalStorage.cpp b/BeefRT/rt/ThreadLocalStorage.cpp
index 439f81b8..6861f501 100644
--- a/BeefRT/rt/ThreadLocalStorage.cpp
+++ b/BeefRT/rt/ThreadLocalStorage.cpp
@@ -35,7 +35,7 @@ uint32 BfTLSManager::Alloc()
}
}
- mAllocatedKeys[idx] = BfpTLS_Create();
+ mAllocatedKeys[idx] = BfpTLS_Create(NULL);
mAssociatedTLSDatums[idx] = NULL;
return idx;
}
diff --git a/BeefRT/rt/ThreadLocalStorage.h b/BeefRT/rt/ThreadLocalStorage.h
index 93c171d1..ff1ea718 100644
--- a/BeefRT/rt/ThreadLocalStorage.h
+++ b/BeefRT/rt/ThreadLocalStorage.h
@@ -43,7 +43,7 @@ public:
BfTLSManager()
{
- sInternalThreadKey = BfpTLS_Create();
+ sInternalThreadKey = BfpTLS_Create(NULL);
mAssociatedTLSDatums = NULL;
mAllocSize = 0;
mAllocIdx = 1;
diff --git a/BeefTools/BeefMem/CMakeLists.txt b/BeefTools/BeefMem/CMakeLists.txt
index 2d6d5b3c..1e9ffff1 100644
--- a/BeefTools/BeefMem/CMakeLists.txt
+++ b/BeefTools/BeefMem/CMakeLists.txt
@@ -23,9 +23,9 @@ endif(NOT CMAKE_BUILD_TYPE)
# Definition of Macros
add_definitions(
- -D_DEBUG
- -DIDEHELPER_EXPORTS
- -DBFSYSLIB_DYNAMIC
+ -D_DEBUG
+ -DIDEHELPER_EXPORTS
+ -DBFSYSLIB_DYNAMIC
-DUNICODE
-D_UNICODE
-DBF_NO_FBX
@@ -40,9 +40,9 @@ include_directories(
../BeefySysLib/third_party
../BeefySysLib/third_party/freetype/include
../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/include
- ../
+ ../
../extern
- ../extern/llvm/include
+ ../extern/llvm/include
../extern/llvm_linux/include
../extern/llvm/lib/Target
../extern/llvm_linux/lib/Target/X86
@@ -66,16 +66,16 @@ endif()
# Add Dependencies to project. #
###################################################
-option(BUILD_DEPENDS
- "Build other CMake project."
- ON
+option(BUILD_DEPENDS
+ "Build other CMake project."
+ ON
)
# Dependencies : disable BUILD_DEPENDS to link with lib already build.
if(BUILD_DEPENDS)
-
+
else()
-
+
endif()
################# Flags ################
@@ -87,7 +87,7 @@ if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
endif(MSVC)
if(NOT MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
@@ -97,8 +97,8 @@ endif(NOT MSVC)
# -- Add files to project. -- #
#######################################
-file(GLOB SRC_FILES
-
+file(GLOB SRC_FILES
+
)
# Add library to build.
diff --git a/BeefTools/BeefPerf/src/BPApp.bf b/BeefTools/BeefPerf/src/BPApp.bf
index fffe1822..2b255562 100644
--- a/BeefTools/BeefPerf/src/BPApp.bf
+++ b/BeefTools/BeefPerf/src/BPApp.bf
@@ -106,11 +106,6 @@ namespace BeefPerf
delete client;
}
- Widget.RemoveAndDelete(mWorkspacePanel);
- Widget.RemoveAndDelete(mBoard);
- Widget.RemoveAndDelete(mProfilePanel);
- Widget.RemoveAndDelete(mFindPanel);
-
if (!mLogLines.IsEmpty)
{
var fs = scope FileStream();
@@ -122,7 +117,7 @@ namespace BeefPerf
}
}
}
-
+
static uint32 TimeToUnixTime(DateTime ft)
{
// takes the last modified date
@@ -267,6 +262,15 @@ namespace BeefPerf
{
base.Stop();
mListenSocket.Close();
+
+ Widget.RemoveAndDelete(mWorkspacePanel);
+ mWorkspacePanel = null;
+ Widget.RemoveAndDelete(mBoard);
+ mBoard = null;
+ Widget.RemoveAndDelete(mProfilePanel);
+ mProfilePanel = null;
+ Widget.RemoveAndDelete(mFindPanel);
+ mFindPanel = null;
}
void ShowWorkspacePanel()
@@ -517,7 +521,6 @@ namespace BeefPerf
public override void Shutdown()
{
base.Shutdown();
-
mShutdownEvent.Set(true);
}
diff --git a/BeefTools/TestDLL/TestDLL.cpp b/BeefTools/TestDLL/TestDLL.cpp
index d889c73b..377d4eb2 100644
--- a/BeefTools/TestDLL/TestDLL.cpp
+++ b/BeefTools/TestDLL/TestDLL.cpp
@@ -138,9 +138,7 @@ void TestMem()
char* mem = (char*)::VirtualAlloc(0, 4096 * 2, MEM_RESERVE, PAGE_READWRITE);
::VirtualAlloc(mem, 4096, MEM_COMMIT, PAGE_READWRITE);
- char* str = "Hey";
- char* cPtr = mem + 4096 - 3;
- memcpy(cPtr, str, 3);
+
}
void Test6()
@@ -163,10 +161,41 @@ void Test3(int a)
Test4(100, 200, 300);
}
+
+#pragma pack(1)
+class TestStruct
+{
+public:
+ int mA;
+ int mB;
+ int mC;
+ int mD;
+};
+
+enum EnumVal
+{
+ EnumVal_A,
+ EnumVal_B,
+ EnumVal_C
+};
+
+struct Color
+{
+ float r, g, b, a;
+};
+
// THIS IS VERSION 6.
extern "C"
-__declspec(dllexport) void Test2(int aa, int bb, int cc, int dd)
+__declspec(dllexport) void Test2(int aa, int bb, int cc, int dd, Color func(int a, int b))
{
+ Color clr = func(100, 200);
+
+ EnumVal ev = EnumVal_A;
+
+ TestStruct ts;
+ ts.mA = 123;
+ ts.mB = 234;
+
int a = 1234;
for (int i = 0; i < 100; i++)
@@ -174,9 +203,7 @@ __declspec(dllexport) void Test2(int aa, int bb, int cc, int dd)
a++;
}
- Test3(10);
-
- char* strP = "Hey yo";
+ Test3(10);
TestMem();
diff --git a/BeefTools/TestDLL/TestDLL.vcxproj b/BeefTools/TestDLL/TestDLL.vcxproj
index c4b1c718..4d5c6e14 100644
--- a/BeefTools/TestDLL/TestDLL.vcxproj
+++ b/BeefTools/TestDLL/TestDLL.vcxproj
@@ -22,32 +22,32 @@
{14700A80-0FC4-4A3D-99EF-8B78D4B070F1}
Win32Proj
TestDLL
- 10.0.17763.0
+ 10.0.16299.0
DynamicLibrary
true
- v141
+ v142
Unicode
Application
false
- v141
+ v142
true
Unicode
DynamicLibrary
true
- v141
+ v142
Unicode
DynamicLibrary
false
- v141
+ v142
true
Unicode
@@ -104,7 +104,7 @@
Level3
Disabled
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- \Beef\BeefySysLib;\Beef\BeefySysLib\third_party
+ \Beef\BeefySysLib;\Beef\BeefySysLib\third_party;C:\temp\Chipmunk-7.0.3\include
stdcpplatest
@@ -112,7 +112,8 @@
DebugFull
- copy C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll c:\beef\ide\mintest\build\release_win64\mintest
+
+
@@ -152,6 +153,7 @@
+
diff --git a/BeefySysLib/BFApp.cpp b/BeefySysLib/BFApp.cpp
index d95c0907..6b50391f 100644
--- a/BeefySysLib/BFApp.cpp
+++ b/BeefySysLib/BFApp.cpp
@@ -222,7 +222,7 @@ void BFApp::Process()
mClientUpdateCntF = mUpdateCntF - 1;
}
- while ((int)mClientUpdateCntF < (int)mUpdateCntF)
+ while ((mRunning) && ((int)mClientUpdateCntF < (int)mUpdateCntF))
{
Update(didUpdateCnt == 0);
didUpdateCnt++;
@@ -232,7 +232,7 @@ void BFApp::Process()
}
// Only attempt UpdateF updates if our rates aren't nearly the same
- if ((mRefreshRate != 0) && (fabs(physRefreshRate - mRefreshRate) / (float)mRefreshRate > 0.1f))
+ if ((mRunning) && (mRefreshRate != 0) && (fabs(physRefreshRate - mRefreshRate) / (float)mRefreshRate > 0.1f))
{
float updateFAmt = (float)(mUpdateCntF - mClientUpdateCntF);
if ((updateFAmt > 0.05f) && (updateFAmt < 1.0f) && (didUpdateCnt < maxUpdates))
diff --git a/BeefySysLib/BeefySysLib.vcxproj b/BeefySysLib/BeefySysLib.vcxproj
index d9ee8d82..c6953223 100644
--- a/BeefySysLib/BeefySysLib.vcxproj
+++ b/BeefySysLib/BeefySysLib.vcxproj
@@ -188,6 +188,7 @@
./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include
MultiThreadedDebugDLL
false
+ true
Windows
@@ -224,6 +225,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"MultiThreadedDebug
false
false
+ true
Windows
@@ -311,6 +313,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"BFP_NOEXPORT;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)
MultiThreadedDLL
./; ./platform/win/; ./platform/sdl/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include; third_party/SDL2-2.0.1/include;;../extern/fbxsdk/include
+ true
Windows
@@ -348,6 +351,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"MultiThreaded
./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include
false
+ true
Windows
@@ -1926,6 +1930,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"TurnOffAllWarnings
TurnOffAllWarnings
+
@@ -2152,6 +2157,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"
+
diff --git a/BeefySysLib/BeefySysLib.vcxproj.filters b/BeefySysLib/BeefySysLib.vcxproj.filters
index 3b2dc190..f766dc93 100644
--- a/BeefySysLib/BeefySysLib.vcxproj.filters
+++ b/BeefySysLib/BeefySysLib.vcxproj.filters
@@ -78,6 +78,9 @@
{a159b9ee-1a71-44f5-a412-1e01e20b70c7}
+
+ {0007a912-9292-4e32-8884-0f0cd276e42d}
+
@@ -731,6 +734,9 @@
src\util
+
+ src\third_party\putty
+
@@ -1123,6 +1129,9 @@
src\util
+
+ src\third_party\putty
+
diff --git a/BeefySysLib/BeefySysLib_static.vcxproj b/BeefySysLib/BeefySysLib_static.vcxproj
index e81e9e3a..582167f8 100644
--- a/BeefySysLib/BeefySysLib_static.vcxproj
+++ b/BeefySysLib/BeefySysLib_static.vcxproj
@@ -102,6 +102,7 @@
BFP_INTERNAL;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;BF_NO_FBX;%(PreprocessorDefinitions)
./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include
MultiThreadedDebug
+ true
Windows
@@ -125,6 +126,7 @@
MultiThreadedDebug
false
false
+ true
Windows
@@ -143,6 +145,7 @@
_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)
MultiThreaded
./; ./platform/win/; ./platform/sdl/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include; third_party/SDL2-2.0.1/include;;../extern/fbxsdk/include
+ true
Windows
@@ -167,6 +170,7 @@
MultiThreaded
./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include
false
+ true
Windows
@@ -859,6 +863,7 @@
Level1
Level1
+
@@ -1025,6 +1030,7 @@
+
diff --git a/BeefySysLib/BeefySysLib_static.vcxproj.filters b/BeefySysLib/BeefySysLib_static.vcxproj.filters
index 34f64889..62458bbe 100644
--- a/BeefySysLib/BeefySysLib_static.vcxproj.filters
+++ b/BeefySysLib/BeefySysLib_static.vcxproj.filters
@@ -69,6 +69,9 @@
{d32cb9b0-e79b-49fe-82e2-33302be0baf6}
+
+ {bec18ceb-a7ca-4150-99ee-60a16944b93c}
+
@@ -584,6 +587,9 @@
src\third_party\miniz
+
+ src\third_party\putty
+
@@ -898,6 +904,9 @@
src\third_party\miniz
+
+ src\third_party\putty
+
diff --git a/BeefySysLib/CMakeLists.txt b/BeefySysLib/CMakeLists.txt
index 9a1f1e25..c335cb28 100644
--- a/BeefySysLib/CMakeLists.txt
+++ b/BeefySysLib/CMakeLists.txt
@@ -16,7 +16,7 @@ set(OUTPUT_RELEASE Release/bin)
project(${PROJECT_NAME} CXX C)
-# Define Release by default.
+# Define Debug by default.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
message(STATUS "Build type not specified: Use Debug by default.")
@@ -24,8 +24,8 @@ endif(NOT CMAKE_BUILD_TYPE)
# Definition of Macros
add_definitions(
- -DIDEHELPER_EXPORTS
- -DBFSYSLIB_DYNAMIC
+ -DIDEHELPER_EXPORTS
+ -DBFSYSLIB_DYNAMIC
-DUNICODE
-D_UNICODE
-DBF_NO_FBX
@@ -82,16 +82,16 @@ endif()
# Add Dependencies to project. #
###################################################
-option(BUILD_DEPENDS
- "Build other CMake project."
- ON
+option(BUILD_DEPENDS
+ "Build other CMake project."
+ ON
)
# Dependencies : disable BUILD_DEPENDS to link with lib already build.
if(BUILD_DEPENDS)
-
+
else()
-
+
endif()
################# Flags ################
@@ -103,7 +103,7 @@ if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
endif(MSVC)
if(NOT MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar")
endif(NOT MSVC)
################ Files ################
@@ -119,9 +119,9 @@ file(GLOB SRC_FILES
DataStream.cpp
FileStream.cpp
HeadlessApp.cpp
- MemStream.cpp
- ResLib.cpp
- Startup.cpp
+ MemStream.cpp
+ ResLib.cpp
+ Startup.cpp
fbx/FBXReader.cpp
gfx/DrawLayer.cpp
@@ -132,7 +132,7 @@ file(GLOB SRC_FILES
gfx/RenderDevice.cpp
gfx/RenderTarget.cpp
gfx/Shader.cpp
- gfx/Texture.cpp
+ gfx/Texture.cpp
img/BFIData.cpp
img/ImageAdjustments.cpp
img/ImageData.cpp
@@ -142,8 +142,8 @@ file(GLOB SRC_FILES
img/PNGData.cpp
img/PSDReader.cpp
img/PVRData.cpp
- img/TGAData.cpp
-
+ img/TGAData.cpp
+
third_party/freetype/src/autofit/autofit.c
third_party/freetype/src/base/ftbase.c
third_party/freetype/src/base/ftbbox.c
@@ -274,6 +274,7 @@ file(GLOB SRC_FILES
third_party/zlib/uncompr.c
third_party/zlib/zutil.c
third_party/miniz/miniz.c
+ third_party/putty/wildcard.c
util/AllocDebug.cpp
util/BeefPerf.cpp
util/BSpline.cpp
@@ -323,6 +324,6 @@ add_library(${PROJECT_NAME} SHARED
# Link with other dependencies.
if(MSVC)
- target_link_libraries(${PROJECT_NAME} imm32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
+ target_link_libraries(${PROJECT_NAME} imm32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
)
endif(MSVC)
diff --git a/BeefySysLib/Common.h b/BeefySysLib/Common.h
index 72c0de8a..e2a61beb 100644
--- a/BeefySysLib/Common.h
+++ b/BeefySysLib/Common.h
@@ -15,10 +15,10 @@
inline size_t HashBytes(const uint8* ptr, size_t count) noexcept
{
-#ifdef BF64
+#ifdef BF64
const size_t _FNV_offset_basis = 14695981039346656037ULL;
const size_t _FNV_prime = 1099511628211ULL;
-#else
+#else
const size_t _FNV_offset_basis = 2166136261U;
const size_t _FNV_prime = 16777619U;
#endif
@@ -29,7 +29,7 @@ inline size_t HashBytes(const uint8* ptr, size_t count) noexcept
val ^= (size_t)ptr[_Next];
val *= _FNV_prime;
}
- return (val);
+ return (val);
}
template
@@ -245,7 +245,7 @@ int16 EndianSwap(int16 val);
template
struct RemoveTypePointer
-{
+{
};
template
diff --git a/BeefySysLib/platform/PlatformInterface.h b/BeefySysLib/platform/PlatformInterface.h
index 79b08843..0a260f87 100644
--- a/BeefySysLib/platform/PlatformInterface.h
+++ b/BeefySysLib/platform/PlatformInterface.h
@@ -223,6 +223,7 @@ enum BfpThreadCreateFlags
};
typedef void (BFP_CALLTYPE *BfpThreadStartProc)(void* threadParam);
+typedef void (BFP_CALLTYPE* BfpTLSProc)(void* threadParam);
enum BfpThreadPriority
{
@@ -273,8 +274,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Enter(BfpCritSect* critSect);
BFP_EXPORT bool BFP_CALLTYPE BfpCritSect_TryEnter(BfpCritSect* critSect, int waitMS);
BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Leave(BfpCritSect* critSect);
+
struct BfpTLS;
-BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create();
+BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create(BfpTLSProc exitProc);
BFP_EXPORT void BFP_CALLTYPE BfpTLS_Release(BfpTLS* tls);
BFP_EXPORT void BFP_CALLTYPE BfpTLS_SetValue(BfpTLS* tls, void* value);
BFP_EXPORT void* BFP_CALLTYPE BfpTLS_GetValue(BfpTLS* tls);
diff --git a/BeefySysLib/platform/posix/PosixCommon.cpp b/BeefySysLib/platform/posix/PosixCommon.cpp
index ebbc35b8..03f70b4b 100644
--- a/BeefySysLib/platform/posix/PosixCommon.cpp
+++ b/BeefySysLib/platform/posix/PosixCommon.cpp
@@ -22,6 +22,7 @@
#include "../../util/CritSect.h"
#include "../../util/Dictionary.h"
#include "../../util/Hash.h"
+#include "../../third_party/putty/wildcard.h"
#ifdef BFP_HAS_EXECINFO
#include
#endif
@@ -1528,10 +1529,10 @@ BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Leave(BfpCritSect* critSect)
pthread_mutex_unlock(&critSect->mPMutex);
}
-BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create()
+BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create(BfpTLSProc exitProc)
{
pthread_key_t key = 0;
- pthread_key_create(&key, NULL);
+ pthread_key_create(&key, exitProc);
return (BfpTLS*)(intptr)key;
}
@@ -2378,9 +2379,10 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData)
{
if ((findData->mFlags & BfpFindFileFlag_Files) == 0)
return false;
- }
+ }
- //TODO: Check actual wildcards.
+ if (!wc_match(findData->mWildcard.c_str(), findData->mDirEnt->d_name))
+ return false;
return true;
}
diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp
index 4893040e..da744546 100644
--- a/BeefySysLib/platform/win/Platform.cpp
+++ b/BeefySysLib/platform/win/Platform.cpp
@@ -25,6 +25,7 @@
#include "../util/CritSect.h"
#include "../util/Dictionary.h"
#include "../util/HashSet.h"
+#include "../../third_party/putty/wildcard.h"
#include "util/AllocDebug.h"
@@ -2530,24 +2531,24 @@ BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Leave(BfpCritSect* critSect)
#define BFPTLS_TO_DWORD(val) ((DWORD)(intptr)(val))
struct BfpTLS;
-BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create()
+BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create(BfpTLSProc exitProc)
{
- return DWORD_TO_BFPTLS(::TlsAlloc());
+ return DWORD_TO_BFPTLS(::FlsAlloc(exitProc));
}
BFP_EXPORT void BFP_CALLTYPE BfpTLS_Release(BfpTLS* tls)
{
- ::TlsFree(BFPTLS_TO_DWORD(tls));
+ ::FlsFree(BFPTLS_TO_DWORD(tls));
}
BFP_EXPORT void BFP_CALLTYPE BfpTLS_SetValue(BfpTLS* tls, void* value)
{
- ::TlsSetValue(BFPTLS_TO_DWORD(tls), value);
+ ::FlsSetValue(BFPTLS_TO_DWORD(tls), value);
}
BFP_EXPORT void* BFP_CALLTYPE BfpTLS_GetValue(BfpTLS* tls)
{
- return ::TlsGetValue(BFPTLS_TO_DWORD(tls));
+ return ::FlsGetValue(BFPTLS_TO_DWORD(tls));
}
BFP_EXPORT BfpEvent* BFP_CALLTYPE BfpEvent_Create(BfpEventFlags flags)
@@ -3485,6 +3486,7 @@ struct BfpFindFileData
{
BfpFindFileFlags mFlags;
WIN32_FIND_DATA mFindData;
+ Beefy::String mWildcard;
HANDLE mHandle;
};
@@ -3496,29 +3498,45 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData)
bool isDir = (findData->mFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (isDir)
{
- if ((findData->mFlags & BfpFindFileFlag_Directories) != 0)
- {
- if ((wcscmp(findData->mFindData.cFileName, L".") == 0) || (wcscmp(findData->mFindData.cFileName, L"..") == 0))
- {
- return false;
- }
- return true;
- }
+ if ((findData->mFlags & BfpFindFileFlag_Directories) == 0)
+ return false;
+
+ if ((wcscmp(findData->mFindData.cFileName, L".") == 0) || (wcscmp(findData->mFindData.cFileName, L"..") == 0))
+ return false;
}
else
{
- if ((findData->mFlags & BfpFindFileFlag_Files) != 0)
- return true;
+ if ((findData->mFlags & BfpFindFileFlag_Files) == 0)
+ return false;
}
- return false;
+
+ Beefy::String fileName = UTF8Encode(findData->mFindData.cFileName);
+ Beefy::MakeUpper(fileName);
+ if (!wc_match(findData->mWildcard.c_str(), fileName.c_str()))
+ return false;
+
+ return true;
}
BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const char* path, BfpFindFileFlags flags, BfpFileResult* outResult)
{
- UTF16String wPath = UTF8Decode(path);
+ Beefy::String findStr = path;
+ Beefy::String wildcard;
+
+ int lastSlashPos = std::max((int)findStr.LastIndexOf('/'), (int)findStr.LastIndexOf('\\'));
+ if (lastSlashPos != -1)
+ {
+ wildcard = findStr.Substring(lastSlashPos + 1);
+ findStr = findStr.Substring(0, lastSlashPos + 1);
+ findStr.Append("*");
+ }
+ if (wildcard == "*.*")
+ wildcard = "*";
BfpFindFileData* findData = new BfpFindFileData();
findData->mFlags = flags;
+ findData->mWildcard = wildcard;
+ Beefy::MakeUpper(findData->mWildcard);
FINDEX_SEARCH_OPS searchOps;
if ((flags & BfpFindFileFlag_Files) == 0)
@@ -3526,6 +3544,7 @@ BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const cha
else
searchOps = FindExSearchNameMatch;
+ UTF16String wPath = UTF8Decode(findStr);
findData->mHandle = ::FindFirstFileExW(wPath.c_str(), FindExInfoBasic, &findData->mFindData, searchOps, NULL, 0);
if (findData->mHandle == INVALID_HANDLE_VALUE)
{
diff --git a/BeefySysLib/platform/win/WinBFApp.cpp b/BeefySysLib/platform/win/WinBFApp.cpp
index c219b78e..b1d7cc83 100644
--- a/BeefySysLib/platform/win/WinBFApp.cpp
+++ b/BeefySysLib/platform/win/WinBFApp.cpp
@@ -39,7 +39,7 @@ static BOOL CALLBACK BFEnumResNameProc(
LPWSTR lpszName,
LONG_PTR lParam
)
-{
+{
gMainIcon = ::LoadIconW(hModule, lpszName);
return FALSE;
}
@@ -56,23 +56,23 @@ struct AdjustedMonRect
static BOOL ClipToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM userArg)
{
AdjustedMonRect* outRect = (AdjustedMonRect*)userArg;
-
+
MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
if (::GetMonitorInfo(mon, &monitorInfo) == 0)
return TRUE;
outRect->mMonCount++;
-
+
if (outRect->mX < monitorInfo.rcWork.left)
outRect->mX = monitorInfo.rcWork.left;
else if (outRect->mX + outRect->mWidth >= monitorInfo.rcWork.right)
outRect->mX = BF_MAX((int)monitorInfo.rcWork.left, monitorInfo.rcWork.right - outRect->mWidth);
-
+
if (outRect->mY < monitorInfo.rcWork.top)
outRect->mY = monitorInfo.rcWork.top;
else if (outRect->mY + outRect->mHeight >= monitorInfo.rcWork.bottom)
outRect->mY = BF_MAX((int)monitorInfo.rcWork.top, monitorInfo.rcWork.bottom - outRect->mHeight);
-
+
return TRUE;
}
@@ -97,9 +97,9 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
//OutputDebugStrF("Wnd %p Create\n", this);
HINSTANCE hInstance = GetModuleHandle(NULL);
-
+
mMinWidth = 128;
- mMinHeight = 128;
+ mMinHeight = 128;
WNDCLASSW wc;
wc.style = 0;
@@ -107,7 +107,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
wc.cbWndExtra = 0;
wc.hbrBackground = NULL;
//wc.hbrBackground = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
- wc.hCursor = NULL;
+ wc.hCursor = NULL;
//wc.hIcon = (HICON) ::LoadImageA(hInstance, "MainIcon", IMAGE_ICON, 0, 0, 0);
//wc.hIcon = (HICON) ::LoadImageA(hInstance, MAKEINTRESOURCEA(32512), IMAGE_ICON, 0, 0, 0);
if (gMainIcon != NULL)
@@ -117,7 +117,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
else
{
wc.hIcon = (HICON) ::LoadIconA(hInstance, "MainIcon");
- if (wc.hIcon == NULL)
+ if (wc.hIcon == NULL)
{
EnumResourceNamesW(hInstance, (LPCWSTR)RT_GROUP_ICON, BFEnumResNameProc, 0);
wc.hIcon = gMainIcon;
@@ -127,15 +127,15 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProcStub;
wc.lpszClassName = L"BFWindow";
- wc.lpszMenuName = NULL;
- RegisterClassW(&wc);
+ wc.lpszMenuName = NULL;
+ RegisterClassW(&wc);
int requestedX = x;
int requestedY = y;
int aWindowFlags = 0;
bool hasDestAlpha = (windowFlags & BFWINDOW_DEST_ALPHA) != 0;
-
+
if (windowFlags & BFWINDOW_MENU)
{
WinBFMenu* aMenu = new WinBFMenu();
@@ -143,8 +143,8 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
mHMenuMap[aMenu->mMenu] = aMenu;
mMenu = aMenu;
}
-
- int windowFlagsEx = /*WS_EX_COMPOSITED |*/ WS_EX_LAYERED;
+
+ int windowFlagsEx = /*WS_EX_COMPOSITED |*/ WS_EX_LAYERED;
if (windowFlags & BFWINDOW_TOOLWINDOW)
windowFlagsEx |= WS_EX_TOOLWINDOW;
if (windowFlags & BFWINDOW_BORDER)
@@ -152,11 +152,11 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
if (windowFlags & BFWINDOW_THICKFRAME)
aWindowFlags |= WS_THICKFRAME;
if ((windowFlags & BFWINDOW_RESIZABLE) && (!hasDestAlpha))
- aWindowFlags |= WS_SIZEBOX;
+ aWindowFlags |= WS_SIZEBOX;
if (windowFlags & BFWINDOW_SYSMENU)
aWindowFlags |= WS_SYSMENU;
if (windowFlags & BFWINDOW_CAPTION)
- aWindowFlags |= WS_CAPTION;
+ aWindowFlags |= WS_CAPTION;
else
aWindowFlags |= WS_POPUP;
if (windowFlags & BFWINDOW_MINIMIZE)
@@ -177,10 +177,10 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
width = rect.right - rect.left;
height = rect.bottom - rect.top;
}
-
+
if (windowFlags & BFWINDOW_POPUP_POSITION)
{
- AdjustedMonRect adjustRect = { 0, x, y, width, height };
+ AdjustedMonRect adjustRect = { 0, x, y, width, height };
RECT wantRect = { x, y, x + width, y + height };
EnumDisplayMonitors(NULL, &wantRect, ClipToMonitor, (LPARAM)&adjustRect);
@@ -191,7 +191,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
width = adjustRect.mWidth;
height = adjustRect.mHeight;
}
-
+
mFlags = windowFlags;
mMouseVisible = true;
@@ -204,8 +204,8 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
{
WinBFMenu* placeholderMenu = (WinBFMenu*) AddMenuItem(mMenu, 0, ": Placeholder Menu Item :", NULL, NULL, false, -1, false);
placeholderMenu->mIsPlaceholder = true;
- }
-
+ }
+
mHWnd = CreateWindowExW(windowFlagsEx, L"BFWindow", UTF8Decode(title).c_str(),
aWindowFlags,
x, y,
@@ -215,7 +215,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
(mMenu != NULL) ? ((WinBFMenu*) mMenu)->mMenu : NULL,
hInstance,
0);
-
+
if ((windowFlags & BFWINDOW_ALPHA_MASK) == 0)
SetLayeredWindowAttributes(mHWnd, 0, 255, 0);
@@ -225,7 +225,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
int showFlags = SWP_SHOWWINDOW;
// if (windowFlags & BFWINDOW_SHOWMINIMIZED)
// showFlags = SWP_
- mHasFocus = true;
+ mHasFocus = true;
mSoftHasFocus = true;
if (windowFlags & BFWINDOW_FAKEFOCUS)
{
@@ -253,7 +253,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
else if (windowFlags & BFWINDOW_SHOWMAXIMIZED)
wndPlacement.showCmd = SW_SHOWMAXIMIZED;
else
- wndPlacement.showCmd = SW_SHOWNORMAL;
+ wndPlacement.showCmd = SW_SHOWNORMAL;
wndPlacement.rcNormalPosition.left = x;
wndPlacement.rcNormalPosition.top = y;
@@ -266,11 +266,11 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
SetWindowPos(mHWnd, relativeWindow, x, y, width, height, showFlags);
}
-
+
SetTimer(mHWnd, 0, 10, NULL);
-
+
mIsMouseInside = false;
- mRenderWindow = new DXRenderWindow((DXRenderDevice*) gBFApp->mRenderDevice, this, (windowFlags & BFWINDOW_FULLSCREEN) == 0);
+ mRenderWindow = new DXRenderWindow((DXRenderDevice*) gBFApp->mRenderDevice, this, (windowFlags & BFWINDOW_FULLSCREEN) == 0);
gBFApp->mRenderDevice->AddRenderWindow(mRenderWindow);
SetWindowLongPtr(mHWnd, GWLP_USERDATA, (LONG_PTR)this);
@@ -281,7 +281,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
mAlphaMaskPixels = NULL;
mAlphaMaskWidth = 0;
mAlphaMaskHeight = 0;
- mNeedsStateReset = false;
+ mNeedsStateReset = false;
mAwaitKeyReleases = false;
mAwaitKeyReleasesEventTick = 0;
mAwaitKeyReleasesCheckIdx = 0;
@@ -293,11 +293,11 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
DwmExtendFrameIntoClientArea(mHWnd, &dWMMargins);
}
- if (windowFlags & BFWINDOW_MODAL)
- {
- EnableWindow(parentHWnd, FALSE);
+ if (windowFlags & BFWINDOW_MODAL)
+ {
+ EnableWindow(parentHWnd, FALSE);
}
-
+
if (parent != NULL)
{
auto winParent = (WinBFWindow*)parent;
@@ -310,7 +310,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
}
WinBFWindow::~WinBFWindow()
-{
+{
//OutputDebugStrF("Wnd %p Destroyed\n", this);
if (mHWnd != NULL)
@@ -354,7 +354,7 @@ void WinBFWindow::SetTitle(const char* title)
}
void WinBFWindow::LostFocus(BFWindow* newFocus)
-{
+{
///OutputDebugStrF("Lost focus\n");
mFocusLostTick = ::GetTickCount();
WinBFWindow* bfNewFocus = (WinBFWindow*)newFocus;
@@ -362,8 +362,8 @@ void WinBFWindow::LostFocus(BFWindow* newFocus)
for (int i = 0; i < KEYCODE_MAX; i++)
{
// Only transfer mode keys
- if (mIsKeyDown[i])
- {
+ if (mIsKeyDown[i])
+ {
mIsKeyDown[i] = false;
mKeyUpFunc(this, i);
@@ -374,7 +374,7 @@ void WinBFWindow::LostFocus(BFWindow* newFocus)
newFocus->mKeyDownFunc(newFocus, i, 0);
}
}
- }
+ }
}
void WinBFWindow::GotFocus()
@@ -388,7 +388,7 @@ void WinBFWindow::GotFocus()
mAwaitKeyReleases = true;
mAwaitKeyReleasesCheckIdx = 0;
mAwaitKeyReleasesEventTick = ::GetTickCount();
- }
+ }
}
void WinBFWindow::SetForeground()
@@ -405,7 +405,7 @@ void WinBFWindow::SetForeground()
::SetFocus(mHWnd);
::SetForegroundWindow(mHWnd);
-
+
//OutputDebugStrF("SetForeground %p %d %d %d\n", mHWnd, hadFocus, ::GetTickCount() - prevFocusLostTick, mAwaitKeyReleases);
}
@@ -450,7 +450,7 @@ bool WinBFWindow::CheckKeyReleases(bool isKeyDown)
bool hasKeyDown = false;
uint8 keysDown[256] = { 0 };
- ::GetKeyboardState((PBYTE)&keysDown);
+ ::GetKeyboardState((PBYTE)&keysDown);
for (int i = 1; i < 256; i++)
if (keysDown[i] & 0x80)
hasKeyDown = true;
@@ -476,7 +476,7 @@ bool WinBFWindow::CheckKeyReleases(bool isKeyDown)
}
LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
+{
WinBFApp* app = (WinBFApp*) gBFApp;
if (app == NULL)
@@ -494,7 +494,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
{
auto childWindow = (WinBFWindow*)child;
if ((childWindow->mSoftHasFocus) && (childWindow->mFlags & BFWINDOW_FAKEFOCUS))
- {
+ {
return childWindow->WindowProc(hWnd, uMsg, wParam, lParam);
}
}
@@ -521,8 +521,8 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
for (auto checkChild : winWindow->mChildren)
{
auto checkWinChild = (WinBFWindow*)checkChild;
- if (checkWinChild->mFlags & BFWINDOW_FAKEFOCUS)
- altFocusWindow = checkWinChild;
+ if (checkWinChild->mFlags & BFWINDOW_FAKEFOCUS)
+ altFocusWindow = checkWinChild;
}
if (altFocusWindow == NULL)
break;
@@ -541,7 +541,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_DESTROY:
/*if (mFlags & BFWINDOW_QUIT_ON_CLOSE)
{
- gBFApp->mRunning = false;
+ gBFApp->mRunning = false;
}*/
SetWindowLongPtr(mHWnd, GWLP_USERDATA, (LONG_PTR)0);
mHWnd = NULL;
@@ -549,7 +549,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
{
NOP;
}
- break;
+ break;
}
LRESULT result = 0;
@@ -558,7 +558,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if (!app->mInMsgProc)
{
if (mNeedsStateReset)
- {
+ {
for (int i = 0; i < KEYCODE_MAX; i++)
{
if (mIsKeyDown[i])
@@ -585,21 +585,21 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
//OutputDebugStrF("Rehup ReleaseCapture()\n");
ReleaseCapture();
-
+
mNeedsStateReset = false;
mIsMouseInside = false;
}
-
+
WinBFWindow* menuTarget = this;
- if (mFlags & BFWINDOW_USE_PARENT_MENU)
- menuTarget = ((WinBFWindow*)mParent);
- auto* menuIDMap = &menuTarget->mMenuIDMap;
+ if (mFlags & BFWINDOW_USE_PARENT_MENU)
+ menuTarget = ((WinBFWindow*)mParent);
+ auto* menuIDMap = &menuTarget->mMenuIDMap;
auto* hMenuMap = &menuTarget->mHMenuMap;
app->mInMsgProc = true;
switch (uMsg)
- {
+ {
case WM_DISPLAYCHANGE:
((DXRenderWindow*)mRenderWindow)->mRefreshRate = 0;
break;
@@ -608,7 +608,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if (mMovedFunc != NULL)
mMovedFunc(this);
break;
- case WM_PAINT:
+ case WM_PAINT:
break;
case WM_NCHITTEST:
{
@@ -618,23 +618,23 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
int y = (short)HIWORD(lParam);
result = mHitTestFunc(this, x, y);
- doResult = (result != -3);
+ doResult = (result != -3);
}
break;
- case WM_LBUTTONDOWN:
+ case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
case WM_MOUSEMOVE:
- {
+ {
int x = (short)LOWORD(lParam);
int y = (short)HIWORD(lParam);
@@ -660,7 +660,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
bool isMouseOver = windowAtPoint == hWnd;
RehupMouseOver(isMouseOver);
//OutputDebugStrF("HWnd: %X Focus Window: %X Capture: %X\n", hWnd, windowAtPoint, ::GetCapture());
-
+
bool checkNonTransparentMousePosition = mNonExclusiveMouseCapture;
auto _BtnDown = [&](int btn)
@@ -688,7 +688,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
}
mIsMouseDown[btn] = true;
BFCoord mouseCoords = { x, y };
- if ((mouseCoords.mX != mMouseDownCoords[btn].mX) || (mouseCoords.mY != mMouseDownCoords[btn].mY) ||
+ if ((mouseCoords.mX != mMouseDownCoords[btn].mX) || (mouseCoords.mY != mMouseDownCoords[btn].mY) ||
(tickNow - mMouseDownTicks[btn] > ::GetDoubleClickTime()))
mMouseClickCount[btn] = 0;
mMouseDownCoords[btn] = mouseCoords;
@@ -722,19 +722,19 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
break;
case WM_MBUTTONDOWN:
_BtnDown(2);
- break;
+ break;
case WM_XBUTTONDOWN:
_BtnDown((int)(wParam >> 16) + 2);
break;
case WM_LBUTTONUP:
- _BtnUp(0);
+ _BtnUp(0);
break;
- case WM_RBUTTONUP:
+ case WM_RBUTTONUP:
_BtnUp(1);
break;
- case WM_MBUTTONUP:
+ case WM_MBUTTONUP:
_BtnUp(2);
- break;
+ break;
case WM_XBUTTONUP:
_BtnUp((int)(wParam >> 16) + 2);
break;
@@ -746,21 +746,21 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if ((gBFApp->mWindowList.size() > 1) && (GetCapture() == NULL))
{
// See if our mouse is down and has entered into another window's space
- POINT point = { x, y };
- HWND windowAtPoint = ::WindowFromPoint(point);
+ POINT point = { x, y };
+ HWND windowAtPoint = ::WindowFromPoint(point);
BFWindowList::iterator itr = gBFApp->mWindowList.begin();
while (itr != gBFApp->mWindowList.end())
{
- WinBFWindow* aWindow = (WinBFWindow*) *itr;
+ WinBFWindow* aWindow = (WinBFWindow*) *itr;
LONG targetStyle = ::GetWindowLong(aWindow->mHWnd, GWL_EXSTYLE);
if ((::IsWindowEnabled(aWindow->mHWnd)) && ((targetStyle & WS_EX_TRANSPARENT) == 0))
{
if (aWindow->mHWnd == windowAtPoint)
- {
+ {
aWindow->mIsMouseInside = true;
cursorWindow = aWindow;
- }
+ }
}
++itr;
}
@@ -779,7 +779,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
POINT pt = {x, y};
ScreenToClient(cursorWindow->mHWnd, &pt);
-
+
if (uMsg == WM_MOUSEWHEEL)
{
float delta = ((int16)HIWORD(wParam)) / 120.0f * (float)ucNumLines;
@@ -804,7 +804,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
LONG captureStyle = ::GetWindowLong(captureWindow, GWL_EXSTYLE);
if ((captureStyle & WS_EX_TRANSPARENT) != 0)
checkNonTransparentMousePosition = true;
- }
+ }
}
break;
}
@@ -832,18 +832,18 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
POINT clientPt = point;
::ScreenToClient(aWindow->mHWnd, &clientPt);
aWindow->mMouseProxyMoveFunc(aWindow, clientPt.x, clientPt.y);
- aWindow->mIsMouseInside = true;
+ aWindow->mIsMouseInside = true;
}
else if (aWindow->mIsMouseInside)
{
aWindow->mMouseLeaveFunc(aWindow);
- aWindow->mIsMouseInside = false;
+ aWindow->mIsMouseInside = false;
}
}
}
++itr;
}
- }
+ }
if (releaseCapture)
{
@@ -871,11 +871,11 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
++itr;
}
}
- }
+ }
break;
-
+
case WM_COMMAND:
- {
+ {
WinBFMenu* aMenu = (*menuIDMap)[(uint32)wParam];
if (aMenu != NULL)
menuTarget->mMenuItemSelectedFunc(menuTarget, aMenu);
@@ -910,7 +910,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
}
break;
- case WM_MOUSEACTIVATE:
+ case WM_MOUSEACTIVATE:
if (mFlags & BFWINDOW_NO_MOUSE_ACTIVATE)
{
doResult = true;
@@ -930,7 +930,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
//OutputDebugStrF("WM_KILLFOCUS %p\n", hWnd);
mHasFocus = false;
mSoftHasFocus = false;
- LostFocus(NULL);
+ LostFocus(NULL);
mLostFocusFunc(this);
break;
case WM_SETFOCUS:
@@ -951,7 +951,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if (mMenu != NULL)
mNeedsStateReset = true;
break;
- case WM_NCMOUSELEAVE:
+ case WM_NCMOUSELEAVE:
mIsMouseInside = false;
mMouseLeaveFunc(this);
break;
@@ -967,7 +967,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
pD3DDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
pD3DDebug->Release();
}
- }*/
+ }*/
//NOTE: This line broke Alt+Gr for braces and such. Determine why this was needed.
//if ((!mIsKeyDown[VK_MENU]) && (!mIsKeyDown[VK_CONTROL]))
@@ -998,7 +998,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
keyCode = VK_RMENU;
mIsKeyDown[keyCode] = true;
-
+
// if ((keyCode == 192) && (mIsKeyDown[VK_MENU]))
// {
// ((DXRenderDevice*)mRenderWindow->mRenderDevice)->mNeedsReinitNative = true;
@@ -1014,9 +1014,9 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
{
mIsMenuKeyHandled = true;
menuTarget->mMenuItemSelectedFunc(menuTarget, aMenu);
- doResult = true;
+ doResult = true;
break;
- }
+ }
}
if (!mIsMenuKeyHandled)
@@ -1024,14 +1024,14 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if ((CheckKeyReleases(true)) && (mKeyDownFunc(this, keyCode, (lParam & 0x7FFF) != 0)))
{
mIsMenuKeyHandled = true;
- doResult = true;
+ doResult = true;
}
}
}
- break;
+ break;
case WM_SYSCHAR:
{
- int keyCode = toupper((int) wParam);
+ int keyCode = toupper((int) wParam);
for (auto& menuKV : *menuIDMap)
{
@@ -1040,11 +1040,11 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
(aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) &&
(aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) &&
(aMenu->mKeyAlt == mIsKeyDown[VK_MENU]))
- {
+ {
if (CheckKeyReleases(true))
- doResult = true;
+ doResult = true;
break;
- }
+ }
}
if (!mIsKeyDown[VK_MENU])
@@ -1068,7 +1068,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
}
CheckKeyReleases(false);
}
- break;
+ break;
case WM_SYSCOMMAND:
// Ignore F10
if ((wParam == SC_KEYMENU) && (lParam == 0))
@@ -1091,18 +1091,18 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
break;
case WM_TIMER:
if (gBFApp->mSysDialogCnt == 0)
- {
+ {
auto checkNonFake = this;
while (checkNonFake->mFlags & BFWINDOW_FAKEFOCUS)
{
checkNonFake = (WinBFWindow*)checkNonFake->mParent;
}
bool isFocused = GetForegroundWindow() == checkNonFake->mHWnd;
-
+
if ((!isFocused) && (mHasFocus))
{
mSoftHasFocus = false;
- mHasFocus = false;
+ mHasFocus = false;
LostFocus(NULL);
mLostFocusFunc(this);
//OutputDebugStrF("Timer detected lost focus %p\r\n", hWnd);
@@ -1137,7 +1137,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
doResult = true;
}
break;
-
+
case WM_MOVE:
case WM_MOVING:
if (mMovedFunc != NULL)
@@ -1148,7 +1148,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if (mMovedFunc != NULL)
mMovedFunc(this);
if (gBFApp->mSysDialogCnt == 0)
- gBFApp->Process();
+ gBFApp->Process();
break;
case WM_INPUTLANGCHANGE:
@@ -1159,7 +1159,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
{
HDROP hDropInfo = (HDROP)wParam;
char sItem[MAX_PATH];
-
+
for(int i = 0; DragQueryFileA(hDropInfo, i, (LPSTR)sItem, sizeof(sItem)); i++)
mDragDropFileFunc(this, sItem);
@@ -1167,19 +1167,19 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
}
break;
}
-
+
app->mInMsgProc = false;
}
else
{
// We got messages we couldn't process (due to reentrancy)
switch (uMsg)
- {
+ {
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_MOUSEMOVE:
- case WM_KEYUP:
+ case WM_KEYUP:
case WM_MOUSELEAVE:
mNeedsStateReset = true;
break;
@@ -1239,9 +1239,9 @@ static int WinBFReportHook( int reportType, char *message, int *returnValue )
/* Ignore: continue execution */
return 0;
-
-
+
+
return 1;
}
@@ -1252,7 +1252,7 @@ static GetDpiForWindow_t gGetDpiForWindow = NULL;
static HMODULE gUserDll = NULL;
WinBFApp::WinBFApp()
-{
+{
#ifndef BF_MINGW
//_CrtSetReportHook(WinBFReportHook);
#endif
@@ -1264,7 +1264,7 @@ WinBFApp::WinBFApp()
}
mRunning = false;
- mRenderDevice = NULL;
+ mRenderDevice = NULL;
mInstallDir = "Hey";
@@ -1281,7 +1281,7 @@ WinBFApp::WinBFApp()
mDataDir = mInstallDir;
mInMsgProc = false;
mDSoundManager = NULL;
- mDInputManager = NULL;
+ mDInputManager = NULL;
mVSyncThreadId = 0;
mClosing = false;
@@ -1312,8 +1312,8 @@ void WinBFApp::VSyncThreadProc()
AutoCrit autoCrit(mCritSect);
if ((mRenderDevice != NULL) && (!mRenderDevice->mRenderWindowList.IsEmpty()))
{
- auto renderWindow = (DXRenderWindow*)mRenderDevice->mRenderWindowList[0];
- renderWindow->mDXSwapChain->GetContainingOutput(&output);
+ auto renderWindow = (DXRenderWindow*)mRenderDevice->mRenderWindowList[0];
+ renderWindow->mDXSwapChain->GetContainingOutput(&output);
}
}
@@ -1321,8 +1321,8 @@ void WinBFApp::VSyncThreadProc()
{
DWORD startTick = GetTickCount();
bool success = output->WaitForVBlank() == 0;
- DWORD endTick = GetTickCount();
-
+ DWORD endTick = GetTickCount();
+
if (success)
{
int elapsed = (int)(endTick - startTick);
@@ -1341,7 +1341,7 @@ void WinBFApp::VSyncThreadProc()
if (!hadNonZero)
success = false;
}
- }
+ }
if (success)
{
@@ -1353,7 +1353,7 @@ void WinBFApp::VSyncThreadProc()
output->Release();
}
- if (!didWait)
+ if (!didWait)
{
mVSyncActive = false;
BfpThread_Sleep(20);
@@ -1362,7 +1362,7 @@ void WinBFApp::VSyncThreadProc()
}
WinBFApp::~WinBFApp()
-{
+{
mClosing = true;
BfpThread_WaitFor(mVSyncThread, -1);
BfpThread_Release(mVSyncThread);
@@ -1373,14 +1373,14 @@ WinBFApp::~WinBFApp()
}
void WinBFApp::Init()
-{
+{
BP_ZONE("WinBFApp::Init");
AutoCrit autoCrit(mCritSect);
mRunning = true;
mInMsgProc = false;
-
+
mRenderDevice = new DXRenderDevice();
mRenderDevice->Init(this);
}
@@ -1391,14 +1391,14 @@ void WinBFApp::Run()
while (mRunning)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
+ {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (mRunning)
Process();
- }
+ }
}
void WinBFApp::Process()
@@ -1416,9 +1416,9 @@ void WinBFApp::Process()
void WinBFApp::Draw()
{
- mRenderDevice->FrameStart();
+ mRenderDevice->FrameStart();
BFApp::Draw();
- mRenderDevice->FrameEnd();
+ mRenderDevice->FrameEnd();
}
void WinBFApp::GetDesktopResolution(int& width, int& height)
@@ -1460,7 +1460,7 @@ static BOOL InflateRectToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM u
}
void WinBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height)
-{
+{
AdjustedMonRect inflateRect = { 0 };
EnumDisplayMonitors(NULL, NULL, InflateRectToMonitor, (LPARAM)&inflateRect);
@@ -1494,12 +1494,12 @@ void WinBFApp::GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fro
}
BFWindow* WinBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
-{
+{
AutoCrit autoCrit(mCritSect);
BFWindow* aWindow = new WinBFWindow(parent, title, x, y, width, height, windowFlags);
mWindowList.push_back(aWindow);
-
+
return aWindow;
}
@@ -1535,7 +1535,7 @@ void WinBFWindow::SetMinimumSize(int minWidth, int minHeight, bool clientSized)
DWORD windowFlagsEx = ::GetWindowLong(mHWnd, GWL_EXSTYLE);
RECT rect = { 0, 0, minWidth, minHeight };
- AdjustWindowRectEx(&rect, windowFlags, mMenu != NULL, windowFlagsEx);
+ AdjustWindowRectEx(&rect, windowFlags, mMenu != NULL, windowFlagsEx);
minWidth = rect.right - rect.left;
minHeight = rect.bottom - rect.top;
}
@@ -1615,14 +1615,14 @@ void WinBFWindow::GetPlacement(int* normX, int* normY, int* normWidth, int* norm
default:
*showKind = 0;
break;
- }
+ }
}
void WinBFWindow::Resize(int x, int y, int width, int height, int showKind)
-{
+{
WINDOWPLACEMENT wndPlacement = { sizeof(WINDOWPLACEMENT), 0 };
::GetWindowPlacement(mHWnd, &wndPlacement);
-
+
switch (showKind)
{
case 1:
@@ -1634,7 +1634,7 @@ void WinBFWindow::Resize(int x, int y, int width, int height, int showKind)
case 3:
wndPlacement.showCmd = SW_SHOWNORMAL;
break;
- }
+ }
wndPlacement.rcNormalPosition.left = x;
wndPlacement.rcNormalPosition.top = y;
@@ -1645,31 +1645,31 @@ void WinBFWindow::Resize(int x, int y, int width, int height, int showKind)
//::MoveWindow(mHWnd, x, y, width, height, FALSE);
mRenderWindow->Resized();
if (mMovedFunc != NULL)
- mMovedFunc(this);
+ mMovedFunc(this);
}
void WinBFApp::PhysSetCursor()
{
- static HCURSOR cursors [] =
- {
+ static HCURSOR cursors [] =
+ {
::LoadCursor(NULL, IDC_ARROW),
-
+
//TODO: mApp->mHandCursor);
::LoadCursor(NULL, IDC_HAND),
//TODO: mApp->mDraggingCursor);
::LoadCursor(NULL, IDC_SIZEALL),
::LoadCursor(NULL, IDC_IBEAM),
-
- ::LoadCursor(NULL, IDC_NO),
+
+ ::LoadCursor(NULL, IDC_NO),
::LoadCursor(NULL, IDC_SIZEALL),
::LoadCursor(NULL, IDC_SIZENESW),
- ::LoadCursor(NULL, IDC_SIZENS),
+ ::LoadCursor(NULL, IDC_SIZENS),
::LoadCursor(NULL, IDC_SIZENWSE),
- ::LoadCursor(NULL, IDC_SIZEWE),
- ::LoadCursor(NULL, IDC_WAIT),
+ ::LoadCursor(NULL, IDC_SIZEWE),
+ ::LoadCursor(NULL, IDC_WAIT),
NULL
- };
+ };
::SetCursor(cursors[mCursor]);
}
@@ -1705,7 +1705,7 @@ void WinBFWindow::SetMouseVisible(bool isMouseVisible)
void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible)
{
if (destAlphaSrcMask != 0)
- {
+ {
if (mAlphaMaskBitmap == NULL)
{
RECT clientRect;
@@ -1727,7 +1727,7 @@ void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVis
bi.bmiHeader.biWidth = aWidth;
bi.bmiHeader.biHeight = -aHeight;
bi.bmiHeader.biCompression = BI_RGB;
- bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biPlanes = 1;
mAlphaMaskBitmap = CreateDIBSection(mAlphaMaskDC, &bi,
DIB_RGB_COLORS, (void**)&mAlphaMaskPixels, NULL, 0);
@@ -1741,9 +1741,9 @@ void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVis
DXRenderWindow* renderWindow = (DXRenderWindow*) mRenderWindow;
renderWindow->CopyBitsTo(mAlphaMaskPixels, mAlphaMaskWidth, mAlphaMaskHeight);
- //for (int i = 0; i < mAlphaMaskWidth*mAlphaMaskHeight/2; i++)
- //mAlphaMaskPixels[i] = 0x80FF8000;
-
+ //for (int i = 0; i < mAlphaMaskWidth*mAlphaMaskHeight/2; i++)
+ //mAlphaMaskPixels[i] = 0x80FF8000;
+
HGDIOBJ hPrevObj = 0;
POINT ptDest = {0, 0};
POINT ptSrc = {0, 0};
@@ -1752,28 +1752,28 @@ void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVis
hPrevObj = SelectObject(mAlphaMaskDC, mAlphaMaskBitmap);
ClientToScreen(mHWnd, &ptDest);
-
+
BOOL worked = ::UpdateLayeredWindow(mHWnd, hdc, NULL, &client,
mAlphaMaskDC, &ptSrc, 0, &blendFunc, ULW_ALPHA);
DWORD error = GetLastError();
SelectObject(mAlphaMaskDC, hPrevObj);
- ReleaseDC(mHWnd, hdc);
+ ReleaseDC(mHWnd, hdc);
}
}
else
{
::SetLayeredWindowAttributes(mHWnd, 0, (int) (alpha * 255), LWA_ALPHA);
}
- SetMouseVisible(isMouseVisible);
+ SetMouseVisible(isMouseVisible);
}
void WinBFWindow::CaptureMouse()
{
//OutputDebugStrF("Wnd %p CaptureMouse", this);
::SetCapture(mHWnd);
-
+
for (auto window : gBFApp->mWindowList)
{
if (window == this)
@@ -1813,7 +1813,7 @@ uint32 WinBFApp::GetClipboardFormat(const StringImpl& format)
uint32 aFormat;
if (mClipboardFormatMap.TryGetValue(format, &aFormat))
return aFormat;
-
+
aFormat = ::RegisterClipboardFormatA(format.c_str());
mClipboardFormatMap[format] = aFormat;
return aFormat;
@@ -1840,7 +1840,7 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size)
if (aFormat == CF_UNICODETEXT)
{
CloseClipboard();
- // Return ascii text
+ // Return ascii text
return (char*)GetClipboardData("atext", size);
}
@@ -1851,7 +1851,7 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size)
*size = (int)::GlobalSize(globalHandle);
void* aPtr = ::GlobalLock(globalHandle);
-
+
if (aFormat == CF_UNICODETEXT)
{
gClipboardData = UTF8Encode((WCHAR*)aPtr);
@@ -1862,11 +1862,16 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size)
gClipboardData.Clear();
gClipboardData.Insert(0, (char*)aPtr, *size);
}
-
+
::GlobalUnlock(globalHandle);
CloseClipboard();
return (void*)gClipboardData.c_str();
}
+ else
+ {
+ *size = -1;
+ return NULL;
+ }
}
*size = 0;
@@ -1875,7 +1880,7 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size)
void WinBFApp::ReleaseClipboardData(void* ptr)
{
-
+
}
void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard)
@@ -1887,7 +1892,7 @@ void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int s
aWindow = ((WinBFWindow*) mWindowList.front())->mHWnd;
uint32 aFormat = GetClipboardFormat(format);
-
+
if (aFormat != 0)
{
if (OpenClipboard(aWindow))
@@ -1897,7 +1902,7 @@ void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int s
BP_ZONE("WinBFApp::SetClipboardData:empty");
EmptyClipboard();
}
-
+
if (format == "text")
{
BP_ZONE("WinBFApp::SetClipboardData:text");
@@ -1922,14 +1927,14 @@ void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int s
GlobalUnlock(globalHandle);
::SetClipboardData(aFormat, globalHandle);
}
-
+
CloseClipboard();
}
}
}
BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck)
-{
+{
UTF16String lText;
if (text != NULL)
lText = UTF8Decode(text);
@@ -1938,7 +1943,7 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text
lHotKey = UTF8Decode(hotKey);
bool wasEmpty = mMenu->mBFMenuList.size() == 0;
-
+
if (parent == NULL)
parent = mMenu;
@@ -1949,7 +1954,7 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text
RemoveMenuItem(placeholderMenuItem);
delete placeholderMenuItem;
}
-
+
WinBFMenu* winBFMenuParent = (WinBFMenu*) parent;
WinBFMenu* newMenu = new WinBFMenu();
newMenu->mMenuId = ++WinBFMenu::mMenuCount;
@@ -1969,14 +1974,14 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text
menuItem.cbSize = sizeof(MENUITEMINFO);
menuItem.fMask = MIIM_SUBMENU;
menuItem.hSubMenu = winBFMenuParent->mMenu;
-
- ::SetMenuItemInfo(((WinBFMenu*) winBFMenuParent->mParent)->mMenu, winBFMenuParent->mMenuId, FALSE, &menuItem);
+
+ ::SetMenuItemInfo(((WinBFMenu*) winBFMenuParent->mParent)->mMenu, winBFMenuParent->mMenuId, FALSE, &menuItem);
}
mMenuIDMap[newMenu->mMenuId] = newMenu;
BF_ASSERT(insertIdx <= (int) parent->mBFMenuList.size());
-
+
////
UTF16String lCombinedName;
@@ -1986,11 +1991,11 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text
menuItem.fMask = MIIM_FTYPE | MIIM_ID;
if (text != NULL)
{
- menuItem.fMask |= MIIM_STRING;
+ menuItem.fMask |= MIIM_STRING;
menuItem.fType = MFT_STRING;
}
else
- menuItem.fType = MFT_SEPARATOR;
+ menuItem.fType = MFT_SEPARATOR;
menuItem.fState = enabled ? MFS_DEFAULT : MFS_GRAYED;
if (checkState == 0)
menuItem.fState |= MFS_UNCHECKED;
@@ -1998,14 +2003,14 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text
menuItem.fState |= MFS_CHECKED;
if (radioCheck)
menuItem.fType = MFT_RADIOCHECK;
-
+
menuItem.wID = newMenu->mMenuId;
if (text != NULL)
{
menuItem.dwTypeData = (WCHAR*)lText.c_str();
}
- if (hotKey != NULL)
+ if (hotKey != NULL)
{
String combinedName = String(text);
combinedName += "\t";
@@ -2033,7 +2038,7 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text
ModifyMenuItem(newMenu, text, hotKey, sysBitmap, enabled, checkState, radioCheck);
- parent->mBFMenuList.push_back(newMenu);
+ parent->mBFMenuList.push_back(newMenu);
return newMenu;
}
@@ -2051,11 +2056,11 @@ void WinBFWindow::ModifyMenuItem(BFMenu* item, const char* text, const char* hot
WinBFMenu* parentMenu = (WinBFMenu*) item->mParent;
UTF16String lCombinedName;
-
+
MENUITEMINFOW menuItem;
memset(&menuItem, 0, sizeof(MENUITEMINFO));
menuItem.cbSize = sizeof(MENUITEMINFO);
- menuItem.fMask = MIIM_FTYPE | MIIM_ID;
+ menuItem.fMask = MIIM_FTYPE | MIIM_ID;
::GetMenuItemInfoW(parentMenu->mMenu, aMenu->mMenuId, FALSE, &menuItem);
@@ -2082,12 +2087,12 @@ void WinBFWindow::ModifyMenuItem(BFMenu* item, const char* text, const char* hot
menuItem.fType = MFT_RADIOCHECK;
menuItem.wID = aMenu->mMenuId;
- menuItem.dwTypeData = (WCHAR*)lText.c_str();
+ menuItem.dwTypeData = (WCHAR*)lText.c_str();
if (hotKey != NULL)
{
menuItem.fMask |= MIIM_DATA;
-
+
String combinedName = String(text);
combinedName += "\t";
if (hotKey[0] == '#')
@@ -2107,7 +2112,7 @@ void WinBFWindow::ModifyMenuItem(BFMenu* item, const char* text, const char* hot
}
void WinBFWindow::RemoveMenuItem(BFMenu* item)
-{
+{
WinBFMenu* aMenu = (WinBFMenu*) item;
WinBFMenu* parentMenu = (WinBFMenu*) item->mParent;
@@ -2115,7 +2120,7 @@ void WinBFWindow::RemoveMenuItem(BFMenu* item)
//mMenuIDMap.erase(itr);
mMenuIDMap.Remove(aMenu->mMenuId);
- ::RemoveMenu(parentMenu->mMenu, aMenu->mMenuId, MF_BYCOMMAND);
+ ::RemoveMenu(parentMenu->mMenu, aMenu->mMenuId, MF_BYCOMMAND);
}
BFSysBitmap* WinBFApp::LoadSysBitmap(const WCHAR* fileName)
@@ -2148,8 +2153,8 @@ DrawLayer* WinBFApp::CreateDrawLayer(BFWindow* window)
{
DXDrawLayer* drawLayer = new DXDrawLayer();
if (window != NULL)
- {
- drawLayer->mRenderWindow = window->mRenderWindow;
+ {
+ drawLayer->mRenderWindow = window->mRenderWindow;
window->mRenderWindow->mDrawLayerList.push_back(drawLayer);
}
drawLayer->mRenderDevice = mRenderDevice;
diff --git a/BeefySysLib/third_party/putty/LICENSE b/BeefySysLib/third_party/putty/LICENSE
new file mode 100644
index 00000000..478b68d8
--- /dev/null
+++ b/BeefySysLib/third_party/putty/LICENSE
@@ -0,0 +1,28 @@
+PuTTY is copyright 1997-2020 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
+Kuhn, Colin Watson, Christopher Staite, Lorenz Diener, Christian
+Brabandt, Jeff Smith, Pavel Kryukov, Maxim Kuznetsov, Svyatoslav
+Kuzmich, Nico Williams, Viktor Dukhovni, Josh Dersch, Lars Brinkhoff,
+and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/BeefySysLib/third_party/putty/wildcard.c b/BeefySysLib/third_party/putty/wildcard.c
new file mode 100644
index 00000000..2b1f858f
--- /dev/null
+++ b/BeefySysLib/third_party/putty/wildcard.c
@@ -0,0 +1,340 @@
+/*
+ * Wildcard matching engine for use with SFTP-based file transfer
+ * programs (PSFTP, new-look PSCP): since SFTP has no notion of
+ * getting the remote side to do globbing (and rightly so) we have
+ * to do it locally, by retrieving all the filenames in a directory
+ * and checking each against the wildcard pattern.
+ */
+
+#include
+#include
+#include
+
+#include "wildcard.h"
+
+/*
+ * Definition of wildcard syntax:
+ *
+ * - * matches any sequence of characters, including zero.
+ * - ? matches exactly one character which can be anything.
+ * - [abc] matches exactly one character which is a, b or c.
+ * - [a-f] matches anything from a through f.
+ * - [^a-f] matches anything _except_ a through f.
+ * - [-_] matches - or _; [^-_] matches anything else. (The - is
+ * non-special if it occurs immediately after the opening
+ * bracket or ^.)
+ * - [a^] matches an a or a ^. (The ^ is non-special if it does
+ * _not_ occur immediately after the opening bracket.)
+ * - \*, \?, \[, \], \\ match the single characters *, ?, [, ], \.
+ * - All other characters are non-special and match themselves.
+ */
+
+/*
+ * Some notes on differences from POSIX globs (IEEE Std 1003.1, 2003 ed.):
+ * - backslashes act as escapes even within [] bracket expressions
+ * - does not support [!...] for non-matching list (POSIX are weird);
+ * NB POSIX allows [^...] as well via "A bracket expression starting
+ * with an unquoted circumflex character produces unspecified
+ * results". If we wanted to allow [!...] we might want to define
+ * [^!] as having its literal meaning (match '^' or '!').
+ * - none of the scary [[:class:]] stuff, etc
+ */
+
+/*
+ * The wildcard matching technique we use is very simple and
+ * potentially O(N^2) in running time, but I don't anticipate it
+ * being that bad in reality (particularly since N will be the size
+ * of a filename, which isn't all that much). Perhaps one day, once
+ * PuTTY has grown a regexp matcher for some other reason, I might
+ * come back and reimplement wildcards by translating them into
+ * regexps or directly into NFAs; but for the moment, in the
+ * absence of any other need for the NFA->DFA translation engine,
+ * anything more than the simplest possible wildcard matcher is
+ * vast code-size overkill.
+ *
+ * Essentially, these wildcards are much simpler than regexps in
+ * that they consist of a sequence of rigid fragments (? and [...]
+ * can never match more or less than one character) separated by
+ * asterisks. It is therefore extremely simple to look at a rigid
+ * fragment and determine whether or not it begins at a particular
+ * point in the test string; so we can search along the string
+ * until we find each fragment, then search for the next. As long
+ * as we find each fragment in the _first_ place it occurs, there
+ * will never be a danger of having to backpedal and try to find it
+ * again somewhere else.
+ */
+
+enum {
+ WC_TRAILINGBACKSLASH = 1,
+ WC_UNCLOSEDCLASS,
+ WC_INVALIDRANGE
+};
+
+/*
+ * Error reporting is done by returning various negative values
+ * from the wildcard routines. Passing any such value to wc_error
+ * will give a human-readable message.
+ */
+const char *wc_error(int value)
+{
+ value = abs(value);
+ switch (value) {
+ case WC_TRAILINGBACKSLASH:
+ return "'\' occurred at end of string (expected another character)";
+ case WC_UNCLOSEDCLASS:
+ return "expected ']' to close character class";
+ case WC_INVALIDRANGE:
+ return "character range was not terminated (']' just after '-')";
+ }
+ return "INTERNAL ERROR: unrecognised wildcard error number";
+}
+
+/*
+ * This is the routine that tests a target string to see if an
+ * initial substring of it matches a fragment. If successful, it
+ * returns 1, and advances both `fragment' and `target' past the
+ * fragment and matching substring respectively. If unsuccessful it
+ * returns zero. If the wildcard fragment suffers a syntax error,
+ * it returns <0 and the precise value indexes into wc_error.
+ */
+static int wc_match_fragment(const char **fragment, const char **target,
+ const char *target_end)
+{
+ const char *f, *t;
+
+ f = *fragment;
+ t = *target;
+ /*
+ * The fragment terminates at either the end of the string, or
+ * the first (unescaped) *.
+ */
+ while (*f && *f != '*' && t < target_end) {
+ /*
+ * Extract one character from t, and one character's worth
+ * of pattern from f, and step along both. Return 0 if they
+ * fail to match.
+ */
+ if (*f == '\\') {
+ /*
+ * Backslash, which means f[1] is to be treated as a
+ * literal character no matter what it is. It may not
+ * be the end of the string.
+ */
+ if (!f[1])
+ return -WC_TRAILINGBACKSLASH; /* error */
+ if (f[1] != *t)
+ return 0; /* failed to match */
+ f += 2;
+ } else if (*f == '?') {
+ /*
+ * Question mark matches anything.
+ */
+ f++;
+ } else if (*f == '[') {
+ bool invert = false;
+ bool matched = false;
+ /*
+ * Open bracket introduces a character class.
+ */
+ f++;
+ if (*f == '^') {
+ invert = true;
+ f++;
+ }
+ while (*f != ']') {
+ if (*f == '\\')
+ f++; /* backslashes still work */
+ if (!*f)
+ return -WC_UNCLOSEDCLASS; /* error again */
+ if (f[1] == '-') {
+ int lower, upper, ourchr;
+ lower = (unsigned char) *f++;
+ f++; /* eat the minus */
+ if (*f == ']')
+ return -WC_INVALIDRANGE; /* different error! */
+ if (*f == '\\')
+ f++; /* backslashes _still_ work */
+ if (!*f)
+ return -WC_UNCLOSEDCLASS; /* error again */
+ upper = (unsigned char) *f++;
+ ourchr = (unsigned char) *t;
+ if (lower > upper) {
+ int t = lower; lower = upper; upper = t;
+ }
+ if (ourchr >= lower && ourchr <= upper)
+ matched = true;
+ } else {
+ matched |= (*t == *f++);
+ }
+ }
+ if (invert == matched)
+ return 0; /* failed to match character class */
+ f++; /* eat the ] */
+ } else {
+ /*
+ * Non-special character matches itself.
+ */
+ if (*f != *t)
+ return 0;
+ f++;
+ }
+ /*
+ * Now we've done that, increment t past the character we
+ * matched.
+ */
+ t++;
+ }
+ if (!*f || *f == '*') {
+ /*
+ * We have reached the end of f without finding a mismatch;
+ * so we're done. Update the caller pointers and return 1.
+ */
+ *fragment = f;
+ *target = t;
+ return 1;
+ }
+ /*
+ * Otherwise, we must have reached the end of t before we
+ * reached the end of f; so we've failed. Return 0.
+ */
+ return 0;
+}
+
+/*
+ * This is the real wildcard matching routine. It returns 1 for a
+ * successful match, 0 for an unsuccessful match, and <0 for a
+ * syntax error in the wildcard.
+ */
+static int wc_match_inner(
+ const char *wildcard, const char *target, size_t target_len)
+{
+ const char *target_end = target + target_len;
+ int ret;
+
+ /*
+ * Every time we see a '*' _followed_ by a fragment, we just
+ * search along the string for a location at which the fragment
+ * matches. The only special case is when we see a fragment
+ * right at the start, in which case we just call the matching
+ * routine once and give up if it fails.
+ */
+ if (*wildcard != '*') {
+ ret = wc_match_fragment(&wildcard, &target, target_end);
+ if (ret <= 0)
+ return ret; /* pass back failure or error alike */
+ }
+
+ while (*wildcard) {
+ assert(*wildcard == '*');
+ while (*wildcard == '*')
+ wildcard++;
+
+ /*
+ * It's possible we've just hit the end of the wildcard
+ * after seeing a *, in which case there's no need to
+ * bother searching any more because we've won.
+ */
+ if (!*wildcard)
+ return 1;
+
+ /*
+ * Now `wildcard' points at the next fragment. So we
+ * attempt to match it against `target', and if that fails
+ * we increment `target' and try again, and so on. When we
+ * find we're about to try matching against the empty
+ * string, we give up and return 0.
+ */
+ ret = 0;
+ while (*target) {
+ const char *save_w = wildcard, *save_t = target;
+
+ ret = wc_match_fragment(&wildcard, &target, target_end);
+
+ if (ret < 0)
+ return ret; /* syntax error */
+
+ if (ret > 0 && !*wildcard && target != target_end) {
+ /*
+ * Final special case - literally.
+ *
+ * This situation arises when we are matching a
+ * _terminal_ fragment of the wildcard (that is,
+ * there is nothing after it, e.g. "*a"), and it
+ * has matched _too early_. For example, matching
+ * "*a" against "parka" will match the "a" fragment
+ * against the _first_ a, and then (if it weren't
+ * for this special case) matching would fail
+ * because we're at the end of the wildcard but not
+ * at the end of the target string.
+ *
+ * In this case what we must do is measure the
+ * length of the fragment in the target (which is
+ * why we saved `target'), jump straight to that
+ * distance from the end of the string using
+ * strlen, and match the same fragment again there
+ * (which is why we saved `wildcard'). Then we
+ * return whatever that operation returns.
+ */
+ target = target_end - (target - save_t);
+ wildcard = save_w;
+ return wc_match_fragment(&wildcard, &target, target_end);
+ }
+
+ if (ret > 0)
+ break;
+ target++;
+ }
+ if (ret > 0)
+ continue;
+ return 0;
+ }
+
+ /*
+ * If we reach here, it must be because we successfully matched
+ * a fragment and then found ourselves right at the end of the
+ * wildcard. Hence, we return 1 if and only if we are also
+ * right at the end of the target.
+ */
+ return target == target_end;
+}
+
+int wc_match(const char *wildcard, const char *target)
+{
+ return wc_match_inner(wildcard, target, strlen(target));
+}
+
+/*
+ * Another utility routine that translates a non-wildcard string
+ * into its raw equivalent by removing any escaping backslashes.
+ * Expects a target string buffer of anything up to the length of
+ * the original wildcard. You can also pass NULL as the output
+ * buffer if you're only interested in the return value.
+ *
+ * Returns true on success, or false if a wildcard character was
+ * encountered. In the latter case the output string MAY not be
+ * zero-terminated and you should not use it for anything!
+ */
+bool wc_unescape(char *output, const char *wildcard)
+{
+ while (*wildcard) {
+ if (*wildcard == '\\') {
+ wildcard++;
+ /* We are lenient about trailing backslashes in non-wildcards. */
+ if (*wildcard) {
+ if (output)
+ *output++ = *wildcard;
+ wildcard++;
+ }
+ } else if (*wildcard == '*' || *wildcard == '?' ||
+ *wildcard == '[' || *wildcard == ']') {
+ return false; /* it's a wildcard! */
+ } else {
+ if (output)
+ *output++ = *wildcard;
+ wildcard++;
+ }
+ }
+ if (output)
+ *output = '\0';
+ return true; /* it's clean */
+}
\ No newline at end of file
diff --git a/BeefySysLib/third_party/putty/wildcard.h b/BeefySysLib/third_party/putty/wildcard.h
new file mode 100644
index 00000000..3c4a75ee
--- /dev/null
+++ b/BeefySysLib/third_party/putty/wildcard.h
@@ -0,0 +1,18 @@
+#ifndef PUTTY_WILDCARD_H_INCLUDE
+#define PUTTY_WILDCARD_H_INCLUDE
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *wc_error(int value);
+int wc_match(const char *wildcard, const char *target);
+bool wc_unescape(char *output, const char *wildcard);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PUTTY_WILDCARD_H_INCLUDE
\ No newline at end of file
diff --git a/BeefySysLib/util/BeefPerf.cpp b/BeefySysLib/util/BeefPerf.cpp
index 49ffeef1..e1dae1c1 100644
--- a/BeefySysLib/util/BeefPerf.cpp
+++ b/BeefySysLib/util/BeefPerf.cpp
@@ -757,10 +757,15 @@ bool BpManager::Connect()
if (mShutdownEvent.WaitFor(0))
{
// We are shutting down - have we waited enough?
- int minWaitMS = isLocalhost ? 50 : 20*1000;
+ int minWaitMS = isLocalhost ? 50 : 5*1000;
if (totalWaitedMS >= minWaitMS)
return false;
}
+
+ // We don't want to wait too long, otherwise we will buffer up too much
+ int maxWaitMS = isLocalhost ? 5*1000 : 15*1000;
+ if (totalWaitedMS >= maxWaitMS)
+ return false;
}
return true;
diff --git a/BeefySysLib/util/SizedArray.h b/BeefySysLib/util/SizedArray.h
index 63b328ad..51071e59 100644
--- a/BeefySysLib/util/SizedArray.h
+++ b/BeefySysLib/util/SizedArray.h
@@ -925,6 +925,8 @@ public:
this->mSize = val.mSize;
this->mAllocSize = val.mAllocSize;
val.mVals = (T*)&val.mFirstVal;
+ val.mSize = 0;
+ val.mAllocSize = TInternalSize;
}
}
@@ -1006,6 +1008,8 @@ public:
this->mAllocSize = val.mAllocSize;
val.mVals = NULL;
+ val.mSize = 0;
+ val.mAllocSize = 0;
}
}
@@ -1079,6 +1083,8 @@ public:
this->mAllocSize = val.mAllocSize;
val.mVals = &val.mInternalBuffer;
+ val.mSize = 0;
+ val.mAllocSize = 1;
}
}
diff --git a/Debugger32/Debugger32.vcxproj b/Debugger32/Debugger32.vcxproj
index 9c1e17a8..a724f12c 100644
--- a/Debugger32/Debugger32.vcxproj
+++ b/Debugger32/Debugger32.vcxproj
@@ -132,6 +132,7 @@
BF_DBG_32;WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)
../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include
false
+ true
Windows
@@ -150,6 +151,7 @@
-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)
false
MultiThreadedDebug
+ true
Windows
@@ -166,6 +168,7 @@
true
BF_DBG_32;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)
../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include
+ true
Windows
@@ -186,6 +189,7 @@
../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include
MultiThreaded
false
+ true
Windows
diff --git a/Debugger64/Debugger64.vcxproj b/Debugger64/Debugger64.vcxproj
index 57e46574..933ad4f2 100644
--- a/Debugger64/Debugger64.vcxproj
+++ b/Debugger64/Debugger64.vcxproj
@@ -132,6 +132,7 @@
BF_DBG_64;WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)
../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include
false
+ true
Windows
@@ -150,6 +151,7 @@
-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)
false
MultiThreadedDebug
+ true
Windows
@@ -166,6 +168,7 @@
true
BF_DBG_64;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)
../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include
+ true
Windows
@@ -186,6 +189,7 @@
../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include
MultiThreaded
false
+ true
Windows
diff --git a/IDE/BeefProj.toml b/IDE/BeefProj.toml
index 237b630b..ce73e660 100644
--- a/IDE/BeefProj.toml
+++ b/IDE/BeefProj.toml
@@ -13,7 +13,7 @@ Description = "Beef IDE"
Company = "BeefyTech LLC"
Product = "Beef IDE"
Copyright = "Copyright 2019 BeefyTech"
-FileVersion = "0.43.3"
+FileVersion = "0.43.4"
ProductVersion = "0000000000000000"
[Configs.Debug.Win32]
@@ -24,7 +24,7 @@ OtherLinkFlags = ""
TargetDirectory = "$(WorkspaceDir)/dist"
TargetName = "BeefIDE_d"
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
-DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\IDEHelper\\Tests\""
+DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\IDE\""
DebugWorkingDirectory = "$(WorkspaceDir)\\.."
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
@@ -36,7 +36,7 @@ OtherLinkFlags = ""
TargetDirectory = "$(WorkspaceDir)/dist"
TargetName = "BeefIDE"
OtherLinkFlags = "Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib Beef042RT64.lib IDEHelper64.lib BeefySysLib64.lib"
-DebugCommandArguments = "-proddir=C:\\Beef\\IDE\\Tests\\Rando"
+DebugCommandArguments = "-workspace=C:\\proj\\BeefTest"
DebugWorkingDirectory = "$(ProjectDir)\\dist"
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
@@ -48,8 +48,9 @@ OtherLinkFlags = ""
TargetDirectory = "$(WorkspaceDir)/dist"
TargetName = "BeefIDE_d2"
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib BeefySysLib64_d.lib wsock32.lib"
-DebugCommandArguments = "-workspace=c:\\proj\\BeefTest"
-DebugWorkingDirectory = "$(ProjectDir)\\dist"
+BeefLibType = "DynamicDebug"
+DebugCommandArguments = "-proddir=C:\\proj\\BeefTest"
+DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest"
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
[Configs.Paranoid.Win64]
diff --git a/IDE/Tests/CompileFail001/src/Generics.bf b/IDE/Tests/CompileFail001/src/Generics.bf
index 447928b4..d0ac2f3f 100644
--- a/IDE/Tests/CompileFail001/src/Generics.bf
+++ b/IDE/Tests/CompileFail001/src/Generics.bf
@@ -119,6 +119,38 @@ namespace IDETest
{
}
+
+ public class TestExt where T : struct
+ {
+ public struct InnerA
+ {
+
+ }
+
+ public struct InnerB where T2 : struct
+ {
+
+ }
+ }
+
+ extension TestExt
+ where T : Int
+ {
+ public int a = 0;
+
+ public struct InnerC
+ {
+ }
+ }
+
+ static void TestExtMethod()
+ {
+ TestExt.InnerA a; //FAIL
+ TestExt.InnerB b; //FAIL
+ TestExt.InnerB c;
+ TestExt.InnerC d;
+ TestExt.InnerC e; //FAIL
+ }
}
}
diff --git a/IDE/Tests/CompileFail001/src/LocalVars.bf b/IDE/Tests/CompileFail001/src/LocalVars.bf
index 54361d2d..96246310 100644
--- a/IDE/Tests/CompileFail001/src/LocalVars.bf
+++ b/IDE/Tests/CompileFail001/src/LocalVars.bf
@@ -342,5 +342,112 @@ namespace IDETest
int b3 = b; //FAIL
int c3 = c; //FAIL
}
+
+ Result Read()
+ {
+ return 0;
+ }
+
+ public void Local8()
+ {
+ int read;
+ loop: repeat
+ {
+ switch (Read())
+ {
+ case .Err: return;
+ case .Ok(let val): read = val;
+ }
+ }
+ while (read > 0);
+ }
+
+ public void Local9()
+ {
+ int read;
+ loop: repeat
+ {
+ switch (Read())
+ {
+ case .Err: break loop;
+ case .Ok(let val): read = val;
+ }
+ int a = read;
+ }
+ while (read > 0);
+ }
+
+ public void Local10()
+ {
+ int read;
+ loop: repeat
+ {
+ switch (Read())
+ {
+ case .Err: break;
+ case .Ok(let val): read = val;
+ }
+ int a = read; //FAIL
+ }
+ while (read > 0); //FAIL
+ }
+
+ public void Local11()
+ {
+ int a = 123;
+
+ int read;
+ Loop: repeat
+ {
+ break;
+ }
+ while (read > 0);
+ }
+
+ public void Local12()
+ {
+ int a = 123;
+
+ int read;
+ Loop: repeat
+ {
+ if (a == 123)
+ break;
+ }
+ while (read > 0); //FAIL
+ }
+
+ public void Local13()
+ {
+ int a = 123;
+ int b;
+ switch (a)
+ {
+ default: b = 0;
+ }
+ int c = b;
+ }
+
+ public void Local14()
+ {
+ int a = 123;
+ int b;
+ switch (a)
+ {
+ default: b = 0; break;
+ }
+ int c = b;
+ }
+
+ public void Local15()
+ {
+ int a = 123;
+ int b;
+ switch (a)
+ {
+ default: break;
+ }
+ int c = b; //FAIL
+ }
}
}
diff --git a/IDE/Tests/Test1/scripts/UsingFields.txt b/IDE/Tests/Test1/scripts/UsingFields.txt
new file mode 100644
index 00000000..9104aae8
--- /dev/null
+++ b/IDE/Tests/Test1/scripts/UsingFields.txt
@@ -0,0 +1,13 @@
+ShowFile("src/UsingFields.bf")
+GotoText("//Test_Start")
+ToggleBreakpoint()
+RunWithCompiling()
+
+AssertEvalEquals("v0.x", "123")
+AssertEvalEquals("v1.x", "345")
+
+# Temporarily broken in LLVM
+if (platform != "Win64") Stop()
+
+AssertEvalEquals("v0.GetX()", "123")
+AssertEvalEquals("v1.GetX()", "345")
\ No newline at end of file
diff --git a/IDE/Tests/Test1/src/Program.bf b/IDE/Tests/Test1/src/Program.bf
index 7db5c7da..e17d8dd2 100644
--- a/IDE/Tests/Test1/src/Program.bf
+++ b/IDE/Tests/Test1/src/Program.bf
@@ -31,6 +31,7 @@ namespace IDETest
Stepping_Scope.Test();
TypedPrimitives.Test();
Unions.Test();
+ UsingFields.Test();
Virtuals.Test();
Bug001.Test();
diff --git a/IDE/Tests/Test1/src/UsingFields.bf b/IDE/Tests/Test1/src/UsingFields.bf
new file mode 100644
index 00000000..f7952135
--- /dev/null
+++ b/IDE/Tests/Test1/src/UsingFields.bf
@@ -0,0 +1,43 @@
+#pragma warning disable 168
+
+using System;
+
+namespace IDETest
+{
+ class UsingFields
+ {
+ struct Vector2Int
+ {
+ [Union]
+ struct XWidth
+ {
+ public int x;
+ public int width;
+
+ public int GetX() => x;
+ }
+ [Union] struct YHeight : this(int y, int height);
+
+ public using XWidth xWidth;
+ public using YHeight yHeight;
+ }
+
+ struct TestVec : Vector2Int
+ {
+ }
+
+ public static void Test()
+ {
+ Vector2Int v0;
+ v0.x = 123;
+ v0.y = 234;
+
+ TestVec v1;
+ v1.x = 345;
+ v0.y = 456;
+
+ //Test_Start
+ int v = v0.GetX();
+ }
+ }
+}
\ No newline at end of file
diff --git a/IDE/dist/BeefDbgVis.toml b/IDE/dist/BeefDbgVis.toml
index eae78df5..ddde0d0f 100644
--- a/IDE/dist/BeefDbgVis.toml
+++ b/IDE/dist/BeefDbgVis.toml
@@ -21,18 +21,18 @@ ValuePointer = "/*(mMethodId < 0) ? &this :*/ __cast(\"_BF_DeferredData_\", mMet
[[Type]]
Name = "System.Event<*>"
-DisplayString = "{{ data={__cast(\"System.Object\", mData & ~3)} }}"
+DisplayString = "{{ data={__cast(\"System.Object\", mData & sDataMask)} }}"
[[Type.Expand.Item]]
Name = "[target]"
Value = "__cast(\"System.Object\", mData)"
-Condition = "(mData & 1) == 0"
+Condition = "(mData & sIsEnumerating) == 0"
[[Type.Expand.Item]]
Name = "[target]"
-Value = "((System.Event<$T1>.Enumerator*)(mData & ~3)).mTarget"
-Condition = "(mData & 1) != 0"
+Value = "((System.Event<$T1>.Enumerator*)(mData & sDataMask)).mTarget"
+Condition = "(mData & sIsEnumerating) != 0"
[[Type.Expand.Item]]
Name = "[flags]"
-Value = "mData & 3"
+Value = "mData & sFlagsMask"
[[Type]]
Name = "_BF_DeferredData_*"
@@ -52,14 +52,14 @@ String = "{{ {__demangleFakeMember(this)} }}"
Name = "System.String"
[[Type.DisplayString]]
Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) == 0"
-String = "{(char8*)&mPtr,s8,count=mLength}"
+String = "{(char8*)&mPtrOrBuffer,s8,count=mLength}"
[[Type.DisplayString]]
-String = "{mPtr,s8,count=mLength}"
+String = "{mPtrOrBuffer,s8,count=mLength}"
[[Type.StringView]]
Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) == 0"
-String = "{(char8*)&mPtr,s8,count=mLength}"
+String = "{(char8*)&mPtrOrBuffer,s8,count=mLength}"
[[Type.StringView]]
-String = "{mPtr,s8,count=mLength}"
+String = "{mPtrOrBuffer,s8,count=mLength}"
[[Type.Expand.Item]]
Name = "[Length]"
Value = "mLength"
@@ -78,11 +78,11 @@ Value = "__clearHighBits(mAllocSizeAndFlags, 2)"
[[Type.Expand.Item]]
Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) == 0"
Name = "[RawChars]"
-Value = "(char8*)&mPtr,arraysize=mLength"
+Value = "(char8*)&mPtrOrBuffer,arraysize=mLength"
[[Type.Expand.Item]]
Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) != 0"
Name = "[RawChars]"
-Value = "mPtr,arraysize=mLength"
+Value = "mPtrOrBuffer,arraysize=mLength"
[[Type]]
Name = "System.StringView"
diff --git a/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf b/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf
index 5df17c60..6c52f3ed 100644
--- a/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf
+++ b/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf
@@ -38,7 +38,7 @@ namespace System.Diagnostics
}
}
- static Result StartSampling(int32 threadId, StringView profileDesc)
+ static Result StartSampling(int threadId, StringView profileDesc)
{
//int32 curId = Interlocked.Increment(ref gProfileId);
int32 curId = gProfileId++;
diff --git a/IDE/mintest/minlib/src/System/Result.bf b/IDE/mintest/minlib/src/System/Result.bf
index 7b5da210..30958aeb 100644
--- a/IDE/mintest/minlib/src/System/Result.bf
+++ b/IDE/mintest/minlib/src/System/Result.bf
@@ -95,7 +95,7 @@ namespace System
extension Result where T : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Ok(var val))
val.Dispose();
@@ -199,7 +199,7 @@ namespace System
extension Result where T : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Ok(var val))
val.Dispose();
@@ -208,7 +208,7 @@ namespace System
extension Result where TErr : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Err(var err))
err.Dispose();
@@ -217,7 +217,7 @@ namespace System
extension Result where T : IDisposable where TErr : IDisposable
{
- public void Dispose()
+ public new void Dispose()
{
if (this case .Ok(var val))
val.Dispose();
diff --git a/IDE/mintest/minlib/src/System/Runtime.bf b/IDE/mintest/minlib/src/System/Runtime.bf
index 7e0b9687..c4235009 100644
--- a/IDE/mintest/minlib/src/System/Runtime.bf
+++ b/IDE/mintest/minlib/src/System/Runtime.bf
@@ -7,7 +7,7 @@ namespace System
[StaticInitPriority(100)]
class Runtime
{
- const int32 cVersion = 9;
+ const int32 cVersion = 10;
[CRepr, AlwaysInclude]
struct BfDebugMessageData
@@ -116,6 +116,7 @@ namespace System
function bool (Object thread) mThread_IsAutoDelete;
function void (Object thread) mThread_AutoDelete;
function int32 (Object thread) mThread_GetMaxStackSize;
+ function void () mThread_Exiting;
function void () mGC_MarkAllStaticMembers;
function bool () mGC_CallRootCallbacks;
function void () mGC_Shutdown;
diff --git a/IDE/mintest/minlib/src/System/Threading/Thread.bf b/IDE/mintest/minlib/src/System/Threading/Thread.bf
index 08ed8546..b4c49b6f 100644
--- a/IDE/mintest/minlib/src/System/Threading/Thread.bf
+++ b/IDE/mintest/minlib/src/System/Threading/Thread.bf
@@ -78,6 +78,11 @@ namespace System.Threading
}
}
+ static void Thread_Exiting()
+ {
+
+ }
+
public static this()
{
var cb = ref Runtime.BfRtCallbacks.[Friend]sCallbacks;
@@ -90,6 +95,7 @@ namespace System.Threading
cb.[Friend]mThread_IsAutoDelete = => Thread_IsAutoDelete;
cb.[Friend]mThread_AutoDelete = => Thread_AutoDelete;
cb.[Friend]mThread_GetMaxStackSize = => Thread_GetMaxStackSize;
+ cb.[Friend]mThread_Exiting = => Thread_Exiting;
}
}
@@ -280,9 +286,10 @@ namespace System.Threading
}
}
- extern int32 GetThreadId();
+ [CallingConvention(.Cdecl)]
+ extern int GetThreadId();
- public int32 Id
+ public int Id
{
get
{
diff --git a/IDE/mintest/src/main.bf b/IDE/mintest/src/main.bf
index 24d0505d..7156c5e5 100644
--- a/IDE/mintest/src/main.bf
+++ b/IDE/mintest/src/main.bf
@@ -21,6 +21,11 @@ namespace Hey.Dude.Bro
}
}
+ struct Color
+ {
+ public float r, g, b, a;
+ }
+
class TestClass
{
/*static void TestFunc()
@@ -37,8 +42,27 @@ namespace Hey.Dude.Bro
}*/
+ //private const uint16[] DebugIndexes = scope uint16[](0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7);
+
+
+
+ [Import(@"C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll"), LinkName("Test2")]
+ public static extern void Test2(int32 a, int32 b, int32 c, int32 d, function Color(int32 a, int32 b) func);
+
+ public static Color GetColor(int32 a, int32 b)
+ {
+ Color c;
+ c.r = 1.2f;
+ c.g = 2.3f;
+ c.b = 3.4f;
+ c.a = 4.5f;
+ return c;
+ }
+
public static int Main(String[] args)
{
+ Test2(1, 2, 3, 4, => GetColor);
+
//Blurg.Hey();
return 1;
}
diff --git a/IDE/src/BeefConfig.bf b/IDE/src/BeefConfig.bf
index 361c1757..bdb1e1fc 100644
--- a/IDE/src/BeefConfig.bf
+++ b/IDE/src/BeefConfig.bf
@@ -13,6 +13,7 @@ namespace IDE
public class RegistryEntry
{
public String mProjName ~ delete _;
+ public Project.TargetType mTargetType;
public SemVer mVersion ~ delete _;
public VerSpec mLocation ~ _.Dispose();
public ConfigFile mConfigFile;
@@ -51,6 +52,29 @@ namespace IDE
using (mMonitor.Enter())
entry.mProjName.Set(projName);
}
+
+ if (sd.Contains("StartupObject"))
+ entry.mTargetType = .BeefConsoleApplication;
+ else
+ entry.mTargetType = .BeefLib;
+
+ var targetTypeName = scope String();
+ sd.GetString("TargetType", targetTypeName);
+
+ if (!targetTypeName.IsEmpty)
+ {
+ switch (targetTypeName)
+ { // Handle Legacy names first
+ case "BeefWindowsApplication":
+ entry.mTargetType = .BeefGUIApplication;
+ case "C_WindowsApplication":
+ entry.mTargetType = .C_GUIApplication;
+ case "BeefDynLib":
+ entry.mTargetType = .BeefLib;
+ default:
+ entry.mTargetType = sd.GetEnum("TargetType", entry.mTargetType);
+ }
+ }
}
}
}
diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf
index 02573971..20ed2542 100644
--- a/IDE/src/BuildContext.bf
+++ b/IDE/src/BuildContext.bf
@@ -627,15 +627,7 @@ namespace IDE
return false;
}
-
String compilerExePath = scope String();
-#if BF_PLATFORM_WINDOWS
- String llvmDir = scope String(IDEApp.sApp.mInstallDir);
- IDEUtils.FixFilePath(llvmDir);
- llvmDir.Append("llvm/");
-#else
- String llvmDir = "";
-#endif
if (gApp.mSettings.mEmscriptenPath.IsEmpty)
{
gApp.OutputErrorLine("Emscripten path not configured. Check Wasm configuration in File\\Preferences\\Settings.");
diff --git a/IDE/src/Commands.bf b/IDE/src/Commands.bf
index f493b56e..f4c5ca86 100644
--- a/IDE/src/Commands.bf
+++ b/IDE/src/Commands.bf
@@ -90,10 +90,11 @@ namespace IDE
{
if (mParent == null)
return;
+ int startIdx = strBuffer.Length;
mParent.ToString(strBuffer);
if (mBoundKeyState != null)
{
- if (!strBuffer.IsEmpty)
+ if (strBuffer.Length > startIdx)
strBuffer.Append(", ");
mBoundKeyState.ToString(strBuffer);
}
diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf
index 214300ce..525318a7 100644
--- a/IDE/src/Compiler/BfCompiler.bf
+++ b/IDE/src/Compiler/BfCompiler.bf
@@ -156,7 +156,7 @@ namespace IDE.Compiler
static extern int32 BfCompiler_GetEmitSourceVersion(void* bfCompiler, char8* fileName);
[CallingConvention(.Stdcall), CLink]
- static extern char8* BfCompiler_GetEmitLocation(void* bfCompiler, char8* typeName, int32 line, out int32 embedLine, out int32 embedLineChar);
+ static extern char8* BfCompiler_GetEmitLocation(void* bfCompiler, char8* typeName, int32 line, out int32 embedLine, out int32 embedLineChar, out uint64 hash);
[CallingConvention(.Stdcall), CLink]
static extern void BfCompiler_WriteEmitData(void* bfCompiler, char8* filePath, void* bfProject);
@@ -362,11 +362,11 @@ namespace IDE.Compiler
return BfCompiler_GetEmitSourceVersion(mNativeBfCompiler, fileName.ToScopeCStr!());
}
- public void GetEmitLocation(StringView typeName, int line, String outFilePath, out int embedLine, out int embedLineChar)
+ public void GetEmitLocation(StringView typeName, int line, String outFilePath, out int embedLine, out int embedLineChar, out uint64 hash)
{
int32 embedLine32;
int32 embedLineChar32;
- outFilePath.Append(BfCompiler_GetEmitLocation(mNativeBfCompiler, typeName.ToScopeCStr!(), (.)line, out embedLine32, out embedLineChar32));
+ outFilePath.Append(BfCompiler_GetEmitLocation(mNativeBfCompiler, typeName.ToScopeCStr!(), (.)line, out embedLine32, out embedLineChar32, out hash));
embedLine = embedLine32;
embedLineChar = embedLineChar32;
}
@@ -603,6 +603,8 @@ namespace IDE.Compiler
UpdateRebuildFileWatches();
mBfSystem.RemoveOldParsers();
mBfSystem.RemoveOldData();
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
+ QueueRefreshViewCommand(.Collapse);
}
if (command is ResolveAllCommand)
diff --git a/IDE/src/Compiler/BfSystem.bf b/IDE/src/Compiler/BfSystem.bf
index 9fb64746..60cbcd38 100644
--- a/IDE/src/Compiler/BfSystem.bf
+++ b/IDE/src/Compiler/BfSystem.bf
@@ -239,6 +239,16 @@ namespace IDE.Compiler
}
}
+ public BfParser GetParser(ProjectSource projectSource)
+ {
+ using (mMonitor.Enter())
+ {
+ BfParser parser;
+ mParserMap.TryGetValue(projectSource, out parser);
+ return parser;
+ }
+ }
+
public BfParser CreateNewParserRevision(BfParser prevParser)
{
using (mMonitor.Enter())
diff --git a/IDE/src/FileRecovery.bf b/IDE/src/FileRecovery.bf
index 1cbc6ce4..97cefb35 100644
--- a/IDE/src/FileRecovery.bf
+++ b/IDE/src/FileRecovery.bf
@@ -57,6 +57,14 @@ namespace IDE
String mWorkspaceDir = new String() ~ delete _;
bool mWantWorkspaceCleanup;
public bool mDisabled;
+ Dictionary> mDB = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
+ public bool mDBDirty;
+ public String mDBWorkspaceDir = new String() ~ delete _;
+
+ public this()
+ {
+
+ }
public ~this()
{
@@ -84,6 +92,26 @@ namespace IDE
bool wantWorkspaceCleanup = false;
using (mMonitor.Enter())
{
+ if (mDBDirty)
+ {
+ String recoverPath = scope String();
+ recoverPath.Append(mWorkspaceDir);
+ recoverPath.Append("/recovery/db.bin");
+
+ FileStream fs = scope .();
+ if (fs.Create(recoverPath) case .Ok)
+ {
+ fs.Write((uint32)0xBEEF0701);
+ for (var kv in mDB)
+ {
+ fs.WriteStrSized32(kv.key).IgnoreError();
+ fs.Write((int32)kv.value.Count);
+ fs.TryWrite(kv.value).IgnoreError();
+ }
+ }
+ mDBDirty = false;
+ }
+
for (var entry in mFileSet)
{
if (entry.mRecoveryFileName == null)
@@ -250,6 +278,104 @@ namespace IDE
}
}
+ public void CheckDB()
+ {
+ if (mDBWorkspaceDir == gApp.mWorkspace.mDir)
+ return;
+
+ using (mMonitor.Enter())
+ {
+ for (var kv in mDB)
+ {
+ delete kv.key;
+ delete kv.value;
+ }
+ mDB.Clear();
+
+ mDBWorkspaceDir.Set(gApp.mWorkspace.mDir);
+ if (mDBWorkspaceDir.IsEmpty)
+ return;
+
+ String recoverPath = scope String();
+ recoverPath.Append(mDBWorkspaceDir);
+ recoverPath.Append("/recovery/db.bin");
+
+ FileStream fs = scope .();
+ if (fs.Open(recoverPath) case .Ok)
+ {
+ if (fs.Read() == 0xBEEF0701)
+ {
+ String filePath = scope .();
+ while (true)
+ {
+ filePath.Clear();
+ if (fs.ReadStrSized32(filePath) case .Err)
+ break;
+ if (filePath.IsEmpty)
+ break;
+
+ int32 dataSize = fs.Read();
+ List list = new List();
+ mDB[new String(filePath)] = list;
+
+ list.Resize(dataSize);
+ if (fs.TryRead(.(list.Ptr, dataSize)) case .Err)
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public void SetDB(StringView key, Span data)
+ {
+ using (mMonitor.Enter())
+ {
+ CheckDB();
+
+ if (mDB.TryAddAlt(key, var keyPtr, var valuePtr))
+ {
+ *keyPtr = new .(key);
+ *valuePtr = new .();
+ }
+ (*valuePtr).Clear();
+ (*valuePtr).AddRange(data);
+ mDBDirty = true;
+ }
+ }
+
+ public bool GetDB(StringView key, List data)
+ {
+ using (mMonitor.Enter())
+ {
+ CheckDB();
+
+ if (mDB.TryGetAlt(key, var matchKey, var value))
+ {
+ data.AddRange(value);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public bool DeleteDB(StringView key)
+ {
+ using (mMonitor.Enter())
+ {
+ CheckDB();
+
+ if (mDB.GetAndRemoveAlt(key) case .Ok((var mapKey, var value)))
+ {
+ mDBDirty = true;
+ delete mapKey;
+ delete value;
+ return true;
+ }
+ return false;
+ }
+ }
+
public void Update()
{
if (mProcessingEvent != null)
@@ -261,7 +387,7 @@ namespace IDE
using (mMonitor.Enter())
{
- if ((!mDirty) && (!mWantWorkspaceCleanup))
+ if ((!mDirty) && (!mDBDirty) && (!mWantWorkspaceCleanup))
return;
}
diff --git a/IDE/src/FileWatcher.bf b/IDE/src/FileWatcher.bf
index 63401fce..39b2f34a 100644
--- a/IDE/src/FileWatcher.bf
+++ b/IDE/src/FileWatcher.bf
@@ -95,6 +95,16 @@ namespace IDE
FileChanged(starPath, null, .Changed);
}
+ if ((isDirectory) && (changeType == .Renamed))
+ {
+ // On Windows, renaming a directory with only case changes will result in a remove before a rename
+ var dirName = scope String();
+ Path.GetDirectoryPath(newPath.Substring(0, newPath.Length - 1), dirName);
+ dirName.Append(Path.DirectorySeparatorChar);
+
+ FileChanged(dirName, newPath, .DirectoryCreated);
+ }
+
var newPath;
if (isDirectory)
{
diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf
index b19656d1..7e70fd23 100644
--- a/IDE/src/IDEApp.bf
+++ b/IDE/src/IDEApp.bf
@@ -119,7 +119,7 @@ namespace IDE
public class IDEApp : BFApp
{
public static String sRTVersionStr = "042";
- public const String cVersion = "0.43.3";
+ public const String cVersion = "0.43.4";
#if BF_PLATFORM_WINDOWS
public static readonly String sPlatform64Name = "Win64";
@@ -1475,6 +1475,14 @@ namespace IDE
return true;
}
+ public void SetEmbedCompiler(Settings.EditorSettings.CompilerKind emitCompiler)
+ {
+ gApp.mSettings.mEditorSettings.mEmitCompiler = emitCompiler;
+ mBfResolveCompiler?.QueueRefreshViewCommand(.Collapse);
+ if (emitCompiler == .Resolve)
+ mBfResolveCompiler?.QueueRefreshViewCommand(.FullRefresh);
+ }
+
public Result LoadTextFile(String fileName, String outBuffer, bool autoRetry = true, delegate void() onPreFilter = null)
{
if (mWorkspace.IsSingleFileWorkspace)
@@ -1490,9 +1498,23 @@ namespace IDE
if (fileName.StartsWith("$Emit$"))
{
- BfCompiler compiler = mBfResolveCompiler;
+ String useFileName = fileName;
+
+ BfCompiler compiler = (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve) ? mBfResolveCompiler : mBfBuildCompiler;
+
+ if (useFileName.StartsWith("$Emit$Build$"))
+ {
+ useFileName = scope:: $"$Emit${useFileName.Substring("$Emit$Build$".Length)}";
+ compiler = mBfBuildCompiler;
+ }
+ else if (useFileName.StartsWith("$Emit$Resolve$"))
+ {
+ useFileName = scope:: $"$Emit${useFileName.Substring("$Emit$Resolve$".Length)}";
+ compiler = mBfResolveCompiler;
+ }
+
if (!compiler.IsPerformingBackgroundOperation())
- compiler.GetEmitSource(fileName, outBuffer);
+ compiler.GetEmitSource(useFileName, outBuffer);
if (onPreFilter != null)
onPreFilter();
@@ -2299,7 +2321,7 @@ namespace IDE
AddNewProjectToWorkspace(project);
project.FinishCreate();
- mProjectPanel.InitProject(project);
+ mProjectPanel.InitProject(project, mProjectPanel.GetSelectedWorkspaceFolder());
mProjectPanel.Sort();
mWorkspace.FixOptions();
mWorkspace.mHasChanged = true;
@@ -2693,7 +2715,7 @@ namespace IDE
AddProjectToWorkspace(project, false);
if (addToUI)
- mProjectPanel.InitProject(project);
+ mProjectPanel.InitProject(project, null);
}
}
if (!hadLoad)
@@ -2977,6 +2999,8 @@ namespace IDE
{
using (mBeefConfig.mRegistry.mMonitor.Enter())
{
+ BeefConfig.RegistryEntry matchedEntry = null;
+
for (int regEntryIdx = mBeefConfig.mRegistry.mEntries.Count - 1; regEntryIdx >= 0; regEntryIdx--)
{
var regEntry = mBeefConfig.mRegistry.mEntries[regEntryIdx];
@@ -2986,11 +3010,19 @@ namespace IDE
if (regEntry.mProjName == projectName)
{
- useVerSpec = regEntry.mLocation;
- verConfigDir = regEntry.mConfigFile.mConfigDir;
- break FindLoop;
+ // Prioritize a lib file over a non-lib
+ if ((matchedEntry == null) ||
+ ((!matchedEntry.mTargetType.IsLib) && (regEntry.mTargetType.IsLib)))
+ matchedEntry = regEntry;
}
}
+
+ if (matchedEntry != null)
+ {
+ useVerSpec = matchedEntry.mLocation;
+ verConfigDir = matchedEntry.mConfigFile.mConfigDir;
+ break FindLoop;
+ }
}
mBeefConfig.mRegistry.WaitFor();
}
@@ -5429,6 +5461,20 @@ namespace IDE
sysMenu.Modify(null, null, null, true, checkVal ? 1 : 0);
}
+ public Menu AddMenuItem(Menu menu, StringView label, StringView command = default)
+ {
+ var command;
+ if (command.IsEmpty)
+ command = label;
+ String labelStr = scope String(label);
+ if (mCommands.mCommandMap.TryGetAlt(command, var matchKey, var ideCommand))
+ {
+ labelStr.Append("|");
+ ideCommand.ToString(labelStr);
+ }
+ return menu.AddItem(labelStr);
+ }
+
public bool AreTestsRunning()
{
return (mTestManager != null);
@@ -5683,6 +5729,17 @@ namespace IDE
AddMenuItem(bookmarkMenu, "&Previous Bookmark", "Bookmark Prev");
AddMenuItem(bookmarkMenu, "&Clear Bookmarks", "Bookmark Clear");
+ var comptimeMenu = subMenu.AddMenuItem("Comptime");
+ var emitViewCompiler = comptimeMenu.AddMenuItem("Emit View Compiler");
+ var subItem = emitViewCompiler.AddMenuItem("Resolve", null,
+ new (menu) => { SetEmbedCompiler(.Resolve); } ,
+ new (menu) => { menu.SetCheckState((mSettings.mEditorSettings.mEmitCompiler == .Resolve) ? 1 : 0); },
+ null, true, (mSettings.mEditorSettings.mEmitCompiler == .Resolve) ? 1 : 0);
+ subItem = emitViewCompiler.AddMenuItem("Build", null,
+ new (menu) => { SetEmbedCompiler(.Build); } ,
+ new (menu) => { menu.SetCheckState((mSettings.mEditorSettings.mEmitCompiler == .Build) ? 1 : 0); },
+ null, true, (mSettings.mEditorSettings.mEmitCompiler == .Build) ? 1 : 0);
+
var advancedEditMenu = subMenu.AddMenuItem("Advanced");
AddMenuItem(advancedEditMenu, "Duplicate Line", "Duplicate Line");
AddMenuItem(advancedEditMenu, "Move Line Up", "Move Line Up");
@@ -6285,6 +6342,11 @@ namespace IDE
let process = scope SpawnedProcess();
process.Start(procInfo).IgnoreError();
});
+ item = menu.AddItem("Show in Workspace Panel");
+ item.mOnMenuItemSelected.Add(new (menu) =>
+ {
+ sourceViewPanel.SyncWithWorkspacePanel();
+ });
item = menu.AddItem("Close");
item.mOnMenuItemSelected.Add(new (menu) =>
{
@@ -7155,10 +7217,11 @@ namespace IDE
public SourceViewPanel ShowSourceFileLocation(String filePath, int showHotIdx, int refHotIdx, int line, int column, LocatorType hilitePosition, bool showTemp = false)
{
+ var useFilePath = filePath;
+
if (filePath.StartsWith("$Emit$"))
{
- var compiler = mBfResolveCompiler;
- if (compiler.IsPerformingBackgroundOperation())
+ if ((mBfBuildCompiler.IsPerformingBackgroundOperation()) || (mBfResolveCompiler.IsPerformingBackgroundOperation()))
{
DeleteAndNullify!(mDeferredShowSource);
mDeferredShowSource = new DeferredShowSource()
@@ -7174,18 +7237,76 @@ namespace IDE
return null;
}
- var itr = filePath.Split('$');
- itr.GetNext();
- itr.GetNext();
- var typeName = itr.GetNext().Value;
+ String embedFilePath;
+ bool isViewValid = true;
+ StringView typeName;
+ int embedLine;
+ int embedLineChar;
- //var compiler = (kindStr == "Emit") ? mBfBuildCompiler : mBfResolveCompiler;
-
- compiler.mBfSystem.Lock(0);
- var embedFilePath = compiler.GetEmitLocation(typeName, line, .. scope .(), var embedLine, var embedLineChar);
- compiler.mBfSystem.Unlock();
+ if (filePath.StartsWith("$Emit$Resolve$"))
+ {
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+ {
+ var itr = filePath.Split('$');
+ itr.GetNext();
+ itr.GetNext();
+ itr.GetNext();
+ typeName = itr.GetNext().Value;
+
+ mBfResolveCompiler.mBfSystem.Lock(0);
+ embedFilePath = mBfResolveCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash);
+ mBfResolveCompiler.mBfSystem.Unlock();
+
+ useFilePath = scope:: $"$Emit${useFilePath.Substring("$Emit$Resolve$".Length)}";
+ }
+ else
+ isViewValid = false;
+ }
+ else if (filePath.StartsWith("$Emit$Build$"))
+ {
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
+ {
+ var itr = filePath.Split('$');
+ itr.GetNext();
+ itr.GetNext();
+ itr.GetNext();
+ typeName = itr.GetNext().Value;
+
+ mBfBuildCompiler.mBfSystem.Lock(0);
+ embedFilePath = mBfBuildCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash);
+ mBfBuildCompiler.mBfSystem.Unlock();
+
+ useFilePath = scope:: $"$Emit${useFilePath.Substring("$Emit$Build$".Length)}";
+ }
+ else
+ isViewValid = false;
+ }
+ else
+ {
+ var itr = filePath.Split('$');
+ itr.GetNext();
+ itr.GetNext();
+ typeName = itr.GetNext().Value;
- if (!embedFilePath.IsEmpty)
+ mBfBuildCompiler.mBfSystem.Lock(0);
+ embedFilePath = mBfBuildCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash);
+ mBfBuildCompiler.mBfSystem.Unlock();
+
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+ {
+ mBfResolveCompiler.mBfSystem.Lock(0);
+ mBfResolveCompiler.GetEmitLocation(typeName, line, scope .(), var resolveLine, var resolveLineChar, var resolveHash);
+ mBfResolveCompiler.mBfSystem.Unlock();
+
+ if ((resolveLine != embedLine) || (resolveLineChar != embedLineChar) || (embedHash != resolveHash))
+ {
+ isViewValid = false;
+ useFilePath = scope:: $"$Emit$Build${useFilePath.Substring("$Emit$".Length)}";
+ }
+ }
+ }
+
+ if ((isViewValid) && (!embedFilePath.IsEmpty))
{
var sourceViewPanel = ShowSourceFile(scope .(embedFilePath), null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting).panel;
if (sourceViewPanel == null)
@@ -7201,11 +7322,7 @@ namespace IDE
emitShowData.mColumn = (.)column;
DeleteAndNullify!(sourceViewPanel.[Friend]mQueuedEmitShowData);
sourceViewPanel.[Friend]mQueuedEmitShowData = emitShowData;
-
- //sourceViewPanel.ShowHotFileIdx(showHotIdx);
sourceViewPanel.ShowFileLocation(refHotIdx, embedLine, embedLineChar, .None);
- //sourceViewPanel.QueueFullRefresh(false);
- //sourceViewPanel.mBackgroundDelay = 1; // Don't immediately perform the full classify
if (typeName.Contains('<'))
{
@@ -7220,7 +7337,7 @@ namespace IDE
}
}
- var (sourceViewPanel, tabButton) = ShowSourceFile(filePath, null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting);
+ var (sourceViewPanel, tabButton) = ShowSourceFile(useFilePath, null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting);
if (sourceViewPanel == null)
return null;
if (((filePath.StartsWith("$")) && (var svTabButton = tabButton as SourceViewTabButton)))
@@ -14259,7 +14376,8 @@ namespace IDE
if (IDEApp.sApp.mSpellChecker != null)
IDEApp.sApp.mSpellChecker.CheckThreadDone();
- if ((mDeferredShowSource != null) && (mBfResolveCompiler?.IsPerformingBackgroundOperation() == false))
+ if ((mDeferredShowSource != null) && (!mBfBuildCompiler.IsPerformingBackgroundOperation()) &&
+ (mBfResolveCompiler?.IsPerformingBackgroundOperation() != true))
{
var deferredShowSource = mDeferredShowSource;
mDeferredShowSource = null;
diff --git a/IDE/src/IDEUtils.bf b/IDE/src/IDEUtils.bf
index f39761fc..1b2c41e8 100644
--- a/IDE/src/IDEUtils.bf
+++ b/IDE/src/IDEUtils.bf
@@ -636,6 +636,38 @@ namespace IDE
label.Append('\x02');
}
}
+
+ static String sHexUpperChars = "0123456789ABCDEF";
+ public static void URLEncode(StringView inStr, String outStr)
+ {
+ for (var c in inStr)
+ {
+ if ((c.IsLetterOrDigit) || (c == '-') || (c == '_') || (c == '.') || (c == '~') || (c == '/'))
+ {
+ outStr.Append(c);
+ }
+ else
+ {
+ outStr.Append('%');
+ outStr.Append(sHexUpperChars[(.)c>>4]);
+ outStr.Append(sHexUpperChars[(.)c&0xF]);
+ }
+ }
+ }
+
+ public static void URLDecode(StringView inStr, String outStr)
+ {
+ for (int i < inStr.Length)
+ {
+ char8 c = inStr[i];
+ if ((c == '%') && (i < inStr.Length-2))
+ {
+ c = (.)int32.Parse(inStr.Substring(i+1, 2), .HexNumber).GetValueOrDefault();
+ i += 2;
+ }
+ outStr.Append(c);
+ }
+ }
}
}
diff --git a/IDE/src/Project.bf b/IDE/src/Project.bf
index 9ef7c60f..f7a630c7 100644
--- a/IDE/src/Project.bf
+++ b/IDE/src/Project.bf
@@ -979,6 +979,20 @@ namespace IDE
}
}
}
+
+ public bool IsLib
+ {
+ get
+ {
+ switch (this)
+ {
+ case BeefLib:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
}
public class WindowsOptions
diff --git a/IDE/src/Settings.bf b/IDE/src/Settings.bf
index a15e00f3..5323cfb1 100644
--- a/IDE/src/Settings.bf
+++ b/IDE/src/Settings.bf
@@ -304,6 +304,7 @@ namespace IDE
public Color mWorkspaceFailedText = 0xFFE04040;
public Color mWorkspaceManualIncludeText = 0xFFE0E0FF;
public Color mWorkspaceIgnoredText = 0xFF909090;
+ public Color mWorkspaceCutText = 0xFFC0B0B0;
public Color mCode = 0xFFFFFFFF;
public Color mKeyword = 0xFFE1AE9A;
@@ -628,6 +629,12 @@ namespace IDE
Spaces
}
+ public enum CompilerKind
+ {
+ Resolve,
+ Build
+ }
+
public List mFonts = new .() ~ DeleteContainerAndItems!(_);
public float mFontSize = 12;
public AutoCompleteShowKind mAutoCompleteShowKind = .PanelIfVisible;
@@ -641,6 +648,7 @@ namespace IDE
public bool mHiliteCurrentLine = false;
public bool mLockEditing;
public LockWhileDebuggingKind mLockEditingWhenDebugging = .WhenNotHotSwappable;// Only applicable for
+ public CompilerKind mEmitCompiler;
// non-Beef sources
public bool mPerforceAutoCheckout = true;
public bool mSpellCheckEnabled = true;
@@ -674,6 +682,7 @@ namespace IDE
sd.Add("HiliteCurrentLine", mHiliteCurrentLine);
sd.Add("LockEditing", mLockEditing);
sd.Add("LockEditingWhenDebugging", mLockEditingWhenDebugging);
+ sd.Add("EmitCompiler", mEmitCompiler);
sd.Add("PerforceAutoCheckout", mPerforceAutoCheckout);
sd.Add("SpellCheckEnabled", mSpellCheckEnabled);
sd.Add("ShowLineNumbers", mShowLineNumbers);
@@ -710,6 +719,7 @@ namespace IDE
sd.Get("HiliteCurrentLine", ref mHiliteCurrentLine);
sd.Get("LockEditing", ref mLockEditing);
sd.Get("LockEditingWhenDebugging", ref mLockEditingWhenDebugging);
+ sd.Get("EmitCompiler", ref mEmitCompiler);
sd.Get("PerforceAutoCheckout", ref mPerforceAutoCheckout);
sd.Get("SpellCheckEnabled", ref mSpellCheckEnabled);
sd.Get("ShowLineNumbers", ref mShowLineNumbers);
@@ -944,7 +954,7 @@ namespace IDE
curCmdMap = (*valuePtr) as CommandMap;
if (curCmdMap == null)
{
- curCmdMap.FailValues.Add(ideCommand);
+ gApp.OutputLineSmart("ERROR: The same key is bound for '{0}' and as part of a key chord", entry.mCommand);
break;
}
}
diff --git a/IDE/src/ui/AutoComplete.bf b/IDE/src/ui/AutoComplete.bf
index 1c4122fc..aa118a9f 100644
--- a/IDE/src/ui/AutoComplete.bf
+++ b/IDE/src/ui/AutoComplete.bf
@@ -1017,6 +1017,72 @@ namespace IDE.ui
if (cursorSection >= textSections.Count - 1)
cursorSection = textSections.Count - 2;
+ if ((cursorSection >= 0) && (cursorSection < mAutoComplete.mInvokeSrcPositions.Count))
+ {
+ var argText = mAutoComplete.mTargetEditWidget.mEditWidgetContent.ExtractString(mAutoComplete.mInvokeSrcPositions[cursorSection - 1],
+ mAutoComplete.mInvokeSrcPositions[cursorSection] - mAutoComplete.mInvokeSrcPositions[cursorSection - 1], .. scope .());
+
+ int colonPos = argText.IndexOf(':');
+
+ if (colonPos != -1)
+ {
+ do
+ {
+ bool foundSep = false;
+ int nameStart = -1;
+ for (int i = colonPos - 1; i >= 0; i--)
+ {
+ char8 c = argText[i];
+ if (nameStart == -1)
+ {
+ if ((c != '_') && (!c.IsLetterOrDigit))
+ nameStart = i + 1;
+ }
+ else
+ {
+ if (!c.IsWhiteSpace)
+ {
+ if ((!foundSep) &&
+ ((c == ',') || (c == '(')))
+ foundSep = true;
+ else
+ break;
+ }
+ }
+ }
+
+ if (nameStart == -1)
+ break;
+
+ var argParamName = argText.Substring(nameStart, colonPos - nameStart);
+ for (int checkSectionIdx = 1; checkSectionIdx < textSections.Count; checkSectionIdx++)
+ {
+ var sectionStr = textSections[checkSectionIdx];
+
+ var checkParamName = sectionStr;
+ if (checkParamName.EndsWith(','))
+ checkParamName.RemoveFromEnd(1);
+
+ for (int checkIdx = checkParamName.Length - 1; checkIdx >= 0; checkIdx--)
+ {
+ char8 c = checkParamName[checkIdx];
+ if (c.IsWhiteSpace)
+ {
+ checkParamName.RemoveFromStart(checkIdx + 1);
+ break;
+ }
+ }
+
+ if (checkParamName == argParamName)
+ {
+ cursorSection = checkSectionIdx;
+ break;
+ }
+ }
+ }
+ }
+ }
+
float paramX = 0;
for (int sectionIdx = 0; sectionIdx < textSections.Count; sectionIdx++)
{
diff --git a/IDE/src/ui/FindResultsPanel.bf b/IDE/src/ui/FindResultsPanel.bf
index 02eedf32..ea710597 100644
--- a/IDE/src/ui/FindResultsPanel.bf
+++ b/IDE/src/ui/FindResultsPanel.bf
@@ -552,7 +552,7 @@ namespace IDE.ui
return base.Deserialize(data);
}
- public void QueueLine(String text)
+ public void AddPendingLine(String text)
{
mCurLineNum++;
using (mMonitor.Enter())
@@ -591,7 +591,17 @@ namespace IDE.ui
String outStr = scope String();
outStr.AppendF("{0}({1}):{2}", fileEditData.mFilePath, line + 1, lineStr);
- gApp.mFindResultsPanel.QueueLine(outStr);
+ gApp.mFindResultsPanel.AddPendingLine(outStr);
+ }
+
+ public void QueueLine(String text)
+ {
+ using (mMonitor.Enter())
+ {
+ QueuedEntry entry = new .();
+ entry.mText = new .(text);
+ mQueuedEntries.Add(entry);
+ }
}
public void QueueLine(String fileName, int32 line, int32 column, String text)
@@ -641,7 +651,10 @@ namespace IDE.ui
while (!mQueuedEntries.IsEmpty)
{
var entry = mQueuedEntries.PopFront();
- QueueLine(gApp.GetEditData(entry.mFileName, true, false), entry.mLine, entry.mColumn, entry.mText);
+ if (entry.mFileName == null)
+ AddPendingLine(entry.mText);
+ else
+ QueueLine(gApp.GetEditData(entry.mFileName, true, false), entry.mLine, entry.mColumn, entry.mText);
delete entry;
}
diff --git a/IDE/src/ui/HoverWatch.bf b/IDE/src/ui/HoverWatch.bf
index 07762cad..1b51eeb7 100644
--- a/IDE/src/ui/HoverWatch.bf
+++ b/IDE/src/ui/HoverWatch.bf
@@ -406,14 +406,12 @@ namespace IDE.ui
void HandleMouseWheel(MouseEvent evt)
{
- if (mChildWidgets.Count == 0)
- return;
-
- var lastListView = mChildWidgets[mChildWidgets.Count - 1] as HoverListView;
- if ((lastListView != null) && (lastListView.mVertScrollbar != null))
- return;
-
if (mListViews.Count > 1)
+ {
+ return;
+ }
+
+ if (evt.mSender != mWidgetWindow)
{
var widgetWindow = evt.mSender as BFWindow;
while (widgetWindow != null)
@@ -423,6 +421,7 @@ namespace IDE.ui
widgetWindow = widgetWindow.mParent;
}
}
+
EditWidget editWidget = mEditWidget;
if (var sourceViewPanel = mTextPanel as SourceViewPanel)
editWidget = sourceViewPanel.mEditWidget;
diff --git a/IDE/src/ui/InstalledProjectDialog.bf b/IDE/src/ui/InstalledProjectDialog.bf
index 88dbf864..832e6627 100644
--- a/IDE/src/ui/InstalledProjectDialog.bf
+++ b/IDE/src/ui/InstalledProjectDialog.bf
@@ -16,9 +16,11 @@ namespace IDE.ui
public String mName ~ delete _;
public String mPath ~ delete _;
public VerSpecRecord mVersion;
+ public Project.TargetType mTargetType;
}
protected IDEListView mProjectList;
+ DarkComboBox mKindCombo;
EditWidget mEditWidget;
bool mFilterChanged;
List mInstalledProjectList = new .() ~ DeleteContainerAndItems!(_);
@@ -58,6 +60,21 @@ namespace IDE.ui
mEditWidget.mOnKeyDown.Add(new => EditKeyDownHandler);
mEditWidget.mOnContentChanged.Add(new (evt) => { mFilterChanged = true; });
+ mKindCombo = new DarkComboBox();
+ mKindCombo.Label = "Libraries";
+ mKindCombo.mPopulateMenuAction.Add(new (menu) =>
+ {
+ for (var kind in String[?]("All", "Libraries"))
+ {
+ menu.AddItem(kind).mOnMenuItemSelected.Add(new (menu) =>
+ {
+ mFilterChanged = true;
+ mKindCombo.Label = kind;
+ });
+ }
+ });
+ AddWidget(mKindCombo);
+
FindProjects();
}
@@ -78,6 +95,7 @@ namespace IDE.ui
installedProject.mPath.Append("BeefProj.toml");
default:
}
+ installedProject.mTargetType = registryEntry.mTargetType;
mInstalledProjectList.Add(installedProject);
}
}
@@ -128,9 +146,14 @@ namespace IDE.ui
mEditWidget.GetText(filterString);
filterString.Trim();
+ bool onlyLibs = mKindCombo.Label == "Libraries";
+
mFilteredList.Clear();
for (var installedProject in mInstalledProjectList)
{
+ if ((onlyLibs) && (!installedProject.mTargetType.IsLib))
+ continue;
+
if ((!filterString.IsEmpty) && (installedProject.mName.IndexOf(filterString, true) == -1))
continue;
@@ -138,7 +161,7 @@ namespace IDE.ui
listViewItem.Label = installedProject.mName;
var subListViewItem = listViewItem.CreateSubItem(1);
- subListViewItem.Label = installedProject.mPath;
+ subListViewItem.Label = Path.GetDirectoryPath(installedProject.mPath, .. scope .());
mFilteredList.Add(installedProject);
}
@@ -180,7 +203,7 @@ namespace IDE.ui
VerSpec verSpec = .SemVer(new .("*"));
defer verSpec.Dispose();
- let project = gApp.mProjectPanel.ImportProject(entry.mPath, verSpec);
+ let project = gApp.mProjectPanel.ImportProject(entry.mPath, null, verSpec);
if (project == null)
{
return;
@@ -223,6 +246,7 @@ namespace IDE.ui
float insetSize = GS!(6);
mProjectList.Resize(insetSize, insetSize, mWidth - insetSize - insetSize, mHeight - GS!(66));
mEditWidget.Resize(insetSize, mProjectList.mY + mProjectList.mHeight + insetSize, mWidth - insetSize - insetSize, GS!(22));
+ mKindCombo.Resize(insetSize, mHeight - GS!(26), Math.Min(GS!(160), mDefaultButton.mX - GS!(6)), GS!(26));
}
public override void CalcSize()
diff --git a/IDE/src/ui/ProjectPanel.bf b/IDE/src/ui/ProjectPanel.bf
index 500fc926..1ce74655 100644
--- a/IDE/src/ui/ProjectPanel.bf
+++ b/IDE/src/ui/ProjectPanel.bf
@@ -61,6 +61,17 @@ namespace IDE.ui
else if (projectItem.mIncludeKind == .Ignore)
color = Color.Mult(color, gApp.mSettings.mUISettings.mColors.mWorkspaceIgnoredText);
+ if (let projectFileItem = projectItem as ProjectFileItem)
+ {
+ if (projectPanel.mClipboardCutQueued != null)
+ {
+ var path = projectFileItem.mProject.GetProjectFullPath(projectFileItem.mPath, .. scope .());
+ IDEUtils.MakeComparableFilePath(path);
+ if (projectPanel.mClipboardCutQueued.Contains(path))
+ color = Color.Mult(color, gApp.mSettings.mUISettings.mColors.mWorkspaceCutText);
+ }
+ }
+
if (let projectSource = projectItem as ProjectSource)
{
if (projectSource.mLoadFailed)
@@ -146,6 +157,7 @@ namespace IDE.ui
public bool mShowIgnored = true;
public bool mSortDirty;
public bool mWantsRehup;
+ public HashSet mClipboardCutQueued ~ DeleteContainerAndItems!(_);
public this()
{
@@ -518,10 +530,22 @@ namespace IDE.ui
}
}
- public void InitProject(Project project)
- {
+ public void InitProject(Project project, WorkspaceFolder workspaceFolder)
+ {
var projectListViewItem = InitProjectItem(project.mRootFolder);
projectListViewItem.mRefObject = project;
+ if (workspaceFolder != null)
+ {
+ let root = mListView.GetRoot();
+ root.RemoveChildItem(projectListViewItem, false);
+ workspaceFolder.mListView.MakeParent();
+ workspaceFolder.mListView.AddChild(projectListViewItem);
+ workspaceFolder.mListView.Open(true);
+ mProjectToWorkspaceFolderMap[project.mRootFolder] = workspaceFolder;
+
+ workspaceFolder.mProjects.Add(project);
+ QueueSortItem(workspaceFolder.mListView);
+ }
}
public void RebuildUI()
@@ -564,7 +588,7 @@ namespace IDE.ui
mProjectToWorkspaceFolderMap.Clear();
for (var project in IDEApp.sApp.mWorkspace.mProjects)
- InitProject(project);
+ InitProject(project, null);
let root = mListView.GetRoot();
@@ -1489,6 +1513,14 @@ namespace IDE.ui
#endif
}
+ public WorkspaceFolder GetSelectedWorkspaceFolder()
+ {
+ ListViewItem selectedItem = mListView.GetRoot().FindFirstSelectedItem();
+ if (mListViewToWorkspaceFolderMap.TryGetValue(selectedItem, let folder))
+ return folder;
+ return null;
+ }
+
ListViewItem GetSelectedParentItem()
{
ListViewItem selectedItem = mListView.GetRoot().FindFirstSelectedItem();
@@ -1764,33 +1796,59 @@ namespace IDE.ui
let root = mListView.GetRoot();
List itemsToMove = scope .();
List foldersToDelete = scope .();
+
root.WithSelectedItems(scope [&] (selectedItem) => {
if (mListViewToWorkspaceFolderMap.GetValue(selectedItem) case .Ok(let folder))
{
foldersToDelete.Add(folder);
+ mListViewToWorkspaceFolderMap.Remove(folder.mListView);
selectedItem.WithItems(scope [&] (item) => {
if (mListViewToProjectMap.GetValue(item) case .Ok(let project))
{
if (project.mParentFolder == null)
itemsToMove.Add(item);
}
+ else if (mListViewToWorkspaceFolderMap.GetValue(item) case .Ok(let itemFolder))
+ {
+ foldersToDelete.Add(itemFolder);
+ mListViewToWorkspaceFolderMap.Remove(itemFolder.mListView);
+ }
});
}
});
-
- for (let projectListViewItem in itemsToMove)
+
+ for (let listViewItem in itemsToMove)
{
- projectListViewItem.mParentItem.RemoveChildItem(projectListViewItem, false);
- root.AddChildAtIndex(1, projectListViewItem);
- if (mListViewToProjectMap.TryGetValue(projectListViewItem, let projectItem))
+ listViewItem.mParentItem.RemoveChildItem(listViewItem, false);
+ root.AddChildAtIndex(1, listViewItem);
+ if (mListViewToProjectMap.TryGetValue(listViewItem, let projectItem))
mProjectToWorkspaceFolderMap.Remove(projectItem);
}
- for (let folder in foldersToDelete)
+
+ bool HasDeletedParent(WorkspaceFolder folder)
+ {
+ WorkspaceFolder parent = folder;
+ repeat
+ {
+ parent = parent.mParent;
+
+ if (foldersToDelete.Contains(parent))
+ return true;
+ }
+ while (parent != null);
+
+ return false;
+ }
+
+ for (let folder in foldersToDelete)
{
- let folderItem = folder.mListView;
- mListViewToWorkspaceFolderMap.Remove(folderItem);
- folderItem.mParentItem.RemoveChildItem(folderItem);
- gApp.mWorkspace.mWorkspaceFolders.Remove(folder);
+ if (!HasDeletedParent(folder))
+ {
+ let folderItem = folder.mListView;
+ folderItem.mParentItem.RemoveChildItem(folderItem);
+ }
+
+ gApp.mWorkspace.mWorkspaceFolders.Remove(folder);
delete folder;
}
@@ -2004,6 +2062,307 @@ namespace IDE.ui
}
}
+ void CopyToClipboard()
+ {
+ String clipData = scope .();
+ mListView.GetRoot().WithSelectedItems(scope (selectedItem) =>
+ {
+ if (mListViewToProjectMap.GetValue(selectedItem) case .Ok(var sourceProjectItem))
+ {
+ String path = scope .();
+ if (var projectFileItem = sourceProjectItem as ProjectFileItem)
+ {
+ sourceProjectItem.mProject.GetProjectFullPath(projectFileItem.mPath, path);
+ path.Replace('\\', '/');
+
+ if (!clipData.IsEmpty)
+ clipData.Append("\n");
+ clipData.Append("file:///");
+ IDEUtils.URLEncode(path, clipData);
+ }
+ }
+ });
+ if (!clipData.IsEmpty)
+ gApp.SetClipboardData("code/file-list", clipData.Ptr, (.)clipData.Length, true);
+ }
+
+ void CutToClipboard()
+ {
+ DeleteContainerAndItems!(mClipboardCutQueued);
+ mClipboardCutQueued = null;
+
+ CopyToClipboard();
+ mClipboardCutQueued = new .();
+ ValidateCutClipboard();
+ }
+
+ void ValidateCutClipboard()
+ {
+ if (mClipboardCutQueued == null)
+ return;
+
+ void* data = gApp.GetClipboardData("code/file-list", var size, 0);
+ if (size == -1)
+ return;
+
+ ClearAndDeleteItems!(mClipboardCutQueued);
+
+ if (data != null)
+ {
+ StringView sv = .((.)data, size);
+ for (var line in sv.Split('\n'))
+ {
+ var uri = IDEUtils.URLDecode(line, .. scope .());
+ if (uri.StartsWith("file:///"))
+ {
+ var srcPath = scope String()..Append(uri.Substring("file:///".Length));
+ IDEUtils.MakeComparableFilePath(srcPath);
+ if (mClipboardCutQueued.TryAddAlt(srcPath, var entryPtr))
+ *entryPtr = new String(srcPath);
+ }
+ }
+ }
+
+ if (mClipboardCutQueued.IsEmpty)
+ DeleteAndNullify!(mClipboardCutQueued);
+ }
+
+ void PasteFromClipboard()
+ {
+ ValidateCutClipboard();
+
+ var projectItem = GetSelectedProjectItem();
+ var projectFolder = projectItem as ProjectFolder;
+ if (projectFolder == null)
+ projectFolder = projectItem.mParentFolder;
+ if (projectFolder == null)
+ return;
+
+ var folderPath = projectFolder.GetFullImportPath(.. scope .());
+
+ void* data = gApp.GetClipboardData("code/file-list", var size);
+ if (data == null)
+ return;
+
+ bool isCut = mClipboardCutQueued != null;
+ Dictionary sourceViewPanelMap = null;
+ List<(SourceViewPanel sourceViewPanel, String fromPath, String toPath)> moveList = null;
+
+ HashSet foundDirs = scope .();
+
+ if (isCut)
+ {
+ sourceViewPanelMap = scope:: .();
+ gApp.WithSourceViewPanels(scope (sourceViewPanel) =>
+ {
+ if (sourceViewPanel.mFilePath === null)
+ return;
+ if (sourceViewPanel.mProjectSource == null)
+ return;
+
+ var path = scope String()..Append(sourceViewPanel.mFilePath);
+ IDEUtils.MakeComparableFilePath(path);
+ if (sourceViewPanelMap.TryAdd(path, var keyPtr, var valuePtr))
+ {
+ *keyPtr = new String(path);
+ *valuePtr = sourceViewPanel;
+ }
+ });
+
+ moveList = scope:: .();
+ }
+
+ defer
+ {
+ DeleteContainerAndItems!(mClipboardCutQueued);
+ mClipboardCutQueued = null;
+
+ if (sourceViewPanelMap != null)
+ {
+ for (var key in sourceViewPanelMap.Keys)
+ delete key;
+ }
+
+ if (moveList != null)
+ {
+ for (var val in moveList)
+ {
+ delete val.fromPath;
+ delete val.toPath;
+ }
+ }
+
+ ClearAndDeleteItems!(foundDirs);
+ }
+
+ void QueueDirectoryMove(StringView fromDir, StringView toDir)
+ {
+ var searchStr = scope String();
+ searchStr.Append(fromDir);
+ searchStr.Append("/*");
+ for (var dirEntry in Directory.Enumerate(searchStr, .Directories | .Files))
+ {
+ var fromChildPath = dirEntry.GetFilePath(.. scope .());
+
+ String toChildPath = scope String()..Append(toDir);
+ toChildPath.Append(Path.DirectorySeparatorChar);
+ dirEntry.GetFileName(toChildPath);
+
+ if (dirEntry.IsDirectory)
+ {
+ QueueDirectoryMove(fromChildPath, toChildPath);
+ continue;
+ }
+
+ var cmpPath = IDEUtils.MakeComparableFilePath(.. scope String()..Append(fromChildPath));
+ if (sourceViewPanelMap.TryGet(cmpPath, var matchKey, var sourceViewPanel))
+ {
+ moveList.Add((sourceViewPanel, new String(fromChildPath), new String(toChildPath)));
+ }
+ }
+ }
+
+ Result CopyDirectory(StringView fromDir, StringView toDir)
+ {
+ if (Directory.CreateDirectory(toDir) case .Err)
+ {
+ gApp.Fail(scope $"Failed to create directory '{toDir}'");
+ return .Err;
+ }
+
+ var searchStr = scope String();
+ searchStr.Append(fromDir);
+ searchStr.Append("/*");
+ for (var dirEntry in Directory.Enumerate(searchStr, .Directories | .Files))
+ {
+ var fromChildPath = dirEntry.GetFilePath(.. scope .());
+
+ String toChildPath = scope String()..Append(toDir);
+ toChildPath.Append("/");
+ dirEntry.GetFileName(toChildPath);
+
+ if (dirEntry.IsDirectory)
+ {
+ CopyDirectory(fromChildPath, toChildPath);
+ continue;
+ }
+
+ if (File.Copy(fromChildPath, toChildPath) case .Err)
+ {
+ gApp.Fail(scope $"Failed to copy '{fromChildPath}' to '{toChildPath}'");
+ return .Err;
+ }
+ }
+
+ return .Ok;
+ }
+
+ StringView sv = .((.)data, size);
+ SrcLoop: for (var line in sv.Split('\n'))
+ {
+ var uri = IDEUtils.URLDecode(line, .. scope .());
+ if (uri.StartsWith("file:///"))
+ {
+ var srcPath = scope String()..Append(uri.Substring("file:///".Length));
+
+ for (int i < 100)
+ {
+ var fileName = Path.GetFileNameWithoutExtension(srcPath, .. scope .());
+ var destPath = scope String();
+ destPath.Append(folderPath);
+ destPath.Append("/");
+ destPath.Append(fileName);
+ if ((i > 0) && (!fileName.Contains(" - Copy")))
+ destPath.Append(" - Copy");
+ if (i > 1)
+ destPath.AppendF($" ({i})");
+ Path.GetExtension(srcPath, destPath);
+
+ IDEUtils.FixFilePath(srcPath);
+ IDEUtils.FixFilePath(destPath);
+
+ if ((isCut) && (Path.Equals(srcPath, destPath)))
+ break;
+
+ if (File.Exists(destPath))
+ continue;
+ if (Directory.Exists(destPath))
+ continue;
+
+ if (Directory.Exists(srcPath))
+ {
+ if (foundDirs.TryAdd(srcPath, var entryPtr))
+ *entryPtr = new String(srcPath);
+
+ if (isCut)
+ {
+ QueueDirectoryMove(srcPath, destPath);
+
+ if (Directory.Move(srcPath, destPath) case .Err)
+ {
+ gApp.Fail(scope $"Failed to move '{srcPath}' to '{destPath}'");
+ return;
+ }
+
+ for (var val in moveList)
+ {
+ gApp.FileRenamed(val.sourceViewPanel.mProjectSource, val.fromPath, val.toPath);
+ }
+ }
+ else
+ {
+ if (CopyDirectory(srcPath, destPath) case .Err)
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ var checkPath = scope String()..Append(srcPath);
+ while (true)
+ {
+ String checkDir = scope .();
+ if (Path.GetDirectoryPath(checkPath, checkDir) case .Err)
+ break;
+ if (foundDirs.Contains(checkDir))
+ {
+ // Already handled
+ continue SrcLoop;
+ }
+ checkPath.Set(checkDir);
+ }
+
+ if (isCut)
+ {
+ if (File.Move(srcPath, destPath) case .Err)
+ {
+ gApp.Fail(scope $"Failed to move '{srcPath}' to '{destPath}'");
+ return;
+ }
+
+ var cmpPath = IDEUtils.MakeComparableFilePath(.. scope String()..Append(srcPath));
+ if (sourceViewPanelMap.TryGet(cmpPath, var matchKey, var sourceViewPanel))
+ {
+ gApp.FileRenamed(sourceViewPanel.mProjectSource, srcPath, destPath);
+ }
+ }
+ else
+ {
+ if (File.Copy(srcPath, destPath) case .Err)
+ {
+ gApp.Fail(scope $"Failed to copy '{srcPath}' to '{destPath}'");
+ return;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
public override void KeyDown(KeyCode keyCode, bool isRepeat)
{
mListView.KeyDown(keyCode, isRepeat);
@@ -2015,8 +2374,25 @@ namespace IDE.ui
}
base.KeyDown(keyCode, isRepeat);
- if (keyCode == KeyCode.Delete)
- RemoveSelectedItems();
+
+ if (mWidgetWindow.GetKeyFlags() == .Ctrl)
+ {
+ switch (keyCode)
+ {
+ case (.)'C':
+ CopyToClipboard();
+ case (.)'X':
+ CutToClipboard();
+ case (.)'V':
+ PasteFromClipboard();
+ default:
+ }
+ }
+ else if (mWidgetWindow.GetKeyFlags() == .None)
+ {
+ if (keyCode == KeyCode.Delete)
+ RemoveSelectedItems();
+ }
}
void ItemClicked(MouseEvent theEvent)
@@ -2374,7 +2750,7 @@ namespace IDE.ui
return true;
}
- public void AddWorkspaceFolder(ProjectListViewItem parentListViewItem)
+ public WorkspaceFolder AddWorkspaceFolder(ProjectListViewItem parentListViewItem)
{
ProjectListViewItem listViewItem;
listViewItem = (ProjectListViewItem)parentListViewItem.CreateChildItem();
@@ -2406,10 +2782,11 @@ namespace IDE.ui
mListView.GetRoot().SelectItemExclusively(listViewItem);
EditListViewItem(listViewItem);
gApp.mWorkspace.SetChanged();
+ return folder;
}
- public Project ImportProject(String filePath, VerSpec verSpec = .None)
+ public Project ImportProject(String filePath, WorkspaceFolder workspaceFolder, VerSpec verSpec = .None)
{
if (gApp.IsCompiling)
return null;
@@ -2456,7 +2833,7 @@ namespace IDE.ui
gApp.AddNewProjectToWorkspace(proj, verSpec);
gApp.mWorkspace.FixOptions();
gApp.[Friend]FlushDeferredLoadProjects(true);
- InitProject(proj);
+ InitProject(proj, workspaceFolder);
if (failed)
{
gApp.Fail(StackStringFormat!("Failed to load project: {0}", filePath));
@@ -2502,6 +2879,8 @@ namespace IDE.ui
initialDir.Concat(Path.DirectorySeparatorChar, "Samples");
}
+ var workspaceFolder = GetSelectedWorkspaceFolder();
+
fileDialog.InitialDirectory = initialDir;
fileDialog.ValidateNames = true;
fileDialog.DefaultExt = ".toml";
@@ -2511,7 +2890,7 @@ namespace IDE.ui
{
for (String origProjFilePath in fileDialog.FileNames)
{
- ImportProject(origProjFilePath);
+ ImportProject(origProjFilePath, workspaceFolder);
}
}
#endif
@@ -2616,6 +2995,43 @@ namespace IDE.ui
{
Menu anItem;
+ void AddWorkspaceMenuItems()
+ {
+ anItem = menu.AddItem("Add New Project...");
+ anItem.mOnMenuItemSelected.Add(new (item) => {
+ AddNewProject();
+ });
+ if (gApp.IsCompiling)
+ anItem.SetDisabled(true);
+
+ anItem = menu.AddItem("Add Existing Project...");
+ anItem.mOnMenuItemSelected.Add(new (item) => {
+ mImportProjectDeferred = true;
+ });
+ if (gApp.IsCompiling)
+ anItem.SetDisabled(true);
+
+ anItem = menu.AddItem("Add From Installed...");
+ anItem.mOnMenuItemSelected.Add(new (item) => {
+ mImportInstalledDeferred = true;
+ });
+ if (gApp.IsCompiling)
+ anItem.SetDisabled(true);
+ anItem = menu.AddItem("New Folder");
+ anItem.mOnMenuItemSelected.Add(new (item) => {
+ var workspaceFolder = GetSelectedWorkspaceFolder();
+ if (workspaceFolder != null)
+ {
+ let newFolder = AddWorkspaceFolder(workspaceFolder.mListView);
+ newFolder.mParent = workspaceFolder;
+ }
+ else
+ {
+ AddWorkspaceFolder((ProjectListViewItem)mListView.GetRoot());
+ }
+ });
+ }
+
if (mListViewToWorkspaceFolderMap.TryGetValue(focusedItem, let folder))
{
anItem = menu.AddItem("Remove");
@@ -2623,8 +3039,9 @@ namespace IDE.ui
anItem = menu.AddItem("Rename");
anItem.mOnMenuItemSelected.Add(new (item) => { EditListViewItem(focusedItem); });
menu.AddItem();
- anItem = menu.AddItem("New Folder");
- anItem.mOnMenuItemSelected.Add(new (item) => { AddWorkspaceFolder(folder.mListView); });
+
+ AddWorkspaceMenuItems();
+
handled = true;
}
else if (gApp.mWorkspace.IsInitialized)
@@ -2632,23 +3049,7 @@ namespace IDE.ui
AddOpenContainingFolder();
menu.AddItem();
- anItem = menu.AddItem("Add New Project...");
- anItem.mOnMenuItemSelected.Add(new (item) => { AddNewProject(); });
- if (gApp.IsCompiling)
- anItem.SetDisabled(true);
-
- anItem = menu.AddItem("Add Existing Project...");
- anItem.mOnMenuItemSelected.Add(new (item) => { mImportProjectDeferred = true; });
- if (gApp.IsCompiling)
- anItem.SetDisabled(true);
-
- anItem = menu.AddItem("Add From Installed...");
- anItem.mOnMenuItemSelected.Add(new (item) => { mImportInstalledDeferred = true; });
- if (gApp.IsCompiling)
- anItem.SetDisabled(true);
-
- anItem = menu.AddItem("New Folder");
- anItem.mOnMenuItemSelected.Add(new (item) => { AddWorkspaceFolder((ProjectListViewItem)mListView.GetRoot()); });
+ AddWorkspaceMenuItems();
menu.AddItem();
anItem = menu.AddItem("Properties...");
anItem.mOnMenuItemSelected.Add(new (item) => { ShowWorkspaceProperties(); });
@@ -2717,7 +3118,7 @@ namespace IDE.ui
});
}
- item = menu.AddItem("Remove...");
+ item = menu.AddItem("Remove...|Del");
if (gApp.IsCompiling)
item.SetDisabled(true);
item.mOnMenuItemSelected.Add(new (item) =>
@@ -2725,7 +3126,7 @@ namespace IDE.ui
RemoveSelectedItems();
});
- item = menu.AddItem("Rename");
+ item = gApp.AddMenuItem(menu, "Rename", "Rename Item");
if (gApp.IsCompiling)
item.SetDisabled(true);
item.mOnMenuItemSelected.Add(new (item) =>
@@ -2769,13 +3170,13 @@ namespace IDE.ui
if ((projectItem != null) && (!isProject))
{
- item = menu.AddItem("Remove ...");
+ item = menu.AddItem("Remove ...|Del");
item.mOnMenuItemSelected.Add(new (item) =>
{
RemoveSelectedItems();
});
- item = menu.AddItem("Rename");
+ item = gApp.AddMenuItem(menu, "Rename", "Rename Item");
item.mOnMenuItemSelected.Add(new (item) =>
{
var projectItem = GetSelectedProjectItem();
@@ -2926,6 +3327,14 @@ namespace IDE.ui
if (!isFailedLoad)
{
+ item = menu.AddItem("Copy|Ctrl+C");
+ item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard());
+ item = menu.AddItem("Cut|Ctrl+X");
+ item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard());
+ item = menu.AddItem("Paste|Ctrl+V");
+ item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard());
+ menu.AddItem();
+
item = menu.AddItem("New Folder");
item.mOnMenuItemSelected.Add(new (item) =>
{
@@ -3098,6 +3507,8 @@ namespace IDE.ui
mImportInstalledDeferred = false;
ImportInstalledProject();
}
+
+ ValidateCutClipboard();
}
public override void Resize(float x, float y, float width, float height)
@@ -3114,3 +3525,5 @@ namespace IDE.ui
}
}
+
+///////////////////////
\ No newline at end of file
diff --git a/IDE/src/ui/RenameSymbolDialog.bf b/IDE/src/ui/RenameSymbolDialog.bf
index 3ff90b37..ab19e118 100644
--- a/IDE/src/ui/RenameSymbolDialog.bf
+++ b/IDE/src/ui/RenameSymbolDialog.bf
@@ -244,7 +244,12 @@ namespace IDE.ui
if (mKind == .GoToDefinition)
{
mSourceViewPanel.RecordHistoryLocation();
- var sourceViewPanel = gApp.ShowSourceFileLocation(scope .(filePath), -1, -1, line, lineChar, LocatorType.Smart, true);
+
+ var usePath = scope String(filePath);
+ if (usePath.StartsWith("$Emit$"))
+ usePath.Insert("$Emit$".Length, "Resolve$");
+
+ var sourceViewPanel = gApp.ShowSourceFileLocation(usePath, -1, -1, line, lineChar, LocatorType.Smart, true);
sourceViewPanel.RecordHistoryLocation(true);
Close();
return;
diff --git a/IDE/src/ui/SettingsDialog.bf b/IDE/src/ui/SettingsDialog.bf
index 8c4e9c93..e7e1da9a 100644
--- a/IDE/src/ui/SettingsDialog.bf
+++ b/IDE/src/ui/SettingsDialog.bf
@@ -221,6 +221,30 @@ namespace IDE.ui
}
}
+ // Do chord prefix search
+ for (var propEntries in mPropPage.mPropEntries.Values)
+ {
+ var propEntry = propEntries[0];
+ let keyEntry = (KeyEntry)propEntry.mTarget;
+ let origKeys = propEntry.mCurValue.Get>();
+ var keys = scope List(origKeys.GetEnumerator());
+ while (keys.Count > 1)
+ {
+ keys.PopBack();
+ let keyEntryStr = scope String();
+ KeyState.ToString(keys, keyEntryStr);
+ keyEntryStr.Append(" ");
+ CommandContextToString(keyEntry.mContextFlags, keyEntryStr);
+
+ if (mappedEntries.TryGet(keyEntryStr, var keyPtr, var valuePtr))
+ {
+ let other = valuePtr;
+ other.mHasConflict = true;
+ keyEntry.mHasConflict = true;
+ }
+ }
+ }
+
for (let keyEntryStr in mappedEntries.Keys)
delete keyEntryStr;
diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf
index f51d83ff..b977d064 100644
--- a/IDE/src/ui/SourceEditWidgetContent.bf
+++ b/IDE/src/ui/SourceEditWidgetContent.bf
@@ -14,6 +14,8 @@ using IDE.Debugger;
using IDE.Compiler;
using Beefy.geom;
using Beefy.events;
+using System.Security.Cryptography;
+using System.IO;
namespace IDE.ui
{
@@ -224,7 +226,7 @@ namespace IDE.ui
{
mTypeName = new .(emitEmbed.mTypeName);
mEmitEmbed = emitEmbed;
- mSourceViewPanel = new SourceViewPanel((emitEmbed.mEmitKind == .Method) ? .Method : .Type);
+ mSourceViewPanel = new SourceViewPanel((emitEmbed.mEmitKind == .Emit_Method) ? .Method : .Type);
mSourceViewPanel.mEmbedParent = mEmitEmbed.mEditWidgetContent.mSourceViewPanel;
var emitPath = scope $"$Emit${emitEmbed.mTypeName}";
@@ -382,7 +384,7 @@ namespace IDE.ui
}
mAwaitingLoad = false;
- if (!mEmitRemoved)
+ if ((!mEmitRemoved) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve))
{
for (var explicitTypeName in mEmitEmbed.mEditWidgetContent.mSourceViewPanel.[Friend]mExplicitEmitTypes)
{
@@ -397,6 +399,9 @@ namespace IDE.ui
if ((mAwaitingLoad) && (gApp.mUpdateCnt % 4 == 0))
MarkDirty();
+
+ if (mSourceViewPanel.HasFocus())
+ mEmitEmbed.mEditWidgetContent.mEmbedSelected = mEmitEmbed;
}
public void GetGenericTypes()
@@ -516,6 +521,10 @@ namespace IDE.ui
public int32 mEndLine;
public View mView;
+ public this()
+ {
+ }
+
public ~this()
{
if (mView != null)
@@ -525,17 +534,29 @@ namespace IDE.ui
}
}
+ public bool IsSelected => mEditWidgetContent.mEmbedSelected == this;
+ public float LabelWidth = GS!(42);
+
public override float GetWidth(bool hideLine)
{
- return GS!(42);
+ return IsSelected ? GS!(60) : LabelWidth;
}
public override void Draw(Graphics g, Rect rect, bool hideLine)
{
+ var rect;
+ rect.mWidth = LabelWidth;
+
if (rect.mHeight >= DarkTheme.sDarkTheme.mSmallBoldFont.GetLineSpacing())
g.SetFont(DarkTheme.sDarkTheme.mSmallBoldFont);
- using (g.PushColor(0x80707070))
+ uint32 fillColor = 0x80707070;
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
+ {
+ fillColor = 0x805050E0;
+ }
+
+ using (g.PushColor(fillColor))
{
g.FillRect(rect.mX + 1, rect.mY + 1, rect.mWidth - 2, rect.mHeight - 2);
}
@@ -558,6 +579,40 @@ namespace IDE.ui
var summaryString = "Emit";
g.DrawString(summaryString, rect.mX, rect.mY + (int)((rect.mHeight - g.mFont.GetLineSpacing()) * 0.5f), .Centered, rect.mWidth);
+
+ if (IsSelected)
+ {
+ g.Draw(DarkTheme.sDarkTheme.GetImage(.DropMenuButton), rect.Right, rect.Top);
+ }
+ }
+
+ public override void MouseDown(Rect rect, float x, float y, int btn, int btnCount)
+ {
+ base.MouseDown(rect, x, y, btn, btnCount);
+ if (x >= rect.mX + LabelWidth)
+ ShowMenu(x, y);
+ }
+
+ public void ShowMenu(float x, float y)
+ {
+ Menu menuItem;
+
+ Menu menu = new Menu();
+ menuItem = menu.AddItem("Compiler");
+
+ var subItem = menuItem.AddItem("Resolve");
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+ subItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check);
+ subItem.mOnMenuItemSelected.Add(new (menu) => { gApp.SetEmbedCompiler(.Resolve); });
+
+ subItem = menuItem.AddItem("Build");
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
+ subItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check);
+ subItem.mOnMenuItemSelected.Add(new (menu) => { gApp.SetEmbedCompiler(.Build); });
+
+ MenuWidget menuWidget = DarkTheme.sDarkTheme.CreateMenuWidget(menu);
+
+ menuWidget.Init(mEditWidgetContent, x, y);
}
}
@@ -575,10 +630,11 @@ namespace IDE.ui
case UsingNamespaces = 'U';
case Unknown = '?';
case HasUncertainEmits = '~';
- case Emit = 'e';
+ case Emit_Type = 't';
+ case Emit_Method = 'm';
case EmitAddType = '+';
- public bool IsEmit => (this == .Emit);
+ public bool IsEmit => (this == .Emit_Type) || (this == .Emit_Method);
}
public Kind mKind;
@@ -602,6 +658,8 @@ namespace IDE.ui
public int32 mParseRevision;
public int32 mTextRevision;
public bool mDeleted;
+
+ public bool DefaultOpen => mKind != .Region;
}
public struct EmitData
@@ -614,6 +672,7 @@ namespace IDE.ui
public bool mOnlyInResolveAll;
public bool mIncludedInClassify;
public bool mIncludedInResolveAll;
+ public bool mIncludedInBuild;
public int32 mAnchorId;
}
@@ -757,6 +816,8 @@ namespace IDE.ui
public int32 mCollapseTextVersionId;
public bool mCollapseNeedsUpdate;
public bool mCollapseNoCheckOpen;
+ public bool mCollapseDBDirty;
+ public bool mCollapseAwaitingDB = true;
public List PersistentTextPositions
{
@@ -1784,7 +1845,19 @@ namespace IDE.ui
int line;
int lineChar;
GetCursorLineChar(out line, out lineChar);
- return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, mSourceViewPanel.mFilePath, line, lineChar, ignoreIfClose);
+
+ String useFilePath = mSourceViewPanel.mFilePath;
+ if ((mSourceViewPanel.mFilePath.StartsWith("$Emit$")) &&
+ (!mSourceViewPanel.mFilePath.StartsWith("$Emit$Build$")) &&
+ (!mSourceViewPanel.mFilePath.StartsWith("$Emit$Resolve$")))
+ {
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+ useFilePath = scope:: String("$Emit$Resolve$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length));
+ else
+ useFilePath = scope:: String("$Emit$Build$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length));
+ }
+
+ return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, useFilePath, line, lineChar, ignoreIfClose);
}
return null;
}
@@ -3901,7 +3974,7 @@ namespace IDE.ui
prevChar = mData.mText[cursorTextPos - 1].mChar;
}
- if (((keyChar == '\n') || (keyChar == '\r')) && (mIsMultiline) && (!CheckReadOnly()))
+ if (((keyChar == '\n') || (keyChar == '\r')) && (!HasSelection()) && (mIsMultiline) && (!CheckReadOnly()))
{
UndoBatchStart undoBatchStart = new UndoBatchStart("newline");
mData.mUndoManager.Add(undoBatchStart);
@@ -4408,6 +4481,7 @@ namespace IDE.ui
public override void KeyDown(KeyCode keyCode, bool isRepeat)
{
mIgnoreKeyChar = false;
+ mEmbedSelected = null;
bool autoCompleteRequireControl = (gApp.mSettings.mEditorSettings.mAutoCompleteRequireControl) && (mIsMultiline);
@@ -4463,7 +4537,6 @@ namespace IDE.ui
{
return;
}
-
if ((keyCode == KeyCode.Escape) && (mSelection != null) && (mSelection.Value.HasSelection))
{
@@ -4696,6 +4769,23 @@ namespace IDE.ui
{
base.MouseClicked(x, y, origX, origY, btn);
+ if (btn == 1)
+ {
+ int line = GetLineAt(y);
+ if (mEmbeds.GetValue((.)line) case .Ok(let embed))
+ {
+ Rect embedRect = GetEmbedRect(line, embed);
+ if (embedRect.Contains(x, y))
+ {
+ if (var emitEmbed = embed as EmitEmbed)
+ {
+ emitEmbed.ShowMenu(x, y);
+ }
+ return;
+ }
+ }
+ }
+
var useX = x;
var useY = y;
@@ -4735,15 +4825,15 @@ namespace IDE.ui
{
Menu menuItem;
- menuItem = menu.AddItem("Go to Definition");
+ menuItem = gApp.AddMenuItem(menu, "Go to Definition", "Goto Definition");
menuItem.SetDisabled(!hasText);
menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.GoToDefinition(true));
- menuItem = menu.AddItem("Find All References");
+ menuItem = gApp.AddMenuItem(menu, "Find All References");
menuItem.SetDisabled(!hasText);
menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.Cmd_FindAllReferences());
- menuItem = menu.AddItem("Rename Symbol");
+ menuItem = gApp.AddMenuItem(menu, "Rename Symbol");
menuItem.SetDisabled(!hasText);
menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.Cmd_RenameSymbol());
@@ -4823,7 +4913,12 @@ namespace IDE.ui
var autoComplete = new AutoComplete(mEditWidget);
autoComplete.SetInfo(infoCopy);
autoComplete.mAutoCompleteListWidget.mSelectIdx = fixitIdx;
+
+ UndoBatchStart undoBatchStart = new UndoBatchStart("autocomplete");
+ mData.mUndoManager.Add(undoBatchStart);
autoComplete.InsertSelection(0);
+ mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
+
autoComplete.Close();
}
~
@@ -4866,10 +4961,14 @@ namespace IDE.ui
menu.AddItem();
var debugger = IDEApp.sApp.mDebugger;
bool isPaused = debugger.IsPaused();
- menuItem = menu.AddItem("Show Disassembly");
+ menuItem = gApp.AddMenuItem(menu, "Show Disassembly");
menuItem.SetDisabled(!isPaused);
menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.ShowDisassemblyAtCursor());
+ menuItem = gApp.AddMenuItem(menu, "Set Next Statement");
+ menuItem.SetDisabled(!isPaused);
+ menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.[Friend]SetNextStatement());
+
var stepIntoSpecificMenu = menu.AddItem("Step into Specific");
stepIntoSpecificMenu.SetDisabled(!isPaused);
stepIntoSpecificMenu.IsParent = true;
@@ -5019,20 +5118,26 @@ namespace IDE.ui
Rect embedRect = GetEmbedRect(line, embed);
if (embedRect.Contains(x, y))
{
- if ((btn == 0) && (btnCount % 2 == 0))
+ mEmbedSelected = embed;
+ embed.MouseDown(GetEmbedRect(line, embed), x, y, btn, btnCount);
+ if (btn == 0)
{
- if (var collapseSummary = embed as SourceEditWidgetContent.CollapseSummary)
- SetCollapseOpen(collapseSummary.mCollapseIndex, true);
- else if (var emitEmbed = embed as EmitEmbed)
+ if (btnCount % 2 == 0)
{
- emitEmbed.mIsOpen = !emitEmbed.mIsOpen;
- mCollapseNeedsUpdate = true;
+ if (var collapseSummary = embed as SourceEditWidgetContent.CollapseSummary)
+ SetCollapseOpen(collapseSummary.mCollapseIndex, true);
+ else if (var emitEmbed = embed as EmitEmbed)
+ {
+ emitEmbed.mIsOpen = !emitEmbed.mIsOpen;
+ mCollapseNeedsUpdate = true;
+ }
}
}
return;
}
}
+ mEmbedSelected = null;
base.MouseDown(x, y, btn, btnCount);
}
@@ -5727,6 +5832,13 @@ namespace IDE.ui
}
}
+ void DeleteEmbed(Embed embed)
+ {
+ if (mEmbedSelected == embed)
+ mEmbedSelected = null;
+ delete embed;
+ }
+
public override void GetTextData()
{
var data = Data;
@@ -5755,8 +5867,14 @@ namespace IDE.ui
}
}
+ IdSpan.LookupContext lookupCtx = null;
+
for (var emitData in ref data.mEmitData)
{
+ if (lookupCtx == null)
+ lookupCtx = scope:: .(mData.mTextIdData);
+ emitData.mAnchorIdx = (.)lookupCtx.GetIndexFromId(emitData.mAnchorId);
+
GetLineCharAtIdx(emitData.mAnchorIdx, var line, var lineChar);
SourceEditWidgetContent.EmitEmbed emitEmbed = null;
@@ -5776,7 +5894,7 @@ namespace IDE.ui
else
{
//Debug.WriteLine($" Occupied- deleting {emitEmbed}");
- delete emitEmbed;
+ DeleteEmbed(emitEmbed);
emitEmbed = null;
}
}
@@ -5837,13 +5955,14 @@ namespace IDE.ui
{
mCollapseNeedsUpdate = true;
mEmbeds.Remove(emitEmbed.mLine);
- delete emitEmbed;
+ DeleteEmbed(emitEmbed);
}
}
for (var collapseData in ref data.mCollapseData)
{
- if (mCollapseMap.TryAdd(collapseData.mAnchorId, ?, var entry))
+ bool isNew = mCollapseMap.TryAdd(collapseData.mAnchorId, ?, var entry);
+ if (isNew)
{
*entry = .();
}
@@ -5852,6 +5971,12 @@ namespace IDE.ui
entry.mPrevAnchorLine = prevAnchorLine;
entry.mParseRevision = mCollapseParseRevision;
entry.mDeleted = false;
+
+ if ((isNew) && (!entry.DefaultOpen) && (!mCollapseAwaitingDB))
+ {
+ // Likely a '#region' that we need to serialize as being open
+ mCollapseDBDirty = true;
+ }
}
for (var entry in ref mCollapseMap.Values)
@@ -5863,7 +5988,7 @@ namespace IDE.ui
if (!(value is EmitEmbed))
{
mEmbeds.Remove(entry.mAnchorLine);
- delete value;
+ DeleteEmbed(value);
}
}
@entry.Remove();
@@ -5888,7 +6013,7 @@ namespace IDE.ui
{
//Debug.WriteLine($" Removing {val.value}");
if (val.value is CollapseSummary)
- delete val.value;
+ DeleteEmbed(val.value);
}
continue;
}
@@ -5914,11 +6039,68 @@ namespace IDE.ui
else
{
//Debug.WriteLine($" Deleting(3) {val}");
- delete val;
+ DeleteEmbed(val);
}
}
}
+#if !CLI
+ if ((mCollapseAwaitingDB) && (mSourceViewPanel != null))
+ {
+ String filePath = scope .(mSourceViewPanel.mFilePath);
+ IDEUtils.MakeComparableFilePath(filePath);
+
+ HashSet toggledIndices = scope .();
+
+ List dbData = scope .();
+ if (gApp.mFileRecovery.GetDB(filePath, dbData))
+ {
+ MemoryStream memStream = scope .(dbData, false);
+ var dbHash = memStream.Read().GetValueOrDefault();
+
+ String text = scope .();
+ mEditWidget.GetText(text);
+ var curHash = MD5.Hash(.((uint8*)text.Ptr, text.Length));
+ if (curHash == dbHash)
+ {
+ while (true)
+ {
+ if (memStream.Read() case .Ok(let idx))
+ {
+ // We recorded indices, which (upon load) will generate an id of idx+1
+ toggledIndices.Add(idx + 1);
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ bool wasCursorVisible = IsCursorVisible();
+ bool hadCloses = false;
+ for (var collapseEntry in mOrderedCollapseEntries)
+ {
+ bool wantOpen = collapseEntry.DefaultOpen;
+ if (toggledIndices.Contains(collapseEntry.mAnchorId))
+ wantOpen = !wantOpen;
+
+ if (collapseEntry.mIsOpen != wantOpen)
+ {
+ if (!wantOpen)
+ hadCloses = true;
+ SetCollapseOpen(@collapseEntry.Index, wantOpen, true, true);
+ }
+ }
+ if ((wasCursorVisible) && (hadCloses))
+ {
+ UpdateCollapse(0.0f);
+ EnsureCursorVisible();
+ }
+
+ mCollapseAwaitingDB = false;
+ }
+#endif
+
//Debug.WriteLine($"ParseCollapseRegions Count:{mOrderedCollapseEntries.Count} Time:{sw.ElapsedMilliseconds}ms");
}
@@ -6221,17 +6403,26 @@ namespace IDE.ui
}
- public void SetCollapseOpen(int collapseIdx, bool wantOpen, bool immediate = false)
+ public void SetCollapseOpen(int collapseIdx, bool wantOpen, bool immediate = false, bool keepCursorVisible = false)
{
var entry = mOrderedCollapseEntries[collapseIdx];
+ var cursorLineAndColumn = CursorLineAndColumn;
+
+ if ((!wantOpen) && (keepCursorVisible) && (cursorLineAndColumn.mLine >= entry.mStartLine) && (cursorLineAndColumn.mLine <= entry.mEndLine))
+ {
+ if (CursorTextPos < entry.mEndIdx)
+ {
+ // Ignore close
+ return;
+ }
+ }
+
entry.mIsOpen = wantOpen;
if (immediate)
entry.mOpenPct = entry.mIsOpen ? 1.0f : 0.0f;
- else
- mCollapseNeedsUpdate = true;
-
- var cursorLineAndColumn = CursorLineAndColumn;
+ mCollapseNeedsUpdate = true;
+ mCollapseDBDirty = true;
if (wantOpen)
{
@@ -6241,7 +6432,7 @@ namespace IDE.ui
{
if ((embed.mKind == .HideLine) || (embed.mKind == .LineEnd))
{
- delete embed;
+ DeleteEmbed(embed);
mEmbeds.Remove(entry.mAnchorLine);
}
}
@@ -6283,7 +6474,7 @@ namespace IDE.ui
if (!(value is EmitEmbed))
{
mEmbeds.Remove(prevAnchorLine);
- delete value;
+ DeleteEmbed(value);
}
}
@@ -6304,7 +6495,7 @@ namespace IDE.ui
else
{
//Debug.WriteLine($" Occupied- deleting {val}");
- delete val.value;
+ DeleteEmbed(val.value);
}
}
}
@@ -6360,7 +6551,7 @@ namespace IDE.ui
if (entry.mDeleted)
{
if (mEmbeds.GetAndRemove(entry.mAnchorIdx) case .Ok(let val))
- delete val.value;
+ DeleteEmbed(val.value);
continue;
}
@@ -6388,7 +6579,7 @@ namespace IDE.ui
*valuePtr = val.value;
}
else
- delete val.value;
+ DeleteEmbed(val.value);
}
}
}
@@ -6401,7 +6592,7 @@ namespace IDE.ui
RehupLineCoords();
}
- public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan, ResolveType resolveType)
+ public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan, ResolveType? resolveType)
{
/*if (resolveType == .None)
return;*/
@@ -6410,11 +6601,13 @@ namespace IDE.ui
var data = PreparedData;
- if (resolveType != .None)
+ if ((resolveType != null) && (resolveType != .None))
{
data.ClearCollapse();
}
+ bool wantsBuildEmits = gApp.mSettings.mEditorSettings.mEmitCompiler == .Build;
+
//Debug.WriteLine($"ParseCollapseRegions {resolveType} CollapseRevision:{data.mCollapseParseRevision+1} TextVersion:{textVersion} IdSpan:{idSpan:D}");
List typeNameIdxMap = scope .();
@@ -6429,7 +6622,7 @@ namespace IDE.ui
if (emitInitialized)
return;
emitInitialized = true;
- if ((hasUncertainEmits) || (resolveType == .None))
+ if ((hasUncertainEmits) || (wantsBuildEmits) || (resolveType == .None))
{
// Leave emits alone
for (var typeName in data.mTypeNames)
@@ -6437,7 +6630,11 @@ namespace IDE.ui
for (var emitData in ref data.mEmitData)
{
emitAnchorIds[emitData.mAnchorId] = (.)@emitData.Index;
- if (resolveType == .None)
+ if (resolveType == null)
+ {
+ // Do nothing
+ }
+ else if (resolveType == .None)
emitData.mIncludedInResolveAll = false;
else
emitData.mIncludedInClassify = false;
@@ -6491,6 +6688,7 @@ namespace IDE.ui
emitData.mOnlyInResolveAll = resolveType == .None;
emitData.mIncludedInClassify = resolveType != .None;
emitData.mIncludedInResolveAll = resolveType == .None;
+ emitData.mIncludedInBuild = resolveType == null;
if (emitData.mAnchorIdx == -1)
{
@@ -6508,8 +6706,14 @@ namespace IDE.ui
{
curEmitData.mIncludedInResolveAll = true;
}
+ else if ((wantsBuildEmits) && (resolveType != null))
+ {
+ curEmitData.mIncludedInBuild |= emitData.mIncludedInBuild;
+ curEmitData.mIncludedInClassify |= emitData.mIncludedInClassify;
+ }
else
{
+ emitData.mIncludedInBuild |= curEmitData.mIncludedInBuild;
emitData.mIncludedInClassify |= curEmitData.mIncludedInClassify;
curEmitData = emitData;
}
@@ -6517,12 +6721,19 @@ namespace IDE.ui
continue;
}
+ if ((wantsBuildEmits) && (resolveType != null))
+ {
+ // Not included in the build emit data - just show as a marker
+ emitData.mStartLine = 0;
+ emitData.mEndLine = 0;
+ }
+
//Debug.WriteLine($" New emit AnchorIdx:{emitData.mAnchorIdx} AnchorId:{emitData.mAnchorId} CurTextVersion:{textVersion} FoundTextVersion:{foundTextVersion}");
data.mEmitData.Add(emitData);
continue;
}
- if (resolveType == .None)
+ if ((resolveType == null) || (resolveType == .None))
continue;
CollapseData collapseData;
@@ -6554,7 +6765,11 @@ namespace IDE.ui
for (var emitData in ref data.mEmitData)
{
- if (((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInResolveAll)) ||
+ if ((emitData.mIncludedInBuild) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build))
+ {
+ // Allow build-only markers to survive
+ }
+ else if (((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInResolveAll)) ||
((!emitData.mOnlyInResolveAll) && (!emitData.mIncludedInClassify)))
{
@emitData.RemoveFast();
diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf
index 2a7316d6..1112ce42 100644
--- a/IDE/src/ui/SourceViewPanel.bf
+++ b/IDE/src/ui/SourceViewPanel.bf
@@ -367,6 +367,7 @@ namespace IDE.ui
class QueuedCollapseData
{
public String mData = new .() ~ delete _;
+ public String mBuildData ~ delete _;
public int32 mTextVersion;
public IdSpan mCharIdSpan ~ _.Dispose();
public ResolveType mResolveType;
@@ -446,6 +447,7 @@ namespace IDE.ui
int32 mTicksSinceTextChanged;
int32 mErrorLookupTextIdx = -1;
LinePointerDrawData mLinePointerDrawData;
+ bool mIsDraggingLinePointer;
Point? mMousePos;
#if IDE_C_SUPPORT
public String mClangHoverErrorData ~ delete mClangHoverErrorData;
@@ -1262,6 +1264,9 @@ namespace IDE.ui
void FindEmbeds(ResolveParams resolveParams)
{
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler != .Resolve)
+ return;
+
HashSet foundEditData = scope .();
Dictionary remappedTypeNames = scope .();
@@ -1478,11 +1483,31 @@ namespace IDE.ui
var collapseData = bfCompiler.GetCollapseRegions(parser, resolvePassData, explicitEmitTypeNames, .. scope .());
+ String buildCollapseData = null;
+ if ((gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) && (!gApp.mBfBuildCompiler.IsPerformingBackgroundOperation()))
+ {
+ gApp.mBfBuildSystem.Lock(0);
+ var buildParser = gApp.mBfBuildSystem.GetParser(mProjectSource);
+ if (buildParser != null)
+ {
+ var buildResolvePassData = buildParser.CreateResolvePassData(.None);
+ defer delete buildResolvePassData;
+ buildCollapseData = gApp.mBfBuildCompiler.GetCollapseRegions(buildParser, buildResolvePassData, explicitEmitTypeNames, .. scope:: .());
+ }
+ else
+ {
+ buildCollapseData = "";
+ }
+ gApp.mBfBuildSystem.Unlock();
+ }
+
using (mMonitor.Enter())
{
DeleteAndNullify!(mQueuedCollapseData);
mQueuedCollapseData = new .();
mQueuedCollapseData.mData.Set(collapseData);
+ if (buildCollapseData != null)
+ mQueuedCollapseData.mBuildData = new String(buildCollapseData);
mQueuedCollapseData.mTextVersion = textVersion;
mQueuedCollapseData.mCharIdSpan = charIdSpan.Duplicate();
@@ -1524,13 +1549,13 @@ namespace IDE.ui
return;
//var compiler = ResolveCompiler;
- var char8Data = mEditWidget.Content.mData.mText;
- int char8Len = Math.Min(char8Data.Count, mEditWidget.Content.mData.mTextLength);
+ var charData = mEditWidget.Content.mData.mText;
+ int charLen = Math.Min(charData.Count, mEditWidget.Content.mData.mTextLength);
- char8[] chars = new char8[char8Len];
+ char8[] chars = new char8[charLen];
defer delete chars;
- for (int32 i = 0; i < char8Len; i++)
- chars[i] = (char8)char8Data[i].mChar;
+ for (int32 i = 0; i < charLen; i++)
+ chars[i] = (char8)charData[i].mChar;
String text = scope String();
text.Append(chars, 0, chars.Count);
@@ -1554,7 +1579,7 @@ namespace IDE.ui
parser.SetEmbedKind(mEmbedKind);
parser.Reduce(passInstance);
}
- parser.ClassifySource(char8Data, !mIsBeefSource);
+ parser.ClassifySource(charData, !mIsBeefSource);
mWantsParserCleanup = true;
}
@@ -2208,7 +2233,7 @@ namespace IDE.ui
{
parser.CreateClassifier(passInstance, resolvePassData, charData);
- if (resolveParams != null)
+ if ((resolveParams != null) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve))
{
for (var emitEmbedData in resolveParams.mEmitEmbeds)
{
@@ -2484,7 +2509,10 @@ namespace IDE.ui
int32 prevLine = mEditWidget.Content.CursorLineAndColumn.mLine;
mEditWidget.Content.mSelection = null;
- mEditWidget.Content.CursorTextPos = cursorIdx;
+
+ int wantCursorPos = Math.Min(mEditWidget.Content.mData.mTextLength - 1, cursorIdx);
+ if (wantCursorPos >= 0)
+ mEditWidget.Content.CursorTextPos = wantCursorPos;
mEditWidget.Content.CursorMoved();
mEditWidget.Content.EnsureCursorVisible(true, true);
mEditWidget.Content.mCursorImplicitlyMoved = true;
@@ -4476,6 +4504,8 @@ namespace IDE.ui
BreakpointCountMask = 0x7F,
Boomkmark = 0x80
}
+
+ static float sDrawLeftAdjust = GS!(12);
public override void Draw(Graphics g)
{
@@ -4505,7 +4535,6 @@ namespace IDE.ui
using (g.PushTranslate(0, mEditWidget.mY + mEditWidget.Content.Y + GS!(2)))
{
float editX = GetEditX();
- float leftAdjust = GS!(12);
float lineSpacing = ewc.mFont.GetLineSpacing();
int cursorLineNumber = mEditWidget.mEditWidgetContent.CursorLineAndColumn.mLine;
@@ -4623,7 +4652,7 @@ namespace IDE.ui
int breakpointCount = (.)(curLineFlags & .BreakpointCountMask);
curLineFlags++;
- float iconX = Math.Max(GS!(-2), mEditWidget.mX - GS!(24) - leftAdjust) + breakpointCount*-GS!(2);
+ float iconX = Math.Max(GS!(-2), mEditWidget.mX - GS!(24) - sDrawLeftAdjust) + breakpointCount*-GS!(2);
float iconY = 0 + ewc.mLineCoords[drawLineNum] + (lineSpacing - DarkTheme.sUnitSize + GS!(5)) / 2;
// Just leave last digit visible
@@ -4648,7 +4677,7 @@ namespace IDE.ui
continue;
//hadLineIcon[drawLineNum - lineStart] = true;
Image image = DarkTheme.sDarkTheme.GetImage(bookmark.mIsDisabled ? .IconBookmarkDisabled : .IconBookmark);
- g.Draw(image, Math.Max(GS!(-5), mEditWidget.mX - GS!(30) - leftAdjust),
+ g.Draw(image, Math.Max(GS!(-5), mEditWidget.mX - GS!(30) - sDrawLeftAdjust),
0 + bookmark.mLineNum * lineSpacing);
var curLineFlags = ref lineFlags[drawLineNum - lineStart];
@@ -4812,9 +4841,20 @@ namespace IDE.ui
{
mLinePointerDrawData.mUpdateCnt = gApp.mUpdateCnt;
mLinePointerDrawData.mDebuggerContinueIdx = gApp.mDebuggerContinueIdx;
- g.Draw(img, mEditWidget.mX - GS!(20) - leftAdjust,
+ g.Draw(img, mEditWidget.mX - GS!(20) - sDrawLeftAdjust,
0 + ewc.GetLineY(lineNum, 0));
}
+
+ if (mMousePos != null && mIsDraggingLinePointer)
+ {
+ int dragLineNum = GetLineAt(0, mMousePos.Value.y);
+ if (dragLineNum >= 0 && dragLineNum != lineNum)
+ {
+ using (g.PushColor(0x7FFFFFFF))
+ g.Draw(img, mEditWidget.mX - GS!(20) - sDrawLeftAdjust,
+ 0 + ewc.GetLineY(dragLineNum, 0));
+ }
+ }
}
}
}
@@ -6275,15 +6315,15 @@ namespace IDE.ui
emitEmbedView.mGenericMethodCombo?.mEditWidget.SetFocus();
}
- var sourceViewPanel = emitEmbedView.mSourceViewPanel;
+ var firstSourceViewPanel = emitEmbedView.mSourceViewPanel;
- var embedEWC = sourceViewPanel.mEditWidget.mEditWidgetContent;
+ var firstEmbedEWC = firstSourceViewPanel.mEditWidget.mEditWidgetContent;
- var prevCursorLineAndColumn = embedEWC.CursorLineAndColumn;
+ var prevCursorLineAndColumn = firstEmbedEWC.CursorLineAndColumn;
- var editData = sourceViewPanel.mEditWidget.mEditWidgetContent.mData;
+ var editData = firstSourceViewPanel.mEditWidget.mEditWidgetContent.mData;
if (editData.mTextLength == 0)
- DeleteAndNullify!(sourceViewPanel.mTrackedTextElementViewList);
+ DeleteAndNullify!(firstSourceViewPanel.mTrackedTextElementViewList);
delete editData.mText;
editData.mText = embed.mCharData;
@@ -6294,15 +6334,23 @@ namespace IDE.ui
editData.mNextCharId = 0;
editData.mTextIdData.Insert(0, editData.mTextLength, ref editData.mNextCharId);
- sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged();
- // We have a full classify now, FastClassify will just mess it up
- sourceViewPanel.mSkipFastClassify = true;
+ firstSourceViewPanel.mEmitRevision = embed.mRevision;
+ firstSourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true);
- if (prevCursorLineAndColumn.mLine >= embedEWC.GetLineCount())
- embedEWC.CursorLineAndColumn = .(embedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn);
-
- sourceViewPanel.mEmitRevision = embed.mRevision;
- sourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true);
+ for (var user in editData.mUsers)
+ {
+ if (var embedEWC = user as SourceEditWidgetContent)
+ {
+ var sourceViewPanel = embedEWC.mSourceViewPanel;
+
+ sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged();
+ // We have a full classify now, FastClassify will just mess it up
+ sourceViewPanel.mSkipFastClassify = true;
+
+ if (prevCursorLineAndColumn.mLine >= firstEmbedEWC.GetLineCount())
+ embedEWC.CursorLineAndColumn = .(firstEmbedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn);
+ }
+ }
}
}
}
@@ -6595,7 +6643,7 @@ namespace IDE.ui
}
if ((mTicksSinceTextChanged >= 60) && (mWantsSpellCheck))
{
- if (IsControllingEditData())
+ if ((IsControllingEditData()) && (mEmbedKind == .None))
StartSpellCheck();
mWantsSpellCheck = false;
}
@@ -6850,7 +6898,59 @@ namespace IDE.ui
using (mMonitor.Enter())
{
if (mQueuedCollapseData != null)
+ {
+ if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
+ {
+ if (mQueuedCollapseData.mBuildData != null)
+ {
+ bool foundData = false;
+
+ using (gApp.mMonitor.Enter())
+ {
+ var projectSourceCompileInstance = gApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, gApp.mWorkspace.HotCompileIdx);
+ if (projectSourceCompileInstance != null)
+ {
+ foundData = true;
+ ewc.ParseCollapseRegions(mQueuedCollapseData.mBuildData, mQueuedCollapseData.mTextVersion, ref projectSourceCompileInstance.mSourceCharIdData, null);
+
+ HashSet dataLoaded = scope .();
+
+ for (var embed in ewc.mEmbeds.Values)
+ {
+ if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed)
+ {
+ if (emitEmbed.mView != null)
+ {
+ if (dataLoaded.Add(emitEmbed.mView.mSourceViewPanel.mEditWidget.mEditWidgetContent.mData))
+ {
+ emitEmbed.mView.mSourceViewPanel.mSkipFastClassify = false;
+ emitEmbed.mView.mSourceViewPanel.Reload();
+ emitEmbed.mView.mSourceViewPanel.mWantsFastClassify = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!foundData)
+ {
+ for (var embed in ewc.mEmbeds.Values)
+ {
+ if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed)
+ {
+ if (emitEmbed.mView != null)
+ {
+ emitEmbed.mView.mSourceViewPanel.mEditWidget.mEditWidgetContent.ClearText();
+ }
+ }
+ }
+ }
+ }
+ }
+
ewc.ParseCollapseRegions(mQueuedCollapseData.mData, mQueuedCollapseData.mTextVersion, ref mQueuedCollapseData.mCharIdSpan, mQueuedCollapseData.mResolveType);
+ }
DeleteAndNullify!(mQueuedCollapseData);
}
@@ -6858,6 +6958,38 @@ namespace IDE.ui
// Process after mQueuedCollapseData so mCharIdSpan is still valid
ProcessDeferredResolveResults(0);
+
+#if !CLI
+ if (ewc.mCollapseDBDirty)
+ {
+ MemoryStream memStream = scope .();
+
+ String text = scope .();
+ mEditWidget.GetText(text);
+ var hash = MD5.Hash(.((uint8*)text.Ptr, text.Length));
+ memStream.Write(hash);
+
+ bool hadData = false;
+
+ for (var kv in ewc.mOrderedCollapseEntries)
+ {
+ if (kv.mIsOpen != kv.DefaultOpen)
+ {
+ hadData = true;
+ memStream.Write(kv.mAnchorIdx);
+ }
+ }
+
+ String filePath = scope .(mFilePath);
+ IDEUtils.MakeComparableFilePath(filePath);
+
+ if (!hadData)
+ gApp.mFileRecovery.DeleteDB(filePath);
+ else
+ gApp.mFileRecovery.SetDB(filePath, memStream.Memory);
+ ewc.mCollapseDBDirty = false;
+ }
+#endif
}
public override void UpdateF(float updatePct)
@@ -7070,7 +7202,7 @@ namespace IDE.ui
float GetEditX()
{
- if (!gApp.mSettings.mEditorSettings.mShowLineNumbers && (mEmbedKind == .None))
+ if ((!gApp.mSettings.mEditorSettings.mShowLineNumbers) || (mEmbedKind != .None))
return GS!(24);
var font = IDEApp.sApp.mTinyCodeFont;
@@ -7268,6 +7400,29 @@ namespace IDE.ui
}
}
+ public override void MouseUp(float x, float y, int32 btn)
+ {
+ base.MouseUp(x, y, btn);
+
+ if (mIsDraggingLinePointer)
+ {
+ mIsDraggingLinePointer = false;
+
+ float origX;
+ float origY;
+ RootToSelfTranslate(mWidgetWindow.mMouseDownX, mWidgetWindow.mMouseDownY, out origX, out origY);
+
+ int newLine = GetLineAt(0, y);
+ if (newLine >= 0 && newLine != GetLineAt(origX, origY))
+ {
+ gApp.mDebugger.SetNextStatement(false, mFilePath, (int)newLine, 0);
+
+ gApp.[Friend]PCChanged();
+ gApp.[Friend]DebuggerUnpaused();
+ }
+ }
+ }
+
public int GetLineAt(float x, float y)
{
if (x > mEditWidget.mX - GS!(4))
@@ -7321,8 +7476,9 @@ namespace IDE.ui
{
if ((x >= GS!(3)) && (x < mEditWidget.mX - GS!(14)))
{
+ int lineMouseDown = GetLineAt(origX, origY);
int lineClick = GetLineAt(x, y);
- if (lineClick >= 0)
+ if (lineClick >= 0 && lineMouseDown == lineClick)
{
ToggleBreakpointAt(lineClick, 0);
}
@@ -7351,6 +7507,37 @@ namespace IDE.ui
{
base.MouseMove(x, y);
mMousePos = .(x, y);
+
+ if (!mIsDraggingLinePointer && IDEApp.sApp.mExecutionPaused && gApp.mDebugger.mActiveCallStackIdx == 0 && mMouseFlags.HasFlag(.Left))
+ {
+ SourceEditWidgetContent ewc = (.)mEditWidget.Content;
+ Rect linePointerRect = .(
+ mEditWidget.mX - GS!(20) - sDrawLeftAdjust,
+ 0 + ewc.GetLineY(mLinePointerDrawData.mLine, 0),
+ GS!(15),
+ GS!(15)
+ );
+
+ float origX;
+ float origY;
+ RootToSelfTranslate(mWidgetWindow.mMouseDownX, mWidgetWindow.mMouseDownY, out origX, out origY);
+
+ if (linePointerRect.Contains(origX, origY - mEditWidget.mY - mEditWidget.Content.Y - GS!(3)))
+ {
+ mIsDraggingLinePointer = true;
+ }
+ }
+ else if (mIsDraggingLinePointer)
+ {
+ SourceEditWidgetContent ewc = (.)mEditWidget.Content;
+ float linePos = ewc.GetLineY(GetLineAt(0, mMousePos.Value.y), 0);
+ Rect visibleRange = mEditWidget.GetVisibleContentRange();
+
+ if (visibleRange.Top > linePos)
+ mEditWidget.mVertScrollbar.ScrollTo(linePos);
+ else if (visibleRange.Bottom - mEditWidget.mHorzScrollbar.mHeight < linePos)
+ mEditWidget.mVertScrollbar.ScrollTo(linePos - visibleRange.mHeight + ewc.GetLineHeight(0));
+ }
}
public override void DrawAll(Graphics g)
diff --git a/IDE/src/ui/TargetedPropertiesDialog.bf b/IDE/src/ui/TargetedPropertiesDialog.bf
index 534b86b5..c590a50c 100644
--- a/IDE/src/ui/TargetedPropertiesDialog.bf
+++ b/IDE/src/ui/TargetedPropertiesDialog.bf
@@ -384,6 +384,8 @@ namespace IDE.ui
protected void ConfigDeleted(String configName)
{
+ int32 category = mPropPage.mCategoryType;
+
bool currentChanged = false;
int idx = mConfigNames.IndexOf(configName);
if (idx != -1)
@@ -422,7 +424,17 @@ namespace IDE.ui
}
if (currentChanged)
- SelectConfig(mConfigNames);
+ {
+ mPropPage = null;
+ SelectConfig(mConfigNames, category);
+ }
+
+ if ((mActiveConfigName == configName) && (!mConfigNames.IsEmpty))
+ {
+ var newConfigName = mConfigNames[0];
+ gApp.mMainFrame.mStatusBar.SelectConfig(newConfigName);
+ mActiveConfigName.Set(newConfigName);
+ }
}
protected void ConfigRenamed(String from, String to)
@@ -761,7 +773,7 @@ namespace IDE.ui
ShowPropPage(categoryType);
}
- protected void SelectConfig(List configNames)
+ protected void SelectConfig(List configNames, int32 category = -1)
{
if (configNames != mConfigNames)
{
@@ -770,7 +782,7 @@ namespace IDE.ui
mConfigNames.Add(configName);
}
if (mConfigNames.Count == 1)
- SelectConfig(mConfigNames[0]);
+ SelectConfig(mConfigNames[0], category);
else
{
mConfigComboBox.Label = "";
@@ -795,13 +807,16 @@ namespace IDE.ui
}
}
- protected void SelectConfig(String configName)
+ protected void SelectConfig(String configName, int32 category = -1)
{
+ var category;
+ if (category == -1)
+ category = mPropPage.mCategoryType;
var newConfigName = new String(configName);
ClearAndDeleteItems(mConfigNames);
mConfigNames.Add(newConfigName);
mConfigComboBox.Label = newConfigName;
- ShowPropPage(mPropPage.mCategoryType);
+ ShowPropPage(category);
}
protected void SelectPlatform(String platformName, int32 category = -1)
diff --git a/IDE/src/ui/WatchPanel.bf b/IDE/src/ui/WatchPanel.bf
index cd03670d..f4de9e67 100644
--- a/IDE/src/ui/WatchPanel.bf
+++ b/IDE/src/ui/WatchPanel.bf
@@ -2752,20 +2752,29 @@ namespace IDE.ui
}
else if (memberVals0 == ":addrs")
{
- WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
- String.NewOrSet!(memberItem.mWatchSeriesInfo.mAddrs, memberVals[1]);
- memberItem.mWatchSeriesInfo.mAddrsEntrySize = 1;
+ if (memberCount > 0)
+ {
+ WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
+ String.NewOrSet!(memberItem.mWatchSeriesInfo.mAddrs, memberVals[1]);
+ memberItem.mWatchSeriesInfo.mAddrsEntrySize = 1;
+ }
}
else if (memberVals0 == ":addrsEntrySize")
{
- int32 addrsEntrySize = int32.Parse(scope String(memberVals[1]));
- WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
- memberItem.mWatchSeriesInfo.mAddrsEntrySize = addrsEntrySize;
+ if (memberCount > 0)
+ {
+ int32 addrsEntrySize = int32.Parse(scope String(memberVals[1]));
+ WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
+ memberItem.mWatchSeriesInfo.mAddrsEntrySize = addrsEntrySize;
+ }
}
else if (memberVals0 == ":continuation")
{
- WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
- String.NewOrSet!(memberItem.mWatchSeriesInfo.mContinuationData, memberVals[1]);
+ if (memberCount > 0)
+ {
+ WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
+ String.NewOrSet!(memberItem.mWatchSeriesInfo.mContinuationData, memberVals[1]);
+ }
}
else if (memberVals0 == ":action")
{
diff --git a/IDEHelper/Backend/BeCOFFObject.cpp b/IDEHelper/Backend/BeCOFFObject.cpp
index e01f4a0b..6a7a8354 100644
--- a/IDEHelper/Backend/BeCOFFObject.cpp
+++ b/IDEHelper/Backend/BeCOFFObject.cpp
@@ -74,15 +74,15 @@ void BeInlineLineBuilder::Update(BeDbgCodeEmission* codeEmission)
}
void BeInlineLineBuilder::Start(BeDbgCodeEmission* codeEmission)
-{
+{
//mCurLine = codeEmission->mDbgLoc->mDbgInlinedAt->mLine;
int lineOfs = codeEmission->mDbgLoc->mLine - mCurLine;
int codeOfs = codeEmission->mPos - mCurCodePos;
-
+
auto usingFile = codeEmission->mDbgLoc->mDbgInlinedAt->GetDbgFile();
auto wantFile = codeEmission->mDbgLoc->GetDbgFile();
-
+
mData.push_back(CodeViewInfo::BA_OP_ChangeLineOffset);
WriteSigned(lineOfs);
@@ -93,10 +93,10 @@ void BeInlineLineBuilder::Start(BeDbgCodeEmission* codeEmission)
}*/
mData.push_back(CodeViewInfo::BA_OP_ChangeCodeOffset);
- Compress(codeOfs);
+ Compress(codeOfs);
mCurLine = codeEmission->mDbgLoc->mLine;
- mCurCodePos = codeEmission->mPos;
+ mCurCodePos = codeEmission->mPos;
/*mData.push_back(CodeViewInfo::BA_OP_ChangeLineOffset);
WriteSigned(-mStartDbgLoc->mDbgInlinedAt->mLine - 1);
@@ -122,14 +122,14 @@ void BeInlineLineBuilder::End(BeDbgCodeEmission* codeEmission)
BeCOFFObject::BeCOFFObject()
{
mWriteToLib = false;
- mBSSPos = 0;
+ mBSSPos = 0;
mCurTagId = 0x1000;
mCurStringId = 0;
mCurJumpTableIdx = 0;
mBeModule = NULL;
mTTagStartPos = -1;
mSTagStartPos = -1;
- mSectionStartPos = -1;
+ mSectionStartPos = -1;
mTypesLocked = false;
mTimestamp = 0;
mPerfManager = NULL;
@@ -178,11 +178,11 @@ void BeCOFFObject::ToString(BeMDNode* mdNode, String& str)
else
{
BF_FATAL("err");
- }
+ }
}
int BeCOFFObject::GetCVRegNum(X64CPURegister reg, int bits)
-{
+{
if (bits == 8)
{
switch (reg)
@@ -361,7 +361,7 @@ int BeCOFFObject::GetCVRegNum(X64CPURegister reg, int bits)
case X64Reg_XMM72: return CV_AMD64_XMM7_2;
case X64Reg_XMM73: return CV_AMD64_XMM7_3;
}
-
+
return 0;
}
@@ -400,7 +400,7 @@ void BeCOFFObject::DbgEncodeString(DynMemStream& memStream, const StringImpl& st
}
void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc)
-{
+{
if (dbgFunc->mCvTypeId != -1)
return;
@@ -435,12 +435,12 @@ void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc)
for (auto paramType : dbgFunc->mType->mParams)
DbgGetTypeId(paramType);
- bool hasThis = dbgFunc->HasThis();
+ bool hasThis = dbgFunc->HasThis();
/*auto argListResultPair = mArgListSet.insert(dbgFunc);
if (!argListResultPair.second)
- {
- dbgFunc->mCvArgListId = (*argListResultPair.first)->mCvArgListId;
+ {
+ dbgFunc->mCvArgListId = (*argListResultPair.first)->mCvArgListId;
}
else*/
@@ -457,12 +457,12 @@ void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc)
outT.Write((int32)(dbgFunc->mType->mParams.size() - (hasThis ? 1 : 0)));
for (int paramIdx = hasThis ? 1 : 0; paramIdx < (int)dbgFunc->mType->mParams.size(); paramIdx++)
{
- BeDbgType* dbgType = dbgFunc->mType->mParams[paramIdx];
+ BeDbgType* dbgType = dbgFunc->mType->mParams[paramIdx];
outT.Write(DbgGetTypeId(dbgType));
}
DbgTEndTag();
}
-
+
dbgFunc->mCvTypeId = mCurTagId++;
DbgTStartTag();
@@ -504,7 +504,7 @@ void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc)
void BeCOFFObject::DbgMakeFunc(BeDbgFunction* dbgFunc)
{
auto& outT = mDebugTSect.mData;
- BF_ASSERT(dbgFunc->mCvTypeId == -1);
+ BF_ASSERT(dbgFunc->mCvTypeId == -1);
DbgMakeFuncType(dbgFunc);
@@ -534,7 +534,7 @@ void BeCOFFObject::DbgMakeFunc(BeDbgFunction* dbgFunc)
void BeCOFFObject::DbgTAlign()
{
int curPos = mDebugTSect.mData.GetPos();
- // Perform alignment
+ // Perform alignment
int addPadding = (4 - (curPos & 3)) % 4;
while (addPadding > 0)
{
@@ -544,17 +544,17 @@ void BeCOFFObject::DbgTAlign()
}
void BeCOFFObject::DbgTStartTag()
-{
+{
BF_ASSERT(mTTagStartPos == -1);
mTTagStartPos = mDebugTSect.mData.GetPos();
mDebugTSect.mData.Write((int16)0);
}
void BeCOFFObject::DbgTEndTag()
-{
+{
BF_ASSERT(mTTagStartPos != -1);
DbgTAlign();
- int tagSize = mDebugTSect.mData.GetPos() - mTTagStartPos;
+ int tagSize = mDebugTSect.mData.GetPos() - mTTagStartPos;
BF_ASSERT(tagSize <= 0xFFFF);
*((int16*)&mDebugTSect.mData.mData[mTTagStartPos]) = (int16)(tagSize - 2);
mTTagStartPos = -1;
@@ -576,20 +576,20 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
auto& outT = mDebugTSect.mData;
auto structType = BeValueDynCast(dbgType);
-
+
if (structType != NULL)
{
- //lfClass classInfo;
+ //lfClass classInfo;
//BF_CLEAR_VALUE(classInfo);
- //classInfo.leaf = LF_STRUCTURE;
-
- CV_prop_t structProp = { 0 };
+ //classInfo.leaf = LF_STRUCTURE;
+
+ CV_prop_t structProp = { 0 };
if (structType->mAlign == 1)
structProp.packed = true;
int fieldListTag = 0;
- int memberCount = 0;
+ int memberCount = 0;
if (doDefine)
{
// Pass over all needed types first to make sure we generate any forward references we'll need
@@ -598,18 +598,18 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
DbgGetTypeId(structType->mDerivedFrom);
for (auto member : structType->mMembers)
{
- auto type = member->mType;
+ auto type = member->mType;
DbgGetTypeId(type);
}
for (auto func : structType->mMethods)
- DbgMakeFuncType(func);
+ DbgMakeFuncType(func);
fieldListTag = mCurTagId++;
//int tagStartPos = -1;
DbgTStartTag();
outT.Write((int16)LF_FIELDLIST);
-
+
if (structType->mDerivedFrom != NULL)
{
outT.Write((int16)LF_BCLASS);
@@ -629,7 +629,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
int extFieldListTag = mCurTagId++;
outT.Write((int16)LF_INDEX);
- outT.Write((int16)0); // Padding
+ outT.Write((int16)0); // Padding
outT.Write((int32)extFieldListTag); // Padding
DbgTEndTag();
@@ -639,7 +639,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
};
for (auto member : structType->mMembers)
- {
+ {
_CheckFieldOverflow();
if (member->mIsStatic)
@@ -657,7 +657,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
outT.Write(*(int16*)&attr);
outT.Write(DbgGetTypeId(member->mType));
if (!member->mIsStatic)
- DbgEncodeConstant(outT, member->mOffset);
+ DbgEncodeConstant(outT, member->mOffset);
DbgEncodeString(outT, member->mName);
memberCount++;
DbgTAlign();
@@ -706,15 +706,15 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
outT.Write((int32)0); //derivedfrom - should we ever set this?
outT.Write((int32)0); //vshape
if (doDefine)
- DbgEncodeConstant(outT, structType->mSize);
+ DbgEncodeConstant(outT, structType->mSize);
else
DbgEncodeConstant(outT, 0);
String fullName;
- ToString(structType, fullName);
+ ToString(structType, fullName);
- DbgEncodeString(outT, fullName);
+ DbgEncodeString(outT, fullName);
DbgTEndTag(); // LF_STRUCTURE
-
+
if (doDefine)
dbgType->mCvDefTypeId = mCurTagId++;
else
@@ -753,9 +753,9 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
return dbgType->mCvDefTypeId;
}
-
+
return dbgType->mCvDeclTypeId;
- }
+ }
else if (auto enumType = BeValueDynCast(dbgType))
{
int fieldListId = 0;
@@ -766,14 +766,14 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
//int tagStartPos = -1;
DbgTStartTag();
outT.Write((int16)LF_FIELDLIST);
-
+
for (auto member : enumType->mMembers)
- {
+ {
outT.Write((int16)LF_ENUMERATE);
CV_fldattr_t attr = { 0 };
attr.access = 3; // public
- outT.Write(*(int16*)&attr);
+ outT.Write(*(int16*)&attr);
DbgEncodeConstant(outT, member->mValue);
DbgEncodeString(outT, member->mName);
DbgTAlign();
@@ -789,13 +789,13 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
//int32 elementId = DbgGetTypeId(enumType->mElementType);
- CV_prop_t structProp = { 0 };
+ CV_prop_t structProp = { 0 };
if (!enumType->mIsFullyDefined)
structProp.fwdref = 1;
DbgTStartTag();
outT.Write((int16)LF_ENUM);
- outT.Write((int16)enumType->mMembers.size());
+ outT.Write((int16)enumType->mMembers.size());
outT.Write(*(int16*)&structProp);
outT.Write(elementId);
outT.Write((int32)fieldListId);
@@ -833,7 +833,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
break;
case llvm::dwarf::DW_ATE_float:
switch (dbgBasicType->mSize)
- {
+ {
case 4: dbgBasicType->mCvDefTypeId = T_REAL32; break;
case 8: dbgBasicType->mCvDefTypeId = T_REAL64; break;
}
@@ -914,10 +914,10 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
int32 elementId = DbgGetTypeId(ptrType->mElement);
DbgTStartTag();
- outT.Write((int16)LF_POINTER);
+ outT.Write((int16)LF_POINTER);
outT.Write(elementId);
outT.Write(*(int32*)&attr);
- DbgTEndTag();
+ DbgTEndTag();
dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
return dbgType->mCvDefTypeId;
}
@@ -930,23 +930,23 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
int32 elementId = DbgGetTypeId(refType->mElement);
DbgTStartTag();
- outT.Write((int16)LF_POINTER);
+ outT.Write((int16)LF_POINTER);
outT.Write(elementId);
- outT.Write(*(int32*)&attr);
+ outT.Write(*(int32*)&attr);
DbgTEndTag();
dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
return dbgType->mCvDefTypeId;
}
else if (auto constType = BeValueDynCast(dbgType))
- {
- CV_modifier_t attr = { 0 };
+ {
+ CV_modifier_t attr = { 0 };
attr.MOD_const = 1;
int32 elementId = DbgGetTypeId(BeValueDynCast(constType->mElement));
DbgTStartTag();
- outT.Write((int16)LF_MODIFIER);
+ outT.Write((int16)LF_MODIFIER);
outT.Write(elementId);
- outT.Write(*(int16*)&attr);
+ outT.Write(*(int16*)&attr);
DbgTEndTag();
dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
return dbgType->mCvDefTypeId;
@@ -958,7 +958,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
else if (auto arrayType = BeValueDynCast(dbgType))
{
int32 elementId = DbgGetTypeId(arrayType->mElement);
-
+
DbgTStartTag();
outT.Write((int16)LF_ARRAY);
outT.Write((int32)elementId);
@@ -968,11 +968,10 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
DbgTEndTag();
dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
return dbgType->mCvDefTypeId;
- }
+ }
else
BF_FATAL("NotImpl");
-
BF_FATAL("Invalid type");
return -1;
}
@@ -986,12 +985,12 @@ void BeCOFFObject::DbgGenerateTypeInfo()
outT.Write((int)CV_SIGNATURE_C13);
for (auto mdNode : mBeModule->mDbgModule->mTypes)
- {
+ {
bool defineType = true;
if (auto dbgStructType = BeValueDynCast(mdNode))
{
if (!dbgStructType->mIsFullyDefined)
- defineType = false;
+ defineType = false;
}
if (defineType)
@@ -1010,8 +1009,8 @@ void BeCOFFObject::DbgGenerateTypeInfo()
void BeCOFFObject::DbgStartSection(int sectionNum)
{
- auto& outS = mDebugSSect.mData;
- BF_ASSERT(mSectionStartPos == -1);
+ auto& outS = mDebugSSect.mData;
+ BF_ASSERT(mSectionStartPos == -1);
outS.Write((int32)sectionNum);
outS.Write(0); // Temporary - size
mSectionStartPos = outS.GetPos();
@@ -1019,9 +1018,9 @@ void BeCOFFObject::DbgStartSection(int sectionNum)
void BeCOFFObject::DbgEndSection()
{
- auto& outS = mDebugSSect.mData;
- int totalLen = outS.GetPos() - mSectionStartPos;
- *((int32*)&outS.mData[mSectionStartPos - 4]) = totalLen;
+ auto& outS = mDebugSSect.mData;
+ int totalLen = outS.GetPos() - mSectionStartPos;
+ *((int32*)&outS.mData[mSectionStartPos - 4]) = totalLen;
mSectionStartPos = -1;
while ((outS.GetPos() & 3) != 0)
outS.Write((uint8)0);
@@ -1030,12 +1029,12 @@ void BeCOFFObject::DbgEndSection()
void BeCOFFObject::DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar, const BeDbgVariableLoc& varLoc, int offset, int range)
{
BF_ASSERT(range >= 0);
-
+
auto funcSym = GetSymbol(dbgFunc->mValue);
auto varType = BeValueDynCast(dbgVar->mType);
- auto& outS = mDebugSSect.mData;
+ auto& outS = mDebugSSect.mData;
if (varLoc.mKind == BeDbgVariableLoc::Kind_SymbolAddr)
{
BF_FATAL("Not supported");
@@ -1079,10 +1078,9 @@ void BeCOFFObject::DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* db
reloc.mSymTableIdx = funcSym->mIdx;
mDebugSSect.mRelocs.push_back(reloc);
outS.Write((int16)0); // section
- outS.Write((int16)range); // Range
+ outS.Write((int16)range); // Range
}
-
void BeCOFFObject::DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array& emissions, int blockStartPos, int emissionStartIdx, int lineCount)
{
auto& outS = mDebugSSect.mData;
@@ -1111,7 +1109,7 @@ void BeCOFFObject::DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array 0)
{
@@ -1137,23 +1135,23 @@ void BeCOFFObject::DbgSEndTag()
}
void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar)
-{
+{
auto varType = BeValueDynCast(dbgVar->mType);
// CodeView only allows 16-bit lengths, so we need to split ranges for very long spans
if (dbgVar->mDeclEnd - dbgVar->mDeclStart > 0xFFFF)
- {
+ {
int splitPos = dbgVar->mDeclStart + 0xFFFF;
BeDbgVariable varStart = *dbgVar;
varStart.mDeclEnd = splitPos;
Array* startArrs[2] = { &varStart.mSavedRanges, &varStart.mGaps };
for (auto& arr : startArrs)
- {
+ {
for (int arrIdx = 0; arrIdx < (int)arr->size(); arrIdx++)
{
auto& gap = (*arr)[arrIdx];
-
+
int gapStart = gap.mOffset;
int gapEnd = gap.mOffset + gap.mLength;
@@ -1186,17 +1184,17 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV
{
auto& gap = (*arr)[arrIdx];
- int gapStart = gap.mOffset;
+ int gapStart = gap.mOffset;
if (gapStart < splitPos)
gapStart = splitPos;
if (gap.mLength == -1)
- {
+ {
gap.mOffset = gapStart;
continue;
}
- int gapEnd = gap.mOffset + gap.mLength;
+ int gapEnd = gap.mOffset + gap.mLength;
if (gapEnd < splitPos)
gapEnd = splitPos;
@@ -1229,13 +1227,13 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV
outS.Write(*(int16*)&flags);
bool isConst = false;
- String varName = dbgVar->mName;
+ String varName = dbgVar->mName;
bool isGlobal = false;
//
{
auto checkVal = dbgVar->mValue;
-
+
if (auto beCast = BeValueDynCast(checkVal))
checkVal = beCast->mTarget;
if (auto beGlobal = BeValueDynCast(checkVal))
@@ -1278,8 +1276,8 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV
{
declEnd = dbgFunc->mCodeLen;
if ((dbgVar->mGaps.size() == 1) && (dbgVar->mGaps[0].mOffset == dbgVar->mDeclStart) && (dbgVar->mGaps[0].mLength == -1) && (!isConst))
- {
- // Variable not used
+ {
+ // Variable not used
declEnd = dbgVar->mDeclStart;
}
}
@@ -1294,7 +1292,7 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV
continue;
if (gap.mLength == -1)
- {
+ {
// Not a real gap, and not an unused variable indicator
if (gap.mOffset > dbgVar->mDeclStart)
continue;
@@ -1348,7 +1346,7 @@ void BeCOFFObject::DbgOutputLocalVars(BeInlineLineBuilder* curInlineBuilder, BeD
{
auto& outS = mDebugSSect.mData;
for (auto dbgVar : curInlineBuilder->mVariables)
- {
+ {
if (dbgVar == NULL)
continue;
DbgOutputLocalVar(dbgFunc, dbgVar);
@@ -1362,15 +1360,15 @@ void BeCOFFObject::DbgGenerateModuleInfo()
auto& outS = mDebugSSect.mData;
outS.Write((int)CV_SIGNATURE_C13);
-
+
Array fileDataPositions;
Array inlinees;
-
+
// Funcs
for (auto dbgFunc : mBeModule->mDbgModule->mFuncs)
{
if (dbgFunc->mValue == NULL)
- continue;
+ continue;
if (dbgFunc->mCvFuncId == -1)
continue;
@@ -1380,9 +1378,9 @@ void BeCOFFObject::DbgGenerateModuleInfo()
auto funcSym = GetSymbol(dbgFunc->mValue, false);
if (funcSym == NULL)
continue;
-
+
DbgStartSection(DEBUG_S_SYMBOLS);
-
+
DbgSStartTag();
if (dbgFunc->mValue->mLinkageType == BfIRLinkageType_Internal)
outS.Write((int16)S_LPROC32_ID);
@@ -1394,7 +1392,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
outS.Write((int32)BF_MAX(dbgFunc->mCodeLen, 0)); // CodeSize
outS.Write((int32)0); // DbgStart
outS.Write((int32)0); // DbgEnd
- outS.Write(dbgFunc->mCvFuncId);
+ outS.Write(dbgFunc->mCvFuncId);
BeMCRelocation reloc;
reloc.mKind = BeMCRelocationKind_SECREL;
@@ -1402,7 +1400,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
reloc.mSymTableIdx = funcSym->mIdx;
mDebugSSect.mRelocs.push_back(reloc);
outS.Write((int32)0); // off
-
+
reloc.mKind = BeMCRelocationKind_SECTION;
reloc.mOffset = outS.GetPos();
reloc.mSymTableIdx = funcSym->mIdx;
@@ -1420,7 +1418,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
fullName += "::";
fullName += dbgFunc->mName;
DbgEncodeString(outS, fullName);
- DbgSEndTag();
+ DbgSEndTag();
BeInlineLineBuilder* curInlineBuilder = NULL;
BeDbgLoc* curDbgLoc = NULL;
@@ -1437,28 +1435,28 @@ void BeCOFFObject::DbgGenerateModuleInfo()
if (curDbgLoc != newDbgLoc)
{
curDbgLoc = newDbgLoc;
- int newInlineDepth = newDbgLoc->GetInlineDepth();
+ int newInlineDepth = newDbgLoc->GetInlineDepth();
int curInlineDepth = 0;
if (curInlineBuilder != NULL)
curInlineDepth = curInlineBuilder->mStartDbgLoc->GetInlineDepth();
-
+
int depthMatch = 0;
if (curInlineBuilder != NULL)
- depthMatch = curDbgLoc->GetInlineMatchDepth(curInlineBuilder->mStartDbgLoc);
+ depthMatch = curDbgLoc->GetInlineMatchDepth(curInlineBuilder->mStartDbgLoc);
while (curInlineDepth > depthMatch)
- {
+ {
curInlineBuilder->End(&codeEmission);
inlineStack.pop_back();
if (inlineStack.empty())
curInlineBuilder = NULL;
else
- curInlineBuilder = inlineStack.back();
+ curInlineBuilder = inlineStack.back();
curInlineDepth--;
}
// Check for new inlines
while (newInlineDepth > curInlineDepth)
- {
+ {
auto inlineBuilder = inlineBuilders.Alloc();
// If we add more than one inline depth at a time then we need to set startDbgLoc appropriately
int inlineIdx = newInlineDepth - curInlineDepth - 2;
@@ -1472,7 +1470,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
inlinees.Add(dbgFunc);
inlineBuilder->mCurLine = dbgFunc->mLine;
- inlineBuilder->Start(&codeEmission);
+ inlineBuilder->Start(&codeEmission);
curInlineBuilder = inlineBuilder;
inlineStack.push_back(curInlineBuilder);
curInlineDepth++;
@@ -1482,18 +1480,18 @@ void BeCOFFObject::DbgGenerateModuleInfo()
}
if (curInlineBuilder != NULL)
- curInlineBuilder->Update(&codeEmission);
- }
+ curInlineBuilder->Update(&codeEmission);
+ }
}
BF_ASSERT(inlineStack.empty());
for (auto dbgVar : dbgFunc->mVariables)
{
- if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL))
+ if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL))
continue;
if (dbgVar->mDeclDbgLoc->mDbgInlinedAt == NULL)
continue;
-
+
BeInlineLineBuilder* inlineBuilder = NULL;
if (inlineMap.TryGetValue(dbgVar->mDeclDbgLoc->mDbgInlinedAt, &inlineBuilder))
{
@@ -1504,19 +1502,19 @@ void BeCOFFObject::DbgGenerateModuleInfo()
// Emit inlines and variables
int inlineBuilderIdx = 0;
-
+
curInlineBuilder = NULL;
-
+
for (auto dbgVar : dbgFunc->mVariables)
- {
- if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL))
+ {
+ if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL))
continue;
if (dbgVar->mDeclDbgLoc->mDbgInlinedAt == NULL)
DbgOutputLocalVar(dbgFunc, dbgVar);
}
while ((inlineBuilderIdx < (int)inlineBuilders.size()) || (curInlineBuilder != NULL) /*|| (varIdx < (int)dbgFunc->mVariables.size())*/)
- {
+ {
BeInlineLineBuilder* newInlineBuilder = NULL;
int curInlineDepth = 0;
@@ -1549,7 +1547,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
if (inlineStack.empty())
curInlineBuilder = NULL;
else
- curInlineBuilder = inlineStack.back();
+ curInlineBuilder = inlineStack.back();
}
if (newInlineDepth > curInlineDepth)
@@ -1562,7 +1560,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
auto inlinedDbgFunc = newInlineBuilder->mStartDbgLoc->GetDbgFunc();
if (inlinedDbgFunc->mCvFuncId == -1)
DbgMakeFunc(inlinedDbgFunc);
- outS.Write(inlinedDbgFunc->mCvFuncId);
+ outS.Write(inlinedDbgFunc->mCvFuncId);
outS.Write(&newInlineBuilder->mData[0], (int)newInlineBuilder->mData.size());
DbgSEndTag();
newInlineDepth++;
@@ -1575,8 +1573,8 @@ void BeCOFFObject::DbgGenerateModuleInfo()
// This can fail if an inlined method is not emitted contiguously, or if multiple copies of the same method
// get inlined at exactly the same DbgLoc -- which isn't possible in Beef
//BF_ASSERT(curInlineBuilder == newInlineBuilder);
- }
-
+ }
+
DbgSStartTag();
outS.Write((int16)S_PROC_ID_END);
DbgSEndTag();
@@ -1611,21 +1609,21 @@ void BeCOFFObject::DbgGenerateModuleInfo()
curDbgLoc = NULL;
BeDbgFile* curFile = NULL;
- int lastBlockStartPos = -1;
- int lineCount = 0;
+ int lastBlockStartPos = -1;
+ int lineCount = 0;
Array emissions;
- emissions.Reserve(dbgFunc->mEmissions.size());
+ emissions.Reserve(dbgFunc->mEmissions.size());
for (int emissionIdx = 0; emissionIdx < (int)dbgFunc->mEmissions.size(); emissionIdx++)
{
auto& codeEmission = dbgFunc->mEmissions[emissionIdx];
auto rootDbgLoc = codeEmission.mDbgLoc->GetRoot();
-
+
bool doEmission = true;
if (!emissions.empty())
{
if (rootDbgLoc == emissions.back().mDbgLoc)
- doEmission = false;
+ doEmission = false;
}
if (doEmission)
@@ -1636,7 +1634,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
emissions.push_back(newEmission);
}
}
-
+
///
{
int fileDataPos = 0;
@@ -1656,7 +1654,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
for (int emissionIdx = 0; emissionIdx < (int)emissions.size(); emissionIdx++)
{
auto& codeEmission = emissions[emissionIdx];
-
+
auto dbgLoc = codeEmission.mDbgLoc;
BeDbgFile* dbgFile = dbgLoc->GetDbgFile();
@@ -1669,9 +1667,9 @@ void BeCOFFObject::DbgGenerateModuleInfo()
emissionStartIdx = emissionIdx;
}
- curDbgLoc = dbgLoc;
+ curDbgLoc = dbgLoc;
curDbgFile = dbgFile;
-
+
lastBlockStartPos = outS.GetPos();
outS.Write((int32)fileDataPositions[dbgFile->mIdx]);
outS.Write((int32)0); // placeholder nLines
@@ -1691,29 +1689,29 @@ void BeCOFFObject::DbgGenerateModuleInfo()
if (curDbgLoc != NULL)
DbgEndLineBlock(dbgFunc, emissions, lastBlockStartPos, emissionStartIdx, lineCount);
DbgEndSection(); // DEBUG_S_LINES
- }
+ }
if (!inlinees.empty())
- {
+ {
DbgStartSection(DEBUG_S_INLINEELINES);
outS.Write((int32)0); // Lines type
for (auto inlinedDbgFunc : inlinees)
- {
- BF_ASSERT(inlinedDbgFunc->mCvFuncId != -1);
+ {
+ BF_ASSERT(inlinedDbgFunc->mCvFuncId != -1);
outS.Write(inlinedDbgFunc->mCvFuncId);
-
+
auto dbgFile = inlinedDbgFunc->mFile;
outS.Write((int32)fileDataPositions[dbgFile->mIdx]);
outS.Write((int32)inlinedDbgFunc->mLine + 1);
}
DbgEndSection();
- }
+ }
- // Global variables
+ // Global variables
{
- bool startedSymbols = false;
+ bool startedSymbols = false;
for (auto dbgGlobalVar : mBeModule->mDbgModule->mGlobalVariables)
- {
+ {
auto gvSym = GetSymbol(dbgGlobalVar->mValue);
if (gvSym == NULL)
{
@@ -1722,24 +1720,24 @@ void BeCOFFObject::DbgGenerateModuleInfo()
}
if (!startedSymbols)
- {
+ {
DbgStartSection(DEBUG_S_SYMBOLS);
startedSymbols = true;
}
DbgSStartTag();
bool isTLS = false;
- if (auto beGlobalVar = BeValueDynCast(dbgGlobalVar->mValue))
+ if (auto beGlobalVar = BeValueDynCast(dbgGlobalVar->mValue))
isTLS = beGlobalVar->mIsTLS;
-
+
if (isTLS)
outS.Write(dbgGlobalVar->mIsLocalToUnit ? (int16)S_LTHREAD32 : (int16)S_GTHREAD32);
else
outS.Write(dbgGlobalVar->mIsLocalToUnit ? (int16)S_LDATA32 : (int16)S_GDATA32);
-
+
outS.Write(DbgGetTypeId(BeValueDynCast(dbgGlobalVar->mType)));
- BF_ASSERT(dbgGlobalVar->mValue != NULL);
+ BF_ASSERT(dbgGlobalVar->mValue != NULL);
BeMCRelocation reloc;
reloc.mKind = BeMCRelocationKind_SECREL;
@@ -1761,7 +1759,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
if (startedSymbols)
DbgEndSection(); // DEBUG_S_SYMBOLS
- }
+ }
bool startedUDT = false;
for (auto dbgType : mBeModule->mDbgModule->mTypes)
@@ -1798,7 +1796,7 @@ void BeCOFFObject::DbgGenerateModuleInfo()
if (dbgFile->mMD5Hash.IsZero())
{
- outS.Write((int32)0); // hashLen, hashType, padding
+ outS.Write((int32)0); // hashLen, hashType, padding
}
else
{
@@ -1838,8 +1836,8 @@ void BeCOFFObject::AlignConst(BeCOFFSection& sect, BeConstant* constVal)
}
void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal)
-{
- auto beType = constVal->GetType();
+{
+ auto beType = constVal->GetType();
if (auto globalVar = BeValueDynCast(constVal))
{
auto sym = GetSymbol(globalVar);
@@ -1892,7 +1890,7 @@ void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal)
}
else
BF_FATAL("Invalid StructConst type");
- }
+ }
else if (auto constStr = BeValueDynCast(constVal))
{
sect.mData.Write((void*)constStr->mString.c_str(), (int)constStr->mString.length() + 1);
@@ -1905,8 +1903,8 @@ void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal)
{
if (auto globalVar = BeValueDynCast(constGep->mTarget))
{
- BF_ASSERT(constGep->mIdx0 == 0);
-
+ BF_ASSERT(constGep->mIdx0 == 0);
+
int64 dataOfs = 0;
if (globalVar->mType->mTypeCode == BeTypeCode_Struct)
{
@@ -1944,7 +1942,7 @@ void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal)
else if (beType->IsComposite())
{
BF_ASSERT(constVal->mInt64 == 0);
-
+
int64 zero = 0;
int sizeLeft = beType->mSize;
while (sizeLeft > 0)
@@ -1985,7 +1983,7 @@ void BeCOFFObject::Generate(BeModule* module)
InitSect(mDebugTSect, ".debug$T", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_READ, true, false);
}
InitSect(mPDataSect, ".pdata", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ, true, false);
-
+
mTextSect.mData.mData.Reserve(4096);
BfSizedVector globalVarSyms;
@@ -2005,7 +2003,7 @@ void BeCOFFObject::Generate(BeModule* module)
sym->mIsStatic = globalVar->mLinkageType == BfIRLinkageType_Internal;
sym->mSymKind = BeMCSymbolKind_External;
sym->mIdx = (int)mSymbols.size() - 1;
- sym->mIsTLS = globalVar->mIsTLS;
+ sym->mIsTLS = globalVar->mIsTLS;
globalVarSyms.push_back(sym);
mSymbolMap[globalVar] = sym;
@@ -2015,7 +2013,7 @@ void BeCOFFObject::Generate(BeModule* module)
{
auto globalVar = module->mGlobalVariables[globalVarIdx];
- if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL))
+ if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL))
continue;
auto sym = globalVarSyms[globalVarIdx];
@@ -2037,7 +2035,7 @@ void BeCOFFObject::Generate(BeModule* module)
mRDataSect.mAlign = BF_MAX(mRDataSect.mAlign, globalVar->mAlign);
AlignConst(mRDataSect, constVal);
- sym->mValue = mRDataSect.mData.GetSize();
+ sym->mValue = mRDataSect.mData.GetSize();
WriteConst(mRDataSect, constVal);
}
else if (globalVar->mIsTLS)
@@ -2085,8 +2083,8 @@ void BeCOFFObject::Generate(BeModule* module)
mBSSSect.mSizeOverride = (mBSSSect.mSizeOverride + globalVar->mAlign - 1) & ~(globalVar->mAlign - 1);
mBSSSect.mAlign = BF_MAX(mBSSSect.mAlign, globalVar->mAlign);
sym->mValue = mBSSSect.mSizeOverride;
- mBSSSect.mSizeOverride += globalVar->mType->mSize;
- }
+ mBSSSect.mSizeOverride += globalVar->mType->mSize;
+ }
}
if (globalVar->mStorageKind == BfIRStorageKind_Export)
@@ -2113,10 +2111,10 @@ void BeCOFFObject::Generate(BeModule* module)
{
auto func = mFuncWorkList[0];
mFuncWorkList.RemoveAt(0);
-
+
module->mActiveFunction = func;
if (!func->IsDecl())
- {
+ {
BeMCSymbol* sym = GetSymbol(func);
BF_ASSERT(sym != NULL);
sym->mValue = mTextSect.mData.GetSize();
@@ -2138,7 +2136,7 @@ void BeCOFFObject::Generate(BeModule* module)
InitSect(mDirectiveSect, ".drectve", IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_ALIGN_1BYTES, true, false);
mDirectiveSect.mData.Write((void*)mDirectives.c_str(), (int)mDirectives.length());
}
-
+
if (hasDebugInfo)
{
DbgGenerateTypeInfo();
@@ -2153,7 +2151,7 @@ void BeCOFFObject::Generate(BeModule* module)
bool BeCOFFObject::Generate(BeModule* module, const StringImpl& fileName)
{
BP_ZONE_F("BeCOFFObject::Generate %s", fileName.c_str());
- AutoPerf perf("BeCOFFObject::Generate", mPerfManager);
+ AutoPerf perf("BeCOFFObject::Generate", mPerfManager);
if (mWriteToLib)
{
@@ -2171,13 +2169,13 @@ bool BeCOFFObject::Generate(BeModule* module, const StringImpl& fileName)
return false;
for (auto sym : mSymbols)
- {
+ {
if (sym->mIsStatic)
continue;
if (((sym->mSymKind == BeMCSymbolKind_External) && (sym->mSectionNum != 0)) ||
((sym->mSymKind == BeMCSymbolKind_Function)))
- {
+ {
libEntry->AddSymbol(sym->mName);
}
}
@@ -2228,7 +2226,7 @@ void BeCOFFObject::Finish()
memset(§Hdr, 0, sizeof(sectHdr));
BeCOFFSection* sect = mUsedSections[sectNum];
strcpy(sectHdr.mName, sect->mSectName.c_str());
-
+
int characteristics = sect->mCharacteristics;
if (sect->mAlign != 0)
{
@@ -2246,8 +2244,8 @@ void BeCOFFObject::Finish()
else if (sect->mAlign == 4) characteristics |= IMAGE_SCN_ALIGN_4BYTES;
else if (sect->mAlign == 2) characteristics |= IMAGE_SCN_ALIGN_2BYTES;
}
-
- sectData[sectNum] = sect;
+
+ sectData[sectNum] = sect;
int dataSize = sect->mData.GetSize();
if (dataSize != 0)
{
@@ -2267,9 +2265,9 @@ void BeCOFFObject::Finish()
filePos += sizeof(COFFRelocation);
}
else
- {
+ {
sectHdr.mNumberOfRelocations = (int)sect->mRelocs.size();
- }
+ }
filePos += (int)sect->mRelocs.size() * sizeof(COFFRelocation);
}
}
@@ -2281,8 +2279,8 @@ void BeCOFFObject::Finish()
sectHdr.mCharacteristics = characteristics;
BF_ASSERT(characteristics != 0);
}
-
- header.mPointerToSymbolTable = filePos;
+
+ header.mPointerToSymbolTable = filePos;
header.mNumberOfSymbols = (int)mSymbols.size();
mStream->WriteT(header);
@@ -2323,7 +2321,7 @@ void BeCOFFObject::Finish()
coffReloc.mVirtualAddress = reloc.mOffset;
coffReloc.mSymbolTableIndex = reloc.mSymTableIdx;
coffReloc.mType = IMAGE_REL_AMD64_ABSOLUTE;
-
+
switch (reloc.mKind)
{
case BeMCRelocationKind_ADDR32NB:
@@ -2350,7 +2348,7 @@ void BeCOFFObject::Finish()
}
BF_ASSERT(mStream->GetPos() == filePos);
-
+
SizedArray symInfoVec;
symInfoVec.reserve(mSymbols.size() + 16);
@@ -2358,8 +2356,8 @@ void BeCOFFObject::Finish()
{
//BP_ZONE("Finish - AddSym");
- if (sym->mSymKind == BeMCSymbolKind_AuxPlaceholder)
- continue;
+ if (sym->mSymKind == BeMCSymbolKind_AuxPlaceholder)
+ continue;
PE_SymInfo symInfo;
memset(&symInfo, 0, sizeof(symInfo));
@@ -2370,9 +2368,9 @@ void BeCOFFObject::Finish()
symInfo.mNameOfs[1] = strTablePos + 4;
}
else
- strcpy(symInfo.mName, sym->mName.c_str());
+ strcpy(symInfo.mName, sym->mName.c_str());
if (sym->mSymKind == BeMCSymbolKind_SectionDef)
- {
+ {
symInfo.mSectionNum = sym->mSectionNum;
symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC;
symInfo.mNumOfAuxSymbols = 1;
@@ -2390,41 +2388,41 @@ void BeCOFFObject::Finish()
auxSymInfo.mSelection = 2; // Pick any (only applicable for COMDAT but ignored elsewhere)
auxSymInfo.mUnused = 0;
auxSymInfo.mUnused2 = 0;
- auxSymInfo.mUnused3 = 0;
+ auxSymInfo.mUnused3 = 0;
symInfoVec.push_back(*(PE_SymInfo*)&auxSymInfo);
continue;
}
else if (sym->mSymKind == BeMCSymbolKind_SectionRef)
{
- symInfo.mSectionNum = sym->mSectionNum;
- symInfo.mStorageClass = IMAGE_SYM_CLASS_SECTION;
+ symInfo.mSectionNum = sym->mSectionNum;
+ symInfo.mStorageClass = IMAGE_SYM_CLASS_SECTION;
}
else if (sym->mSymKind == BeMCSymbolKind_Function)
{
symInfo.mValue = sym->mValue;
- symInfo.mSectionNum = mTextSect.mSectionIdx + 1;
+ symInfo.mSectionNum = mTextSect.mSectionIdx + 1;
symInfo.mType = 0x20; //DT_FUNCTION
if (sym->mIsStatic)
symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC;
else
symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL;
- }
+ }
else if (sym->mSymKind == BeMCSymbolKind_COMDAT)
{
symInfo.mValue = sym->mValue;
- symInfo.mSectionNum = sym->mSectionNum;
+ symInfo.mSectionNum = sym->mSectionNum;
symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL;
}
else
- {
+ {
if (sym->mIsStatic)
symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC;
else
symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL;
symInfo.mValue = sym->mValue;
symInfo.mSectionNum = sym->mSectionNum;
- }
+ }
symInfoVec.push_back(symInfo);
}
if (!symInfoVec.IsEmpty())
@@ -2437,7 +2435,7 @@ void BeCOFFObject::Finish()
}
BeMCSymbol* BeCOFFObject::GetSymbol(BeValue* value, bool allowCreate)
-{
+{
/*auto itr = mSymbolMap.find(value);
if (itr != mSymbolMap.end())
return itr->second;*/
@@ -2446,7 +2444,7 @@ BeMCSymbol* BeCOFFObject::GetSymbol(BeValue* value, bool allowCreate)
return *symbolPtr;
if (allowCreate)
- {
+ {
if (auto func = BeValueDynCast(value))
{
mFuncWorkList.Add(func);
@@ -2475,7 +2473,7 @@ BeMCSymbol* BeCOFFObject::GetSymbol(BeValue* value, bool allowCreate)
}
BeMCSymbol* BeCOFFObject::GetSymbolRef(const StringImpl& name)
-{
+{
/*auto itr = mNamedSymbolMap.find(name);
if (itr != mNamedSymbolMap.end())
return itr->second;*/
@@ -2502,8 +2500,8 @@ void BeCOFFObject::MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol)
if (getSectSymbol)
{
//TODO: We previously only did sectionDefs when we needed the SelectionNum value, but
- // omitting this causes the MS linker to throw "multiple '' sections found with different
- // attributes (0000000000) errors. This change could potentially break LIB creation in the
+ // omitting this causes the MS linker to throw "multiple '' sections found with different
+ // attributes (0000000000) errors. This change could potentially break LIB creation in the
// linker. Verify it still works.
if (((sect.mCharacteristics & IMAGE_SCN_LNK_COMDAT) != 0) || (true))
{
@@ -2524,7 +2522,7 @@ void BeCOFFObject::MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol)
else
{
// It's important for the linker's import library output to include
- // section refs and not section defs, even when they aren't an external
+ // section refs and not section defs, even when they aren't an external
// reference
BeMCSymbol* sym;
sym = mSymbols.Alloc();
@@ -2549,8 +2547,8 @@ BeMCSymbol* BeCOFFObject::GetCOMDAT(const StringImpl& name, void* data, int size
BeCOFFSection mRData8Sect;
auto* rdataSect = mDynSects.Alloc();
- int characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_MEM_READ;
- InitSect(*rdataSect, ".rdata", characteristics, true, true);
+ int characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_MEM_READ;
+ InitSect(*rdataSect, ".rdata", characteristics, true, true);
rdataSect->mAlign = align;
auto sym = mSymbols.Alloc();
@@ -2559,9 +2557,9 @@ BeMCSymbol* BeCOFFObject::GetCOMDAT(const StringImpl& name, void* data, int size
sym->mIdx = (int)mSymbols.size() - 1;
sym->mSectionNum = rdataSect->mSectionIdx + 1;
sym->mValue = rdataSect->mData.GetPos();
- mNamedSymbolMap[name] = sym;
- rdataSect->mData.Write(data, size);
- return sym;
+ mNamedSymbolMap[name] = sym;
+ rdataSect->mData.Write(data, size);
+ return sym;
}
BeCOFFSection* BeCOFFObject::CreateSect(const StringImpl& name, int characteristics, bool makeSectSymbol)
diff --git a/IDEHelper/Backend/BeCOFFObject.h b/IDEHelper/Backend/BeCOFFObject.h
index 78ce5a40..b69ca7a6 100644
--- a/IDEHelper/Backend/BeCOFFObject.h
+++ b/IDEHelper/Backend/BeCOFFObject.h
@@ -26,7 +26,7 @@ public:
bool mIsStatic;
bool mIsTLS;
BeMCSymbolKind mSymKind;
- int mValue;
+ int mValue;
int mIdx;
int mSectionNum;
@@ -169,7 +169,7 @@ public:
return false;
for (int i = 0; i < (int)lhs->mType->mParams.size(); i++)
if (lhs->mType->mParams[i] != rhs->mType->mParams[i])
- return false;
+ return false;
return true;
}
};
@@ -215,16 +215,16 @@ public:
PerfManager* mPerfManager;
DataStream* mStream;
BumpAllocator mAlloc;
- BeModule* mBeModule;
- OwnedVector mSymbols;
+ BeModule* mBeModule;
+ OwnedVector mSymbols;
OwnedVector mDynSects;
uint32 mTimestamp;
BeCOFFSection mTextSect;
BeCOFFSection mDataSect;
- BeCOFFSection mRDataSect;
- BeCOFFSection mBSSSect;
- BeCOFFSection mTLSSect;
+ BeCOFFSection mRDataSect;
+ BeCOFFSection mBSSSect;
+ BeCOFFSection mTLSSect;
BeCOFFSection mPDataSect;
BeCOFFSection mXDataSect;
BeCOFFSection mDebugSSect;
@@ -234,8 +234,8 @@ public:
int mBSSPos;
Array mUsedSections;
Dictionary mSymbolMap;
- Dictionary mNamedSymbolMap;
- HashSet mArgListSet;
+ Dictionary mNamedSymbolMap;
+ HashSet mArgListSet;
HashSet mFuncTypeSet;
Deque mFuncWorkList;
int mTTagStartPos;
@@ -244,10 +244,10 @@ public:
int mSectionStartPos;
int mCurStringId;
int mCurJumpTableIdx;
- bool mTypesLocked;
+ bool mTypesLocked;
String mDirectives;
-public:
+public:
void ToString(BeMDNode* mdNode, String& str);
int GetCVRegNum(X64CPURegister reg, int bits);
@@ -255,10 +255,10 @@ public:
void DbgTStartTag();
void DbgTEndTag();
void DbgEncodeConstant(DynMemStream& memStream, int64 val);
- void DbgEncodeString(DynMemStream& memStream, const StringImpl& str);
+ void DbgEncodeString(DynMemStream& memStream, const StringImpl& str);
void DbgMakeFuncType(BeDbgFunction* dbgFunc);
void DbgMakeFunc(BeDbgFunction* dbgFunc);
- int DbgGetTypeId(BeDbgType* dbgType, bool doDefine = false);
+ int DbgGetTypeId(BeDbgType* dbgType, bool doDefine = false);
void DbgGenerateTypeInfo();
void DbgSAlign();
@@ -270,18 +270,18 @@ public:
void DbgEndSection();
void DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar, const BeDbgVariableLoc& varLoc, int offset, int range);
void DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array& emissions, int blockStartPos, int emissionStartIdx, int lineCount);
- void DbgGenerateModuleInfo();
+ void DbgGenerateModuleInfo();
void InitSect(BeCOFFSection& sect, const StringImpl& name, int characteristics, bool addNow, bool makeSectSymbol);
void AlignConst(BeCOFFSection& sect, BeConstant* constVal);
void WriteConst(BeCOFFSection& sect, BeConstant* constVal);
-
+
void Generate(BeModule* module);
public:
- BeCOFFObject();
+ BeCOFFObject();
void Finish();
- bool Generate(BeModule* module, const StringImpl& fileName);
+ bool Generate(BeModule* module, const StringImpl& fileName);
BeMCSymbol* GetSymbol(BeValue* value, bool allowCreate = true);
BeMCSymbol* GetSymbolRef(const StringImpl& name);
void MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol = false);
diff --git a/IDEHelper/Backend/BeContext.cpp b/IDEHelper/Backend/BeContext.cpp
index 21c7c707..ed457419 100644
--- a/IDEHelper/Backend/BeContext.cpp
+++ b/IDEHelper/Backend/BeContext.cpp
@@ -28,7 +28,7 @@ BeType* BeContext::GetPrimitiveType(BeTypeCode typeCode)
primType->mTypeCode = typeCode;
switch (typeCode)
{
- case BeTypeCode_None:
+ case BeTypeCode_None:
primType->mSize = 0;
primType->mAlign = 0;
break;
@@ -80,24 +80,24 @@ BeStructType* BeContext::CreateStruct(const StringImpl& name)
BeStructType* structType = mTypes.Alloc();
structType->mContext = this;
structType->mTypeCode = BeTypeCode_Struct;
- structType->mName = name;
+ structType->mName = name;
structType->mIsOpaque = true;
return structType;
}
BeStructType* BeContext::CreateStruct(const SizedArrayImpl& types)
-{
- BeStructType** valuePtr = NULL;
- if (mAnonymousStructMap.TryGetValueWith(types, &valuePtr))
- return *valuePtr;
+{
+ BeStructType** valuePtr = NULL;
+ if (mAnonymousStructMap.TryGetValueWith(types, &valuePtr))
+ return *valuePtr;
Array key;
for (auto type : types)
key.Add(type);
-
+
BeStructType* structType = CreateStruct("");
SetStructBody(structType, types, false);
- mAnonymousStructMap.TryAdd(key, structType);
+ mAnonymousStructMap.TryAdd(key, structType);
return structType;
}
@@ -109,7 +109,7 @@ BePointerType* BeContext::GetPointerTo(BeType* beType)
pointerType->mTypeCode = BeTypeCode_Pointer;
pointerType->mElementType = beType;
pointerType->mSize = mPointerSize;
- pointerType->mAlign = mPointerSize;
+ pointerType->mAlign = mPointerSize;
beType->mPointerType = pointerType;
/*if (beType->IsSizedArray())
@@ -197,12 +197,12 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
{
if (lhs == rhs)
return true;
-
+
if (lhs->mTypeCode != rhs->mTypeCode)
return false;
switch (lhs->mTypeCode)
- {
+ {
case BeTypeCode_None:
case BeTypeCode_NullPtr:
case BeTypeCode_Boolean:
@@ -214,7 +214,7 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
case BeTypeCode_Double:
return true;
case BeTypeCode_Pointer:
- return AreTypesEqual(((BePointerType*)lhs)->mElementType, ((BePointerType*)rhs)->mElementType);
+ return AreTypesEqual(((BePointerType*)lhs)->mElementType, ((BePointerType*)rhs)->mElementType);
case BeTypeCode_SizedArray:
{
auto lhsSizedArray = (BeSizedArrayType*)lhs;
@@ -222,7 +222,7 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
if (lhsSizedArray->mLength != rhsSizedArray->mLength)
return false;
return AreTypesEqual(lhsSizedArray->mElementType, rhsSizedArray->mElementType);
- }
+ }
case BeTypeCode_Vector:
{
auto lhsSizedArray = (BeVectorType*)lhs;
@@ -233,5 +233,4 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
}
}
return false;
-}
-
+}
\ No newline at end of file
diff --git a/IDEHelper/Backend/BeContext.h b/IDEHelper/Backend/BeContext.h
index 20d24152..e65f69f9 100644
--- a/IDEHelper/Backend/BeContext.h
+++ b/IDEHelper/Backend/BeContext.h
@@ -88,7 +88,6 @@ public:
virtual ~BeType()
{
-
}
int GetStride()
@@ -120,7 +119,6 @@ public:
{
return (mTypeCode == BeTypeCode_Float) || (mTypeCode == BeTypeCode_Double);
}
-
bool IsStruct()
{
@@ -159,10 +157,10 @@ public:
}
virtual void HashContent(BeHashContext& hashCtx)
- {
+ {
BF_ASSERT(mTypeCode < BeTypeCode_Struct);
hashCtx.Mixin(mTypeCode);
- }
+ }
};
class BeStructMember
@@ -174,21 +172,21 @@ public:
class BeStructType : public BeType
{
-public:
+public:
BeContext* mContext;
String mName;
- Array mMembers;
+ Array mMembers;
bool mIsPacked;
bool mIsOpaque;
-
+
virtual void HashContent(BeHashContext& hashCtx) override
- {
+ {
hashCtx.MixinStr(mName);
hashCtx.Mixin(mMembers.size());
for (auto& member : mMembers)
{
member.mType->HashReference(hashCtx);
- hashCtx.Mixin(member.mByteOffset);
+ hashCtx.Mixin(member.mByteOffset);
}
hashCtx.Mixin(mIsPacked);
hashCtx.Mixin(mIsOpaque);
@@ -213,9 +211,9 @@ public:
BeContext* mContext;
BeType* mElementType;
int mLength;
-
+
virtual void HashContent(BeHashContext& hashCtx) override
- {
+ {
hashCtx.Mixin(BeTypeCode_SizedArray);
hashCtx.Mixin(mLength);
mElementType->HashReference(hashCtx);
@@ -247,27 +245,27 @@ class BeFunctionType : public BeType
{
public:
String mName;
- BeType* mReturnType;
+ BeType* mReturnType;
Array mParams;
bool mIsVarArg;
-
+
virtual void HashContent(BeHashContext& hashCtx) override
{
hashCtx.Mixin(BeTypeCode_Function);
hashCtx.MixinStr(mName);
- mReturnType->HashReference(hashCtx);
+ mReturnType->HashReference(hashCtx);
hashCtx.Mixin(mParams.size());
for (auto& param : mParams)
{
param.mType->HashReference(hashCtx);
}
- hashCtx.Mixin(mIsVarArg);
+ hashCtx.Mixin(mIsVarArg);
}
};
class BeContext
{
-public:
+public:
int mPointerSize;
//BumpAllocator mAlloc;
BeType* mPrimitiveTypes[BeTypeCode_COUNT];
@@ -278,8 +276,8 @@ public:
void NotImpl();
public:
- BeContext();
- BeType* GetPrimitiveType(BeTypeCode typeCode);
+ BeContext();
+ BeType* GetPrimitiveType(BeTypeCode typeCode);
BeType* GetVoidPtrType();
BeStructType* CreateStruct(const StringImpl& name);
BeStructType* CreateStruct(const SizedArrayImpl& types);
diff --git a/IDEHelper/Backend/BeDbgModule.h b/IDEHelper/Backend/BeDbgModule.h
index e40ce902..0c0cf57f 100644
--- a/IDEHelper/Backend/BeDbgModule.h
+++ b/IDEHelper/Backend/BeDbgModule.h
@@ -8,4 +8,3 @@
NS_BF_BEGIN
NS_BF_END
-
diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp
index b4b7e497..64d09dbb 100644
--- a/IDEHelper/Backend/BeIRCodeGen.cpp
+++ b/IDEHelper/Backend/BeIRCodeGen.cpp
@@ -231,7 +231,7 @@ BeIRCodeGen::BeIRCodeGen()
mBeContext = NULL;
mBeModule = NULL;
mHasDebugLoc = false;
- mDebugging = false;
+ mDebugging = false;
mCmdCount = 0;
}
@@ -239,7 +239,7 @@ BeIRCodeGen::~BeIRCodeGen()
{
BF_ASSERT(mSavedDebugLocs.size() == 0);
delete mBeModule;
- delete mBeContext;
+ delete mBeContext;
delete mStream;
}
@@ -254,7 +254,7 @@ void BeIRCodeGen::Hash(BeHashContext& hashCtx)
hashCtx.Mixin(mPtrSize);
hashCtx.Mixin(mIsOptimized);
if (mBeModule != NULL)
- mBeModule->Hash(hashCtx);
+ mBeModule->Hash(hashCtx);
Array structHashList;
@@ -385,7 +385,7 @@ BeType* BeIRCodeGen::GetBeType(BfTypeCode typeCode, bool& isSigned)
isSigned = true;
beTypeCode = BeTypeCode_Float;
break;
- case BfTypeCode_Double:
+ case BfTypeCode_Double:
isSigned = true;
beTypeCode = BeTypeCode_Double;
break;
@@ -395,7 +395,7 @@ BeType* BeIRCodeGen::GetBeType(BfTypeCode typeCode, bool& isSigned)
}
BeIRTypeEntry& BeIRCodeGen::GetTypeEntry(int typeId)
-{
+{
BeIRTypeEntry& typeEntry = mTypes[typeId];
if (typeEntry.mTypeId == -1)
typeEntry.mTypeId = typeId;
@@ -482,7 +482,7 @@ void BeIRCodeGen::ProcessBfIRData(const BfSizedArray& buffer)
{
BP_ZONE("BeIRCodeGen::ProcessBfIRData");
- Init(buffer);
+ Init(buffer);
Process();
}
@@ -490,7 +490,7 @@ BfTypeCode BeIRCodeGen::GetTypeCode(BeType * type, bool isSigned)
{
switch (type->mTypeCode)
{
- case BeTypeCode_Int8:
+ case BeTypeCode_Int8:
return (isSigned) ? BfTypeCode_Int8 : BfTypeCode_UInt8;
case BeTypeCode_Int16:
return (isSigned) ? BfTypeCode_Int16 : BfTypeCode_UInt16;
@@ -518,7 +518,7 @@ void BeIRCodeGen::SetResult(int id, BeValue* value)
void BeIRCodeGen::SetResult(int id, BeType* type)
{
BeIRCodeGenEntry entry;
- entry.mKind = BeIRCodeGenEntryKind_Type;
+ entry.mKind = BeIRCodeGenEntryKind_Type;
entry.mBeType = type;
mResults.TryAdd(id, entry);
}
@@ -549,7 +549,6 @@ int64 BeIRCodeGen::ReadSLEB128()
byteVal = mStream->Read();
val |= ((int64)(byteVal & 0x7f)) << shift;
shift += 7;
-
} while (byteVal >= 128);
// Sign extend negative numbers.
if ((byteVal & 0x40) && (shift < 64))
@@ -700,7 +699,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
CMD_PARAM(bool, isTLS);
BF_ASSERT(varType != NULL);
-
+
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
globalVariable->mModule = mBeModule;
globalVariable->mType = varType;
@@ -710,7 +709,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
globalVariable->mName = name;
globalVariable->mIsTLS = isTLS;
globalVariable->mAlign = varType->mAlign;
- globalVariable->mUnnamedAddr = false;
+ globalVariable->mUnnamedAddr = false;
globalVariable->mStorageKind = BfIRStorageKind_Normal;
if (initializer != NULL)
BF_ASSERT(varType->mAlign > 0);
@@ -723,16 +722,16 @@ void BeIRCodeGen::Read(BeValue*& beValue)
beValue->mRefCount++;
BE_MEM_END("ParamType_Const_GlobalVar");
return;
- }
+ }
else if ((constType == BfConstType_BitCast) || (constType == BfConstType_BitCastNull))
- {
+ {
CMD_PARAM(BeConstant*, target);
CMD_PARAM(BeType*, toType);
auto castedVal = mBeModule->mAlloc.Alloc();
castedVal->mInt64 = target->mInt64;
castedVal->mType = toType;
- castedVal->mTarget = target;
+ castedVal->mTarget = target;
BF_ASSERT(target->GetType() != NULL);
BF_ASSERT(!target->GetType()->IsComposite());
beValue = castedVal;
@@ -742,12 +741,12 @@ void BeIRCodeGen::Read(BeValue*& beValue)
else if (constType == BfConstType_GEP32_1)
{
CMD_PARAM(BeConstant*, target);
- CMD_PARAM(int, idx0);
+ CMD_PARAM(int, idx0);
BF_ASSERT(target->GetType()->IsPointer());
auto gepConstant = mBeModule->mAlloc.Alloc();
gepConstant->mTarget = target;
- gepConstant->mIdx0 = idx0;
+ gepConstant->mIdx0 = idx0;
beValue = gepConstant;
BE_MEM_END("ParamType_Const_GEP32_1");
@@ -758,7 +757,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
CMD_PARAM(BeConstant*, target);
CMD_PARAM(int, idx0);
CMD_PARAM(int, idx1);
-
+
BF_ASSERT(target->GetType()->IsPointer());
auto gepConstant = mBeModule->mAlloc.Alloc();
gepConstant->mTarget = target;
@@ -772,11 +771,11 @@ void BeIRCodeGen::Read(BeValue*& beValue)
else if (constType == BfConstType_ExtractValue)
{
CMD_PARAM(BeConstant*, target);
- CMD_PARAM(int, idx0);
-
+ CMD_PARAM(int, idx0);
+
auto gepConstant = mBeModule->mAlloc.Alloc();
gepConstant->mTarget = target;
- gepConstant->mIdx0 = idx0;
+ gepConstant->mIdx0 = idx0;
beValue = gepConstant;
BE_MEM_END("ParamType_Const_ExtractValue");
@@ -794,7 +793,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
auto castedVal = mBeModule->mAlloc.Alloc();
castedVal->mInt64 = target->mInt64;
castedVal->mType = toType;
- castedVal->mTarget = target;
+ castedVal->mTarget = target;
BF_ASSERT(target->GetType() != NULL);
beValue = castedVal;
BE_MEM_END("ParamType_Const_PtrToInt");
@@ -858,11 +857,11 @@ void BeIRCodeGen::Read(BeValue*& beValue)
}
auto constStruct = mBeModule->mOwnedValues.Alloc();
- constStruct->mType = type;
+ constStruct->mType = type;
for (int i = 0; i < (int)values.size(); i++)
{
auto val = values[i];
- BeConstant* constant = BeValueDynCast(val);
+ BeConstant* constant = BeValueDynCast(val);
if (type->IsSizedArray())
{
@@ -882,7 +881,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
{
BF_ASSERT(type->IsStruct());
auto structType = (BeStructType*)type;
- auto valType = constant->GetType();
+ auto valType = constant->GetType();
if (structType->mIsOpaque)
{
Fail("ConstAgg with opaque struct");
@@ -922,7 +921,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
}
else if (constType == BfConstType_Undef)
{
- CMD_PARAM(BeType*, type);
+ CMD_PARAM(BeType*, type);
auto constUndef = mBeModule->mOwnedValues.Alloc