diff --git a/CHANGELOG.md b/CHANGELOG.md index 849b497b4d..f6fbd3a477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +# 2.65.3 + +Changes: +* Fixed compatibility with WSL 2.9.3 (#2433, WM, Linux) + +Features: +* Added Astra Linux version detection (OS, Linux) +* Improved performance of Windows PowerShell version detection (Shell, Windows) +* Improved performance of Media module on macOS (Media, macOS) + +Logos: +* Added Flatcar, Azure Linux +* Added Chimera_small, Chimera2, Parabola2_small, PostmarketOS2, Qubes_small +* Cleaned up a lot of distro names + # 2.65.2 Changes: @@ -10,7 +25,7 @@ Bugfixes: * Fixed a crash when detecting hardware codec support with the `amdgpu` driver on Linux. (#2419, Codec, Linux) Logos: -* Updated CachyOS_small +* Updated CachyOS_small; fixed CachyOS logo colors to match the official logo better * Added Turkish # 2.65.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 810cd9d44f..a6f5db24de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.65.2 + VERSION 2.65.3 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" @@ -105,6 +105,7 @@ cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" option(ENABLE_ZLIB "Enable zlib" ON) option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF) option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF) +option(ENABLE_TRACER "Build fastfetch with function tracing" OFF) option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON) option(BUILD_FLASHFETCH "Build flashfetch" ON) # Also build the flashfetch binary option(BUILD_TESTS "Build tests" OFF) # Also create test executables @@ -1365,6 +1366,22 @@ elseif(GNU) ) endif() +if(ENABLE_TRACER) + message(STATUS "Tracer is enabled") + list(APPEND LIBFASTFETCH_SRC src/common/impl/tracer.c) + if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finstrument-functions-after-inlining") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finstrument-functions -Dinline=\"__attribute__((no_instrument_function)) inline\"") + endif() + if(NOT WIN32) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") + elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gcodeview -fuse-ld=lld") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--pdb=${CMAKE_BINARY_DIR}/fastfetch.pdb") + endif() +endif() + # Proprietary GPU driver APIs if(LINUX OR FreeBSD OR WIN32) list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c) @@ -1889,6 +1906,11 @@ elseif(WIN32) PRIVATE "runtimeobject" ) endif() + if(ENABLE_TRACER) + target_link_libraries(libfastfetch + PRIVATE "dbghelp" + ) + endif() elseif(FreeBSD) target_link_libraries(libfastfetch PRIVATE "m" diff --git a/debian/changelog.tpl b/debian/changelog.tpl index 9780c230be..ccf540012a 100644 --- a/debian/changelog.tpl +++ b/debian/changelog.tpl @@ -1,3 +1,9 @@ +fastfetch (2.65.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium + + * Update to 2.65.2 + + -- Carter Li Mon, 29 Jun 2026 10:05:47 +0800 + fastfetch (2.65.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium * Update to 2.65.1 diff --git a/src/common/FFlist.h b/src/common/FFlist.h index 80cef0b542..b409c6d4bc 100644 --- a/src/common/FFlist.h +++ b/src/common/FFlist.h @@ -15,8 +15,6 @@ typedef struct FFlist { uint32_t capacity; } FFlist; -void* ffListAdd(FFlist* list, uint32_t elementSize); - // Removes the first element, and copy its value to `*result` bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result); // Removes the last element, and copy its value to `*result` @@ -105,6 +103,15 @@ static inline void ffListReserve(FFlist* list, uint32_t elementSize, uint32_t ne list->capacity = newCapacity; } +static inline void* ffListAdd(FFlist* list, uint32_t elementSize) { + if (__builtin_expect(list->length == list->capacity, false)) { + ffListReserve(list, elementSize, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2); + } + + ++list->length; + return ffListGet(list, elementSize, list->length - 1); +} + #define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \ for (itemType* itemVarName = (itemType*) (listVar).data; \ itemVarName - (itemType*) (listVar).data < (intptr_t) (listVar).length; \ diff --git a/src/common/FFstrbuf.h b/src/common/FFstrbuf.h index 2279152dbf..4c89b9a32e 100644 --- a/src/common/FFstrbuf.h +++ b/src/common/FFstrbuf.h @@ -37,16 +37,13 @@ static inline void ffStrbufInit(FFstrbuf* strbuf); void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate); void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments); void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr); +FF_A_PRINTF(2, 3) void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...); +FF_A_PRINTF(1, 2) FF_A_NODISCARD FFstrbuf ffStrbufCreateF(const char* format, ...); -void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free); void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free); - -void ffStrbufClear(FFstrbuf* strbuf); +void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free); static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value); -void ffStrbufAppendC(FFstrbuf* strbuf, char c); -void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c); -void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value); void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int)); FF_A_PRINTF(2, 3) void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...); void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments); @@ -88,13 +85,6 @@ bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end); bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c); -void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file); -void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file); - -FF_A_NODISCARD double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue); -FF_A_NODISCARD int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue); -FF_A_NODISCARD uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue); - void ffStrbufUpperCase(FFstrbuf* strbuf); void ffStrbufLowerCase(FFstrbuf* strbuf); @@ -182,31 +172,6 @@ FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src) { return strbuf; } -FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateVF(const char* format, va_list arguments) { - FFstrbuf strbuf; - ffStrbufInitVF(&strbuf, format, arguments); - return strbuf; -} - -FF_A_PRINTF(2, 3) static inline void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) { - va_list arguments; - va_start(arguments, format); - ffStrbufInitVF(strbuf, format, arguments); - va_end(arguments); -} - -FF_A_PRINTF(1, 2) FF_A_NODISCARD static inline FFstrbuf -ffStrbufCreateF(const char* format, ...) { - FFstrbuf strbuf; - - va_list arguments; - va_start(arguments, format); - ffStrbufInitVF(&strbuf, format, arguments); - va_end(arguments); - - return strbuf; -} - static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr) { ffStrbufInitMoveNS(strbuf, (uint32_t) strlen(heapStr), heapStr); } @@ -229,6 +194,76 @@ FF_A_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) { return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte } +static inline void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) { + if (__builtin_expect(free == 0, false)) { + if (__builtin_expect(!(strbuf->allocated == 0 && strbuf->length > 0), true)) { + return; + } + } else { + if (__builtin_expect(ffStrbufGetFree(strbuf) >= free, true)) { + return; + } + } + + ffStrbufEnsureFreeNoCheck(strbuf, free); +} + + +static inline void ffStrbufClear(FFstrbuf* strbuf) { + assert(strbuf != NULL); + extern char* CHAR_NULL_PTR; + + if (strbuf->allocated == 0) { + strbuf->chars = CHAR_NULL_PTR; + } else { + strbuf->chars[0] = '\0'; + } + + strbuf->length = 0; +} + +static inline void ffStrbufAppendC(FFstrbuf* strbuf, char c) { + if (__builtin_expect(ffStrbufGetFree(strbuf) == 0, false)) { + ffStrbufEnsureFreeNoCheck(strbuf, 1); + } + strbuf->chars[strbuf->length++] = c; + strbuf->chars[strbuf->length] = '\0'; +} + +static inline void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) { + if (__builtin_expect(num == 0, false)) { + return; + } + if (__builtin_expect(ffStrbufGetFree(strbuf) < num, false)) { + ffStrbufEnsureFreeNoCheck(strbuf, num); + } + + memset(&strbuf->chars[strbuf->length], c, num); + strbuf->length += num; + strbuf->chars[strbuf->length] = '\0'; +} + +static inline void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value) { + if (__builtin_expect(value == NULL || length == 0, false)) { + return; + } + if (__builtin_expect(ffStrbufGetFree(strbuf) < length, false)) { + ffStrbufEnsureFreeNoCheck(strbuf, length); + } + + memcpy(&strbuf->chars[strbuf->length], value, length); + strbuf->length += length; + strbuf->chars[strbuf->length] = '\0'; +} + +static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) { + assert(value != strbuf); + if (value == NULL) { + return; + } + ffStrbufAppendNS(strbuf, value->length, value->chars); +} + static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) { strbuf->length = (uint32_t) strlen(strbuf->chars); } @@ -338,14 +373,6 @@ FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateS(const char* str) { return strbuf; } -static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) { - assert(value != strbuf); - if (value == NULL) { - return; - } - ffStrbufAppendNS(strbuf, value->length, value->chars); -} - static inline void ffStrbufPrepend(FFstrbuf* strbuf, FFstrbuf* value) { if (value == NULL) { return; @@ -578,6 +605,33 @@ static inline bool ffStrbufSeparatedContainIgnCase(const FFstrbuf* strbuf, const return ffStrbufSeparatedContainIgnCaseNS(strbuf, comp->length, comp->chars, separator); } +static inline void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) { + fwrite(strbuf->chars, sizeof(*strbuf->chars), strbuf->length, file); +} + +static inline void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) { + ffStrbufWriteTo(strbuf, file); + fputc('\n', file); +} + +FF_A_NODISCARD static inline double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue) { + char* str_end; + double result = strtod(strbuf->chars, &str_end); + return str_end == strbuf->chars ? defaultValue : result; +} + +FF_A_NODISCARD static inline uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue) { + char* str_end; + unsigned long long result = strtoull(strbuf->chars, &str_end, 10); + return str_end == strbuf->chars ? defaultValue : (uint64_t) result; +} + +FF_A_NODISCARD static inline int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue) { + char* str_end; + long long result = strtoll(strbuf->chars, &str_end, 10); + return str_end == strbuf->chars ? defaultValue : (int64_t) result; +} + // Returns true if the strbuf is modified bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf); diff --git a/src/common/impl/FFPlatform_windows.c b/src/common/impl/FFPlatform_windows.c index 083d20aa00..b07e9c8c9a 100644 --- a/src/common/impl/FFPlatform_windows.c +++ b/src/common/impl/FFPlatform_windows.c @@ -236,54 +236,38 @@ static void getSystemPageSize(FFPlatformSysinfo* info) { } static void getSystemArchitecture(FFPlatformSysinfo* info) { - SYSTEM_PROCESSOR_INFORMATION spi; - if (NT_SUCCESS(NtQuerySystemInformation(SystemProcessorInformation, &spi, sizeof(spi), NULL))) { - switch (spi.ProcessorArchitecture) { - case PROCESSOR_ARCHITECTURE_AMD64: - ffStrbufSetStatic(&info->architecture, "x86_64"); - break; - case PROCESSOR_ARCHITECTURE_IA64: - ffStrbufSetStatic(&info->architecture, "ia64"); - break; - case PROCESSOR_ARCHITECTURE_INTEL: - switch (spi.ProcessorLevel) { - case 4: - ffStrbufSetStatic(&info->architecture, "i486"); - break; - case 5: - ffStrbufSetStatic(&info->architecture, "i586"); - break; - case 6: - ffStrbufSetStatic(&info->architecture, "i686"); - break; - default: - ffStrbufSetStatic(&info->architecture, "i386"); - break; - } - break; - case PROCESSOR_ARCHITECTURE_ARM64: - ffStrbufSetStatic(&info->architecture, "aarch64"); - break; - case PROCESSOR_ARCHITECTURE_ARM: - ffStrbufSetStatic(&info->architecture, "arm"); - break; - case PROCESSOR_ARCHITECTURE_PPC: - ffStrbufSetStatic(&info->architecture, "ppc"); - break; - case PROCESSOR_ARCHITECTURE_MIPS: - ffStrbufSetStatic(&info->architecture, "mips"); - break; - case PROCESSOR_ARCHITECTURE_ALPHA: - ffStrbufSetStatic(&info->architecture, "alpha"); - break; - case PROCESSOR_ARCHITECTURE_ALPHA64: - ffStrbufSetStatic(&info->architecture, "alpha64"); - break; - case PROCESSOR_ARCHITECTURE_UNKNOWN: - default: - ffStrbufSetStatic(&info->architecture, "unknown"); - break; - } + switch (SharedUserData->NativeProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_AMD64: + ffStrbufSetStatic(&info->architecture, "x86_64"); + break; + case PROCESSOR_ARCHITECTURE_IA64: + ffStrbufSetStatic(&info->architecture, "ia64"); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + ffStrbufSetStatic(&info->architecture, "i686"); + break; + case PROCESSOR_ARCHITECTURE_ARM64: + ffStrbufSetStatic(&info->architecture, "aarch64"); + break; + case PROCESSOR_ARCHITECTURE_ARM: + ffStrbufSetStatic(&info->architecture, "arm"); + break; + case PROCESSOR_ARCHITECTURE_PPC: + ffStrbufSetStatic(&info->architecture, "ppc"); + break; + case PROCESSOR_ARCHITECTURE_MIPS: + ffStrbufSetStatic(&info->architecture, "mips"); + break; + case PROCESSOR_ARCHITECTURE_ALPHA: + ffStrbufSetStatic(&info->architecture, "alpha"); + break; + case PROCESSOR_ARCHITECTURE_ALPHA64: + ffStrbufSetStatic(&info->architecture, "alpha64"); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN: + default: + ffStrbufSetStatic(&info->architecture, "unknown"); + break; } } diff --git a/src/common/impl/FFlist.c b/src/common/impl/FFlist.c index eddd0fa464..b6fa2cd283 100644 --- a/src/common/impl/FFlist.c +++ b/src/common/impl/FFlist.c @@ -3,15 +3,6 @@ #include #include -void* ffListAdd(FFlist* list, uint32_t elementSize) { - if (list->length == list->capacity) { - ffListReserve(list, elementSize, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2); - } - - ++list->length; - return ffListGet(list, elementSize, list->length - 1); -} - bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result) { if (list->length == 0) { return false; diff --git a/src/common/impl/FFstrbuf.c b/src/common/impl/FFstrbuf.c index 1f6477ba7b..5fa7743f61 100644 --- a/src/common/impl/FFstrbuf.c +++ b/src/common/impl/FFstrbuf.c @@ -45,11 +45,25 @@ void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr) { strbuf->chars = heapStr; } -void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) { - if (ffStrbufGetFree(strbuf) >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) { - return; - } +void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) { + va_list arguments; + va_start(arguments, format); + ffStrbufInitVF(strbuf, format, arguments); + va_end(arguments); +} + +FFstrbuf ffStrbufCreateF(const char* format, ...) { + FFstrbuf strbuf; + va_list arguments; + va_start(arguments, format); + ffStrbufInitVF(&strbuf, format, arguments); + va_end(arguments); + + return strbuf; +} + +void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free) { uint32_t allocate = strbuf->allocated; if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) { allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC; @@ -100,46 +114,6 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) { strbuf->allocated = newCap; } -void ffStrbufClear(FFstrbuf* strbuf) { - assert(strbuf != NULL); - - if (strbuf->allocated == 0) { - strbuf->chars = CHAR_NULL_PTR; - } else { - strbuf->chars[0] = '\0'; - } - - strbuf->length = 0; -} - -void ffStrbufAppendC(FFstrbuf* strbuf, char c) { - ffStrbufEnsureFree(strbuf, 1); - strbuf->chars[strbuf->length++] = c; - strbuf->chars[strbuf->length] = '\0'; -} - -void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) { - if (num == 0) { - return; - } - - ffStrbufEnsureFree(strbuf, num); - memset(&strbuf->chars[strbuf->length], c, num); - strbuf->length += num; - strbuf->chars[strbuf->length] = '\0'; -} - -void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value) { - if (value == NULL || length == 0) { - return; - } - - ffStrbufEnsureFree(strbuf, length); - memcpy(&strbuf->chars[strbuf->length], value, length); - strbuf->length += length; - strbuf->chars[strbuf->length] = '\0'; -} - void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int)) { if (value == NULL) { return; @@ -168,7 +142,7 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) { int written = vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated > 0 ? free + 1 : 0, format, arguments); if (written > 0 && (uint32_t) written > free) { - ffStrbufEnsureFree(strbuf, (uint32_t) written); + ffStrbufEnsureFreeNoCheck(strbuf, (uint32_t) written); written = vsnprintf(strbuf->chars + strbuf->length, (uint32_t) written + 1, format, copy); } @@ -550,33 +524,6 @@ bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c) { return true; } -void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) { - fwrite(strbuf->chars, sizeof(*strbuf->chars), strbuf->length, file); -} - -void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) { - ffStrbufWriteTo(strbuf, file); - fputc('\n', file); -} - -double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue) { - char* str_end; - double result = strtod(strbuf->chars, &str_end); - return str_end == strbuf->chars ? defaultValue : result; -} - -uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue) { - char* str_end; - unsigned long long result = strtoull(strbuf->chars, &str_end, 10); - return str_end == strbuf->chars ? defaultValue : (uint64_t) result; -} - -int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue) { - char* str_end; - long long result = strtoll(strbuf->chars, &str_end, 10); - return str_end == strbuf->chars ? defaultValue : (int64_t) result; -} - void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value) { ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number char* start = strbuf->chars + strbuf->length; diff --git a/src/common/impl/io_windows.c b/src/common/impl/io_windows.c index 24b8d05d1e..e085bf2ca9 100644 --- a/src/common/impl/io_windows.c +++ b/src/common/impl/io_windows.c @@ -177,7 +177,7 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) { } static inline void readWithLength(HANDLE handle, FFstrbuf* buffer, uint32_t length) { - ffStrbufEnsureFree(buffer, length); + ffStrbufEnsureFixedLengthFree(buffer, length); DWORD bytesRead = 0; while ( length > 0 && diff --git a/src/common/impl/library.c b/src/common/impl/library.c index 6f96e968b2..c16e0b11d8 100644 --- a/src/common/impl/library.c +++ b/src/common/impl/library.c @@ -27,7 +27,7 @@ #endif #endif -static void* libraryLoad(const char* path, int maxVersion) { +void* ffLibraryLoadSingle(const char* path, int maxVersion) { void* result = dlopen(path, FF_DLOPEN_FLAGS); #if _WIN32 @@ -81,8 +81,8 @@ static void* libraryLoad(const char* path, int maxVersion) { return result; } -void* ffLibraryLoad(const char* path, int maxVersion, ...) { - void* result = libraryLoad(path, maxVersion); +void* ffLibraryLoadMulti(const char* path, int maxVersion, ...) { + void* result = ffLibraryLoadSingle(path, maxVersion); if (!result) { va_list defaultNames; @@ -95,7 +95,7 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...) { } int maxVersionRest = va_arg(defaultNames, int); - result = libraryLoad(pathRest, maxVersionRest); + result = ffLibraryLoadSingle(pathRest, maxVersionRest); } while (!result); va_end(defaultNames); diff --git a/src/common/impl/tracer.c b/src/common/impl/tracer.c new file mode 100644 index 0000000000..46c0bc072a --- /dev/null +++ b/src/common/impl/tracer.c @@ -0,0 +1,148 @@ +// DON'T CALL ANY EXTERNAL FUNCTION IN THIS FILE + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !_WIN32 + #include + #include + #include +#else + #include + #include +#endif + +#if _WIN32 +static LARGE_INTEGER freq; + #define NtCurrentProcess() ((HANDLE) (-1)) +#endif + +static struct trace_event { + uint64_t ts; + uint64_t tid; + void* func; +} events[4 * 1024 * 1024]; // 4M events, 96 MiB memory usage +static _Atomic uint32_t event_count; + +__attribute__((no_instrument_function, always_inline)) static inline uint64_t get_time_us() { +#if !_WIN32 + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000); +#else + LARGE_INTEGER now; + QueryPerformanceCounter(&now); + return (uint64_t) (now.QuadPart * 1000000 / freq.QuadPart); +#endif +} + +#if _WIN32 +__attribute__((constructor, no_instrument_function)) void trace_init() { + QueryPerformanceFrequency(&freq); +} +#endif + +__attribute__((destructor, no_instrument_function)) void trace_fini() { +#if _WIN32 + uint32_t pid = (uint32_t) GetCurrentProcessId(); +#else + uint32_t pid = (uint32_t) getpid(); +#endif + + char fileName[64]; + snprintf(fileName, sizeof(fileName), "trace_%d.json", pid); + FILE* trace_file = fopen(fileName, "wb"); + if (!trace_file) { + fprintf(stderr, "Failed to open trace file %s for writing\n", fileName); + abort(); + } + + fputs("[\n", trace_file); + +#if _WIN32 + SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME); + SymInitialize(NtCurrentProcess(), NULL, TRUE); +#endif + + const char* fnName = NULL; + + uint32_t count = atomic_load_explicit(&event_count, memory_order_acquire); + for (uint32_t i = 0; i < count; ++i) { + void* fn = events[i].func; + uint64_t ts = events[i].ts; + bool is_exit = (ts >> 63) != 0; + ts &= ~(1ULL << 63); // clear the highest bit + uint64_t tid = events[i].tid; + +#if _WIN32 + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; + PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) buffer; + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_SYM_NAME; + + DWORD64 displacement = 0; + if (SymFromAddr(NtCurrentProcess(), (DWORD64) fn, &displacement, pSymbol)) { + fnName = pSymbol->Name; + } +#else + char buffer[32]; + Dl_info info; + if (dladdr(fn, &info) && info.dli_sname) { + fnName = info.dli_sname; + } +#endif + + else { + snprintf(buffer, sizeof(buffer), "%p", fn); + fnName = buffer; + } + + fprintf(trace_file, "{\"name\":\"%s\",\"ph\":\"%c\",\"pid\":%" PRIu32 ",\"tid\":%" PRIu64 ",\"ts\":%" PRIu64 "}%c\n", fnName, is_exit ? 'E' : 'B', pid, tid, ts, i < count - 1 ? ',' : ' '); + } + + fputc(']', trace_file); + fclose(trace_file); + fprintf(stderr, "Trace written to trace_%d.json with %u events. Use https://ui.perfetto.dev/ to view it.\n", pid, count); + +#if _WIN32 + SymCleanup(NtCurrentProcess()); +#endif +} + +__attribute__((no_instrument_function)) static void write_event(void* this_fn, bool is_exit) { + uint32_t idx = atomic_fetch_add_explicit(&event_count, 1, memory_order_relaxed); + if (__builtin_expect(idx >= sizeof(events) / sizeof(events[0]), false)) { + abort(); + } + + events[idx].ts = get_time_us(); +#if ENABLE_THREADS + #if _WIN32 + events[idx].tid = (uint64_t) GetCurrentThreadId(); + #else + events[idx].tid = (uint64_t) (uintptr_t) pthread_self(); + #endif +#else + events[idx].tid = 0; +#endif + events[idx].func = this_fn; + if (is_exit) { + events[idx].ts |= (1ULL << 63); // set the highest bit to indicate function exit + } +} + +__attribute__((no_instrument_function)) void __cyg_profile_func_enter(void* this_fn, void* call_site) { + (void) call_site; + write_event(this_fn, false); +} + +__attribute__((no_instrument_function)) void __cyg_profile_func_exit(void* this_fn, void* call_site) { + (void) call_site; + write_event(this_fn, true); +} diff --git a/src/common/library.h b/src/common/library.h index 97500ac9ee..a584fbfc86 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -35,9 +35,10 @@ static inline void ffLibraryUnload(void** handle) { #define FF_LIBRARY_SYMBOL(symbolName) \ __typeof__(&symbolName) ff##symbolName; - #define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \ - void* FF_A_CLEANUP(ffLibraryUnload) libraryObjectName = ffLibraryLoad(__VA_ARGS__, NULL); \ - if (libraryObjectName == NULL) \ + #define FF_LIBRARY_LOAD(libraryObjectName, returnValue, libraryFileName, maxVersion, ...) \ + void* FF_A_CLEANUP(ffLibraryUnload) libraryObjectName = ffLibraryLoadSingle(libraryFileName, maxVersion); \ + __VA_OPT__(if (__builtin_expect(libraryObjectName == NULL, false)) libraryObjectName = ffLibraryLoadMulti(__VA_ARGS__, NULL);) \ + if (__builtin_expect(libraryObjectName == NULL, false)) \ return returnValue; #define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \ @@ -45,7 +46,7 @@ static inline void ffLibraryUnload(void** handle) { #define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \ symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \ - if (symbolMapping == NULL) \ + if (__builtin_expect(symbolMapping == NULL, false)) \ return returnValue; #define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \ @@ -66,7 +67,8 @@ static inline void ffLibraryUnload(void** handle) { #define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \ FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff##symbolName, symbolName, returnValue); -void* ffLibraryLoad(const char* path, int maxVersion, ...); +void* ffLibraryLoadSingle(const char* path, int maxVersion); +void* ffLibraryLoadMulti(const char* path, int maxVersion, ...); #else diff --git a/src/common/thread.h b/src/common/thread.h index 64d8478d9c..84c247cae8 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -4,7 +4,7 @@ #ifdef FF_HAVE_THREADS #if defined(_WIN32) - #include + #include "common/windows/nt.h" #include #include #include @@ -41,6 +41,9 @@ static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout) { } NtClose(thread); return true; +} +static inline uintptr_t ffThreadGetCurrentId() { + return (uintptr_t) ffGetTeb()->ClientId.UniqueThread; } #else #include @@ -104,6 +107,9 @@ static inline bool ffThreadJoin(FFThreadType thread, FF_A_UNUSED uint32_t timeou #endif pthread_join(thread, NULL); return true; +} +static inline uintptr_t ffThreadGetCurrentId() { + return (uintptr_t) pthread_self(); } #endif #else // FF_HAVE_THREADS diff --git a/src/detection/media/media_apple.m b/src/detection/media/media_apple.m index d9501d1fb0..6dcc782811 100644 --- a/src/detection/media/media_apple.m +++ b/src/detection/media/media_apple.m @@ -111,8 +111,7 @@ static uint32_t getTrueElapsedTime(CFDictionaryRef info) { } #if !FF_MODULE_DISABLE_MEDIA -__attribute__((visibility("default"), used)) -int ffPrintMediaByMediaRemote(bool saveCover) { +__attribute__((visibility("default"), used)) int ffPrintMediaByMediaRemote(int saveCover) { FFMediaResult media = { .status = ffStrbufCreate(), .song = ffStrbufCreate(), @@ -122,7 +121,7 @@ int ffPrintMediaByMediaRemote(bool saveCover) { .player = ffStrbufCreate(), .cover = ffStrbufCreate(), }; - if (getMediaByMediaRemote(&media, saveCover) != NULL) { + if (getMediaByMediaRemote(&media, !!saveCover) != NULL) { return 1; } ffStrbufAppendC(&media.status, '\n'); @@ -157,13 +156,19 @@ int ffPrintMediaByMediaRemote(bool saveCover) { static const char* getMediaByAuthorizedProcess(FFMediaResult* result, bool saveCover) { // #1737 - FF_STRBUF_AUTO_DESTROY script = ffStrbufCreateF("import ctypes;ctypes.CDLL('%s').ffPrintMediaByMediaRemote(%s)", instance.state.platform.exePath.chars, saveCover ? "True" : "False"); + FF_STRBUF_AUTO_DESTROY script = ffStrbufCreateF("require DynaLoader;\ +my $so = DynaLoader::dl_load_file('%s', 0);\ +my $sym = DynaLoader::dl_find_symbol($so, 'ffPrintMediaByMediaRemote');\ +DynaLoader::dl_install_xsub('fn', $sym, __FILE__);\ +exit(fn(%c))", + instance.state.platform.exePath.chars, + saveCover ? '1' : '0'); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); const char* error = ffProcessAppendStdOut( &buffer, - (char* const[]) { "/usr/bin/python3", // Must be signed by Apple. Homebrew python doesn't work - "-c", + (char* const[]) { "/usr/bin/perl", // Must be signed by Apple. Homebrew version doesn't work + "-e", script.chars, nil }); if (error) { diff --git a/src/detection/os/os_linux.c b/src/detection/os/os_linux.c index d3eeb43268..9e1fcef371 100644 --- a/src/detection/os/os_linux.c +++ b/src/detection/os/os_linux.c @@ -330,6 +330,17 @@ FF_A_UNUSED static void detectDeepinEnhancement(FFOSResult* result) { } } +FF_A_UNUSED static void detectAstraVersion(FFOSResult* result) { + // `PRETTY_NAME` is just `Astra Linux`; the version is in `VERSION_ID`, e.g. `2.12_x86-64` + if (result->version.length == 0) { // Should be empty. Just in case + ffStrbufAppendSUntilC(&result->version, result->versionID.chars, '_'); + } + if (result->version.length > 0) { + ffStrbufAppendC(&result->prettyName, ' '); + ffStrbufAppend(&result->prettyName, &result->version); + } +} + static void detectOS(FFOSResult* os) { #ifdef FF_CUSTOM_OS_RELEASE_PATH parseOsRelease(FF_STR(FF_CUSTOM_OS_RELEASE_PATH), os); @@ -389,6 +400,8 @@ void ffDetectOSImpl(FFOSResult* os) { } } else if (ffStrbufEqualS(&os->id, "deepin")) { detectDeepinEnhancement(os); + } else if (ffStrbufEqualS(&os->id, "astra")) { + detectAstraVersion(os); } #endif } diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index b3c7d67108..1d22083b66 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -19,6 +19,7 @@ #define _PATH_LOCALBASE "/usr/pkg" #elif _WIN32 + #include "common/windows/registry.h" #include "common/windows/version.h" #include @@ -248,6 +249,12 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) { return true; } + FF_AUTO_CLOSE_FD HANDLE hKey = NULL; + if (ffRegOpenSubkeyForRead(ffRegGetRootKeyHandle(HKEY_LOCAL_MACHINE), L"SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine", &hKey, NULL) && ffRegReadStrbuf(hKey, L"PowerShellVersion", version, NULL)) { + return true; + } + + // Extremely slow return ffProcessAppendStdOut(version, (char* const[]) { exe->chars, "-NoLogo", "-NoProfile", "-Command", "$PSVersionTable.PSVersion.ToString()", NULL }) == NULL; } #endif diff --git a/src/detection/wm/wm_linux.c b/src/detection/wm/wm_linux.c index 35dbeb12e8..c890de4aa7 100644 --- a/src/detection/wm/wm_linux.c +++ b/src/detection/wm/wm_linux.c @@ -191,14 +191,19 @@ static const char* getWslg(FFstrbuf* result) { return "Failed to read /mnt/wslg/versions.txt"; } - if (!ffStrbufStartsWithS(result, "WSLg ")) { - return "Failed to find WSLg version"; + if (ffStrbufStartsWithS(result, "WSLg: ")) { // WSL 2.9.3+ + ffStrbufSubstrBeforeFirstC(result, '\n'); + ffStrbufSubstrAfter(result, (uint32_t) (strlen("WSLg: ") - 1)); + } else if (ffStrbufStartsWithS(result, "WSLg ")) { + ffStrbufSubstrBeforeFirstC(result, '\n'); + ffStrbufSubstrBeforeFirstC(result, '+'); + ffStrbufSubstrAfterFirstC(result, ':'); + ffStrbufTrimLeft(result, ' '); + } else { + ffStrbufClear(result); + return "Failed to parse WSLg version from /mnt/wslg/versions.txt"; } - ffStrbufSubstrBeforeFirstC(result, '\n'); - ffStrbufSubstrBeforeFirstC(result, '+'); - ffStrbufSubstrAfterFirstC(result, ':'); - ffStrbufTrimLeft(result, ' '); return NULL; } #endif diff --git a/src/logo/ascii/a.inc b/src/logo/ascii/a.inc index 848cad1dca..dfda555db6 100644 --- a/src/logo/ascii/a.inc +++ b/src/logo/ascii/a.inc @@ -804,7 +804,7 @@ static const FFlogo A[] = { #ifdef FASTFETCH_DATATEXT_LOGO_JANUSLINUX // Ataraxia { - .names = { "Ataraxia Linux", "Ataraxia" }, + .names = { "Ataraxia" }, // New name of JanusLinux .lines = FASTFETCH_DATATEXT_LOGO_JANUSLINUX, .colors = { FF_COLOR_FG_BLUE, @@ -876,6 +876,31 @@ static const FFlogo A[] = { }, }, #endif + #ifdef FASTFETCH_DATATEXT_LOGO_AZURELINUX + // AzureLinux + { + .names = { "AzureLinux" }, + .lines = FASTFETCH_DATATEXT_LOGO_AZURELINUX, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, // konsole... + }, + }, + #endif + #ifdef FASTFETCH_DATATEXT_LOGO_AZURELINUX2 + // AzureLinux2 + { + .names = { "AzureLinux2" }, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_AZURELINUX2, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, // konsole... + }, + }, + #endif // LAST {}, }; diff --git a/src/logo/ascii/a/azurelinux.txt b/src/logo/ascii/a/azurelinux.txt new file mode 100644 index 0000000000..5cf23f4670 --- /dev/null +++ b/src/logo/ascii/a/azurelinux.txt @@ -0,0 +1,16 @@ + $1_((((((((((_ + $1_(((((((((($2///////// + $1_((((((($2//////////// + $1_(((((($2///////////// + $1_(((((($2///////////// + $1_((((((($2\\\\\\\\\\\\\ + $1_((((((((($2\\\\\\\\\\\\\ + $1_((((((($3.........$2\\\\\\\\ + $1_((((($3...............$2\\\\\\ + $1_((((($3..................$2\\\\\ + $1_((((($3.....................$2\\\\ + $1_((((($3.......................$2\\\\ + $1_((((($3.........................$2\\\\ + $1_((((($3...........................$2\\\ + $1_((((($3.............................$2\\ +$1_(((($3................................$2\ \ No newline at end of file diff --git a/src/logo/ascii/a/azurelinux2.txt b/src/logo/ascii/a/azurelinux2.txt new file mode 100644 index 0000000000..b6a9e7562c --- /dev/null +++ b/src/logo/ascii/a/azurelinux2.txt @@ -0,0 +1,16 @@ + $1############ + $1###########$2@@@@@@@@@ + $1########$2@@@@@@@@@@@@ + $1#######$2@@@@@@@@@@@@@ + $1#######$2@@@@@@@@@@@@@ + $1########$2@@@@@@@@@@@@@ + $1##########$2@@@@@@@@@@@@@ + $1########$3&&&&&&&&&$2@@@@@@@@ + $1######$3&&&&&&&&&&&&&&&$2@@@@@@ + $1######$3&&&&&&&&&&&&&&&&&&$2@@@@@ + $1######$3&&&&&&&&&&&&&&&&&&&&&$2@@@@ + $1######$3&&&&&&&&&&&&&&&&&&&&&&&$2@@@@ + $1######$3&&&&&&&&&&&&&&&&&&&&&&&&&$2@@@@ + $1######$3&&&&&&&&&&&&&&&&&&&&&&&&&&&$2@@@ + $1######$3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$2@@ +$1#####$3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$2@ \ No newline at end of file diff --git a/src/logo/ascii/c.inc b/src/logo/ascii/c.inc index 62be28e3de..7c751ec8aa 100644 --- a/src/logo/ascii/c.inc +++ b/src/logo/ascii/c.inc @@ -60,7 +60,7 @@ static const FFlogo C[] = { #ifdef FASTFETCH_DATATEXT_LOGO_CALINIXOS // CalinixOS { - .names = { "Calinix", "calinixos" }, + .names = { "CalinixOS" }, .lines = FASTFETCH_DATATEXT_LOGO_CALINIXOS, .colors = { FF_COLOR_FG_MAGENTA, @@ -72,7 +72,7 @@ static const FFlogo C[] = { #ifdef FASTFETCH_DATATEXT_LOGO_CALINIXOS_SMALL // CalinixOSSmall { - .names = { "Calinix_small", "calinixos_small" }, + .names = { "CalinixOS_small" }, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_CALINIXOS_SMALL, .colors = { @@ -109,7 +109,7 @@ static const FFlogo C[] = { #ifdef FASTFETCH_DATATEXT_LOGO_CELOS // CelOS { - .names = { "Cel", "celos", "cel-linux", "celos-linux" }, + .names = { "CelOS" }, .lines = FASTFETCH_DATATEXT_LOGO_CELOS, .colors = { FF_COLOR_FG_MAGENTA, @@ -166,7 +166,7 @@ static const FFlogo C[] = { #ifdef FASTFETCH_DATATEXT_LOGO_CEREUS // Cereus { - .names = { "Cereus", "Cereus Linux" }, + .names = { "Cereus" }, .lines = FASTFETCH_DATATEXT_LOGO_CEREUS, .colors = { FF_COLOR_FG_256 "173", @@ -232,6 +232,37 @@ static const FFlogo C[] = { .colorTitle = FF_COLOR_FG_RED, }, #endif + #ifdef FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX2 + // Chimera2 + { + .names = { "Chimera2" }, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX2, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_RED, + }, + #endif + #ifdef FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX_SMALL + // Chimera_small + { + .names = { "Chimera_small" }, + .lines = FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX_SMALL, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_RED, + }, + #endif #ifdef FASTFETCH_DATATEXT_LOGO_CHONKYSEALOS // ChonkySealOS { @@ -366,7 +397,7 @@ static const FFlogo C[] = { #ifdef FASTFETCH_DATATEXT_LOGO_FEDORA_COREOS // ContainerLinux { - .names = { "ContainerLinux", "Container Linux", "Container Linux by CoreOS" }, + .names = { "CoreOS", "Container Linux by CoreOS" }, .lines = FASTFETCH_DATATEXT_LOGO_FEDORA_COREOS, .colors = { FF_COLOR_FG_BLUE, diff --git a/src/logo/ascii/c/chimera_linux2.txt b/src/logo/ascii/c/chimera_linux2.txt new file mode 100644 index 0000000000..bdcfaf8795 --- /dev/null +++ b/src/logo/ascii/c/chimera_linux2.txt @@ -0,0 +1,15 @@ +888888888888 $2888 +$1888888888888 $2888 +$1888888888888 $2888 +$188888888P"' $2_,888 +$1888888P' $2,jd88888 +$188888P $2d88P' +$18888b $2j88' xxxxxxxxxx +$3_____ $218{ 8888888888 +$38888b. $2l88, ,88" $3______ +$3888888 $218b,_ ,d88P $3888888 +$3888888b. $2`188bwwd88P' $3,d888888 +$388888888b._ $2`"^^"'`$3.,d88888888 +$3888888888888bo od888888888888 +$388888888888888 88888888888888 +$388888888888888 88888888888888 \ No newline at end of file diff --git a/src/logo/ascii/c/chimera_linux_small.txt b/src/logo/ascii/c/chimera_linux_small.txt new file mode 100644 index 0000000000..405f708557 --- /dev/null +++ b/src/logo/ascii/c/chimera_linux_small.txt @@ -0,0 +1,7 @@ +$3XXXXX $1I: +$3XXX' $1,I; +$3XX $1,f""'.,,,, +$2,, $1I: ;P""" +$2XX $1`t...f' $4jj +$2XXX. $1`"' $4.XXX +$2OOOOOC $4lXXXXX diff --git a/src/logo/ascii/f.inc b/src/logo/ascii/f.inc index 8be44fa17f..eaa0ae0366 100644 --- a/src/logo/ascii/f.inc +++ b/src/logo/ascii/f.inc @@ -169,10 +169,23 @@ static const FFlogo F[] = { .colorTitle = FF_COLOR_FG_DEFAULT, }, #endif + #ifdef FASTFETCH_DATATEXT_LOGO_FLATCAR + // Flatcar + { + .names = { "Flatcar" }, + .lines = FASTFETCH_DATATEXT_LOGO_FLATCAR, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_DEFAULT, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_DEFAULT, + }, + #endif #ifdef FASTFETCH_DATATEXT_LOGO_FILOTIMO // Filotimo { - .names = { "filotimo" }, + .names = { "Filotimo" }, .lines = FASTFETCH_DATATEXT_LOGO_FILOTIMO, .colors = { FF_COLOR_FG_BLUE, diff --git a/src/logo/ascii/f/flatcar.txt b/src/logo/ascii/f/flatcar.txt new file mode 100644 index 0000000000..e0eba3d3a7 --- /dev/null +++ b/src/logo/ascii/f/flatcar.txt @@ -0,0 +1,9 @@ + ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ + ΞΞ ΞΞΞ ΞΞΞ ΞΞ ΞΞΞ + ΞΞ ΞΞΞ Ξ Ξ ΞΞ ΞΞΞΞ + ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ + ΞΞ ΞΞ ΞΞ ΞΞ + Ξ ΞΞ ΞΞΞΞ Ξ ΞΞ Ξ + Ξ ΞΞ ΞΞ ΞΞ Ξ Ξ ΞΞΞ Ξ + Ξ ΞΞ ΞΞ ΞΞ Ξ ΞΞΞ ΞΞΞ Ξ +ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ \ No newline at end of file diff --git a/src/logo/ascii/g.inc b/src/logo/ascii/g.inc index 3fa3f7af72..9ad0d87057 100644 --- a/src/logo/ascii/g.inc +++ b/src/logo/ascii/g.inc @@ -19,7 +19,7 @@ static const FFlogo G[] = { #ifdef FASTFETCH_DATATEXT_LOGO_GARUDA // Garuda { - .names = { "Garuda", "garuda-linux" }, + .names = { "Garuda" }, .lines = FASTFETCH_DATATEXT_LOGO_GARUDA, .colors = { FF_COLOR_FG_RED, @@ -167,7 +167,7 @@ static const FFlogo G[] = { #ifdef FASTFETCH_DATATEXT_LOGO_GOLDENDOGLINUX // GoldenDogLinux { - .names = { "GoldenDog Linux", "GDL", "goldendoglinux" }, + .names = { "GoldenDogLinux" }, .lines = FASTFETCH_DATATEXT_LOGO_GOLDENDOGLINUX, .colors = { FF_COLOR_FG_YELLOW, diff --git a/src/logo/ascii/j.inc b/src/logo/ascii/j.inc index 023f66dfb0..23e16a2d99 100644 --- a/src/logo/ascii/j.inc +++ b/src/logo/ascii/j.inc @@ -6,7 +6,7 @@ static const FFlogo J[] = { #ifdef FASTFETCH_DATATEXT_LOGO_JANUSLINUX // Januslinux { - .names = { "januslinux", "janus" }, + .names = { "januslinux" }, .lines = FASTFETCH_DATATEXT_LOGO_JANUSLINUX, .colors = { FF_COLOR_FG_BLUE, diff --git a/src/logo/ascii/k.inc b/src/logo/ascii/k.inc index 354b7026d8..644106903a 100644 --- a/src/logo/ascii/k.inc +++ b/src/logo/ascii/k.inc @@ -129,7 +129,7 @@ static const FFlogo K[] = { #ifdef FASTFETCH_DATATEXT_LOGO_KISS // KISSLinux { - .names = { "KISS", "kiss-linux", "kisslinux" }, + .names = { "KISS" }, .lines = FASTFETCH_DATATEXT_LOGO_KISS, .colors = { FF_COLOR_FG_MAGENTA, diff --git a/src/logo/ascii/o.inc b/src/logo/ascii/o.inc index b1840dc28e..b5b32a9025 100644 --- a/src/logo/ascii/o.inc +++ b/src/logo/ascii/o.inc @@ -52,7 +52,7 @@ static const FFlogo O[] = { #ifdef FASTFETCH_DATATEXT_LOGO_OPENKYLIN // OpenKylin { - .names = { "openkylin", "open-kylin" }, + .names = { "openKylin" }, .lines = FASTFETCH_DATATEXT_LOGO_OPENKYLIN, .colors = { FF_COLOR_FG_GREEN, @@ -277,7 +277,7 @@ static const FFlogo O[] = { #ifdef FASTFETCH_DATATEXT_LOGO_OPENMANDRIVA // OpenMandriva { - .names = { "openmandriva", "open-mandriva", "open_mandriva", "openmandriva lx" }, + .names = { "OpenMandriva" }, .lines = FASTFETCH_DATATEXT_LOGO_OPENMANDRIVA, .colors = { FF_COLOR_FG_BLUE, @@ -340,7 +340,7 @@ static const FFlogo O[] = { #ifdef FASTFETCH_DATATEXT_LOGO_ORACLE // Oracle { - .names = { "oracle", "oracle linux", "oracle linux server" }, + .names = { "ol", "oracle" }, // ID="ol" .lines = FASTFETCH_DATATEXT_LOGO_ORACLE, .colors = { FF_COLOR_FG_RED, diff --git a/src/logo/ascii/p.inc b/src/logo/ascii/p.inc index be00006f1b..38611147c7 100644 --- a/src/logo/ascii/p.inc +++ b/src/logo/ascii/p.inc @@ -29,7 +29,7 @@ static const FFlogo P[] = { #ifdef FASTFETCH_DATATEXT_LOGO_PARABOLA // Parabola { - .names = { "parabola", "parabola-gnulinux" }, + .names = { "Parabola" }, .lines = FASTFETCH_DATATEXT_LOGO_PARABOLA, .colors = { FF_COLOR_FG_MAGENTA, @@ -41,7 +41,7 @@ static const FFlogo P[] = { #ifdef FASTFETCH_DATATEXT_LOGO_PARABOLA_SMALL // ParabolaSmall { - .names = { "parabola_small", "parabola-gnulinux_small" }, + .names = { "Parabola_small", }, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_PARABOLA_SMALL, .colors = { @@ -51,6 +51,19 @@ static const FFlogo P[] = { .colorTitle = FF_COLOR_FG_MAGENTA, }, #endif + #ifdef FASTFETCH_DATATEXT_LOGO_PARABOLA2_SMALL + // Parabola2Small + { + .names = { "Parabola2_small", }, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_PARABOLA2_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + #endif #ifdef FASTFETCH_DATATEXT_LOGO_PARCH // Parch { @@ -171,7 +184,7 @@ static const FFlogo P[] = { #ifdef FASTFETCH_DATATEXT_LOGO_PEROPESIS // Peropesis { - .names = { "Peropesis", "Peropesis Linux" }, + .names = { "Peropesis" }, .lines = FASTFETCH_DATATEXT_LOGO_PEROPESIS, .colors = { FF_COLOR_FG_WHITE, @@ -271,6 +284,18 @@ static const FFlogo P[] = { }, }, #endif + #ifdef FASTFETCH_DATATEXT_LOGO_POSTMARKETOS2 + // PostMarketOS2 + { + .names = { "PostMarketOS2" }, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_POSTMARKETOS2, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + }, + #endif #ifdef FASTFETCH_DATATEXT_LOGO_POSTMARKETOS_SMALL // PostMarketOSSmall { diff --git a/src/logo/ascii/p/parabola2_small.txt b/src/logo/ascii/p/parabola2_small.txt new file mode 100644 index 0000000000..423fc0720f --- /dev/null +++ b/src/logo/ascii/p/parabola2_small.txt @@ -0,0 +1,7 @@ + _. .d;' ,b, + _.=: `" "` ,d88} +` "888!' + }8!' + ,P/ + ,1' + /' diff --git a/src/logo/ascii/p/postmarketos2.txt b/src/logo/ascii/p/postmarketos2.txt new file mode 100644 index 0000000000..10d22fdfeb --- /dev/null +++ b/src/logo/ascii/p/postmarketos2.txt @@ -0,0 +1,17 @@ + db + d88b + d8888b + d888888b + j88888888b + !888888888b + j| J8^"888888b + d8[;__, '888888b + d88888P' '888888b + d88888P '888888b + d88888P '888888b + d88888P '1^`,.__ + d88888P " ,A888b + d888888, =ooooooooooo888888b + d88888888, "J8888888888888888b + d888888888" ,d88888888888888888b +d88888888P' ,d8888888888888888888b diff --git a/src/logo/ascii/q.inc b/src/logo/ascii/q.inc index 732261e178..be2901fb4a 100644 --- a/src/logo/ascii/q.inc +++ b/src/logo/ascii/q.inc @@ -50,6 +50,18 @@ static const FFlogo Q[] = { }, }, #endif + #ifdef FASTFETCH_DATATEXT_LOGO_QUBES_SMALL + // Qubes + { + .names = { "Qubes_small" }, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_QUBES_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + }, + }, + #endif #ifdef FASTFETCH_DATATEXT_LOGO_QUBYT // Qubyt { diff --git a/src/logo/ascii/q/qubes_small.txt b/src/logo/ascii/q/qubes_small.txt new file mode 100644 index 0000000000..504d5ddaa5 --- /dev/null +++ b/src/logo/ascii/q/qubes_small.txt @@ -0,0 +1,14 @@ + .,dQb,. + .,qdQQQQQQQbq,. + .,qdQQQQQQQQQQQQQQQbq,. +dIQQQQQQQQP"'"1QQQQQQQQ^b +ttttI%QP'` `'1Q%^---| +tttttt |----| +tttttt |----| +tttttt |----| +tttttt |----| +ttttttti, .,;-----| +1ttttttttti, ,----------' + '"^1ttttttt|----------;, + '"^1ttt|---^-------->, + '"1|^'` "^==-:" diff --git a/src/logo/ascii/r.inc b/src/logo/ascii/r.inc index 1052d2a1e9..b0570e08a6 100644 --- a/src/logo/ascii/r.inc +++ b/src/logo/ascii/r.inc @@ -157,7 +157,7 @@ static const FFlogo R[] = { #ifdef FASTFETCH_DATATEXT_LOGO_REDSTAR // RedstarOS { - .names = { "redstar", "redstar-os", "redstaros" }, + .names = { "Redstar" }, .lines = FASTFETCH_DATATEXT_LOGO_REDSTAR, .colors = { FF_COLOR_FG_RED, @@ -257,7 +257,7 @@ static const FFlogo R[] = { #ifdef FASTFETCH_DATATEXT_LOGO_ROSA // RosaLinux { - .names = { "rosa", "rosa-linux", "rosalinux" }, + .names = { "ROSA" }, .lines = FASTFETCH_DATATEXT_LOGO_ROSA, .colors = { FF_COLOR_FG_RGB "250;250;250", diff --git a/src/logo/ascii/s.inc b/src/logo/ascii/s.inc index 78f64f2d80..8fc7e0c66b 100644 --- a/src/logo/ascii/s.inc +++ b/src/logo/ascii/s.inc @@ -75,7 +75,7 @@ static const FFlogo S[] = { #ifdef FASTFETCH_DATATEXT_LOGO_SAMBABOX // SambaBOX { - .names = { "SambaBOX", "Profelis SambaBOX" }, + .names = { "SambaBOX" }, .lines = FASTFETCH_DATATEXT_LOGO_SAMBABOX, .colors = { FF_COLOR_FG_YELLOW, diff --git a/src/logo/ascii/u.inc b/src/logo/ascii/u.inc index 79bad1a23a..05a61b1c06 100644 --- a/src/logo/ascii/u.inc +++ b/src/logo/ascii/u.inc @@ -35,7 +35,7 @@ static const FFlogo U[] = { #ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU // Ubuntu { - .names = { "ubuntu", "ubuntu-linux" }, + .names = { "ubuntu" }, .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU, .colors = { FF_COLOR_FG_RED, @@ -46,7 +46,7 @@ static const FFlogo U[] = { #ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL // UbuntuSmall { - .names = { "ubuntu_small", "ubuntu-linux_small" }, + .names = { "ubuntu_small" }, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL, .colors = { @@ -58,7 +58,7 @@ static const FFlogo U[] = { #ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD // UbuntuOld { - .names = { "ubuntu_old", "ubuntu-linux_old" }, + .names = { "ubuntu_old" }, .type = FF_LOGO_LINE_TYPE_ALTER_BIT, .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD, .colors = { @@ -87,7 +87,7 @@ static const FFlogo U[] = { #ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2_SMALL // UbuntuOld2Small { - .names = { "ubuntu_old2_small", "ubuntu_old2_small" }, + .names = { "ubuntu_old2_small" }, .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2_SMALL, .colors = { @@ -211,7 +211,7 @@ static const FFlogo U[] = { #ifdef FASTFETCH_DATATEXT_LOGO_ULTRAMARINE // Ultramarine { - .names = { "Ultramarine", "Ultramarine Linux" }, + .names = { "Ultramarine" }, .lines = FASTFETCH_DATATEXT_LOGO_ULTRAMARINE, .colors = { FF_COLOR_FG_BLUE, diff --git a/src/logo/image/im6.c b/src/logo/image/im6.c index 3e9d7227e3..824e25a553 100644 --- a/src/logo/image/im6.c +++ b/src/logo/image/im6.c @@ -12,7 +12,12 @@ static FF_LIBRARY_SYMBOL(ResizeImage) } FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData) { - FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8) + // clang-format off + FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, + "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, + "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8 + ) + // clang-format on FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR) FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) { diff --git a/src/logo/image/im7.c b/src/logo/image/im7.c index 636a5fa5b2..796a2caeef 100644 --- a/src/logo/image/im7.c +++ b/src/logo/image/im7.c @@ -12,8 +12,18 @@ static FF_LIBRARY_SYMBOL(ResizeImage) } FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData) { - FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, -1 // Required for Windows + // clang-format off + #if _WIN32 + FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, + "libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, 0 ) + #else + FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, + "libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11, + "libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11 + ) + #endif + // clang-format on FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR) FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) { diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 6dd3212151..673582fe1a 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -553,8 +553,11 @@ static bool printImageKitty(FFLogoRequestData* requestData, const ImageData* ima #ifdef FF_HAVE_CHAFA #include static bool printImageChafa(FFLogoRequestData* requestData, const ImageData* imageData) { - FF_LIBRARY_LOAD(chafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1, "libchafa-0" FF_LIBRARY_EXTENSION, -1 // Required for Windows - ) + #if _WIN32 + FF_LIBRARY_LOAD(chafa, false, "libchafa-0" FF_LIBRARY_EXTENSION, 0) + #else + FF_LIBRARY_LOAD(chafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1) + #endif FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_apply_selectors, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_new, false)