This page documents the foundational infrastructure and utility libraries that underpin the fastfetch codebase. These libraries provide the core data structures and cross-platform abstractions that are used throughout all major systems, including detection, configuration, and output.
For details on how these utilities are used in platform abstraction, see Cross-Platform Abstraction Patterns. For their role in the format string system, see Format String System.
The infrastructure layer consists of:
src/util/platform/FFPlatform.c and related files.__attribute__((__cleanup__)).These utilities are designed for performance, safety, and portability, and are used by all major subsystems in fastfetch.
Sources:
src/util/FFstrbuf.h src/util/FFstrbuf.c src/util/FFlist.h src/util/FFlist.c src/util/platform/FFPlatform.c src/fastfetch.h src/common/init.c
FFstrbuf is a dynamic string buffer that supports both static (non-owning) and dynamic (owning) memory models. It is used for all string manipulation in fastfetch, including module output, configuration parsing, and format string processing.
Sources:
src/util/FFstrbuf.h27-32 src/util/FFstrbuf.c7 src/util/FFstrbuf.c31-56
The allocated == 0 convention is used to indicate a static string, which allows zero-copy operations on string literals until a modification is required.
Sources:
src/util/FFstrbuf.h34-36 src/util/FFstrbuf.h269-275 src/util/FFstrbuf.h284-308 src/util/FFstrbuf.h190-205
The FF_STRBUF_AUTO_DESTROY macro enables automatic cleanup of buffers at scope exit using GCC's __cleanup__ attribute.
FFstrbuf provides a comprehensive set of string manipulation functions, including append, prepend, insert, substring, search, trim, replace, comparison, and transformation.
| Category | Key Functions | Description |
|---|---|---|
| Append | ffStrbufAppendC, ffStrbufAppendS, ffStrbufAppendNS, ffStrbufAppendF | Add to end |
| Prepend | ffStrbufPrependC, ffStrbufPrependNS | Add to beginning |
| Insert | ffStrbufInsertNC | Insert at position |
| Substring | ffStrbufSubstrBefore, ffStrbufSubstrAfter, ffStrbufSubstr | Extract portions |
| Search | ffStrbufFirstIndexC, ffStrbufNextIndexS, ffStrbufCountC | Find characters/strings |
| Trim | ffStrbufTrimLeft, ffStrbufTrimRight, ffStrbufTrimLeftSpace, ffStrbufTrimRightSpace | Remove whitespace/chars |
| Replace | ffStrbufReplaceAllC, ffStrbufRemoveS, ffStrbufRemoveSubstr | Modify content |
| Comparison | ffStrbufEqual, ffStrbufStartsWith, ffStrbufEndsWith, ffStrbufIgnCaseComp | Compare strings |
| Transform | ffStrbufUpperCase, ffStrbufLowerCase, ffStrbufAppendTransformS | Change case |
Sources:
src/util/FFstrbuf.h43-87 src/util/FFstrbuf.c95-268 src/util/FFstrbuf.c317-503
Static string optimization is a key feature of FFstrbuf. When initialized with a string literal, no memory is allocated until a write operation occurs.
Sources:
src/util/FFstrbuf.c235-246 src/util/FFstrbuf.c260-268 src/util/FFstrbuf.c282-293 tests/strbuf.c260-372
FFstrbuf integrates with yyjson for efficient numeric formatting and parsing, avoiding temporary allocations.
Sources:
src/util/FFstrbuf.c546-625 src/util/FFstrbuf.c525-544 src/util/FFstrbuf.h13-17
FFstrbuf provides functions for working with separator-delimited strings, such as those found in environment variables or module lists.
Sources:
src/util/FFstrbuf.c733-785 src/util/FFstrbuf.c824-856 tests/strbuf.c654-708
int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint) appends a UTF-32 codepoint as UTF-8, supporting internationalization and logo rendering.Sources:
src/util/FFstrbuf.c787-817 tests/strbuf.c757-763
ffStrbufGetline() and ffStrbufGetlineRestore() allow efficient iteration over multi-line buffers without copying.Sources:
src/util/FFstrbuf.c663-709 tests/strbuf.c478-582
FFlist is a generic, type-agnostic dynamic array used for storing collections of arbitrary structs (e.g., GPU results, module lists).
Sources:
src/util/FFlist.h12-18 src/util/FFlist.h10 src/util/FFlist.c6-17
FFlist uses macro wrappers to provide type safety for generic storage and iteration.
Sources:
src/util/FFlist.h109-128 src/util/FFlist.h50-54 src/util/FFlist.c6-17
Example usage is found throughout detection and module code, e.g., for storing GPU results or module configurations.
| Operation | Function/Macro | Description | Time Complexity |
|---|---|---|---|
| Initialize | ffListInit(list, elementSize) | Create empty list | O(1) |
| Add | ffListAdd(list) | Append element, return pointer | O(1) amortized |
| Get | ffListGet(list, index) | Access element by index | O(1) |
| Shift | ffListShift(list, result) | Remove and return first element | O(n) |
| Pop | ffListPop(list, result) | Remove and return last element | O(1) |
| Sort | ffListSort(list, compar) | Sort using qsort | O(n log n) |
| Find | ffListFirstIndexComp(list, elem, cmp) | Linear search | O(n) |
| Contains | ffListContains(list, elem, cmp) | Check membership | O(n) |
| Clear | ffListClear(list) | Reset length to 0 | O(1) |
| Destroy | ffListDestroy(list) | Free memory | O(1) |
Sources:
src/util/FFlist.h20-108 src/util/FFlist.c19-38
Both FFstrbuf and FFlist support automatic cleanup using GCC's __attribute__((__cleanup__)), preventing memory leaks even in early returns or exceptions.
Sources:
src/util/FFstrbuf.h602 src/util/FFlist.h115 tests/strbuf.c255-257 tests/list.c118-122
Both data structures use exponential growth to amortize allocation costs.
Sources:
src/util/FFstrbuf.c31-56 src/util/FFstrbuf.c59-81 src/util/FFlist.c6-17 tests/strbuf.c390-450
Both structures support efficient transfer of ownership:
ffStrbufInitMove(&dest, &src) moves buffer contents, leaving src empty.ffListInitMove(&destList, &srcList) moves list contents, leaving srcList empty.Sources:
src/util/FFstrbuf.h141-152 src/util/FFlist.h78-92
FFstrbuf uses yyjson's optimized number formatting for appending integers and doubles.
Sources:
src/util/FFstrbuf.c546-625
Key advantages:
ffStrbufSetJsonVal(&strbuf, jsonVal) reads a JSON string value directly into FFstrbuf with zero-copy, when possible.
Sources:
src/util/FFstrbuf.h228-236 src/util/FFstrbuf.h263-267
Detection modules use FFstrbuf and FFlist for result collection and aggregation.
Sources:
Pattern observed throughout detection modules
The format string system uses FFstrbuf for template parsing and output construction.
Sources:
Pattern from format string system usage
The configuration system uses FFlist for module lists and FFstrbuf for string fields in options.
Sources:
Configuration parsing patterns throughout codebase
| Data Structure | Empty (struct only) | Small (default alloc) | Large (expanded) |
|---|---|---|---|
| FFstrbuf | 12 bytes | 12 + 32 bytes | 12 + allocated |
| FFlist | 20 bytes | 20 + 16*elementSize | 20 + capacity*elementSize |
Assumes 64-bit pointers.
| Operation | FFstrbuf | FFlist |
|---|---|---|
| Append/Add | O(1) amortized | O(1) amortized |
| Prepend | O(n) | N/A |
| Get/Index | O(1) | O(1) |
| Search | O(n) | O(n) |
| Substring | O(1) static, O(n) dynamic | N/A |
| Clear | O(1) | O(1) |
| Destroy | O(1) | O(1) |
Sources:
Implementation analysis, src/util/FFstrbuf.h src/util/FFlist.h
Both data structures have comprehensive test suites:
tests/strbuf.c: 864 lines testing all FFstrbuf operationstests/list.c: 127 lines testing all FFlist operationsTest coverage includes:
Sources: tests/strbuf.c1-864 tests/list.c1-127
Refresh this wiki