Format: support syntax of {$ENV_VAR} in custom format
Some checks are pending
CI / spellcheck (push) Waiting to run
CI / No-features-test (push) Waiting to run
CI / Linux-amd64 (push) Waiting to run
CI / Linux-aarch64 (push) Waiting to run
CI / Linux-armv7 (push) Waiting to run
CI / Linux-armv6 (push) Waiting to run
CI / Linux-riscv64 (push) Waiting to run
CI / Linux-ppc64le (push) Waiting to run
CI / Musl-amd64 (push) Waiting to run
CI / macOS-universal (push) Waiting to run
CI / SunOS-amd64 (push) Waiting to run
CI / FreeBSD-amd64 (push) Waiting to run
CI / DragonFly-amd64 (push) Waiting to run
CI / OpenBSD-amd64 (push) Waiting to run
CI / NetBSD-amd64 (push) Waiting to run
CI / Windows-amd64 (push) Waiting to run
CI / Release (push) Blocked by required conditions

Fix #1541
This commit is contained in:
Carter Li 2025-02-08 22:11:41 +08:00 committed by 李通洲
parent 486ade0e71
commit 016b1e6961
5 changed files with 61 additions and 26 deletions

View File

@ -56,7 +56,7 @@ jobs:
run: ldd fastfetch run: ldd fastfetch
- name: run tests - name: run tests
run: ctest run: ctest --output-on-failure
linux-amd64: linux-amd64:
name: Linux-amd64 name: Linux-amd64
@ -111,7 +111,7 @@ jobs:
run: ldd fastfetch run: ldd fastfetch
- name: run tests - name: run tests
run: ctest run: ctest --output-on-failure
- name: get fastfetch version - name: get fastfetch version
id: ffversion id: ffversion
@ -150,7 +150,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -189,7 +189,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -225,7 +225,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -260,7 +260,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -295,7 +295,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -334,7 +334,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
shell: alpine.sh {0} shell: alpine.sh {0}
- name: upload artifacts - name: upload artifacts
@ -390,7 +390,7 @@ jobs:
run: otool -L fastfetch run: otool -L fastfetch
- name: run tests - name: run tests
run: ctest run: ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -422,7 +422,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
cpack cpack
- name: upload artifacts - name: upload artifacts
@ -460,7 +460,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -495,7 +495,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -531,7 +531,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -567,7 +567,7 @@ jobs:
time ./fastfetch -c presets/ci.jsonc --format json time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch time ./flashfetch
ldd fastfetch ldd fastfetch
ctest ctest --output-on-failure
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -626,7 +626,7 @@ jobs:
run: ldd fastfetch run: ldd fastfetch
- name: run tests - name: run tests
run: ctest run: ctest --output-on-failure
- name: create zip archive - name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets

View File

@ -16,6 +16,8 @@ Features:
* Capitalize `{type}`'s first letter in custom format (#1543, Display) * Capitalize `{type}`'s first letter in custom format (#1543, Display)
* Support model name detection for s390x (CPU, Linux) * Support model name detection for s390x (CPU, Linux)
* Support more Armbian variants detection (#1547, OS, Linux) * Support more Armbian variants detection (#1547, OS, Linux)
* Support the syntax of `{$ENV_VAR}` in custom format, which will be replaced by the value of the environment variable `ENV_VAR` (#1541)
* This is another way to pass 3rd-party data to fastfetch besides `Custom` module.
Logo: Logo:
* Update arch_old * Update arch_old

View File

@ -259,24 +259,33 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue; continue;
} }
//test for constant, if so evaluate it //test for constant or env var, if so evaluate it
if (firstChar == '$') if (firstChar == '$')
{ {
char* pend = NULL; char* pend = NULL;
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10); int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
uint32_t index = (uint32_t) indexSigned; if (pend == placeholderValue.chars + 1)
bool backward = indexSigned < 0;
if (indexSigned == 0 || *pend != '\0' || instance.config.display.constants.length < index)
{ {
// treat placeholder as an environment variable
char* envValue = getenv(placeholderValue.chars + 1);
if (envValue)
ffStrbufAppendS(buffer, envValue);
else
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length); appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
} }
else
{
// treat placeholder as a constant
uint32_t index = (uint32_t) (indexSigned < 0 ? (int32_t) instance.config.display.constants.length + indexSigned : indexSigned - 1);
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, backward if (*pend != '\0' || instance.config.display.constants.length <= index)
? instance.config.display.constants.length - index appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
: index - 1); else
{
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, index);
ffStrbufAppend(buffer, item); ffStrbufAppend(buffer, item);
}
}
continue; continue;
} }

View File

@ -21,6 +21,8 @@ In 2.24.0 or newer, `{~startIndex,endIndex}` can be specified to slice a string.
If an index is omitted, 0 is used. For example, both `{~,0}` `{~0,}` and `{~,}` are same as `{~0,0}` and will always generate a empty string. If an index is omitted, 0 is used. For example, both `{~,0}` `{~0,}` and `{~,}` are same as `{~0,0}` and will always generate a empty string.
If `,endIndex` is omitted or greater than the length of the string, the length of string is used. If `,endIndex` is omitted or greater than the length of the string, the length of string is used.
In 2.36.0 or newer, `{$NUM}` can be specified to reference a constant defined in `display.constants`. `{$ENV_VAR}` can be specified to reference an environment variable.
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index. 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: {} ({})". 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 value, then the first, and then the second again. 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.

View File

@ -2,6 +2,8 @@
#include "util/textModifier.h" #include "util/textModifier.h"
#include "fastfetch.h" #include "fastfetch.h"
#include <stdlib.h>
static void verify(const char* format, const char* arg, const char* expected, int lineNo) static void verify(const char* format, const char* arg, const char* expected, int lineNo)
{ {
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
@ -113,6 +115,26 @@ int main(void)
VERIFY("output({?1}OK{?}{/1}NOT OK{/})", "", "output(NOT OK)"); VERIFY("output({?1}OK{?}{/1}NOT OK{/})", "", "output(NOT OK)");
} }
#ifndef _WIN32 // Windows doesn't have setenv
{
ffListInit(&instance.config.display.constants, sizeof(FFstrbuf));
ffStrbufInitStatic(ffListAdd(&instance.config.display.constants), "CONST1");
ffStrbufInitStatic(ffListAdd(&instance.config.display.constants), "CONST2");
setenv("FF_TEST", "ENVVAR", 1);
VERIFY("output({$FF_TEST})", "", "output(ENVVAR)");
VERIFY("output({$1})", "", "output(CONST1)");
VERIFY("output({$FF_TEST}{$1})", "", "output(ENVVARCONST1)");
VERIFY("output({$1}{$FF_TEST})", "", "output(CONST1ENVVAR)");
VERIFY("output({$FF_TEST}{$FF_TEST})", "", "output(ENVVARENVVAR)");
VERIFY("output({$1}{$-1})", "", "output(CONST1CONST2)");
VERIFY("output({$FF_INVAL})", "", "output({$FF_INVAL})");
VERIFY("output({$9}{$0}${-9})", "", "output({$9}{$0}${-9})");
VERIFY("output({$1NO})", "", "output({$1NO})");
ffListDestroy(&instance.config.display.constants);
}
#endif
//Success //Success
puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET); puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
} }