diff options
| author | Stefan Boberg <[email protected]> | 2026-04-13 14:05:03 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-04-13 14:05:03 +0200 |
| commit | c49e5b15e0f86080d7d33e4e31aecfb701f8f96f (patch) | |
| tree | ff41dcec20502c0cc4cf853222273f50d025cda3 /src/zencore/include | |
| parent | Add MemoryCidStore and ChunkStore interface (#940) (diff) | |
| download | archived-zen-c49e5b15e0f86080d7d33e4e31aecfb701f8f96f.tar.xz archived-zen-c49e5b15e0f86080d7d33e4e31aecfb701f8f96f.zip | |
Some minor polish from tourist branch (#949)
- Replace per-type fmt::formatter specializations (StringBuilderBase, NiceBase) with a single generic formatter using a HasStringViewConversion concept
- Add ThousandsNum for comma-separated integer formatting (e.g. "1,234,567")
- Thread naming now accepts a sort hint for trace ordering
- Fix main thread trace registration to use actual thread ID and sort first
- Add ExpandEnvironmentVariables() for expanding %VAR% references in strings, with tests
- Add ParseHexBytes() overload with expected byte count validation
- Add Flag_BelowNormalPriority to CreateProcOptions (BELOW_NORMAL_PRIORITY_CLASS on Windows, setpriority on POSIX)
- Add PrettyScroll progress bar mode that pins the status line to the bottom of the terminal using scroll regions, with signal handler cleanup for Ctrl+C/SIGTERM
Diffstat (limited to 'src/zencore/include')
| -rw-r--r-- | src/zencore/include/zencore/filesystem.h | 4 | ||||
| -rw-r--r-- | src/zencore/include/zencore/fmtutils.h | 22 | ||||
| -rw-r--r-- | src/zencore/include/zencore/process.h | 3 | ||||
| -rw-r--r-- | src/zencore/include/zencore/string.h | 37 | ||||
| -rw-r--r-- | src/zencore/include/zencore/thread.h | 2 |
5 files changed, 55 insertions, 13 deletions
diff --git a/src/zencore/include/zencore/filesystem.h b/src/zencore/include/zencore/filesystem.h index 6dc159a83..73769cdb4 100644 --- a/src/zencore/include/zencore/filesystem.h +++ b/src/zencore/include/zencore/filesystem.h @@ -400,6 +400,10 @@ void GetDirectoryContent(const std::filesystem::path& RootDir, std::string GetEnvVariable(std::string_view VariableName); +// Expands %VAR% environment variable references in a string. +// Unknown or empty variables are left unexpanded. +std::string ExpandEnvironmentVariables(std::string_view Input); + std::filesystem::path SearchPathForExecutable(std::string_view ExecutableName); std::error_code RotateFiles(const std::filesystem::path& Filename, std::size_t MaxFiles); diff --git a/src/zencore/include/zencore/fmtutils.h b/src/zencore/include/zencore/fmtutils.h index 4ec05f901..2a829d2d5 100644 --- a/src/zencore/include/zencore/fmtutils.h +++ b/src/zencore/include/zencore/fmtutils.h @@ -38,27 +38,25 @@ struct fmt::formatter<T> : fmt::formatter<std::string_view> } }; -// Custom formatting for some zencore types +// Generic formatter for any type that is explicitly convertible to std::string_view. +// This covers NiceNum, NiceBytes, ThousandsNum, StringBuilder, and similar types +// without needing per-type fmt::formatter specializations. template<typename T> -requires DerivedFrom<T, zen::StringBuilderBase> -struct fmt::formatter<T> : fmt::formatter<std::string_view> +concept HasStringViewConversion = std::is_class_v<T> && requires(const T& v) { - template<typename FormatContext> - auto format(const zen::StringBuilderBase& a, FormatContext& ctx) const { - return fmt::formatter<std::string_view>::format(a.ToView(), ctx); - } -}; + std::string_view(v) + } -> std::same_as<std::string_view>; +} && !HasFreeToString<T> && !std::is_same_v<T, std::string> && !std::is_same_v<T, std::string_view>; -template<typename T> -requires DerivedFrom<T, zen::NiceBase> +template<HasStringViewConversion T> struct fmt::formatter<T> : fmt::formatter<std::string_view> { template<typename FormatContext> - auto format(const zen::NiceBase& a, FormatContext& ctx) const + auto format(const T& Value, FormatContext& ctx) const { - return fmt::formatter<std::string_view>::format(std::string_view(a), ctx); + return fmt::formatter<std::string_view>::format(std::string_view(Value), ctx); } }; diff --git a/src/zencore/include/zencore/process.h b/src/zencore/include/zencore/process.h index 8cbed781d..19804795b 100644 --- a/src/zencore/include/zencore/process.h +++ b/src/zencore/include/zencore/process.h @@ -183,6 +183,9 @@ struct CreateProcOptions // Flag_NoConsole the child still gets a console (and a conhost.exe) but no visible // window. Use this when the child needs a console for stdio but should not show a window. Flag_NoWindow = 1 << 5, + // Launch the child at below-normal scheduling priority. + // On Windows: BELOW_NORMAL_PRIORITY_CLASS. On POSIX: nice(5). + Flag_BelowNormalPriority = 1 << 6, }; const std::filesystem::path* WorkingDirectory = nullptr; diff --git a/src/zencore/include/zencore/string.h b/src/zencore/include/zencore/string.h index 60293a313..308a8a7d2 100644 --- a/src/zencore/include/zencore/string.h +++ b/src/zencore/include/zencore/string.h @@ -609,6 +609,17 @@ ParseHexBytes(std::string_view InputString, uint8_t* OutPtr) return ParseHexBytes(InputString.data(), InputString.size(), OutPtr); } +/** Parse hex string into a byte buffer, validating that the hex string is exactly ExpectedByteCount * 2 characters. */ +inline bool +ParseHexBytes(std::string_view InputString, uint8_t* OutPtr, size_t ExpectedByteCount) +{ + if (InputString.size() != ExpectedByteCount * 2) + { + return false; + } + return ParseHexBytes(InputString.data(), InputString.size(), OutPtr); +} + inline void ToHexBytes(const uint8_t* InputData, size_t ByteCount, char* OutString) { @@ -722,6 +733,32 @@ struct NiceNum : public NiceBase inline NiceNum(uint64_t Num) { NiceNumToBuffer(Num, m_Buffer); } }; +size_t ThousandsToBuffer(uint64_t Num, std::span<char> Buffer); + +/// Integer formatted with comma thousands separators (e.g. "1,234,567") +struct ThousandsNum +{ + inline ThousandsNum(UnsignedIntegral auto Number) { ThousandsToBuffer(uint64_t(Number), m_Buffer); } + inline ThousandsNum(SignedIntegral auto Number) + { + if (Number < 0) + { + m_Buffer[0] = '-'; + ThousandsToBuffer(uint64_t(-Number), std::span<char>(m_Buffer + 1, sizeof(m_Buffer) - 1)); + } + else + { + ThousandsToBuffer(uint64_t(Number), m_Buffer); + } + } + + inline const char* c_str() const { return m_Buffer; } + inline operator std::string_view() const { return std::string_view(m_Buffer); } + +private: + char m_Buffer[28]; // max uint64: "18,446,744,073,709,551,615" (26) + NUL + sign +}; + struct NiceBytes : public NiceBase { inline NiceBytes(uint64_t Num) { NiceBytesToBuffer(Num, m_Buffer); } diff --git a/src/zencore/include/zencore/thread.h b/src/zencore/include/zencore/thread.h index 56ce5904b..0f7733df5 100644 --- a/src/zencore/include/zencore/thread.h +++ b/src/zencore/include/zencore/thread.h @@ -14,7 +14,7 @@ namespace zen { -void SetCurrentThreadName(std::string_view ThreadName); +void SetCurrentThreadName(std::string_view ThreadName, int32_t SortHint = 0); /** * Reader-writer lock |