Skip to content

Commit

Permalink
Merge pull request #752 from fastfetch-cli/dev
Browse files Browse the repository at this point in the history
Release: v2.8.8
  • Loading branch information
CarterLi committed Mar 8, 2024
2 parents 6a82d73 + 77d71b5 commit 912f6c4
Show file tree
Hide file tree
Showing 78 changed files with 493 additions and 470 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,15 @@
# 2.8.8

Bugfixes:
* Fix old fish version compatibility (#744)
* Fix truncated texts in `--help format` (#745)
* Fix old vulkan-header and libdrm library compatibility (#748, Linux)
* Fix possible segfaults in `--help *-format` (#749)
* Fix invalid resolution detection when using libdrm (Linux, Display)
* Fix segfault when `/sys/devices/system/cpu/cpufreq/` doesn't exist (#750, CPU, Linux)
* Don't detect `SessionLeader` as terminal (Terminal, Linux)
* Fix detection of client IP (Users, Linux)

# 2.8.7

Bugfixes:
Expand Down
5 changes: 2 additions & 3 deletions 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.8.7
VERSION 2.8.8
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
Expand Down Expand Up @@ -233,10 +233,9 @@ endif()

fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
fastfetch_load_text(src/data/help.txt DATATEXT_HELP)
fastfetch_load_text(src/data/help_footer.txt DATATEXT_HELP_FOOTER)
fastfetch_load_text(src/data/help_color.txt DATATEXT_HELP_COLOR)
fastfetch_load_text(src/data/help_format.txt DATATEXT_HELP_FORMAT)
fastfetch_load_text(src/data/help_config.txt DATATEXT_HELP_CONFIG)

configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
Expand Down
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -27,8 +27,10 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/

### Linux

* Ubuntu: `ppa:zhangsongcui3371/fastfetch`
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `dpkg -i fastfetch-<version>-Linux.deb`
Some distros packaged a outdated fastfetch version. Older version is not supported, please always ensure that the latest version is used.

* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or above)
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `dpkg -i fastfetch-<version>-Linux.deb` (for Ubuntu 22.04 or above and Debian 12 or above).
* Arch Linux: `sudo pacman -S fastfetch`. You can also find fastfetch [on the AUR](https://aur.archlinux.org/packages/fastfetch-git).
* Fedora: `sudo dnf install fastfetch`
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
Expand Down
2 changes: 1 addition & 1 deletion completions/fish
@@ -1,7 +1,7 @@
#!/usr/bin/env fish

if not type -q fastfetch
return
exit
end

complete -c fastfetch -f
Expand Down
6 changes: 3 additions & 3 deletions src/common/commandoption.c
Expand Up @@ -26,7 +26,7 @@ void ffPrepareCommandOption(FFdata* data)
FFOptionsModules* const options = &instance.config.modules;
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); // Cannot use `ffStrbufSetStatic` here because we will modify the string

if(ffStrbufContainIgnCaseS(&data->structure, FF_CPUUSAGE_MODULE_NAME))
ffPrepareCPUUsage();
Expand Down Expand Up @@ -118,7 +118,7 @@ static void parseStructureCommand(
}
}

ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
ffPrintError(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
}

void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
Expand Down Expand Up @@ -168,7 +168,7 @@ void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
{
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); // Cannot use `ffStrbufSetStatic` here because we will modify the string

//Parse the structure and call the modules
uint32_t startIndex = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/common/format.h
Expand Up @@ -24,3 +24,7 @@ typedef struct FFformatarg

void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, numArgs, arguments) do {\
static_assert(sizeof(arguments) / sizeof(*(arguments)) == (numArgs), "Invalid number of format arguments");\
ffParseFormatString((buffer), (formatstr), (numArgs), (arguments));\
} while (0)
2 changes: 1 addition & 1 deletion src/common/jsonconfig.c
Expand Up @@ -235,6 +235,6 @@ void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
yyjson_mut_doc_set_root(jsonDoc, obj);
}
else
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
ffPrintError("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
}
}
16 changes: 4 additions & 12 deletions src/common/printing.c
Expand Up @@ -37,9 +37,9 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
else
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
ffParseFormatString(&key, &moduleArgs->key, 1, (FFformatarg[]){
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 1, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex}
});
}));
ffStrbufWriteTo(&key, stdout);
}

Expand All @@ -60,7 +60,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
}
}

void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments)
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (moduleArgs)
Expand Down Expand Up @@ -93,22 +93,14 @@ static void printError(const char* moduleName, uint8_t moduleIndex, const FFModu
putchar('\n');
}

void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...)
void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...)
{
va_list arguments;
va_start(arguments, message);
printError(moduleName, moduleIndex, moduleArgs, printType, message, arguments);
va_end(arguments);
}

void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...)
{
va_list arguments;
va_start(arguments, message);
printError(moduleName, moduleIndex, moduleArgs, FF_PRINT_TYPE_DEFAULT, message, arguments);
va_end(arguments);
}

void ffPrintColor(const FFstrbuf* colorValue)
{
//If the color is not set, this would reset in \033[m, which resets everything.
Expand Down
17 changes: 10 additions & 7 deletions src/common/printing.h
Expand Up @@ -12,14 +12,17 @@ typedef enum FFPrintType {
} FFPrintType;

void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType);
void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
static inline void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments)
{
ffPrintFormatString(moduleName, moduleIndex, moduleArgs, FF_PRINT_TYPE_DEFAULT, numArgs, arguments);
}
FF_C_PRINTF(5, 6) void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
FF_C_PRINTF(4, 5) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, numArgs, arguments) do {\
static_assert(sizeof(arguments) / sizeof(*(arguments)) == (numArgs), "Invalid number of format arguments");\
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (numArgs), (arguments));\
} while (0)
FF_C_PRINTF(5, 6) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
void ffPrintColor(const FFstrbuf* colorValue);
void ffPrintCharTimes(char c, uint32_t times);

void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
#define FF_PRINT_MODULE_FORMAT_HELP_CHECKED(moduleName, def, numArgs, args) do {\
static_assert(sizeof(args) / sizeof(*(args)) == (numArgs), "Invalid number of format arguments");\
ffPrintModuleFormatHelp((moduleName), (def), (numArgs), (args));\
} while (0)
8 changes: 0 additions & 8 deletions src/data/help_config.txt

This file was deleted.

File renamed without changes.
12 changes: 6 additions & 6 deletions src/data/help_format.txt
@@ -1,31 +1,31 @@
A format string is a string that contains placeholders for values.
These placeholders begin with a '{', containing the index of the value, and end with a '}'.
For example the format string "Values: {1} ({2})", with the values "First" and "My second val", will produce
For example the format string "Values: {1} ({2})", with the values "First" and "My second val", will produce "Values: First (My second val)".
The format string can contain placeholders in any order and have multiple occurrences.
To include spaces when setting from the command line, surround the whole string with double quotes (").

If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second v
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.

To make formatting easier, a double open curly brace ("{{") will be printed as a single open curly brace and not
If a value index is misformatted or wants a non-existing value, it will be printed as is, with the curly braces aro
To make formatting easier, a double open curly brace ("{{") will be printed as a single open curly brace and not counted as the beginning of a placeholder.
If a value index is misformatted or wants a non-existing value, it will be printed as is, with the curly braces around it.
If the last placeholder isn't closed, it will be treated like it was at the end of the format string.

To only print something if a variable is set, use "{?<index>} ... {?}".
For example, to only print a second value if it is set, use "{?2} Second value: {2}{?}".
If a "{?}" is found without an opener, it is printed as is.

To only print something if a variable is not set, do the same as with if, just replace every '?' with a '!'.
For example to print a fallback for a second value if it is not set, use "{?2}{2}{?}{/2}Second value fallback{/}"
For example to print a fallback for a second value if it is not set, use "{?2}{2}{?}{/2}Second value fallback{/}".

To stop formatting at any point in the format string, use "{-}".

To print something with color, start a placeholder with a '#' and then the linux terminal color encoding.
"\033[" at the start, and an 'm' at the end is automatically added, so don't do that.
A "{#}" is equivalent to a "{#0}" and resets everything to normal.
For example to print something pink and underline, use "{#4;35}...{#}".
Information about what the numbers mean can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Sele
Information about what the numbers mean can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters.
Which escape codes are supported and how they look is defined by your terminal.

If a format string evaluates to an empty value, the whole line in the output will be discarded.
Expand Down
2 changes: 2 additions & 0 deletions src/detection/cpu/cpu_linux.c
Expand Up @@ -107,6 +107,8 @@ static bool detectFrequency(FFCPUResult* cpu)
{
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/devices/system/cpu/cpufreq/");
FF_AUTO_CLOSE_DIR DIR* dir = opendir(path.chars);
if (!dir) return false;

FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
uint32_t baseLen = path.length;
bool flag = false;
Expand Down
6 changes: 3 additions & 3 deletions src/detection/displayserver/linux/drm.c
Expand Up @@ -143,7 +143,7 @@ static inline const char* drmType2Name(uint32_t connector_type)
return "DPI";
case DRM_MODE_CONNECTOR_WRITEBACK:
return "Writeback";
case DRM_MODE_CONNECTOR_SPI:
case 19 /*DRM_MODE_CONNECTOR_SPI*/:
return "SPI";
case 20 /*DRM_MODE_CONNECTOR_USB*/:
return "USB";
Expand Down Expand Up @@ -250,8 +250,8 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
if (crtc)
{
width = crtc->mode.vdisplay;
height = crtc->mode.hdisplay;
width = crtc->mode.hdisplay;
height = crtc->mode.vdisplay;
refreshRate = crtc->mode.vrefresh;
if (refreshRate == 0)
{
Expand Down
1 change: 1 addition & 0 deletions src/detection/terminalshell/terminalshell_linux.c
Expand Up @@ -231,6 +231,7 @@ static pid_t getShellInfo(FFShellResult* result, pid_t pid)
ffStrEquals(name, "ltrace") ||
ffStrEquals(name, "perf") ||
ffStrEquals(name, "guake-wrapped") ||
ffStrEquals(name, "SessionLeader") || // #750
ffStrContainsIgnCase(name, "debug") ||
ffStrContainsIgnCase(name, "not-found") ||
ffStrEndsWith(name, ".sh")
Expand Down
12 changes: 8 additions & 4 deletions src/detection/users/users_linux.c
Expand Up @@ -10,6 +10,10 @@
#define setutxent setutent
#define getutxent getutent
#endif
#ifdef __linux__
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

const char* ffDetectUsers(FFlist* users)
{
Expand All @@ -33,11 +37,11 @@ const char* ffDetectUsers(FFlist* users)
ffStrbufInitS(&user->hostName, n->ut_host);
ffStrbufInitS(&user->sessionName, n->ut_line);
#ifdef __linux__
if(n->ut_addr_v6[0] || n->ut_addr_v6[1] || n->ut_addr_v6[2] || n->ut_addr_v6[3])
ffStrbufInitF(&user->clientIp, "%u.%u.%u.%u", n->ut_addr_v6[0], n->ut_addr_v6[1], n->ut_addr_v6[2], n->ut_addr_v6[3]);
else
#endif
// https://www.linuxquestions.org/questions/programming-9/get-the-ip-addr-out-from-an-int32_t-value-287687/#post1458622
ffStrbufInitS(&user->clientIp, inet_ntoa((struct in_addr) { .s_addr = (in_addr_t) n->ut_addr_v6[0] }));
#else
ffStrbufInit(&user->clientIp);
#endif
user->loginTime = (uint64_t) n->ut_tv.tv_sec * 1000 + (uint64_t) n->ut_tv.tv_usec / 1000;
}

Expand Down
6 changes: 3 additions & 3 deletions src/detection/vulkan/vulkan.c
Expand Up @@ -18,7 +18,7 @@ static inline void applyVulkanVersion(uint32_t vulkanVersion, FFVersion* ffVersi
ffVersion->patch = VK_VERSION_PATCH(vulkanVersion);
}

static void applyDriverName(VkPhysicalDeviceDriverProperties* properties, FFstrbuf* result)
static void applyDriverName(VkPhysicalDeviceDriverPropertiesKHR* properties, FFstrbuf* result)
{
if(!ffStrSet(properties->driverName))
return;
Expand Down Expand Up @@ -127,8 +127,8 @@ static const char* detectVulkan(FFVulkanResult* result)
//On VK 1.1 and up, we use vkGetPhysicalDeviceProperties2, so we can put VkPhysicalDeviceDriverProperties in the pNext chain.
//This is required to get the driver name and conformance version.

VkPhysicalDeviceDriverProperties driverProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
VkPhysicalDeviceDriverPropertiesKHR driverProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
};
VkPhysicalDeviceProperties2 physicalDeviceProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
Expand Down
2 changes: 1 addition & 1 deletion src/fastfetch.c
Expand Up @@ -135,7 +135,7 @@ static void printFullHelp()
}
yyjson_doc_free(doc);

puts("\n" FASTFETCH_DATATEXT_HELP);
puts("\n" FASTFETCH_DATATEXT_HELP_FOOTER);
}

static bool printSpecificCommandHelp(const char* command)
Expand Down
2 changes: 1 addition & 1 deletion src/fastfetch_datatext.h.in
Expand Up @@ -5,7 +5,7 @@

#define FASTFETCH_DATATEXT_JSON_HELP @DATATEXT_JSON_HELP@
#define FASTFETCH_DATATEXT_STRUCTURE @DATATEXT_STRUCTURE@
#define FASTFETCH_DATATEXT_HELP @DATATEXT_HELP@
#define FASTFETCH_DATATEXT_HELP_FOOTER @DATATEXT_HELP_FOOTER@
#define FASTFETCH_DATATEXT_HELP_COLOR @DATATEXT_HELP_COLOR@
#define FASTFETCH_DATATEXT_HELP_FORMAT @DATATEXT_HELP_FORMAT@
#define FASTFETCH_DATATEXT_HELP_CONFIG @DATATEXT_HELP_CONFIG@
Expand Down

0 comments on commit 912f6c4

Please sign in to comment.