2021-02-18 22:25:36 +01:00
#include "fastfetch.h"
2022-07-25 13:15:01 +02:00
#include "common/printing.h"
2022-07-25 13:59:19 +02:00
#include "common/parsing.h"
2023-01-28 12:40:12 +01:00
#include "common/io/io.h"
2022-12-14 11:30:50 +08:00
#include "common/time.h"
2023-02-01 15:56:25 +01:00
#include "util/FFvaluestore.h"
#include "util/stringUtils.h"
2021-02-18 22:25:36 +01:00
2022-06-18 14:25:31 +02:00
#include <stdlib.h>
2022-08-21 21:08:11 +02:00
#include <ctype.h>
2021-04-09 14:07:05 +02:00
#include <string.h>
2022-12-14 11:30:50 +08:00
#include <inttypes.h>
2021-02-22 16:52:51 +01:00
2022-10-13 18:12:54 +08:00
#ifdef WIN32
#include "util/windows/getline.h"
#endif
2022-08-20 18:17:00 +02:00
typedef struct CustomValue
{
bool printKey ;
FFstrbuf value ;
} CustomValue ;
2021-06-13 17:44:34 +05:30
// Things only needed by fastfetch
2021-03-03 19:59:39 +01:00
typedef struct FFdata
{
2022-08-20 18:17:00 +02:00
FFvaluestore customValues ;
2021-03-19 20:57:07 +01:00
FFstrbuf structure ;
2022-07-21 14:37:13 +02:00
bool loadUserConfig ;
2021-03-03 19:59:39 +01:00
} FFdata ;
2021-03-21 11:18:06 +01:00
static void constructAndPrintCommandHelpFormat ( const char * name , const char * def , uint32_t numArgs , ...)
2021-03-19 20:57:07 +01:00
{
2021-03-21 11:18:06 +01:00
va_list argp ;
va_start ( argp , numArgs );
2021-03-19 20:57:07 +01:00
2021-03-21 11:18:06 +01:00
printf ( "--%s-format: \n " , name );
printf ( "Sets the format string for %s output. \n " , name );
puts ( "To see how a format string is constructed, take a look at \" fastfetch --help format \" ." );
2021-05-15 08:39:20 +02:00
puts ( "The following values are passed:" );
2021-03-19 20:57:07 +01:00
2021-03-21 11:18:06 +01:00
for ( uint32_t i = 1 ; i <= numArgs ; i ++ )
printf ( " {%u}: %s \n " , i , va_arg ( argp , const char * ));
2021-03-19 20:57:07 +01:00
2022-06-14 17:10:46 +02:00
printf ( "The default is something similar to \" %s \" . \n " , def );
2021-03-19 20:57:07 +01:00
2021-03-21 11:18:06 +01:00
va_end ( argp );
2021-03-11 22:15:48 +01:00
}
2021-03-11 19:40:46 +01:00
static inline void printCommandHelp ( const char * command )
2021-02-20 19:32:57 +01:00
{
2021-10-22 21:53:29 +02:00
if ( command == NULL )
2022-12-12 13:43:10 +01:00
puts ( FASTFETCH_DATATEXT_HELP );
2021-10-22 21:53:29 +02:00
else if ( strcasecmp ( command , "c" ) == 0 || strcasecmp ( command , "color" ) == 0 )
2022-12-12 13:43:10 +01:00
puts ( FASTFETCH_DATATEXT_HELP_COLOR );
2021-03-21 11:18:06 +01:00
else if ( strcasecmp ( command , "format" ) == 0 )
2022-12-12 13:43:10 +01:00
puts ( FASTFETCH_DATATEXT_HELP_FORMAT );
2021-10-22 21:53:29 +02:00
else if ( strcasecmp ( command , "load-config" ) == 0 || strcasecmp ( command , "loadconfig" ) == 0 || strcasecmp ( command , "config" ) == 0 )
2022-12-12 13:43:10 +01:00
puts ( FASTFETCH_DATATEXT_HELP_CONFIG );
2021-03-12 10:17:49 +01:00
else if ( strcasecmp ( command , "os-format" ) == 0 )
2021-03-27 17:48:32 +01:00
{
constructAndPrintCommandHelpFormat ( "os" , "{3} {12}" , 12 ,
2021-05-15 08:39:20 +02:00
"System name (typically just Linux)" ,
2021-03-27 17:48:32 +01:00
"Name of the OS" ,
"Pretty name of the OS" ,
"ID of the OS" ,
"ID like of the OS" ,
"Variant of the OS" ,
"Variant ID of the OS" ,
"Version of the OS" ,
"Version ID of the OS" ,
"Version codename of the OS" ,
"Build ID of the OS" ,
"Architecture of the OS"
);
}
2021-03-12 12:16:41 +01:00
else if ( strcasecmp ( command , "host-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-10-05 17:03:30 +08:00
constructAndPrintCommandHelpFormat ( "host" , "{2} {3}" , 8 ,
2022-06-14 17:10:46 +02:00
"product family" ,
"product name" ,
"product version" ,
"product sku" ,
"chassis type" ,
"chassis vendor" ,
"chassis version" ,
"sys vendor"
2021-04-03 11:39:59 +02:00
);
}
2022-10-05 00:41:43 +08:00
else if ( strcasecmp ( command , "bios-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "bios" , "{2} {3}" , 4 ,
"bios date" ,
"bios release" ,
"bios vendor" ,
"bios version"
);
}
2022-10-05 17:03:30 +08:00
else if ( strcasecmp ( command , "board-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "board" , "{2} {3}" , 3 ,
"board name" ,
"board vendor" ,
"board version"
);
}
2022-12-24 22:48:10 +08:00
else if ( strcasecmp ( command , "chassis-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "chassis" , "{2} {3}" , 4 ,
"chassis type" ,
"chassis vendor" ,
"chassis version"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "kernel-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "kernel" , "{2}" , 3 ,
"Kernel sysname" ,
"Kernel release" ,
"Kernel version"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "uptime-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "uptime" , "{} days {} hours {} mins" , 4 ,
"Days" ,
"Hours" ,
"Minutes" ,
"Seconds"
);
}
2021-10-18 22:38:00 +08:00
else if ( strcasecmp ( command , "processes-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "processes" , "{}" , 1 ,
"Count"
);
}
2021-03-11 19:40:46 +01:00
else if ( strcasecmp ( command , "packages-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-12-27 17:36:58 +08:00
constructAndPrintCommandHelpFormat ( "packages" , "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (eopkg), {8} (xbps), {9} (nix-system), {10} (nix-user), {11} (nix-default), {12} (apk), {13} (pkg), {14} (flatpak), {15} (snap), {16} (brew), {17} (brew-cask), {18} (port), {19} (scoop), {20} (choco)" , 20 ,
2021-04-03 11:39:59 +02:00
"Number of all packages" ,
"Number of pacman packages" ,
2021-05-15 18:17:34 +02:00
"Pacman branch on manjaro" ,
2021-05-01 21:22:07 +02:00
"Number of dpkg packages" ,
2021-06-08 20:01:29 +02:00
"Number of rpm packages" ,
2022-02-12 12:13:02 +01:00
"Number of emerge packages" ,
2022-12-27 17:36:58 +08:00
"Number of eopkg packages" ,
2021-06-08 20:01:29 +02:00
"Number of xbps packages" ,
2022-07-26 19:03:15 +02:00
"Number of nix-system packages" ,
2022-07-26 19:15:00 +02:00
"Number of nix-user packages" ,
2022-06-02 22:58:19 +02:00
"Number of nix-default packages" ,
2022-08-18 22:02:21 +02:00
"Number of apk packages" ,
2022-09-20 11:16:08 +02:00
"Number of pkg packages" ,
2021-04-28 19:45:43 +02:00
"Number of flatpak packages" ,
2022-09-05 05:15:19 -07:00
"Number of snap packages" ,
2022-09-16 11:08:10 -06:00
"Number of brew packages" ,
2022-12-27 17:36:58 +08:00
"Number of brew-cask packages" ,
"Number of macports packages" ,
"Number of scoop packages" ,
"Number of choco packages"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "shell-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2021-06-14 23:22:14 +02:00
constructAndPrintCommandHelpFormat ( "shell" , "{3} {4}" , 7 ,
"Shell process name" ,
"Shell path with exe name" ,
"Shell exe name" ,
"Shell version" ,
"User shell path with exe name" ,
"User shell exe name" ,
"User shell version"
2021-04-03 11:39:59 +02:00
);
}
2023-01-18 01:37:47 +08:00
else if ( strcasecmp ( command , "display-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2023-02-02 18:16:56 +01:00
constructAndPrintCommandHelpFormat ( "display" , "{}x{} @ {}Hz" , 5 ,
2021-04-03 11:39:59 +02:00
"Screen width" ,
"Screen height" ,
2023-01-07 22:37:01 +01:00
"Screen refresh rate" ,
2023-02-02 18:16:56 +01:00
"Screen scaled width" ,
"Screen scaled height"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "de-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-01-02 16:55:26 +01:00
constructAndPrintCommandHelpFormat ( "de" , "{2} {3}" , 3 ,
2021-05-01 13:03:30 +02:00
"DE process name" ,
"DE pretty name" ,
"DE version"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "wm-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-01-02 16:55:26 +01:00
constructAndPrintCommandHelpFormat ( "wm" , "{2} ({3})" , 3 ,
2021-04-03 11:39:59 +02:00
"WM process name" ,
2021-04-25 21:32:35 +02:00
"WM pretty name" ,
"WM protocol name"
2021-04-03 11:39:59 +02:00
);
}
2021-04-03 23:10:14 +02:00
else if ( strcasecmp ( command , "wm-theme-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "wm-theme" , "{}" , 1 ,
"WM theme name"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "theme-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2021-04-09 19:21:56 +02:00
constructAndPrintCommandHelpFormat ( "theme" , "{} ({3}) [Plasma], {7}" , 7 ,
2021-04-03 11:39:59 +02:00
"Plasma theme" ,
2021-04-09 19:21:56 +02:00
"Plasma color scheme" ,
"Plasma color scheme pretty" ,
2021-04-03 11:39:59 +02:00
"GTK2 theme" ,
"GTK3 theme" ,
"GTK4 theme" ,
"Combined GTK themes"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "icons-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "icons" , "{} [Plasma], {5}" , 5 ,
"Plasma icons" ,
"GTK2 icons" ,
"GTK3 icons" ,
"GTK4 icons" ,
"Combined GTK icons"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "font-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-09-29 14:15:11 +02:00
constructAndPrintCommandHelpFormat ( "font" , "{} [QT], {} [GTK2], {} [GTK3], {} [GTK4]" , 4 ,
"Font 1" ,
"Font 2" ,
"Font 3" ,
"Font 4"
2021-04-03 11:39:59 +02:00
);
}
2021-06-20 21:04:55 +02:00
else if ( strcasecmp ( command , "cursor-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "cursor" , "{} ({}pt)" , 2 ,
"Cursor theme" ,
"Cursor size"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "terminal-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-09-12 15:57:05 +10:00
constructAndPrintCommandHelpFormat ( "terminal" , "{3}" , 10 ,
2021-04-03 11:39:59 +02:00
"Terminal process name" ,
2021-06-14 23:22:14 +02:00
"Terminal path with exe name" ,
2022-09-12 15:57:05 +10:00
"Terminal exe name" ,
"Shell process name" ,
"Shell path with exe name" ,
"Shell exe name" ,
"Shell version" ,
"User shell path with exe name" ,
"User shell exe name" ,
"User shell version"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "terminal-font-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-09-18 15:53:51 +02:00
constructAndPrintCommandHelpFormat ( "terminal-font" , "{}" , 4 ,
"Terminal font" ,
2021-04-05 19:25:34 +02:00
"Terminal font name" ,
"Termianl font size" ,
2021-05-23 19:40:34 +02:00
"Terminal font styles"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "cpu-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-09-04 14:12:04 -07:00
constructAndPrintCommandHelpFormat ( "cpu" , "{1} ({5}) @ {7}GHz" , 8 ,
"Name" ,
"Vendor" ,
"Physical core count" ,
"Logical core count" ,
"Online core count" ,
"Min frequency" ,
"Max frequency" ,
"Temperature"
2021-04-03 11:39:59 +02:00
);
}
2021-11-24 16:16:25 +08:00
else if ( strcasecmp ( command , "cpu-usage-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "cpu-usage" , "{0}%" , 1 ,
"CPU usage without percent mark"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "gpu-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2023-01-12 11:41:07 +01:00
constructAndPrintCommandHelpFormat ( "gpu" , "{} {}" , 6 ,
2021-04-03 11:39:59 +02:00
"GPU vendor" ,
2021-05-07 17:10:22 +02:00
"GPU name" ,
2022-06-17 23:38:33 +02:00
"GPU driver" ,
2022-09-16 18:11:39 +08:00
"GPU temperature" ,
2023-01-12 11:41:07 +01:00
"GPU core count" ,
"GPU type"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "memory-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-08-26 16:02:04 +02:00
constructAndPrintCommandHelpFormat ( "memory" , "{} / {} ({}%)" , 3 ,
"Used size" ,
"Total size" ,
"Percentage used"
2021-04-03 11:39:59 +02:00
);
}
2022-09-08 14:51:31 +02:00
else if ( strcasecmp ( command , "swap-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "swap" , "{} / {} ({}%)" , 3 ,
"Used size" ,
"Total size" ,
"Percentage used"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "disk-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2022-10-17 17:35:06 +02:00
constructAndPrintCommandHelpFormat ( "disk" , "{1} / {2} ({3}%)" , 9 ,
"Size used" ,
"Size total" ,
"Size percentage" ,
"Files used" ,
"Files total" ,
"Files percentage" ,
"True if removable volume" ,
"True if hidden volume" ,
"Filesystem"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "battery-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2021-05-30 21:35:04 +02:00
constructAndPrintCommandHelpFormat ( "battery" , "{}%, {}" , 5 ,
2021-04-03 11:39:59 +02:00
"Battery manufactor" ,
"Battery model" ,
"Battery technology" ,
"Battery capacity" ,
"Battery status"
);
}
2022-09-23 14:59:28 +08:00
else if ( strcasecmp ( command , "poweradapter-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "poweradapter" , "{}%, {}" , 5 ,
"PowerAdapter watts" ,
"PowerAdapter name" ,
"PowerAdapter manufacturer" ,
"PowerAdapter model" ,
"PowerAdapter description"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "locale-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "locale" , "{}" , 1 ,
"Locale code"
);
}
2022-01-11 12:36:32 +01:00
else if ( strcasecmp ( command , "local-ip-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "local-ip" , "{}" , 1 ,
"Local IP address"
);
}
else if ( strcasecmp ( command , "public-ip-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "public-ip" , "{}" , 1 ,
"Public IP address"
);
}
2022-11-26 18:23:08 +08:00
else if ( strcasecmp ( command , "wifi-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "wifi" , "{4} - {6}" , 3 ,
"Interface description" ,
"Interface status" ,
"Connection status" ,
"Connection SSID" ,
"Connection mac address" ,
2023-01-17 12:45:26 +08:00
"Connection protocol" ,
2022-11-26 18:23:08 +08:00
"Connection signal quality (percentage)" ,
"Connection RX rate" ,
"Connection TX rate" ,
2023-01-17 12:45:26 +08:00
"Connection Security algorithm"
2022-11-26 18:23:08 +08:00
);
}
2022-02-13 23:51:13 +01:00
else if ( strcasecmp ( command , "player-format" ) == 0 )
{
2022-09-11 13:09:33 +02:00
constructAndPrintCommandHelpFormat ( "player" , "{}" , 4 ,
2022-03-22 18:59:04 +01:00
"Pretty player name" ,
"Player name" ,
2022-09-11 13:09:33 +02:00
"DBus bus name" ,
"URL name"
2022-02-13 23:51:13 +01:00
);
}
2022-12-30 10:47:57 +08:00
else if ( strcasecmp ( command , "media-format" ) == 0 )
2022-02-13 23:51:13 +01:00
{
2022-12-30 10:47:57 +08:00
constructAndPrintCommandHelpFormat ( "media" , "{3} - {1}" , 4 ,
2022-09-11 13:09:33 +02:00
"Pretty media name" ,
"Media name" ,
2022-02-13 23:51:13 +01:00
"Artist name" ,
2022-09-11 13:09:33 +02:00
"Album name"
2022-02-13 23:51:13 +01:00
);
}
2022-02-25 13:30:37 +01:00
else if ( strcasecmp ( command , "datetime-format" ) == 0 || strcasecmp ( command , "date-format" ) == 0 || strcasecmp ( command , "time-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "[date][time]" , "{1}-{4}-{11} {14}:{18}:{20}" , 20 ,
"year" ,
"last two digits of year" ,
"month" ,
"month with leading zero" ,
"month name" ,
"month name short" ,
"week number on year" ,
"weekday" ,
"weekday short" ,
"day in year" ,
"day in month" ,
"day in Week" ,
"hour" ,
2022-06-10 15:12:39 -05:00
"hour with leading zero" ,
2022-02-25 13:30:37 +01:00
"hour 12h format" ,
"hour 12h format with leading zero" ,
"minute" ,
"minute with leading zero" ,
"second" ,
"second with leading zero"
);
}
2022-06-01 00:04:58 +02:00
else if ( strcasecmp ( command , "vulkan-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "vulkan" , "{} (driver), {} (api version)" , 3 ,
"Driver name" ,
"API version" ,
"Conformance version"
);
}
2022-06-04 15:21:34 +02:00
else if ( strcasecmp ( command , "opengl-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "opengl" , "{}" , 3 ,
"version" ,
"renderer" ,
2022-06-04 19:30:26 +02:00
"vendor" ,
"shading language version"
2022-06-04 15:21:34 +02:00
);
}
2022-06-05 00:18:40 +02:00
else if ( strcasecmp ( command , "opencl-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "opencl" , "{}" , 3 ,
"version" ,
"device" ,
"vendor"
);
}
2023-01-24 10:39:33 +01:00
else if ( strcasecmp ( command , "bluetooth-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "bluetooth" , "{1} (4%)" , 4 ,
"Name" ,
"Address" ,
"Type" ,
"Battery percentage"
);
}
2023-01-28 13:45:40 +08:00
else if ( strcasecmp ( command , "sound-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "sound" , "{2} (3%)" , 4 ,
"Main" ,
"Name" ,
"Volume" ,
"Identifier"
);
}
2023-02-01 14:01:39 +08:00
else if ( strcasecmp ( command , "gamepad-format" ) == 0 )
{
constructAndPrintCommandHelpFormat ( "gamepad" , "{1}" , 1 ,
"Name" ,
"Identifier"
);
}
2021-02-20 19:32:57 +01:00
else
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "No specific help for command %s provided \n " , command );
2021-02-20 19:32:57 +01:00
}
2023-01-28 17:19:45 +01:00
static void listAvailablePresets ( FFinstance * instance )
2021-04-25 11:48:25 +02:00
{
2023-01-28 17:19:45 +01:00
FF_LIST_FOR_EACH ( FFstrbuf , path , instance -> state . platform . dataDirs )
2021-04-25 11:48:25 +02:00
{
2023-01-28 17:19:45 +01:00
ffStrbufAppendS ( path , "fastfetch/presets/" );
ffListFilesRecursively ( path -> chars );
2021-04-25 11:48:25 +02:00
}
}
2023-01-28 17:19:45 +01:00
static void listAvailableLogos ( FFinstance * instance )
2021-04-25 11:48:25 +02:00
{
2023-01-15 15:57:26 +01:00
FF_LIST_FOR_EACH ( FFstrbuf , path , instance -> state . platform . dataDirs )
2023-01-08 01:41:09 +01:00
{
2023-01-28 17:19:45 +01:00
ffStrbufAppendS ( path , "fastfetch/logos/" );
ffListFilesRecursively ( path -> chars );
2023-01-08 01:41:09 +01:00
}
2021-04-25 11:48:25 +02:00
}
2023-01-02 16:51:11 +08:00
static void listConfigPaths ( FFinstance * instance )
{
2023-01-15 15:57:26 +01:00
FF_LIST_FOR_EACH ( FFstrbuf , folder , instance -> state . platform . configDirs )
2023-01-02 16:51:11 +08:00
{
ffStrbufAppendS ( folder , "fastfetch/config.conf" );
2023-01-28 11:52:23 +01:00
printf ( "%s%s \n " , folder -> chars , ffPathExists ( folder -> chars , FF_PATHTYPE_FILE ) ? " (*)" : "" );
2023-01-02 16:51:11 +08:00
}
}
2023-01-08 01:41:09 +01:00
static void listDataPaths ( FFinstance * instance )
{
2023-01-15 15:57:26 +01:00
FF_LIST_FOR_EACH ( FFstrbuf , folder , instance -> state . platform . dataDirs )
2023-01-08 01:41:09 +01:00
{
ffStrbufAppendS ( folder , "fastfetch/" );
puts ( folder -> chars );
}
}
2021-04-25 11:48:25 +02:00
static void parseOption ( FFinstance * instance , FFdata * data , const char * key , const char * value );
2022-08-22 12:45:20 +02:00
static bool parseConfigFile ( FFinstance * instance , FFdata * data , const char * path )
2021-04-25 11:48:25 +02:00
{
2022-08-22 12:45:20 +02:00
FILE * file = fopen ( path , "r" );
if ( file == NULL )
return false ;
2022-08-21 21:08:11 +02:00
char * line = NULL ;
2021-04-25 11:48:25 +02:00
size_t len = 0 ;
ssize_t read ;
2022-08-21 21:08:11 +02:00
while (( read = getline ( & line , & len , file )) != - 1 )
2021-04-25 11:48:25 +02:00
{
2022-08-21 21:08:11 +02:00
char * lineStart = line ;
char * lineEnd = line + read - 1 ;
//Trim line left
while ( isspace ( * lineStart ))
++ lineStart ;
2021-04-25 11:48:25 +02:00
2022-08-21 21:08:11 +02:00
//Continue if line is empty or a comment
if ( * lineStart == '\0' || * lineStart == '#' )
2021-04-25 11:48:25 +02:00
continue ;
2022-08-21 21:08:11 +02:00
//Trim line right
while ( lineEnd > lineStart && isspace ( * lineEnd ))
-- lineEnd ;
* ( lineEnd + 1 ) = '\0' ;
char * valueStart = strchr ( lineStart , ' ' );
2021-04-25 11:48:25 +02:00
2022-08-21 21:08:11 +02:00
//If the line has no white space, it is only a key
if ( valueStart == NULL )
2021-04-25 11:48:25 +02:00
{
2022-08-21 21:08:11 +02:00
parseOption ( instance , data , lineStart , NULL );
2021-04-25 11:48:25 +02:00
continue ;
}
2022-08-21 21:08:11 +02:00
//separate the key from the value
2021-04-25 11:48:25 +02:00
* valueStart = '\0' ;
++ valueStart ;
2022-08-21 21:08:11 +02:00
//Trim space of value left
while ( isspace ( * valueStart ))
2021-04-25 11:48:25 +02:00
++ valueStart ;
//If we want whitespace in values, we need to quote it. This is done to keep consistency with shell.
2022-08-21 21:08:11 +02:00
if (( * valueStart == '"' || * valueStart == '\'' ) && * valueStart == * lineEnd && lineEnd > valueStart )
2021-04-25 11:48:25 +02:00
{
2022-08-21 21:08:11 +02:00
++ valueStart ;
2022-08-22 12:14:08 +02:00
* lineEnd = '\0' ;
2022-08-21 21:08:11 +02:00
-- lineEnd ;
2021-04-25 11:48:25 +02:00
}
2022-08-21 21:08:11 +02:00
parseOption ( instance , data , lineStart , valueStart );
2021-04-25 11:48:25 +02:00
}
2022-08-21 21:08:11 +02:00
if ( line != NULL )
free ( line );
2022-08-22 12:45:20 +02:00
fclose ( file );
return true ;
2021-04-25 11:48:25 +02:00
}
2023-01-02 12:43:11 +08:00
static void generateConfigFile ( FFinstance * instance , bool force )
{
2023-01-15 15:57:26 +01:00
FFstrbuf * filename = ( FFstrbuf * ) ffListGet ( & instance -> state . platform . configDirs , 0 );
2023-01-02 12:43:11 +08:00
// Paths generated in `init.c/initConfigDirs` end with `/`
ffStrbufAppendS ( filename , "fastfetch/config.conf" );
2023-01-28 11:52:23 +01:00
if ( ! force && ffPathExists ( filename -> chars , FF_PATHTYPE_FILE ))
2023-01-02 12:43:11 +08:00
{
fprintf ( stderr , "Config file exists in `%s`, use `--gen-config-force` to overwrite \n " , filename -> chars );
exit ( 1 );
}
else
{
ffWriteFileData ( filename -> chars , sizeof ( FASTFETCH_DATATEXT_CONFIG_USER ), FASTFETCH_DATATEXT_CONFIG_USER );
2023-01-21 06:27:39 +08:00
printf ( "A sample config file has been written in `%s` \n " , filename -> chars );
2023-01-02 12:43:11 +08:00
exit ( 0 );
}
}
2021-04-25 11:48:25 +02:00
static void optionParseConfigFile ( FFinstance * instance , FFdata * data , const char * key , const char * value )
{
if ( value == NULL )
{
fprintf ( stderr , "Error: usage: %s <file> \n " , key );
exit ( 413 );
}
2022-08-22 12:45:20 +02:00
//Try to load as an absolute path
if ( parseConfigFile ( instance , data , value ))
2021-04-25 11:48:25 +02:00
return ;
2022-08-22 12:45:20 +02:00
2023-01-08 01:41:09 +01:00
//Try to load as a relative path
2021-04-25 11:48:25 +02:00
2023-01-15 20:03:28 +01:00
FFstrbuf absolutePath ;
ffStrbufInitA ( & absolutePath , 128 );
2023-01-15 15:57:26 +01:00
FF_LIST_FOR_EACH ( FFstrbuf , path , instance -> state . platform . dataDirs )
2021-04-25 11:48:25 +02:00
{
2023-01-15 20:03:28 +01:00
//We need to copy it, because if a config file loads a config file, the value of path must be unchanged
ffStrbufSet ( & absolutePath , path );
ffStrbufAppendS ( & absolutePath , "fastfetch/presets/" );
ffStrbufAppendS ( & absolutePath , value );
2022-08-22 12:45:20 +02:00
2023-01-15 20:03:28 +01:00
bool success = parseConfigFile ( instance , data , absolutePath . chars );
2021-04-25 11:48:25 +02:00
2023-01-08 01:41:09 +01:00
if ( success )
return ;
2021-04-25 11:48:25 +02:00
}
2023-01-15 20:03:28 +01:00
ffStrbufDestroy ( & absolutePath );
2022-08-22 12:45:20 +02:00
//File not found
2021-04-25 11:48:25 +02:00
fprintf ( stderr , "Error: couldn't find config: %s \n " , value );
exit ( 414 );
}
2021-12-20 12:12:55 +01:00
static bool optionParseBoolean ( const char * str )
2021-02-27 20:31:54 +01:00
{
2021-03-07 20:35:17 +01:00
return (
2022-01-07 18:00:38 +01:00
! ffStrSet ( str ) ||
2021-03-03 19:59:39 +01:00
strcasecmp ( str , "true" ) == 0 ||
strcasecmp ( str , "yes" ) == 0 ||
2021-04-07 17:36:03 +02:00
strcasecmp ( str , "on" ) == 0 ||
2021-03-03 19:59:39 +01:00
strcasecmp ( str , "1" ) == 0
2021-03-07 20:35:17 +01:00
);
2021-02-27 20:31:54 +01:00
}
2021-12-20 12:12:55 +01:00
static inline void optionCheckString ( const char * key , const char * value , FFstrbuf * buffer )
2021-03-11 19:40:46 +01:00
{
if ( value == NULL )
{
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: usage: %s <str> \n " , key );
2021-03-11 19:40:46 +01:00
exit ( 477 );
}
2021-11-17 10:59:31 +01:00
ffStrbufEnsureFree ( buffer , 63 ); //This is not needed, as ffStrbufSetS will resize capacity if needed, but giving a higher start should improve performance
2021-12-20 12:12:55 +01:00
}
static void optionParseString ( const char * key , const char * value , FFstrbuf * buffer )
{
optionCheckString ( key , value , buffer );
2021-03-19 20:57:07 +01:00
ffStrbufSetS ( buffer , value );
2021-02-27 20:31:54 +01:00
}
2022-10-22 13:02:04 +08:00
static inline bool startsWith ( const char * str , const char * compareTo )
{
return strncasecmp ( str , compareTo , strlen ( compareTo )) == 0 ;
}
2021-12-20 12:12:55 +01:00
static void optionParseColor ( const char * key , const char * value , FFstrbuf * buffer )
{
optionCheckString ( key , value , buffer );
while ( * value != '\0' )
{
2022-10-22 13:02:04 +08:00
#define FF_APPEND_COLOR_CODE_COND(prefix, code) \
if(startsWith(value, #prefix)) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); }
FF_APPEND_COLOR_CODE_COND ( reset_ , "0;" )
else FF_APPEND_COLOR_CODE_COND ( bright_ , "1;" )
else FF_APPEND_COLOR_CODE_COND ( black , "30" )
else FF_APPEND_COLOR_CODE_COND ( red , "31" )
else FF_APPEND_COLOR_CODE_COND ( green , "32" )
else FF_APPEND_COLOR_CODE_COND ( yellow , "33" )
else FF_APPEND_COLOR_CODE_COND ( blue , "34" )
else FF_APPEND_COLOR_CODE_COND ( magenta , "35" )
else FF_APPEND_COLOR_CODE_COND ( cyan , "36" )
else FF_APPEND_COLOR_CODE_COND ( white , "37" )
2022-12-29 12:51:00 -05:00
else
2021-12-20 12:12:55 +01:00
{
ffStrbufAppendC ( buffer , * value );
++ value ;
}
2022-10-22 13:02:04 +08:00
#undef FF_APPEND_COLOR_CODE_COND
2021-12-20 12:12:55 +01:00
}
}
2022-04-02 14:35:43 +02:00
static uint32_t optionParseUInt32 ( const char * key , const char * value )
{
if ( value == NULL )
{
fprintf ( stderr , "Error: usage: %s <num> \n " , key );
exit ( 480 );
}
char * end ;
uint32_t num = ( uint32_t ) strtoul ( value , & end , 10 );
if ( * end != '\0' )
{
fprintf ( stderr , "Error: usage: %s <num> \n " , key );
exit ( 479 );
}
return num ;
}
2022-08-20 18:17:00 +02:00
static void optionParseCustomValue ( FFdata * data , const char * key , const char * value , bool printKey )
2022-08-18 10:44:21 +02:00
{
if ( value == NULL )
{
fprintf ( stderr , "Error: usage: %s <key=value> \n " , key );
exit ( 411 );
}
char * separator = strchr ( value , '=' );
if ( separator == NULL )
{
fprintf ( stderr , "Error: usage: %s <key=value>, '=' missing \n " , key );
exit ( 412 );
}
* separator = '\0' ;
2022-08-20 18:17:00 +02:00
bool created ;
CustomValue * customValue = ffValuestoreSet ( & data -> customValues , value , & created );
if ( created )
ffStrbufInit ( & customValue -> value );
ffStrbufSetS ( & customValue -> value , separator + 1 );
customValue -> printKey = printKey ;
2022-08-18 10:44:21 +02:00
}
2022-08-26 16:02:04 +02:00
static void optionParseEnum ( const char * argumentKey , const char * requestedKey , void * result , ...)
{
if ( requestedKey == NULL )
{
fprintf ( stderr , "Error: usage: %s <value> \n " , argumentKey );
exit ( 476 );
}
va_list args ;
va_start ( args , result );
while ( true )
{
const char * key = va_arg ( args , const char * );
if ( key == NULL )
break ;
int value = va_arg ( args , int ); //C standard guarantees that enumeration constants are presented as ints
if ( strcasecmp ( requestedKey , key ) == 0 )
{
* ( int * ) result = value ;
va_end ( args );
return ;
}
}
va_end ( args );
fprintf ( stderr , "Error: unknown %s value: %s \n " , argumentKey , requestedKey );
exit ( 478 );
}
2022-10-19 15:03:59 +08:00
static bool optionParseModuleArgs ( const char * argumentKey , const char * value , const char * moduleName , struct FFModuleArgs * result )
{
const char * pkey = argumentKey ;
if ( ! ( pkey [ 0 ] == '-' && pkey [ 1 ] == '-' ))
return false ;
pkey += 2 ;
uint32_t moduleNameLen = ( uint32_t ) strlen ( moduleName );
if ( strncasecmp ( pkey , moduleName , moduleNameLen ) != 0 )
return false ;
pkey += moduleNameLen ;
if ( pkey [ 0 ] != '-' )
return false ;
pkey += 1 ;
if ( strcasecmp ( pkey , "key" ) == 0 )
{
optionParseString ( argumentKey , value , & result -> key );
return true ;
}
else if ( strcasecmp ( pkey , "format" ) == 0 )
{
optionParseString ( argumentKey , value , & result -> outputFormat );
return true ;
}
else if ( strcasecmp ( pkey , "error" ) == 0 )
{
optionParseString ( argumentKey , value , & result -> errorFormat );
return true ;
}
return false ;
}
2021-03-03 19:59:39 +01:00
static void parseOption ( FFinstance * instance , FFdata * data , const char * key , const char * value )
2021-02-27 20:31:54 +01:00
{
2022-04-02 14:35:43 +02:00
///////////////////////
//Informative options//
///////////////////////
2021-03-03 19:59:39 +01:00
if ( strcasecmp ( key , "-h" ) == 0 || strcasecmp ( key , "--help" ) == 0 )
{
2021-10-22 21:53:29 +02:00
printCommandHelp ( value );
2021-03-03 19:59:39 +01:00
exit ( 0 );
}
else if ( strcasecmp ( key , "-v" ) == 0 || strcasecmp ( key , "--version" ) == 0 )
2022-03-20 17:12:52 +01:00
{
2023-01-19 14:57:54 +08:00
#ifndef NDEBUG
#define FF_BUILD_TYPE "-debug"
#else
#define FF_BUILD_TYPE
#endif
#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64)
#define FF_ARCHITECTURE "x86_64"
#elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(__i586__) || defined(__i586) || defined(__i686__) || defined(__i686)
#define FF_ARCHITECTURE "i386"
#elif defined(__aarch64__)
#define FF_ARCHITECTURE "aarch64"
#elif defined(__arm__)
#define FF_ARCHITECTURE "arm"
#elif defined(__mips__)
#define FF_ARCHITECTURE "mips"
#elif defined(__powerpc__) || defined(__powerpc)
#define FF_ARCHITECTURE "powerpc"
#elif defined(__riscv__) || defined(__riscv)
#define FF_ARCHITECTURE "riscv"
2023-01-23 20:09:26 -06:00
#elif defined(__s390x__)
#define FF_ARCHITECTURE "s390x"
2023-01-24 10:11:35 +08:00
#else
2023-01-19 14:57:54 +08:00
#define FF_ARCHITECTURE "unknown"
#endif
puts ( "fastfetch " FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK FF_BUILD_TYPE " (" FF_ARCHITECTURE ")" );
#undef FF_ARCHITECTURE
#undef FF_BUILD_TYPE
2022-03-20 17:12:52 +01:00
exit ( 0 );
}
else if ( strcasecmp ( key , "--version-raw" ) == 0 )
2021-03-03 19:59:39 +01:00
{
2022-03-20 13:16:04 +01:00
puts ( FASTFETCH_PROJECT_VERSION );
2021-03-03 19:59:39 +01:00
exit ( 0 );
}
2022-10-22 13:02:04 +08:00
else if ( startsWith ( key , "--print" ))
2021-03-27 19:26:58 +01:00
{
2022-10-22 13:02:04 +08:00
const char * subkey = key + strlen ( "--print" );
if ( strcasecmp ( subkey , "-config-system" ) == 0 )
{
puts ( FASTFETCH_DATATEXT_CONFIG_SYSTEM );
exit ( 0 );
}
else if ( strcasecmp ( subkey , "-config-user" ) == 0 )
{
puts ( FASTFETCH_DATATEXT_CONFIG_USER );
exit ( 0 );
}
else if ( strcasecmp ( subkey , "-structure" ) == 0 )
{
puts ( FASTFETCH_DATATEXT_STRUCTURE );
exit ( 0 );
}
else if ( strcasecmp ( subkey , "-logos" ) == 0 )
{
ffLogoBuiltinPrint ( instance );
exit ( 0 );
}
else
goto error ;
2021-03-03 19:59:39 +01:00
}
2022-10-22 13:02:04 +08:00
else if ( startsWith ( key , "--list" ))
2021-03-03 19:59:39 +01:00
{
2022-10-22 13:02:04 +08:00
const char * subkey = key + strlen ( "--list" );
if ( strcasecmp ( subkey , "-modules" ) == 0 )
{
puts ( FASTFETCH_DATATEXT_MODULES );
exit ( 0 );
}
else if ( strcasecmp ( subkey , "-presets" ) == 0 )
{
listAvailablePresets ( instance );
exit ( 0 );
}
2023-01-02 16:51:11 +08:00
else if ( strcasecmp ( subkey , "-config-paths" ) == 0 )
{
listConfigPaths ( instance );
exit ( 0 );
}
2023-01-08 01:41:09 +01:00
else if ( strcasecmp ( subkey , "-data-paths" ) == 0 )
{
listDataPaths ( instance );
exit ( 0 );
}
2022-10-22 13:02:04 +08:00
else if ( strcasecmp ( subkey , "-features" ) == 0 )
{
ffListFeatures ();
exit ( 0 );
}
else if ( strcasecmp ( subkey , "-logos" ) == 0 )
{
2023-01-28 17:19:45 +01:00
puts ( "Builtin logos:" );
2022-10-22 13:02:04 +08:00
ffLogoBuiltinList ();
2023-01-28 17:19:45 +01:00
puts ( " \n Custom logos:" );
listAvailableLogos ( instance );
2022-10-22 13:02:04 +08:00
exit ( 0 );
}
else if ( strcasecmp ( subkey , "-logos-autocompletion" ) == 0 )
{
ffLogoBuiltinListAutocompletion ();
exit ( 0 );
}
else
goto error ;
2022-04-02 14:35:43 +02:00
}
2021-03-05 23:00:28 +01:00
2022-04-02 14:35:43 +02:00
///////////////////
//General options//
///////////////////
2021-03-03 19:59:39 +01:00
else if ( strcasecmp ( key , "-r" ) == 0 || strcasecmp ( key , "--recache" ) == 0 )
2021-03-11 19:40:46 +01:00
instance -> config . recache = optionParseBoolean ( value );
2021-04-25 11:48:25 +02:00
else if ( strcasecmp ( key , "--load-config" ) == 0 )
optionParseConfigFile ( instance , data , key , value );
2023-01-02 12:43:11 +08:00
else if ( strcasecmp ( key , "--gen-config" ) == 0 )
generateConfigFile ( instance , false );
else if ( strcasecmp ( key , "--gen-config-force" ) == 0 )
generateConfigFile ( instance , true );
2022-10-22 13:02:04 +08:00
else if ( strcasecmp ( key , "--thread" ) == 0 || strcasecmp ( key , "--multithreading" ) == 0 )
2022-07-25 15:01:11 +02:00
instance -> config . multithreading = optionParseBoolean ( value );
2022-12-14 11:30:50 +08:00
else if ( strcasecmp ( key , "--stat" ) == 0 )
2022-12-14 13:52:16 +08:00
{
if (( instance -> config . stat = optionParseBoolean ( value )))
instance -> config . showErrors = true ;
}
2021-05-09 21:41:17 +02:00
else if ( strcasecmp ( key , "--allow-slow-operations" ) == 0 )
instance -> config . allowSlowOperations = optionParseBoolean ( value );
2022-06-02 23:06:49 +02:00
else if ( strcasecmp ( key , "--escape-bedrock" ) == 0 )
instance -> config . escapeBedrock = optionParseBoolean ( value );
2022-06-06 14:02:21 +02:00
else if ( strcasecmp ( key , "--pipe" ) == 0 )
instance -> config . pipe = optionParseBoolean ( value );
2022-07-21 14:37:13 +02:00
else if ( strcasecmp ( key , "--load-user-config" ) == 0 )
data -> loadUserConfig = optionParseBoolean ( value );
2022-04-02 14:35:43 +02:00
////////////////
//Logo options//
////////////////
else if ( strcasecmp ( key , "-l" ) == 0 || strcasecmp ( key , "--logo" ) == 0 )
2022-06-06 14:02:21 +02:00
{
2022-07-10 18:28:17 +02:00
optionParseString ( key , value , & instance -> config . logo . source );
2022-06-06 14:02:21 +02:00
//this is usally wanted when using the none logo
if ( strcasecmp ( value , "none" ) == 0 )
{
2023-01-01 17:24:37 +08:00
instance -> config . logo . paddingTop = 0 ;
2022-07-10 18:28:17 +02:00
instance -> config . logo . paddingRight = 0 ;
instance -> config . logo . paddingLeft = 0 ;
2023-01-03 15:13:39 +08:00
instance -> config . logo . type = FF_LOGO_TYPE_NONE ;
2022-06-06 14:02:21 +02:00
}
}
2022-10-22 13:02:04 +08:00
else if ( startsWith ( key , "--logo" ))
2022-04-02 14:35:43 +02:00
{
2022-10-22 13:02:04 +08:00
const char * subkey = key + strlen ( "--logo" );
if ( strcasecmp ( subkey , "-type" ) == 0 )
2022-04-02 14:35:43 +02:00
{
2022-10-22 13:02:04 +08:00
optionParseEnum ( key , value , & instance -> config . logo . type ,
"auto" , FF_LOGO_TYPE_AUTO ,
"builtin" , FF_LOGO_TYPE_BUILTIN ,
"file" , FF_LOGO_TYPE_FILE ,
2022-12-12 13:43:10 +01:00
"file-raw" , FF_LOGO_TYPE_FILE_RAW ,
"data" , FF_LOGO_TYPE_DATA ,
"data-raw" , FF_LOGO_TYPE_DATA_RAW ,
"sixel" , FF_LOGO_TYPE_IMAGE_SIXEL ,
"kitty" , FF_LOGO_TYPE_IMAGE_KITTY ,
2023-01-01 17:09:30 +08:00
"iterm" , FF_LOGO_TYPE_IMAGE_ITERM ,
2022-12-12 13:43:10 +01:00
"chafa" , FF_LOGO_TYPE_IMAGE_CHAFA ,
2023-01-01 12:37:39 +08:00
"raw" , FF_LOGO_TYPE_IMAGE_RAW ,
2023-01-03 15:13:39 +08:00
"none" , FF_LOGO_TYPE_NONE ,
2022-10-22 13:02:04 +08:00
NULL
);
2022-04-02 14:35:43 +02:00
}
2022-10-22 13:02:04 +08:00
else if ( startsWith ( subkey , "-color-" ) && key [ 13 ] != '\0' && key [ 14 ] == '\0' ) // matches "--logo-color-*"
{
//Map the number to an array index, so that '1' -> 0, '2' -> 1, etc.
int index = ( int ) key [ 13 ] - 49 ;
2022-04-02 14:35:43 +02:00
2022-10-22 13:02:04 +08:00
//Match only --logo-color-[1-9]
if ( index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS )
{
fprintf ( stderr , "Error: invalid --color-[1-9] index: %c \n " , key [ 13 ]);
exit ( 472 );
}
optionParseColor ( key , value , & instance -> config . logo . colors [ index ]);
}
else if ( strcasecmp ( subkey , "-width" ) == 0 )
instance -> config . logo . width = optionParseUInt32 ( key , value );
else if ( strcasecmp ( subkey , "-height" ) == 0 )
instance -> config . logo . height = optionParseUInt32 ( key , value );
else if ( strcasecmp ( subkey , "-padding" ) == 0 )
{
uint32_t padding = optionParseUInt32 ( key , value );
instance -> config . logo . paddingLeft = padding ;
instance -> config . logo . paddingRight = padding ;
}
2023-01-01 17:24:37 +08:00
else if ( strcasecmp ( subkey , "-padding-top" ) == 0 )
instance -> config . logo . paddingTop = optionParseUInt32 ( key , value );
2022-10-22 13:02:04 +08:00
else if ( strcasecmp ( subkey , "-padding-left" ) == 0 )
instance -> config . logo . paddingLeft = optionParseUInt32 ( key , value );
else if ( strcasecmp ( subkey , "-padding-right" ) == 0 )
instance -> config . logo . paddingRight = optionParseUInt32 ( key , value );
else if ( strcasecmp ( subkey , "-print-remaining" ) == 0 )
instance -> config . logo . printRemaining = optionParseBoolean ( value );
2022-12-22 21:37:16 +08:00
else if ( strcasecmp ( subkey , "-preserve-aspect-radio" ) == 0 )
instance -> config . logo . preserveAspectRadio = optionParseBoolean ( value );
2022-10-22 13:02:04 +08:00
else
goto error ;
2022-04-02 14:35:43 +02:00
}
2022-12-12 13:43:10 +01:00
else if ( strcasecmp ( key , "--file" ) == 0 )
2022-04-06 14:54:39 +02:00
{
2022-07-10 18:28:17 +02:00
optionParseString ( key , value , & instance -> config . logo . source );
2022-12-12 13:43:10 +01:00
instance -> config . logo . type = FF_LOGO_TYPE_FILE ;
2022-04-06 14:54:39 +02:00
}
2022-12-12 13:43:10 +01:00
else if ( strcasecmp ( key , "--file-raw" ) == 0 )
2022-04-13 23:04:42 +02:00
{
2022-07-10 18:28:17 +02:00
optionParseString ( key , value , & instance -> config . logo . source );
2022-12-12 13:43:10 +01:00
instance -> config . logo . type = FF_LOGO_TYPE_FILE_RAW ;
2022-04-13 23:04:42 +02:00
}
2022-12-12 13:43:10 +01:00
else if ( strcasecmp ( key , "--data" ) == 0 )
2022-04-22 15:49:50 +02:00
{
2022-08-29 11:01:29 +02:00
optionParseString ( key , value , & instance -> config . logo . source );
2022-12-12 13:43:10 +01:00
instance -> config . logo . type = FF_LOGO_TYPE_DATA ;
}
else if ( strcasecmp ( key , "--data-raw" ) == 0 )
{
optionParseString ( key , value , & instance -> config . logo . source );
instance -> config . logo . type = FF_LOGO_TYPE_DATA_RAW ;
2022-04-22 15:49:50 +02:00
}
2022-12-12 13:43:10 +01:00
else if ( strcasecmp ( key , "--sixel" ) == 0 )
{
optionParseString ( key , value , & instance -> config . logo . source );
instance -> config . logo . type = FF_LOGO_TYPE_IMAGE_SIXEL ;
}
else if ( strcasecmp ( key , "--kitty" ) == 0 )
2022-04-22 15:49:50 +02:00
{
2022-07-10 18:28:17 +02:00
optionParseString ( key , value , & instance -> config . logo . source );
2022-12-12 13:43:10 +01:00
instance -> config . logo . type = FF_LOGO_TYPE_IMAGE_KITTY ;
2022-04-22 15:49:50 +02:00
}
2022-04-28 19:15:46 +02:00
else if ( strcasecmp ( key , "--chafa" ) == 0 )
{
2022-07-10 18:28:17 +02:00
optionParseString ( key , value , & instance -> config . logo . source );
2022-12-12 13:43:10 +01:00
instance -> config . logo . type = FF_LOGO_TYPE_IMAGE_CHAFA ;
2022-04-28 19:15:46 +02:00
}
2022-12-22 21:37:16 +08:00
else if ( strcasecmp ( key , "--iterm" ) == 0 )
{
optionParseString ( key , value , & instance -> config . logo . source );
instance -> config . logo . type = FF_LOGO_TYPE_IMAGE_ITERM ;
}
2023-01-01 12:37:39 +08:00
else if ( strcasecmp ( key , "--raw" ) == 0 )
{
optionParseString ( key , value , & instance -> config . logo . source );
instance -> config . logo . type = FF_LOGO_TYPE_IMAGE_RAW ;
}
2022-12-22 02:07:35 +08:00
else if ( strcasecmp ( key , "--chafa-fg-only" ) == 0 )
instance -> config . logo . chafaFgOnly = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--chafa-symbols" ) == 0 )
optionParseString ( key , value , & instance -> config . logo . chafaSymbols );
2022-12-22 11:36:13 +08:00
else if ( strcasecmp ( key , "--chafa-canvas-mode" ) == 0 )
instance -> config . logo . chafaCanvasMode = optionParseUInt32 ( key , value );
else if ( strcasecmp ( key , "--chafa-color-space" ) == 0 )
instance -> config . logo . chafaColorSpace = optionParseUInt32 ( key , value );
else if ( strcasecmp ( key , "--chafa-dither-mode" ) == 0 )
instance -> config . logo . chafaDitherMode = optionParseUInt32 ( key , value );
2022-04-02 14:35:43 +02:00
///////////////////
//Display options//
///////////////////
else if ( strcasecmp ( key , "--show-errors" ) == 0 )
instance -> config . showErrors = optionParseBoolean ( value );
2021-06-17 13:49:25 +02:00
else if ( strcasecmp ( key , "--disable-linewrap" ) == 0 )
instance -> config . disableLinewrap = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--hide-cursor" ) == 0 )
instance -> config . hideCursor = optionParseBoolean ( value );
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "-s" ) == 0 || strcasecmp ( key , "--structure" ) == 0 )
2021-03-19 20:57:07 +01:00
optionParseString ( key , value , & data -> structure );
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "--separator" ) == 0 )
2021-05-15 12:36:25 +02:00
optionParseString ( key , value , & instance -> config . separator );
2022-09-07 19:50:10 +02:00
else if ( strcasecmp ( key , "--color-keys" ) == 0 )
optionParseColor ( key , value , & instance -> config . colorKeys );
else if ( strcasecmp ( key , "--color-title" ) == 0 )
optionParseColor ( key , value , & instance -> config . colorTitle );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "-c" ) == 0 || strcasecmp ( key , "--color" ) == 0 )
2022-09-07 19:50:10 +02:00
{
optionParseColor ( key , value , & instance -> config . colorKeys );
ffStrbufSet ( & instance -> config . colorTitle , & instance -> config . colorKeys );
}
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "--set" ) == 0 )
2022-08-20 18:17:00 +02:00
optionParseCustomValue ( data , key , value , true );
2022-08-18 10:44:21 +02:00
else if ( strcasecmp ( key , "--set-keyless" ) == 0 )
2022-08-20 18:17:00 +02:00
optionParseCustomValue ( data , key , value , false );
2022-08-26 16:02:04 +02:00
else if ( strcasecmp ( key , "--binary-prefix" ) == 0 )
{
optionParseEnum ( key , value , & instance -> config . binaryPrefixType ,
"iec" , FF_BINARY_PREFIX_TYPE_IEC ,
"si" , FF_BINARY_PREFIX_TYPE_SI ,
"jedec" , FF_BINARY_PREFIX_TYPE_JEDEC ,
NULL
);
}
2022-04-02 14:35:43 +02:00
2022-10-19 15:03:59 +08:00
///////////////////////
//Module args options//
///////////////////////
else if ( optionParseModuleArgs ( key , value , "os" , & instance -> config . os )) {}
else if ( optionParseModuleArgs ( key , value , "host" , & instance -> config . host )) {}
else if ( optionParseModuleArgs ( key , value , "bios" , & instance -> config . bios )) {}
else if ( optionParseModuleArgs ( key , value , "board" , & instance -> config . board )) {}
2022-12-24 22:48:10 +08:00
else if ( optionParseModuleArgs ( key , value , "chassis" , & instance -> config . chassis )) {}
2022-10-19 15:03:59 +08:00
else if ( optionParseModuleArgs ( key , value , "kernel" , & instance -> config . kernel )) {}
else if ( optionParseModuleArgs ( key , value , "uptime" , & instance -> config . uptime )) {}
else if ( optionParseModuleArgs ( key , value , "processes" , & instance -> config . processes )) {}
else if ( optionParseModuleArgs ( key , value , "packages" , & instance -> config . packages )) {}
else if ( optionParseModuleArgs ( key , value , "shell" , & instance -> config . shell )) {}
2023-01-18 01:37:47 +08:00
else if ( optionParseModuleArgs ( key , value , "display" , & instance -> config . display )) {}
2023-01-09 18:59:02 +08:00
else if ( optionParseModuleArgs ( key , value , "brightness" , & instance -> config . brightness )) {}
2022-10-19 15:03:59 +08:00
else if ( optionParseModuleArgs ( key , value , "de" , & instance -> config . de )) {}
2022-11-26 18:23:08 +08:00
else if ( optionParseModuleArgs ( key , value , "wifi" , & instance -> config . wifi )) {}
2022-10-19 15:03:59 +08:00
else if ( optionParseModuleArgs ( key , value , "wm" , & instance -> config . wm )) {}
else if ( optionParseModuleArgs ( key , value , "wm-theme" , & instance -> config . wmTheme )) {}
else if ( optionParseModuleArgs ( key , value , "theme" , & instance -> config . theme )) {}
else if ( optionParseModuleArgs ( key , value , "icons" , & instance -> config . icons )) {}
else if ( optionParseModuleArgs ( key , value , "font" , & instance -> config . font )) {}
else if ( optionParseModuleArgs ( key , value , "cursor" , & instance -> config . cursor )) {}
else if ( optionParseModuleArgs ( key , value , "terminal" , & instance -> config . terminal )) {}
else if ( optionParseModuleArgs ( key , value , "terminal-font" , & instance -> config . terminalFont )) {}
2022-11-01 18:25:42 +03:00
else if ( optionParseModuleArgs ( key , value , "cpu" , & instance -> config . cpu )) {}
2022-10-19 15:03:59 +08:00
else if ( optionParseModuleArgs ( key , value , "cpu-usage" , & instance -> config . cpuUsage )) {}
else if ( optionParseModuleArgs ( key , value , "gpu" , & instance -> config . gpu )) {}
else if ( optionParseModuleArgs ( key , value , "memory" , & instance -> config . memory )) {}
else if ( optionParseModuleArgs ( key , value , "swap" , & instance -> config . swap )) {}
else if ( optionParseModuleArgs ( key , value , "disk" , & instance -> config . disk )) {}
else if ( optionParseModuleArgs ( key , value , "battery" , & instance -> config . battery )) {}
else if ( optionParseModuleArgs ( key , value , "poweradapter" , & instance -> config . powerAdapter )) {}
else if ( optionParseModuleArgs ( key , value , "locale" , & instance -> config . locale )) {}
else if ( optionParseModuleArgs ( key , value , "local-ip" , & instance -> config . localIP )) {}
else if ( optionParseModuleArgs ( key , value , "public-ip" , & instance -> config . publicIP )) {}
else if ( optionParseModuleArgs ( key , value , "weather" , & instance -> config . weather )) {}
else if ( optionParseModuleArgs ( key , value , "player" , & instance -> config . player )) {}
2022-12-30 10:47:57 +08:00
else if ( optionParseModuleArgs ( key , value , "media" , & instance -> config . media )) {}
2022-10-19 15:03:59 +08:00
else if ( optionParseModuleArgs ( key , value , "datetime" , & instance -> config . dateTime )) {}
else if ( optionParseModuleArgs ( key , value , "date" , & instance -> config . date )) {}
else if ( optionParseModuleArgs ( key , value , "time" , & instance -> config . time )) {}
else if ( optionParseModuleArgs ( key , value , "vulkan" , & instance -> config . vulkan )) {}
else if ( optionParseModuleArgs ( key , value , "opengl" , & instance -> config . openGL )) {}
else if ( optionParseModuleArgs ( key , value , "opencl" , & instance -> config . openCL )) {}
else if ( optionParseModuleArgs ( key , value , "users" , & instance -> config . users )) {}
2023-01-24 10:39:33 +01:00
else if ( optionParseModuleArgs ( key , value , "bluetooth" , & instance -> config . bluetooth )) {}
2023-01-25 14:28:13 +08:00
else if ( optionParseModuleArgs ( key , value , "sound" , & instance -> config . sound )) {}
2023-02-01 14:01:39 +08:00
else if ( optionParseModuleArgs ( key , value , "gamepad" , & instance -> config . gamepad )) {}
2022-04-02 14:35:43 +02:00
///////////////////
//Library options//
///////////////////
2022-10-22 13:02:04 +08:00
else if ( startsWith ( key , "--lib" ))
{
const char * subkey = key + strlen ( "--lib" );
if ( strcasecmp ( subkey , "-PCI" ) == 0 )
optionParseString ( key , value , & instance -> config . libPCI );
else if ( strcasecmp ( subkey , "-vulkan" ) == 0 )
optionParseString ( key , value , & instance -> config . libVulkan );
else if ( strcasecmp ( subkey , "-freetype" ) == 0 )
optionParseString ( key , value , & instance -> config . libfreetype );
else if ( strcasecmp ( subkey , "-wayland" ) == 0 )
optionParseString ( key , value , & instance -> config . libWayland );
else if ( strcasecmp ( subkey , "-xcb-randr" ) == 0 )
optionParseString ( key , value , & instance -> config . libXcbRandr );
else if ( strcasecmp ( subkey , "-xcb" ) == 0 )
optionParseString ( key , value , & instance -> config . libXcb );
else if ( strcasecmp ( subkey , "-Xrandr" ) == 0 )
optionParseString ( key , value , & instance -> config . libXrandr );
else if ( strcasecmp ( subkey , "-X11" ) == 0 )
optionParseString ( key , value , & instance -> config . libX11 );
else if ( strcasecmp ( subkey , "-gio" ) == 0 )
optionParseString ( key , value , & instance -> config . libGIO );
else if ( strcasecmp ( subkey , "-DConf" ) == 0 )
optionParseString ( key , value , & instance -> config . libDConf );
else if ( strcasecmp ( subkey , "-dbus" ) == 0 )
optionParseString ( key , value , & instance -> config . libDBus );
else if ( strcasecmp ( subkey , "-XFConf" ) == 0 )
optionParseString ( key , value , & instance -> config . libXFConf );
else if ( strcasecmp ( subkey , "-sqlite" ) == 0 || strcasecmp ( subkey , "-sqlite3" ) == 0 )
optionParseString ( key , value , & instance -> config . libSQLite3 );
else if ( strcasecmp ( subkey , "-rpm" ) == 0 )
optionParseString ( key , value , & instance -> config . librpm );
else if ( strcasecmp ( subkey , "-imagemagick" ) == 0 )
optionParseString ( key , value , & instance -> config . libImageMagick );
else if ( strcasecmp ( subkey , "-z" ) == 0 )
optionParseString ( key , value , & instance -> config . libZ );
else if ( strcasecmp ( subkey , "-chafa" ) == 0 )
optionParseString ( key , value , & instance -> config . libChafa );
else if ( strcasecmp ( subkey , "-egl" ) == 0 )
optionParseString ( key , value , & instance -> config . libEGL );
else if ( strcasecmp ( subkey , "-glx" ) == 0 )
optionParseString ( key , value , & instance -> config . libGLX );
else if ( strcasecmp ( subkey , "-osmesa" ) == 0 )
optionParseString ( key , value , & instance -> config . libOSMesa );
else if ( strcasecmp ( subkey , "-opencl" ) == 0 )
optionParseString ( key , value , & instance -> config . libOpenCL );
else if ( strcasecmp ( subkey , "-cjson" ) == 0 )
optionParseString ( key , value , & instance -> config . libcJSON );
2022-11-27 16:00:56 +08:00
else if ( strcasecmp ( subkey , "-wlanapi" ) == 0 )
optionParseString ( key , value , & instance -> config . libwlanapi );
2023-01-26 15:48:28 +01:00
else if ( strcasecmp ( key , "-pulse" ) == 0 )
optionParseString ( key , value , & instance -> config . libPulse );
2023-01-17 12:45:26 +08:00
else if ( strcasecmp ( subkey , "-nm" ) == 0 )
optionParseString ( key , value , & instance -> config . libnm );
2022-10-22 13:02:04 +08:00
else
goto error ;
}
2022-04-02 14:35:43 +02:00
//////////////////
//Module options//
//////////////////
2022-09-26 11:06:21 +08:00
else if ( strcasecmp ( key , "--cpu-temp" ) == 0 )
instance -> config . cpuTemp = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--gpu-temp" ) == 0 )
instance -> config . gpuTemp = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--battery-temp" ) == 0 )
instance -> config . batteryTemp = optionParseBoolean ( value );
2023-01-12 11:41:07 +01:00
else if ( strcasecmp ( key , "--gpu-hide-integrated" ) == 0 )
instance -> config . gpuHideIntegrated = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--gpu-hide-discrete" ) == 0 )
instance -> config . gpuHideDiscrete = optionParseBoolean ( value );
2022-07-22 19:36:00 +02:00
else if ( strcasecmp ( key , "--title-fqdn" ) == 0 )
instance -> config . titleFQDN = optionParseBoolean ( value );
2023-01-11 17:17:17 +08:00
else if ( strcasecmp ( key , "--shell-version" ) == 0 )
instance -> config . shellVersion = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--terminal-version" ) == 0 )
instance -> config . terminalVersion = optionParseBoolean ( value );
2021-03-28 15:38:52 +02:00
else if ( strcasecmp ( key , "--disk-folders" ) == 0 )
optionParseString ( key , value , & instance -> config . diskFolders );
2022-10-17 17:35:06 +02:00
else if ( strcasecmp ( key , "--disk-show-removable" ) == 0 )
instance -> config . diskShowRemovable = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--disk-show-hidden" ) == 0 )
instance -> config . diskShowHidden = optionParseBoolean ( value );
2023-01-16 11:52:54 +01:00
else if ( strcasecmp ( key , "--disk-show-subvolumes" ) == 0 )
instance -> config . diskShowSubvolumes = optionParseBoolean ( value );
2023-01-10 17:31:47 +08:00
else if ( strcasecmp ( key , "--disk-show-unknown" ) == 0 )
instance -> config . diskShowUnknown = optionParseBoolean ( value );
2023-01-24 12:02:20 +01:00
else if ( strcasecmp ( key , "--bluetooth-show-disconnected" ) == 0 )
instance -> config . bluetoothShowDisconnected = optionParseBoolean ( value );
2023-01-31 21:12:47 +08:00
else if ( strcasecmp ( key , "--sound-type" ) == 0 )
{
optionParseEnum ( key , value , & instance -> config . soundType ,
"main" , FF_SOUND_TYPE_MAIN ,
"active" , FF_SOUND_TYPE_ACTIVE ,
"all" , FF_SOUND_TYPE_ALL ,
NULL
);
}
2021-04-24 13:05:43 +02:00
else if ( strcasecmp ( key , "--battery-dir" ) == 0 )
optionParseString ( key , value , & instance -> config . batteryDir );
2021-11-18 18:25:24 +01:00
else if ( strcasecmp ( key , "--separator-string" ) == 0 )
optionParseString ( key , value , & instance -> config . separatorString );
2023-02-02 22:25:31 +08:00
else if ( strcasecmp ( key , "--localip-v6first" ) == 0 )
instance -> config . localIpV6First = optionParseBoolean ( value );
2021-10-17 12:42:15 +08:00
else if ( strcasecmp ( key , "--localip-show-ipv4" ) == 0 )
instance -> config . localIpShowIpV4 = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--localip-show-ipv6" ) == 0 )
instance -> config . localIpShowIpV6 = optionParseBoolean ( value );
else if ( strcasecmp ( key , "--localip-show-loop" ) == 0 )
instance -> config . localIpShowLoop = optionParseBoolean ( value );
2022-09-26 16:20:51 +08:00
else if ( strcasecmp ( key , "--localip-name-prefix" ) == 0 )
optionParseString ( key , value , & instance -> config . localIpNamePrefix );
2023-02-02 17:50:22 +08:00
else if ( strcasecmp ( key , "--localip-compact-type" ) == 0 )
{
optionParseEnum ( key , value , & instance -> config . localIpCompactType ,
"none" , FF_LOCALIP_COMPACT_TYPE_NONE ,
2023-02-02 22:25:31 +08:00
"oneline" , FF_LOCALIP_COMPACT_TYPE_ONELINE ,
"multiline" , FF_LOCALIP_COMPACT_TYPE_MULTILINE ,
2023-02-02 17:50:22 +08:00
NULL
);
}
2022-01-18 18:56:37 +01:00
else if ( strcasecmp ( key , "--os-file" ) == 0 )
optionParseString ( key , value , & instance -> config . osFile );
2022-02-13 23:51:13 +01:00
else if ( strcasecmp ( key , "--player-name" ) == 0 )
optionParseString ( key , value , & instance -> config . playerName );
2022-09-29 14:22:40 +08:00
else if ( strcasecmp ( key , "--public-ip-url" ) == 0 )
optionParseString ( key , value , & instance -> config . publicIpUrl );
2022-01-10 20:20:18 +01:00
else if ( strcasecmp ( key , "--public-ip-timeout" ) == 0 )
2022-04-02 14:35:43 +02:00
instance -> config . publicIpTimeout = optionParseUInt32 ( key , value );
2022-09-29 17:05:01 +08:00
else if ( strcasecmp ( key , "--weather-output-format" ) == 0 )
optionParseString ( key , value , & instance -> config . weatherOutputFormat );
else if ( strcasecmp ( key , "--weather-timeout" ) == 0 )
instance -> config . weatherTimeout = optionParseUInt32 ( key , value );
2022-06-04 15:21:34 +02:00
else if ( strcasecmp ( key , "--gl" ) == 0 )
{
2022-08-26 16:02:04 +02:00
optionParseEnum ( key , value , & instance -> config . glType ,
"auto" , FF_GL_TYPE_AUTO ,
"egl" , FF_GL_TYPE_EGL ,
"glx" , FF_GL_TYPE_GLX ,
"osmesa" , FF_GL_TYPE_OSMESA ,
NULL
);
2022-06-04 15:21:34 +02:00
}
2022-10-18 22:55:28 +08:00
else if ( strcasecmp ( key , "--percent-type" ) == 0 )
instance -> config . percentType = optionParseUInt32 ( key , value );
2023-01-13 19:26:00 +08:00
else if ( strcasecmp ( key , "--command-shell" ) == 0 )
optionParseString ( key , value , & instance -> config . commandShell );
else if ( strcasecmp ( key , "--command-key" ) == 0 )
{
FFstrbuf * result = ( FFstrbuf * ) ffListAdd ( & instance -> config . commandKeys );
ffStrbufInit ( result );
optionParseString ( key , value , result );
}
else if ( strcasecmp ( key , "--command-text" ) == 0 )
{
FFstrbuf * result = ( FFstrbuf * ) ffListAdd ( & instance -> config . commandTexts );
ffStrbufInit ( result );
optionParseString ( key , value , result );
}
2022-01-10 20:20:18 +01:00
2022-04-02 14:35:43 +02:00
//////////////////
//Unknown option//
//////////////////
2021-12-19 22:39:22 +01:00
2021-03-03 19:59:39 +01:00
else
{
2022-10-22 13:02:04 +08:00
error :
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: unknown option: %s \n " , key );
2021-03-05 23:00:28 +01:00
exit ( 400 );
2021-03-03 19:59:39 +01:00
}
}
2023-01-07 22:51:47 +01:00
static void parseConfigFiles ( FFinstance * instance , FFdata * data )
2022-07-21 14:37:13 +02:00
{
2023-01-15 15:57:26 +01:00
for ( uint32_t i = instance -> state . platform . configDirs . length ; i > 0 ; -- i )
2023-01-02 17:27:06 +08:00
{
2023-01-07 22:51:47 +01:00
if ( ! data -> loadUserConfig )
return ;
2021-02-27 20:31:54 +01:00
2023-01-15 15:57:26 +01:00
FFstrbuf * dir = ffListGet ( & instance -> state . platform . configDirs , i - 1 );
2023-01-07 22:51:47 +01:00
uint32_t dirLength = dir -> length ;
2023-01-02 17:27:06 +08:00
2023-01-07 22:51:47 +01:00
ffStrbufAppendS ( dir , "fastfetch/config.conf" );
parseConfigFile ( instance , data , dir -> chars );
ffStrbufSubstrBefore ( dir , dirLength );
2023-01-02 17:27:06 +08:00
}
2021-03-03 19:59:39 +01:00
}
static void parseArguments ( FFinstance * instance , FFdata * data , int argc , const char ** argv )
{
2022-07-21 14:37:13 +02:00
if ( ! data -> loadUserConfig )
return ;
2021-03-03 19:59:39 +01:00
for ( int i = 1 ; i < argc ; i ++ )
{
2021-11-18 18:25:24 +01:00
if ( i == argc - 1 || (
* argv [ i + 1 ] == '-' &&
strcasecmp ( argv [ i ], "--separator-string" ) != 0 // Separator string can start with a -
)) {
2021-03-03 19:59:39 +01:00
parseOption ( instance , data , argv [ i ], NULL );
}
else
{
parseOption ( instance , data , argv [ i ], argv [ i + 1 ]);
++ i ;
}
}
2021-02-27 20:31:54 +01:00
}
2021-03-19 20:57:07 +01:00
static void parseStructureCommand ( FFinstance * instance , FFdata * data , const char * line )
{
2022-08-20 18:17:00 +02:00
CustomValue * customValue = ffValuestoreGet ( & data -> customValues , line );
if ( customValue != NULL )
2022-08-18 10:44:21 +02:00
{
2022-08-20 18:17:00 +02:00
ffPrintCustom ( instance , customValue -> printKey ? line : NULL , customValue -> value . chars );
2022-08-18 10:44:21 +02:00
return ;
}
2021-03-19 20:57:07 +01:00
if ( strcasecmp ( line , "break" ) == 0 )
ffPrintBreak ( instance );
else if ( strcasecmp ( line , "title" ) == 0 )
ffPrintTitle ( instance );
2021-05-15 12:36:25 +02:00
else if ( strcasecmp ( line , "separator" ) == 0 )
ffPrintSeparator ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "os" ) == 0 )
ffPrintOS ( instance );
else if ( strcasecmp ( line , "host" ) == 0 )
ffPrintHost ( instance );
2022-10-05 00:41:43 +08:00
else if ( strcasecmp ( line , "bios" ) == 0 )
ffPrintBios ( instance );
2022-10-05 17:03:30 +08:00
else if ( strcasecmp ( line , "board" ) == 0 )
ffPrintBoard ( instance );
2023-01-09 18:59:02 +08:00
else if ( strcasecmp ( line , "brightness" ) == 0 )
ffPrintBrightness ( instance );
2022-12-24 22:48:10 +08:00
else if ( strcasecmp ( line , "chassis" ) == 0 )
ffPrintChassis ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "kernel" ) == 0 )
ffPrintKernel ( instance );
else if ( strcasecmp ( line , "uptime" ) == 0 )
ffPrintUptime ( instance );
2021-10-18 22:38:00 +08:00
else if ( strcasecmp ( line , "processes" ) == 0 )
ffPrintProcesses ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "packages" ) == 0 )
ffPrintPackages ( instance );
else if ( strcasecmp ( line , "shell" ) == 0 )
ffPrintShell ( instance );
2023-01-18 01:37:47 +08:00
else if ( strcasecmp ( line , "display" ) == 0 )
ffPrintDisplay ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "desktopenvironment" ) == 0 || strcasecmp ( line , "de" ) == 0 )
ffPrintDesktopEnvironment ( instance );
else if ( strcasecmp ( line , "windowmanager" ) == 0 || strcasecmp ( line , "wm" ) == 0 )
ffPrintWM ( instance );
else if ( strcasecmp ( line , "theme" ) == 0 )
ffPrintTheme ( instance );
2021-04-03 23:10:14 +02:00
else if ( strcasecmp ( line , "wmtheme" ) == 0 )
ffPrintWMTheme ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "icons" ) == 0 )
ffPrintIcons ( instance );
else if ( strcasecmp ( line , "font" ) == 0 )
ffPrintFont ( instance );
2021-06-20 21:04:55 +02:00
else if ( strcasecmp ( line , "cursor" ) == 0 )
ffPrintCursor ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "terminal" ) == 0 )
ffPrintTerminal ( instance );
else if ( strcasecmp ( line , "terminalfont" ) == 0 )
ffPrintTerminalFont ( instance );
else if ( strcasecmp ( line , "cpu" ) == 0 )
ffPrintCPU ( instance );
2021-11-24 16:16:25 +08:00
else if ( strcasecmp ( line , "cpuusage" ) == 0 )
ffPrintCPUUsage ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "gpu" ) == 0 )
ffPrintGPU ( instance );
else if ( strcasecmp ( line , "memory" ) == 0 )
ffPrintMemory ( instance );
2022-09-08 14:51:31 +02:00
else if ( strcasecmp ( line , "swap" ) == 0 )
ffPrintSwap ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "disk" ) == 0 )
ffPrintDisk ( instance );
else if ( strcasecmp ( line , "battery" ) == 0 )
ffPrintBattery ( instance );
2022-09-23 14:59:28 +08:00
else if ( strcasecmp ( line , "poweradapter" ) == 0 )
ffPrintPowerAdapter ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "locale" ) == 0 )
ffPrintLocale ( instance );
2021-10-17 12:42:15 +08:00
else if ( strcasecmp ( line , "localip" ) == 0 )
ffPrintLocalIp ( instance );
2022-01-10 20:20:18 +01:00
else if ( strcasecmp ( line , "publicip" ) == 0 )
ffPrintPublicIp ( instance );
2022-11-26 18:23:08 +08:00
else if ( strcasecmp ( line , "wifi" ) == 0 )
ffPrintWifi ( instance );
2022-09-29 17:05:01 +08:00
else if ( strcasecmp ( line , "weather" ) == 0 )
ffPrintWeather ( instance );
2022-02-13 23:51:13 +01:00
else if ( strcasecmp ( line , "player" ) == 0 )
ffPrintPlayer ( instance );
2022-12-30 10:47:57 +08:00
else if ( strcasecmp ( line , "media" ) == 0 )
ffPrintMedia ( instance );
2022-02-25 13:30:37 +01:00
else if ( strcasecmp ( line , "datetime" ) == 0 )
ffPrintDateTime ( instance );
else if ( strcasecmp ( line , "date" ) == 0 )
ffPrintDate ( instance );
else if ( strcasecmp ( line , "time" ) == 0 )
ffPrintTime ( instance );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( line , "colors" ) == 0 )
ffPrintColors ( instance );
2022-06-01 00:04:58 +02:00
else if ( strcasecmp ( line , "vulkan" ) == 0 )
ffPrintVulkan ( instance );
2022-06-04 15:21:34 +02:00
else if ( strcasecmp ( line , "opengl" ) == 0 )
ffPrintOpenGL ( instance );
2022-06-05 00:18:40 +02:00
else if ( strcasecmp ( line , "opencl" ) == 0 )
ffPrintOpenCL ( instance );
2022-09-26 14:57:27 +08:00
else if ( strcasecmp ( line , "users" ) == 0 )
ffPrintUsers ( instance );
2023-01-13 19:26:00 +08:00
else if ( strcasecmp ( line , "command" ) == 0 )
ffPrintCommand ( instance );
2023-01-24 10:39:33 +01:00
else if ( strcasecmp ( line , "bluetooth" ) == 0 )
ffPrintBluetooth ( instance );
2023-01-25 14:28:13 +08:00
else if ( strcasecmp ( line , "sound" ) == 0 )
ffPrintSound ( instance );
2023-02-01 14:01:39 +08:00
else if ( strcasecmp ( line , "gamepad" ) == 0 )
ffPrintGamepad ( instance );
2021-03-19 20:57:07 +01:00
else
2022-07-25 11:00:07 +02:00
ffPrintErrorString ( instance , line , 0 , NULL , NULL , "<no implementation provided>" );
2021-03-03 19:59:39 +01:00
}
2021-12-07 17:20:11 +01:00
int main ( int argc , const char ** argv )
2021-03-03 19:59:39 +01:00
{
2021-12-07 17:20:11 +01:00
FFinstance instance ;
ffInitInstance ( & instance );
2021-04-07 17:36:03 +02:00
2021-12-07 17:20:11 +01:00
//Data stores things only needed for the configuration of fastfetch
FFdata data ;
2022-08-20 18:17:00 +02:00
ffValuestoreInit ( & data . customValues , sizeof ( CustomValue ));
2021-12-07 17:20:11 +01:00
ffStrbufInitA ( & data . structure , 256 );
2022-07-21 14:37:13 +02:00
data . loadUserConfig = true ;
2021-03-27 18:14:19 +01:00
2023-01-20 16:05:03 +08:00
if ( ! getenv ( "NO_CONFIG" ))
parseConfigFiles ( & instance , & data );
2021-12-07 17:20:11 +01:00
parseArguments ( & instance , & data , argc , argv );
2021-06-17 13:49:25 +02:00
2021-12-07 17:20:11 +01:00
//If we don't have a custom structure, use the default one
if ( data . structure . length == 0 )
2022-09-23 00:10:48 +02:00
ffStrbufAppendS ( & data . structure , FASTFETCH_DATATEXT_STRUCTURE );
2021-04-07 17:36:03 +02:00
2022-10-10 10:16:43 +02:00
if ( ffStrbufContainIgnCaseS ( & data . structure , "CPUUsage" ))
2022-09-29 17:14:50 +08:00
ffPrepareCPUUsage ();
2022-10-10 10:16:43 +02:00
2023-02-24 17:45:50 +08:00
if ( instance . config . multithreading )
{
if ( ffStrbufContainIgnCaseS ( & data . structure , "PublicIp" ))
ffPreparePublicIp ( & instance );
2022-10-10 10:16:43 +02:00
2023-02-24 17:45:50 +08:00
if ( ffStrbufContainIgnCaseS ( & data . structure , "Weather" ))
ffPrepareWeather ( & instance );
}
2022-09-29 17:14:50 +08:00
2021-12-07 17:20:11 +01:00
ffStart ( & instance );
2021-03-03 19:59:39 +01:00
2023-01-12 00:11:25 +08:00
#if defined(_WIN32) && defined(FF_ENABLE_BUFFER)
fflush ( stdout );
#endif
2021-12-19 22:39:22 +01:00
//Parse the structure and call the modules
2021-12-07 17:20:11 +01:00
uint32_t startIndex = 0 ;
while ( startIndex < data . structure . length )
{
uint32_t colonIndex = ffStrbufNextIndexC ( & data . structure , startIndex , ':' );
data . structure . chars [ colonIndex ] = '\0' ;
2021-03-03 19:59:39 +01:00
2022-12-14 11:30:50 +08:00
uint64_t ms = 0 ;
if ( __builtin_expect ( instance . config . stat , false ))
ms = ffTimeGetTick ();
2021-12-07 17:20:11 +01:00
parseStructureCommand ( & instance , & data , data . structure . chars + startIndex );
2021-03-03 19:59:39 +01:00
2022-12-14 11:30:50 +08:00
if ( __builtin_expect ( instance . config . stat , false ))
{
char str [ 32 ];
int len = snprintf ( str , sizeof str , "%" PRIu64 "ms" , ffTimeGetTick () - ms );
if ( instance . config . pipe )
puts ( str );
else
printf ( " \033 [s \033 [1A \033 [9999999C \033 [%dD%s \033 [u" , len , str ); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
}
2022-12-14 16:27:04 +08:00
#if defined(_WIN32) && defined(FF_ENABLE_BUFFER)
fflush ( stdout );
#endif
2021-12-07 17:20:11 +01:00
startIndex = colonIndex + 1 ;
}
2022-09-22 22:02:58 +02:00
ffFinish ( & instance );
2022-09-22 21:28:20 +08:00
ffStrbufDestroy ( & data . structure );
ffValuestoreDestroy ( & data . customValues );
2021-03-03 19:59:39 +01:00
2022-09-22 22:02:58 +02:00
ffDestroyInstance ( & instance );
2021-02-18 22:25:36 +01:00
}