Skip to content

Commit 016b1e6

Browse files
committed
Format: support syntax of {$ENV_VAR} in custom format
Fix #1541
1 parent 486ade0 commit 016b1e6

File tree

5 files changed

+61
-26
lines changed

5 files changed

+61
-26
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
run: ldd fastfetch
5757

5858
- name: run tests
59-
run: ctest
59+
run: ctest --output-on-failure
6060

6161
linux-amd64:
6262
name: Linux-amd64
@@ -111,7 +111,7 @@ jobs:
111111
run: ldd fastfetch
112112

113113
- name: run tests
114-
run: ctest
114+
run: ctest --output-on-failure
115115

116116
- name: get fastfetch version
117117
id: ffversion
@@ -150,7 +150,7 @@ jobs:
150150
time ./fastfetch -c presets/ci.jsonc --format json
151151
time ./flashfetch
152152
ldd fastfetch
153-
ctest
153+
ctest --output-on-failure
154154
155155
- name: upload artifacts
156156
uses: actions/upload-artifact@v4
@@ -189,7 +189,7 @@ jobs:
189189
time ./fastfetch -c presets/ci.jsonc --format json
190190
time ./flashfetch
191191
ldd fastfetch
192-
ctest
192+
ctest --output-on-failure
193193
194194
- name: upload artifacts
195195
uses: actions/upload-artifact@v4
@@ -225,7 +225,7 @@ jobs:
225225
time ./fastfetch -c presets/ci.jsonc --format json
226226
time ./flashfetch
227227
ldd fastfetch
228-
ctest
228+
ctest --output-on-failure
229229
230230
- name: upload artifacts
231231
uses: actions/upload-artifact@v4
@@ -260,7 +260,7 @@ jobs:
260260
time ./fastfetch -c presets/ci.jsonc --format json
261261
time ./flashfetch
262262
ldd fastfetch
263-
ctest
263+
ctest --output-on-failure
264264
265265
- name: upload artifacts
266266
uses: actions/upload-artifact@v4
@@ -295,7 +295,7 @@ jobs:
295295
time ./fastfetch -c presets/ci.jsonc --format json
296296
time ./flashfetch
297297
ldd fastfetch
298-
ctest
298+
ctest --output-on-failure
299299
300300
- name: upload artifacts
301301
uses: actions/upload-artifact@v4
@@ -334,7 +334,7 @@ jobs:
334334
time ./fastfetch -c presets/ci.jsonc --format json
335335
time ./flashfetch
336336
ldd fastfetch
337-
ctest
337+
ctest --output-on-failure
338338
shell: alpine.sh {0}
339339

340340
- name: upload artifacts
@@ -390,7 +390,7 @@ jobs:
390390
run: otool -L fastfetch
391391

392392
- name: run tests
393-
run: ctest
393+
run: ctest --output-on-failure
394394

395395
- name: upload artifacts
396396
uses: actions/upload-artifact@v4
@@ -422,7 +422,7 @@ jobs:
422422
time ./fastfetch -c presets/ci.jsonc --format json
423423
time ./flashfetch
424424
ldd fastfetch
425-
ctest
425+
ctest --output-on-failure
426426
cpack
427427
428428
- name: upload artifacts
@@ -460,7 +460,7 @@ jobs:
460460
time ./fastfetch -c presets/ci.jsonc --format json
461461
time ./flashfetch
462462
ldd fastfetch
463-
ctest
463+
ctest --output-on-failure
464464
465465
- name: upload artifacts
466466
uses: actions/upload-artifact@v4
@@ -495,7 +495,7 @@ jobs:
495495
time ./fastfetch -c presets/ci.jsonc --format json
496496
time ./flashfetch
497497
ldd fastfetch
498-
ctest
498+
ctest --output-on-failure
499499
500500
- name: upload artifacts
501501
uses: actions/upload-artifact@v4
@@ -531,7 +531,7 @@ jobs:
531531
time ./fastfetch -c presets/ci.jsonc --format json
532532
time ./flashfetch
533533
ldd fastfetch
534-
ctest
534+
ctest --output-on-failure
535535
536536
- name: upload artifacts
537537
uses: actions/upload-artifact@v4
@@ -567,7 +567,7 @@ jobs:
567567
time ./fastfetch -c presets/ci.jsonc --format json
568568
time ./flashfetch
569569
ldd fastfetch
570-
ctest
570+
ctest --output-on-failure
571571
572572
- name: upload artifacts
573573
uses: actions/upload-artifact@v4
@@ -626,7 +626,7 @@ jobs:
626626
run: ldd fastfetch
627627

628628
- name: run tests
629-
run: ctest
629+
run: ctest --output-on-failure
630630

631631
- name: create zip archive
632632
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Features:
1616
* Capitalize `{type}`'s first letter in custom format (#1543, Display)
1717
* Support model name detection for s390x (CPU, Linux)
1818
* Support more Armbian variants detection (#1547, OS, Linux)
19+
* Support the syntax of `{$ENV_VAR}` in custom format, which will be replaced by the value of the environment variable `ENV_VAR` (#1541)
20+
* This is another way to pass 3rd-party data to fastfetch besides `Custom` module.
1921

2022
Logo:
2123
* Update arch_old

src/common/format.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -259,24 +259,33 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
259259
continue;
260260
}
261261

262-
//test for constant, if so evaluate it
262+
//test for constant or env var, if so evaluate it
263263
if (firstChar == '$')
264264
{
265265
char* pend = NULL;
266266
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
267-
uint32_t index = (uint32_t) indexSigned;
268-
bool backward = indexSigned < 0;
269-
270-
if (indexSigned == 0 || *pend != '\0' || instance.config.display.constants.length < index)
267+
if (pend == placeholderValue.chars + 1)
271268
{
272-
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
273-
continue;
269+
// treat placeholder as an environment variable
270+
char* envValue = getenv(placeholderValue.chars + 1);
271+
if (envValue)
272+
ffStrbufAppendS(buffer, envValue);
273+
else
274+
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
274275
}
276+
else
277+
{
278+
// treat placeholder as a constant
279+
uint32_t index = (uint32_t) (indexSigned < 0 ? (int32_t) instance.config.display.constants.length + indexSigned : indexSigned - 1);
275280

276-
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, backward
277-
? instance.config.display.constants.length - index
278-
: index - 1);
279-
ffStrbufAppend(buffer, item);
281+
if (*pend != '\0' || instance.config.display.constants.length <= index)
282+
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
283+
else
284+
{
285+
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, index);
286+
ffStrbufAppend(buffer, item);
287+
}
288+
}
280289
continue;
281290
}
282291

src/data/help_format.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ In 2.24.0 or newer, `{~startIndex,endIndex}` can be specified to slice a string.
2121
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.
2222
If `,endIndex` is omitted or greater than the length of the string, the length of string is used.
2323

24+
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.
25+
2426
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
2527
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
2628
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.

tests/format.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include "util/textModifier.h"
33
#include "fastfetch.h"
44

5+
#include <stdlib.h>
6+
57
static void verify(const char* format, const char* arg, const char* expected, int lineNo)
68
{
79
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
@@ -113,6 +115,26 @@ int main(void)
113115
VERIFY("output({?1}OK{?}{/1}NOT OK{/})", "", "output(NOT OK)");
114116
}
115117

118+
#ifndef _WIN32 // Windows doesn't have setenv
119+
{
120+
ffListInit(&instance.config.display.constants, sizeof(FFstrbuf));
121+
ffStrbufInitStatic(ffListAdd(&instance.config.display.constants), "CONST1");
122+
ffStrbufInitStatic(ffListAdd(&instance.config.display.constants), "CONST2");
123+
setenv("FF_TEST", "ENVVAR", 1);
124+
VERIFY("output({$FF_TEST})", "", "output(ENVVAR)");
125+
VERIFY("output({$1})", "", "output(CONST1)");
126+
VERIFY("output({$FF_TEST}{$1})", "", "output(ENVVARCONST1)");
127+
VERIFY("output({$1}{$FF_TEST})", "", "output(CONST1ENVVAR)");
128+
VERIFY("output({$FF_TEST}{$FF_TEST})", "", "output(ENVVARENVVAR)");
129+
VERIFY("output({$1}{$-1})", "", "output(CONST1CONST2)");
130+
131+
VERIFY("output({$FF_INVAL})", "", "output({$FF_INVAL})");
132+
VERIFY("output({$9}{$0}${-9})", "", "output({$9}{$0}${-9})");
133+
VERIFY("output({$1NO})", "", "output({$1NO})");
134+
ffListDestroy(&instance.config.display.constants);
135+
}
136+
#endif
137+
116138
//Success
117139
puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
118140
}

0 commit comments

Comments
 (0)