aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/include
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-04-13 14:05:03 +0200
committerGitHub Enterprise <[email protected]>2026-04-13 14:05:03 +0200
commitc49e5b15e0f86080d7d33e4e31aecfb701f8f96f (patch)
treeff41dcec20502c0cc4cf853222273f50d025cda3 /src/zencore/include
parentAdd MemoryCidStore and ChunkStore interface (#940) (diff)
downloadarchived-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.h4
-rw-r--r--src/zencore/include/zencore/fmtutils.h22
-rw-r--r--src/zencore/include/zencore/process.h3
-rw-r--r--src/zencore/include/zencore/string.h37
-rw-r--r--src/zencore/include/zencore/thread.h2
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