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-06-11 00:51:29 +08:00
#include "common/jsonconfig.h"
2023-02-01 15:56:25 +01:00
#include "util/stringUtils.h"
2023-03-10 17:49:03 +08:00
#include "logo/logo.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
2023-03-07 16:13:53 +08:00
#include "modules/modules.h"
2023-03-07 14:56:13 +08:00
2023-07-03 16:22:16 +08:00
typedef struct FFCustomValue
2022-08-20 18:17:00 +02:00
{
bool printKey ;
2023-07-03 16:22:16 +08:00
FFstrbuf key ;
2022-08-20 18:17:00 +02:00
FFstrbuf value ;
2023-07-03 16:22:16 +08:00
} FFCustomValue ;
2022-08-20 18:17:00 +02:00
2021-06-13 17:44:34 +05:30
// Things only needed by fastfetch
2021-03-03 19:59:39 +01:00
typedef struct FFdata
{
2021-03-19 20:57:07 +01:00
FFstrbuf structure ;
2023-07-03 16:22:16 +08:00
FFlist customValues ; // List of FFCustomValue
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 );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "c" ) || ffStrEqualsIgnCase ( command , "color" ))
2022-12-12 13:43:10 +01:00
puts ( FASTFETCH_DATATEXT_HELP_COLOR );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "format" ))
2022-12-12 13:43:10 +01:00
puts ( FASTFETCH_DATATEXT_HELP_FORMAT );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "load-config" ) || ffStrEqualsIgnCase ( command , "loadconfig" ) || ffStrEqualsIgnCase ( command , "config" ))
2022-12-12 13:43:10 +01:00
puts ( FASTFETCH_DATATEXT_HELP_CONFIG );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "os-format" ))
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"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "host-format" ))
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "bios-format" ))
2022-10-05 00:41:43 +08:00
{
constructAndPrintCommandHelpFormat ( "bios" , "{2} {3}" , 4 ,
"bios date" ,
"bios release" ,
"bios vendor" ,
"bios version"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "board-format" ))
2022-10-05 17:03:30 +08:00
{
constructAndPrintCommandHelpFormat ( "board" , "{2} {3}" , 3 ,
"board name" ,
"board vendor" ,
"board version"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "chassis-format" ))
2022-12-24 22:48:10 +08:00
{
constructAndPrintCommandHelpFormat ( "chassis" , "{2} {3}" , 4 ,
"chassis type" ,
"chassis vendor" ,
"chassis version"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "kernel-format" ))
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "kernel" , "{2}" , 3 ,
"Kernel sysname" ,
"Kernel release" ,
"Kernel version"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "uptime-format" ))
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "uptime" , "{} days {} hours {} mins" , 4 ,
"Days" ,
"Hours" ,
"Minutes" ,
"Seconds"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "processes-format" ))
2021-10-18 22:38:00 +08:00
{
constructAndPrintCommandHelpFormat ( "processes" , "{}" , 1 ,
"Count"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "packages-format" ))
2021-04-03 11:39:59 +02:00
{
2023-07-03 23:18:36 +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-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (port), {20} (scoop), {21} (choco), {22} (pkgtool)" , 22 ,
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" ,
2023-03-24 17:47:03 +08:00
"Number of flatpak-system packages" ,
"Number of flatpak-user 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" ,
2023-07-03 23:18:36 +08:00
"Number of choco packages" ,
"Number of pkgtool packages"
2021-04-03 11:39:59 +02:00
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "shell-format" ))
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-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "display-format" ))
2021-04-03 11:39:59 +02:00
{
2023-06-12 10:35:28 +08:00
constructAndPrintCommandHelpFormat ( "display" , "{}x{} @ {}Hz" , 7 ,
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" ,
2023-06-12 10:35:28 +08:00
"Screen scaled height" ,
"Screen name" ,
"Screen type" ,
"Screen rotation"
2021-04-03 11:39:59 +02:00
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "de-format" ))
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "wm-format" ))
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
);
}
2023-06-24 07:20:27 +00:00
else if ( ffStrEqualsIgnCase ( command , "wmtheme-format" ))
2021-04-03 23:10:14 +02:00
{
2023-06-24 07:20:27 +00:00
constructAndPrintCommandHelpFormat ( "wmtheme" , "{}" , 1 ,
2021-04-03 23:10:14 +02:00
"WM theme name"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "theme-format" ))
2021-04-03 11:39:59 +02:00
{
2023-06-08 14:32:15 +08:00
constructAndPrintCommandHelpFormat ( "theme" , "{}" , 1 ,
"Combined themes"
2021-04-03 11:39:59 +02:00
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "icons-format" ))
2021-04-03 11:39:59 +02:00
{
2023-06-06 11:26:29 +08:00
constructAndPrintCommandHelpFormat ( "icons" , "{}" , 1 ,
"Combined icons"
2021-04-03 11:39:59 +02:00
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "wallpaper-format" ))
2023-06-06 15:48:24 +08:00
{
constructAndPrintCommandHelpFormat ( "wallpaper" , "{}" , 1 ,
"Wallpaper image file"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "font-format" ))
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "cursor-format" ))
2021-06-20 21:04:55 +02:00
{
constructAndPrintCommandHelpFormat ( "cursor" , "{} ({}pt)" , 2 ,
"Cursor theme" ,
"Cursor size"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "terminal-format" ))
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
);
}
2023-06-24 07:20:27 +00:00
else if ( ffStrEqualsIgnCase ( command , "terminalfont-format" ))
2021-04-03 11:39:59 +02:00
{
2023-06-24 07:20:27 +00:00
constructAndPrintCommandHelpFormat ( "terminalfont" , "{}" , 4 ,
2022-09-18 15:53:51 +02:00
"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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "cpu-format" ))
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "cpu-usage-format" ))
2021-11-24 16:16:25 +08:00
{
constructAndPrintCommandHelpFormat ( "cpu-usage" , "{0}%" , 1 ,
"CPU usage without percent mark"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "gpu-format" ))
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "memory-format" ))
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "swap-format" ))
2022-09-08 14:51:31 +02:00
{
constructAndPrintCommandHelpFormat ( "swap" , "{} / {} ({}%)" , 3 ,
"Used size" ,
"Total size" ,
"Percentage used"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "disk-format" ))
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" ,
2023-06-15 00:30:27 +08:00
"True if external volume" ,
2022-10-17 17:35:06 +02:00
"True if hidden volume" ,
"Filesystem"
2021-04-03 11:39:59 +02:00
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "battery-format" ))
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"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "poweradapter-format" ))
2022-09-23 14:59:28 +08:00
{
constructAndPrintCommandHelpFormat ( "poweradapter" , "{}%, {}" , 5 ,
"PowerAdapter watts" ,
"PowerAdapter name" ,
"PowerAdapter manufacturer" ,
"PowerAdapter model" ,
"PowerAdapter description"
);
}
2023-06-20 23:01:18 +08:00
else if ( ffStrEqualsIgnCase ( command , "lm-format" ))
{
constructAndPrintCommandHelpFormat ( "lm" , "{} ({})" , 2 ,
"LM service" ,
"LM type"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "locale-format" ))
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "locale" , "{}" , 1 ,
"Locale code"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "local-ip-format" ))
2022-01-11 12:36:32 +01:00
{
constructAndPrintCommandHelpFormat ( "local-ip" , "{}" , 1 ,
"Local IP address"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "public-ip-format" ))
2022-01-11 12:36:32 +01:00
{
constructAndPrintCommandHelpFormat ( "public-ip" , "{}" , 1 ,
"Public IP address"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "wifi-format" ))
2022-11-26 18:23:08 +08:00
{
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "player-format" ))
2022-02-13 23:51:13 +01:00
{
2022-09-11 13:09:33 +02:00
constructAndPrintCommandHelpFormat ( "player" , "{}" , 4 ,
2022-03-22 18:59:04 +01:00
"Pretty player name" ,
"Player name" ,
2023-06-08 16:05:01 +08:00
"Player Identifier" ,
2022-09-11 13:09:33 +02:00
"URL name"
2022-02-13 23:51:13 +01:00
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "media-format" ))
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "datetime-format" ) == 0 || ffStrEqualsIgnCase ( command , "date-format" ) || ffStrEqualsIgnCase ( command , "time-format" ))
2022-02-25 13:30:37 +01:00
{
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"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "vulkan-format" ))
2022-06-01 00:04:58 +02:00
{
constructAndPrintCommandHelpFormat ( "vulkan" , "{} (driver), {} (api version)" , 3 ,
"Driver name" ,
"API version" ,
"Conformance version"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "opengl-format" ))
2022-06-04 15:21:34 +02:00
{
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
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "opencl-format" ))
2022-06-05 00:18:40 +02:00
{
constructAndPrintCommandHelpFormat ( "opencl" , "{}" , 3 ,
"version" ,
"device" ,
"vendor"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "bluetooth-format" ))
2023-01-24 10:39:33 +01:00
{
constructAndPrintCommandHelpFormat ( "bluetooth" , "{1} (4%)" , 4 ,
"Name" ,
"Address" ,
"Type" ,
"Battery percentage"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "sound-format" ))
2023-01-28 13:45:40 +08:00
{
constructAndPrintCommandHelpFormat ( "sound" , "{2} (3%)" , 4 ,
"Main" ,
"Name" ,
"Volume" ,
"Identifier"
);
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( command , "gamepad-format" ))
2023-02-01 14:01:39 +08:00
{
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-06-24 10:59:53 +08:00
static void listAvailablePresets ( void )
2021-04-25 11:48:25 +02:00
{
2023-06-24 10:59:53 +08: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-06-24 10:59:53 +08:00
static void listAvailableLogos ( void )
2021-04-25 11:48:25 +02:00
{
2023-06-24 10:59:53 +08: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-06-24 10:59:53 +08:00
static void listConfigPaths ( void )
2023-01-02 16:51:11 +08:00
{
2023-06-24 10:59:53 +08:00
FF_LIST_FOR_EACH ( FFstrbuf , folder , instance . state . platform . configDirs )
2023-01-02 16:51:11 +08:00
{
2023-06-10 21:34:41 +08:00
bool exists = false ;
ffStrbufAppendS ( folder , "fastfetch/config.jsonc" );
exists = ffPathExists ( folder -> chars , FF_PATHTYPE_FILE );
if ( ! exists )
{
ffStrbufSubstrBefore ( folder , folder -> length - ( uint32_t ) strlen ( "jsonc" ));
ffStrbufAppendS ( folder , "conf" );
exists = ffPathExists ( folder -> chars , FF_PATHTYPE_FILE );
}
printf ( "%s%s \n " , folder -> chars , exists ? " (*)" : "" );
2023-01-02 16:51:11 +08:00
}
}
2023-06-24 10:59:53 +08:00
static void listDataPaths ( void )
2023-01-08 01:41:09 +01:00
{
2023-06-24 10:59:53 +08: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 );
}
}
2023-06-24 10:59:53 +08:00
static void parseOption ( FFdata * data , const char * key , const char * value );
2021-04-25 11:48:25 +02:00
2023-06-24 10:59:53 +08:00
static bool parseJsoncFile ( const char * path )
2023-06-10 21:34:41 +08:00
{
2023-06-17 20:39:08 +08:00
yyjson_read_err error ;
yyjson_doc * doc = yyjson_read_file ( path , YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS | YYJSON_READ_ALLOW_INF_AND_NAN , NULL , & error );
2023-06-10 21:34:41 +08:00
if ( doc )
{
2023-06-24 10:59:53 +08:00
instance . state . configDoc = doc ;
2023-06-11 21:31:09 +08:00
const char * error = NULL ;
if (
2023-06-24 10:59:53 +08:00
( error = ffParseLogoJsonConfig ()) ||
( error = ffParseGeneralJsonConfig ()) ||
( error = ffParseDisplayJsonConfig ()) ||
( error = ffParseLibraryJsonConfig ()) ||
2023-06-11 21:31:09 +08:00
false
) {
2023-06-10 21:34:41 +08:00
fputs ( error , stderr );
exit ( 477 );
}
return true ;
}
2023-06-17 20:39:08 +08:00
else if ( error . code != YYJSON_READ_ERROR_FILE_OPEN )
{
fprintf ( stderr , "ERROR: failed to parse JSON config file `%s` at pos %zu: %s \n " , path , error . pos , error . msg );
exit ( 477 );
}
2023-06-10 21:34:41 +08:00
return false ;
}
2023-06-24 10:59:53 +08:00
static bool parseConfigFile ( 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
{
2023-06-24 10:59:53 +08:00
parseOption ( 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
}
2023-06-24 10:59:53 +08:00
parseOption ( 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-06-24 10:59:53 +08:00
static void generateConfigFile ( bool force )
2023-01-02 12:43:11 +08:00
{
2023-06-24 10:59:53 +08: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 );
}
}
2023-06-24 10:59:53 +08:00
static void optionParseConfigFile ( FFdata * data , const char * key , const char * value )
2021-04-25 11:48:25 +02:00
{
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
2023-06-24 10:59:53 +08:00
if ( parseConfigFile ( 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-04-15 15:29:54 +08:00
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA ( 128 );
2023-01-15 20:03:28 +01:00
2023-06-24 10:59:53 +08: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-06-24 10:59:53 +08:00
bool success = parseConfigFile ( 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
}
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 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
}
2023-06-24 10:59:53 +08:00
static void parseOption ( 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//
///////////////////////
2023-06-19 15:21:49 +08:00
if ( ffStrEqualsIgnCase ( key , "-h" ) || ffStrEqualsIgnCase ( key , "--help" ))
2021-03-03 19:59:39 +01:00
{
2021-10-22 21:53:29 +02:00
printCommandHelp ( value );
2021-03-03 19:59:39 +01:00
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "-v" ) || ffStrEqualsIgnCase ( key , "--version" ))
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 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--version-raw" ))
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 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrStartsWithIgnCase ( key , "--print" ))
2021-03-27 19:26:58 +01:00
{
2022-10-22 13:02:04 +08:00
const char * subkey = key + strlen ( "--print" );
2023-06-19 15:21:49 +08:00
if ( ffStrEqualsIgnCase ( subkey , "-config-system" ))
2022-10-22 13:02:04 +08:00
{
puts ( FASTFETCH_DATATEXT_CONFIG_SYSTEM );
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-config-user" ))
2022-10-22 13:02:04 +08:00
{
puts ( FASTFETCH_DATATEXT_CONFIG_USER );
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-structure" ))
2022-10-22 13:02:04 +08:00
{
puts ( FASTFETCH_DATATEXT_STRUCTURE );
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-logos" ))
2022-10-22 13:02:04 +08:00
{
2023-06-24 10:59:53 +08:00
ffLogoBuiltinPrint ();
2022-10-22 13:02:04 +08:00
exit ( 0 );
}
else
goto error ;
2021-03-03 19:59:39 +01:00
}
2023-06-19 15:21:49 +08:00
else if ( ffStrStartsWithIgnCase ( key , "--list" ))
2021-03-03 19:59:39 +01:00
{
2022-10-22 13:02:04 +08:00
const char * subkey = key + strlen ( "--list" );
2023-06-19 15:21:49 +08:00
if ( ffStrEqualsIgnCase ( subkey , "-modules" ))
2022-10-22 13:02:04 +08:00
{
puts ( FASTFETCH_DATATEXT_MODULES );
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-presets" ))
2022-10-22 13:02:04 +08:00
{
2023-06-24 10:59:53 +08:00
listAvailablePresets ();
2022-10-22 13:02:04 +08:00
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-config-paths" ))
2023-01-02 16:51:11 +08:00
{
2023-06-24 10:59:53 +08:00
listConfigPaths ();
2023-01-02 16:51:11 +08:00
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-data-paths" ))
2023-01-08 01:41:09 +01:00
{
2023-06-24 10:59:53 +08:00
listDataPaths ();
2023-01-08 01:41:09 +01:00
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-features" ))
2022-10-22 13:02:04 +08:00
{
ffListFeatures ();
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-logos" ))
2022-10-22 13:02:04 +08:00
{
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:" );
2023-06-24 10:59:53 +08:00
listAvailableLogos ();
2022-10-22 13:02:04 +08:00
exit ( 0 );
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-logos-autocompletion" ))
2022-10-22 13:02:04 +08:00
{
ffLogoBuiltinListAutocompletion ();
exit ( 0 );
}
else
goto error ;
2022-04-02 14:35:43 +02:00
}
2023-07-03 16:22:16 +08:00
else if ( ffStrStartsWithIgnCase ( key , "--set" ))
{
const char * subkey = key + strlen ( "--set" );
if ( * subkey != '\0' && ! ffStrEqualsIgnCase ( subkey , "-keyless" ))
goto error ;
FF_STRBUF_AUTO_DESTROY customValueStr = ffStrbufCreate ();
ffOptionParseString ( key , value , & customValueStr );
uint32_t index = ffStrbufFirstIndexC ( & customValueStr , '=' );
if ( index == 0 || index == customValueStr . length )
{
fprintf ( stderr , "Error: usage: %s <key>=<str> \n " , key );
exit ( 477 );
}
FFCustomValue * customValue = ( FFCustomValue * ) ffListAdd ( & data -> customValues );
ffStrbufInitS ( & customValue -> value , & customValueStr . chars [ index + 1 ]);
ffStrbufSubstrBefore ( & customValueStr , index );
ffStrbufInitMove ( & customValue -> key , & customValueStr );
customValue -> printKey = * subkey == '\0' ;
}
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
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "-r" ) || ffStrEqualsIgnCase ( key , "--recache" ))
2023-06-24 10:59:53 +08:00
instance . config . recache = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--load-config" ))
2023-06-24 10:59:53 +08:00
optionParseConfigFile ( data , key , value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--gen-config" ))
2023-06-24 10:59:53 +08:00
generateConfigFile ( false );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--gen-config-force" ))
2023-06-24 10:59:53 +08:00
generateConfigFile ( true );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--thread" ) || ffStrEqualsIgnCase ( key , "--multithreading" ))
2023-06-24 10:59:53 +08:00
instance . config . multithreading = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--stat" ))
2022-12-14 13:52:16 +08:00
{
2023-06-24 10:59:53 +08:00
if (( instance . config . stat = ffOptionParseBoolean ( value )))
instance . config . showErrors = true ;
2022-12-14 13:52:16 +08:00
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--allow-slow-operations" ))
2023-06-24 10:59:53 +08:00
instance . config . allowSlowOperations = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--escape-bedrock" ))
2023-06-24 10:59:53 +08:00
instance . config . escapeBedrock = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--pipe" ))
2023-06-24 10:59:53 +08:00
instance . config . pipe = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--load-user-config" ))
2023-06-12 15:48:26 +08:00
data -> loadUserConfig = ffOptionParseBoolean ( value );
2022-04-02 14:35:43 +02:00
2023-06-12 15:22:46 +08:00
#if defined(__linux__) || defined(__FreeBSD__)
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--player-name" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . playerName );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--os-file" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . osFile );
2023-06-25 14:33:13 +08:00
#elif defined(_WIN32)
else if ( ffStrEqualsIgnCase ( key , "--wmi-timeout" ))
instance . config . wmiTimeout = ffOptionParseInt32 ( key , value );
2023-06-12 15:22:46 +08:00
#endif
2022-04-02 14:35:43 +02:00
////////////////
//Logo options//
////////////////
2023-06-24 10:59:53 +08:00
else if ( ffParseLogoCommandOptions ( & instance . config . logo , key , value )) {}
2022-04-02 14:35:43 +02:00
///////////////////
//Display options//
///////////////////
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--show-errors" ))
2023-06-24 10:59:53 +08:00
instance . config . showErrors = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--disable-linewrap" ))
2023-06-24 10:59:53 +08:00
instance . config . disableLinewrap = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--hide-cursor" ))
2023-06-24 10:59:53 +08:00
instance . config . hideCursor = ffOptionParseBoolean ( value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "-s" ) || ffStrEqualsIgnCase ( key , "--structure" ))
2023-06-12 15:48:26 +08:00
ffOptionParseString ( key , value , & data -> structure );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--separator" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . keyValueSeparator );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--color-keys" ))
2023-06-10 21:34:41 +08:00
{
2023-06-24 10:59:53 +08:00
optionCheckString ( key , value , & instance . config . colorKeys );
ffOptionParseColor ( value , & instance . config . colorKeys );
2023-06-10 21:34:41 +08:00
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--color-title" ))
2023-06-10 21:34:41 +08:00
{
2023-06-24 10:59:53 +08:00
optionCheckString ( key , value , & instance . config . colorTitle );
ffOptionParseColor ( value , & instance . config . colorTitle );
2023-06-10 21:34:41 +08:00
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "-c" ) || ffStrEqualsIgnCase ( key , "--color" ))
2022-09-07 19:50:10 +02:00
{
2023-06-24 10:59:53 +08:00
optionCheckString ( key , value , & instance . config . colorKeys );
ffOptionParseColor ( value , & instance . config . colorKeys );
ffStrbufSet ( & instance . config . colorTitle , & instance . config . colorKeys );
2022-09-07 19:50:10 +02:00
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--binary-prefix" ))
2022-08-26 16:02:04 +02:00
{
2023-06-24 10:59:53 +08:00
instance . config . binaryPrefixType = ( FFBinaryPrefixType ) ffOptionParseEnum ( key , value , ( FFKeyValuePair []) {
2023-06-12 15:48:26 +08:00
{ "iec" , FF_BINARY_PREFIX_TYPE_IEC },
{ "si" , FF_BINARY_PREFIX_TYPE_SI },
{ "jedec" , FF_BINARY_PREFIX_TYPE_JEDEC },
{}
});
2022-08-26 16:02:04 +02:00
}
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--percent-type" ))
2023-06-24 10:59:53 +08:00
instance . config . percentType = ffOptionParseUInt32 ( key , value );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "--no-buffer" ))
2023-06-24 10:59:53 +08:00
instance . config . noBuffer = ffOptionParseBoolean ( value );
2022-04-02 14:35:43 +02:00
2022-10-19 15:03:59 +08:00
///////////////////////
//Module args options//
///////////////////////
2023-06-24 10:59:53 +08:00
else if ( ffParseOSCommandOptions ( & instance . config . os , key , value )) {}
else if ( ffParseHostCommandOptions ( & instance . config . host , key , value )) {}
else if ( ffParseOSCommandOptions ( & instance . config . os , key , value )) {}
else if ( ffParseBiosCommandOptions ( & instance . config . bios , key , value )) {}
else if ( ffParseBoardCommandOptions ( & instance . config . board , key , value )) {}
else if ( ffParseChassisCommandOptions ( & instance . config . chassis , key , value )) {}
else if ( ffParseCommandCommandOptions ( & instance . config . command , key , value )) {}
else if ( ffParseCustomCommandOptions ( & instance . config . custom , key , value )) {}
else if ( ffParseKernelCommandOptions ( & instance . config . kernel , key , value )) {}
else if ( ffParseUptimeCommandOptions ( & instance . config . uptime , key , value )) {}
else if ( ffParseProcessesCommandOptions ( & instance . config . processes , key , value )) {}
else if ( ffParsePackagesCommandOptions ( & instance . config . packages , key , value )) {}
else if ( ffParseShellCommandOptions ( & instance . config . shell , key , value )) {}
else if ( ffParseDisplayCommandOptions ( & instance . config . display , key , value )) {}
else if ( ffParseBrightnessCommandOptions ( & instance . config . brightness , key , value )) {}
else if ( ffParseDECommandOptions ( & instance . config . de , key , value )) {}
else if ( ffParseWifiCommandOptions ( & instance . config . wifi , key , value )) {}
else if ( ffParseWMCommandOptions ( & instance . config . wm , key , value )) {}
else if ( ffParseWMThemeCommandOptions ( & instance . config . wmTheme , key , value )) {}
else if ( ffParseThemeCommandOptions ( & instance . config . theme , key , value )) {}
else if ( ffParseIconsCommandOptions ( & instance . config . icons , key , value )) {}
else if ( ffParseWallpaperCommandOptions ( & instance . config . wallpaper , key , value )) {}
else if ( ffParseFontCommandOptions ( & instance . config . font , key , value )) {}
else if ( ffParseCursorCommandOptions ( & instance . config . cursor , key , value )) {}
else if ( ffParseTerminalCommandOptions ( & instance . config . terminal , key , value )) {}
else if ( ffParseTerminalFontCommandOptions ( & instance . config . terminalFont , key , value )) {}
else if ( ffParseCPUCommandOptions ( & instance . config . cpu , key , value )) {}
else if ( ffParseCPUUsageCommandOptions ( & instance . config . cpuUsage , key , value )) {}
else if ( ffParseGPUCommandOptions ( & instance . config . gpu , key , value )) {}
else if ( ffParseMemoryCommandOptions ( & instance . config . memory , key , value )) {}
else if ( ffParseSwapCommandOptions ( & instance . config . swap , key , value )) {}
else if ( ffParseDiskCommandOptions ( & instance . config . disk , key , value )) {}
else if ( ffParseBatteryCommandOptions ( & instance . config . battery , key , value )) {}
else if ( ffParsePowerAdapterCommandOptions ( & instance . config . powerAdapter , key , value )) {}
else if ( ffParseLocaleCommandOptions ( & instance . config . locale , key , value )) {}
else if ( ffParseLocalIpCommandOptions ( & instance . config . localIP , key , value )) {}
else if ( ffParsePublicIpCommandOptions ( & instance . config . publicIP , key , value )) {}
else if ( ffParseWeatherCommandOptions ( & instance . config . weather , key , value )) {}
else if ( ffParsePlayerCommandOptions ( & instance . config . player , key , value )) {}
else if ( ffParseMediaCommandOptions ( & instance . config . media , key , value )) {}
else if ( ffParseDateTimeCommandOptions ( & instance . config . dateTime , key , value )) {}
else if ( ffParseVulkanCommandOptions ( & instance . config . vulkan , key , value )) {}
else if ( ffParseOpenGLCommandOptions ( & instance . config . openGL , key , value )) {}
else if ( ffParseOpenCLCommandOptions ( & instance . config . openCL , key , value )) {}
else if ( ffParseUsersCommandOptions ( & instance . config . users , key , value )) {}
else if ( ffParseBluetoothCommandOptions ( & instance . config . bluetooth , key , value )) {}
else if ( ffParseSeparatorCommandOptions ( & instance . config . separator , key , value )) {}
else if ( ffParseSoundCommandOptions ( & instance . config . sound , key , value )) {}
else if ( ffParseGamepadCommandOptions ( & instance . config . gamepad , key , value )) {}
else if ( ffParseColorsCommandOptions ( & instance . config . colors , key , value )) {}
2022-04-02 14:35:43 +02:00
///////////////////
//Library options//
///////////////////
2023-06-19 15:21:49 +08:00
else if ( ffStrStartsWithIgnCase ( key , "--lib" ))
2022-10-22 13:02:04 +08:00
{
const char * subkey = key + strlen ( "--lib" );
2023-06-19 15:21:49 +08:00
if ( ffStrEqualsIgnCase ( subkey , "-PCI" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libPCI );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-vulkan" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libVulkan );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-freetype" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libfreetype );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-wayland" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libWayland );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-xcb-randr" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libXcbRandr );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-xcb" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libXcb );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-Xrandr" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libXrandr );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-X11" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libX11 );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-gio" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libGIO );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-DConf" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libDConf );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-dbus" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libDBus );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-XFConf" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libXFConf );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-sqlite" ) || ffStrEqualsIgnCase ( subkey , "-sqlite3" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libSQLite3 );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-rpm" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . librpm );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-imagemagick" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libImageMagick );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-z" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libZ );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-chafa" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libChafa );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-egl" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libEGL );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-glx" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libGLX );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-osmesa" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libOSMesa );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-opencl" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libOpenCL );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( key , "-pulse" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libPulse );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( subkey , "-nm" ))
2023-06-24 10:59:53 +08:00
ffOptionParseString ( key , value , & instance . config . libnm );
2022-10-22 13:02:04 +08:00
else
goto error ;
}
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-06-24 10:59:53 +08:00
static void parseConfigFiles ( FFdata * data )
2022-07-21 14:37:13 +02:00
{
2023-06-24 10:59:53 +08:00
for ( uint32_t i = instance . state . platform . configDirs . length ; i > 0 ; -- i )
2023-06-10 21:34:41 +08:00
{
2023-06-24 10:59:53 +08:00
FFstrbuf * dir = ffListGet ( & instance . state . platform . configDirs , i - 1 );
2023-06-10 21:34:41 +08:00
uint32_t dirLength = dir -> length ;
ffStrbufAppendS ( dir , "fastfetch/config.jsonc" );
2023-06-24 10:59:53 +08:00
bool success = parseJsoncFile ( dir -> chars );
2023-06-10 21:34:41 +08:00
ffStrbufSubstrBefore ( dir , dirLength );
if ( success ) return ;
}
2023-06-24 10:59:53 +08: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-06-24 10:59:53 +08: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" );
2023-06-24 10:59:53 +08:00
parseConfigFile ( data , dir -> chars );
2023-01-07 22:51:47 +01:00
ffStrbufSubstrBefore ( dir , dirLength );
2023-01-02 17:27:06 +08:00
}
2021-03-03 19:59:39 +01:00
}
2023-06-24 10:59:53 +08:00
static void parseArguments ( FFdata * data , int argc , const char ** argv )
2021-03-03 19:59:39 +01:00
{
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 -
)) {
2023-06-24 10:59:53 +08:00
parseOption ( data , argv [ i ], NULL );
2021-03-03 19:59:39 +01:00
}
else
{
2023-06-24 10:59:53 +08:00
parseOption ( data , argv [ i ], argv [ i + 1 ]);
2021-03-03 19:59:39 +01:00
++ i ;
}
}
2021-02-27 20:31:54 +01:00
}
2023-07-03 16:22:16 +08:00
static void parseStructureCommand ( const char * line , FFlist * customValues )
2021-03-19 20:57:07 +01:00
{
2023-07-03 16:22:16 +08:00
// handle `--set` and `--set-keyless`
FF_LIST_FOR_EACH ( FFCustomValue , customValue , * customValues )
{
if ( ffStrbufEqualS ( & customValue -> key , line ))
{
__attribute__ (( __cleanup__ ( ffDestroyCustomOptions ))) FFCustomOptions options ;
ffInitCustomOptions ( & options );
if ( customValue -> printKey )
ffStrbufAppend ( & options . moduleArgs . key , & customValue -> key );
ffStrbufAppend ( & options . moduleArgs . outputFormat , & customValue -> value );
ffPrintCustom ( & options );
return ;
}
}
2023-06-19 15:21:49 +08:00
if ( ffStrEqualsIgnCase ( line , FF_BREAK_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintBreak ();
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_TITLE_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintTitle ( & instance . config . title );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_SEPARATOR_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintSeparator ( & instance . config . separator );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_OS_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintOS ( & instance . config . os );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_HOST_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintHost ( & instance . config . host );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_BIOS_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintBios ( & instance . config . bios );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_BOARD_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintBoard ( & instance . config . board );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_BRIGHTNESS_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintBrightness ( & instance . config . brightness );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_CHASSIS_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintChassis ( & instance . config . chassis );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_KERNEL_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintKernel ( & instance . config . kernel );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_PROCESSES_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintProcesses ( & instance . config . processes );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_UPTIME_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintUptime ( & instance . config . uptime );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_PACKAGES_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintPackages ( & instance . config . packages );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_SHELL_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintShell ( & instance . config . shell );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_DISPLAY_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintDisplay ( & instance . config . display );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_DE_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintDE ( & instance . config . de );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_WM_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintWM ( & instance . config . wm );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_THEME_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintTheme ( & instance . config . theme );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_WMTHEME_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintWMTheme ( & instance . config . wmTheme );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_ICONS_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintIcons ( & instance . config . icons );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_WALLPAPER_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintWallpaper ( & instance . config . wallpaper );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_FONT_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintFont ( & instance . config . font );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_CURSOR_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintCursor ( & instance . config . cursor );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_TERMINAL_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintTerminal ( & instance . config . terminal );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_TERMINALFONT_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintTerminalFont ( & instance . config . terminalFont );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_CPU_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintCPU ( & instance . config . cpu );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_CPUUSAGE_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintCPUUsage ( & instance . config . cpuUsage );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_CUSTOM_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintCustom ( & instance . config . custom );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_GPU_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintGPU ( & instance . config . gpu );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_MEMORY_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintMemory ( & instance . config . memory );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_SWAP_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintSwap ( & instance . config . swap );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_DISK_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintDisk ( & instance . config . disk );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_BATTERY_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintBattery ( & instance . config . battery );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_POWERADAPTER_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintPowerAdapter ( & instance . config . powerAdapter );
2023-06-20 23:01:18 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_LM_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintLM ( & instance . config . lm );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_LOCALE_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintLocale ( & instance . config . locale );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_LOCALIP_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintLocalIp ( & instance . config . localIP );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_PUBLICIP_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintPublicIp ( & instance . config . publicIP );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_WIFI_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintWifi ( & instance . config . wifi );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_WEATHER_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintWeather ( & instance . config . weather );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_PLAYER_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintPlayer ( & instance . config . player );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_MEDIA_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintMedia ( & instance . config . media );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_DATETIME_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintDateTime ( & instance . config . dateTime );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_COLORS_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintColors ( & instance . config . colors );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_VULKAN_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintVulkan ( & instance . config . vulkan );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_OPENGL_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintOpenGL ( & instance . config . openGL );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_OPENCL_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintOpenCL ( & instance . config . openCL );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_USERS_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintUsers ( & instance . config . users );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_COMMAND_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintCommand ( & instance . config . command );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_BLUETOOTH_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintBluetooth ( & instance . config . bluetooth );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_SOUND_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintSound ( & instance . config . sound );
2023-06-19 15:21:49 +08:00
else if ( ffStrEqualsIgnCase ( line , FF_GAMEPAD_MODULE_NAME ))
2023-06-24 10:59:53 +08:00
ffPrintGamepad ( & instance . config . gamepad );
2021-03-19 20:57:07 +01:00
else
2023-06-24 10:59:53 +08:00
ffPrintErrorString ( 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
{
2023-06-24 10:59:53 +08:00
ffInitInstance ();
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 ;
2023-06-24 10:59:53 +08:00
ffStrbufInit ( & data . structure );
2023-07-03 16:22:16 +08:00
ffListInit ( & data . customValues , sizeof ( FFCustomValue ));
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" ))
2023-06-24 10:59:53 +08:00
parseConfigFiles ( & data );
parseArguments ( & data , argc , argv );
2021-06-17 13:49:25 +02:00
2023-06-20 09:29:58 +08:00
if ( data . structure . length > 0 || ! instance . state . configDoc )
2023-06-10 21:34:41 +08:00
{
//If we don't have a custom structure, use the default one
if ( data . structure . length == 0 )
ffStrbufAppendS ( & data . structure , FASTFETCH_DATATEXT_STRUCTURE );
2021-04-07 17:36:03 +02:00
2023-06-10 21:34:41 +08:00
if ( ffStrbufContainIgnCaseS ( & data . structure , FF_CPUUSAGE_MODULE_NAME ))
ffPrepareCPUUsage ();
2022-10-10 10:16:43 +02:00
2023-06-10 21:34:41 +08:00
if ( instance . config . multithreading )
{
if ( ffStrbufContainIgnCaseS ( & data . structure , FF_PUBLICIP_MODULE_NAME ))
ffPreparePublicIp ( & instance . config . publicIP );
2022-10-10 10:16:43 +02:00
2023-06-10 21:34:41 +08:00
if ( ffStrbufContainIgnCaseS ( & data . structure , FF_WEATHER_MODULE_NAME ))
ffPrepareWeather ( & instance . config . weather );
}
2023-02-24 17:45:50 +08:00
}
2022-09-29 17:14:50 +08:00
2023-06-24 10:59:53 +08:00
ffStart ();
2021-03-03 19:59:39 +01:00
2023-06-13 11:08:49 +08:00
#if defined(_WIN32)
if ( ! instance . config . noBuffer ) fflush ( stdout );
2023-01-12 00:11:25 +08:00
#endif
2023-06-20 09:29:58 +08:00
if ( data . structure . length == 0 && instance . state . configDoc )
2021-12-07 17:20:11 +01:00
{
2023-06-24 10:59:53 +08:00
ffPrintJsonConfig ();
2023-06-11 00:51:29 +08:00
}
else
{
//Parse the structure and call the modules
uint32_t startIndex = 0 ;
while ( startIndex < data . structure . length )
2023-03-09 18:57:57 +08:00
{
2023-06-11 00:51:29 +08:00
uint32_t colonIndex = ffStrbufNextIndexC ( & data . structure , startIndex , ':' );
data . structure . chars [ colonIndex ] = '\0' ;
uint64_t ms = 0 ;
if ( __builtin_expect ( instance . config . stat , false ))
ms = ffTimeGetTick ();
2023-07-03 16:22:16 +08:00
parseStructureCommand ( data . structure . chars + startIndex , & data . customValues );
2023-06-11 00:51:29 +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
}
2023-06-13 11:08:49 +08:00
#if defined(_WIN32)
if ( ! instance . config . noBuffer ) fflush ( stdout );
2023-06-11 00:51:29 +08:00
#endif
startIndex = colonIndex + 1 ;
2023-03-09 18:57:57 +08:00
}
2021-12-07 17:20:11 +01:00
}
2022-09-22 22:02:58 +02:00
2023-06-24 10:59:53 +08:00
ffFinish ();
2022-09-22 22:02:58 +02:00
2022-09-22 21:28:20 +08:00
ffStrbufDestroy ( & data . structure );
2023-07-03 16:22:16 +08:00
FF_LIST_FOR_EACH ( FFCustomValue , customValue , data . customValues )
{
ffStrbufDestroy ( & customValue -> key );
ffStrbufDestroy ( & customValue -> value );
}
ffListDestroy ( & data . customValues );
2021-03-03 19:59:39 +01:00
2023-06-24 10:59:53 +08:00
ffDestroyInstance ();
2021-02-18 22:25:36 +01:00
}