2021-02-18 22:25:36 +01:00
#include "fastfetch.h"
2021-04-09 14:07:05 +02:00
#include <string.h>
2021-02-27 20:31:54 +01:00
#include <malloc.h>
2021-02-27 20:50:13 +01:00
#include <unistd.h>
2021-02-27 20:31:54 +01:00
#include <sys/stat.h>
2021-02-27 20:50:13 +01:00
#include <fcntl.h>
2021-04-25 11:48:25 +02:00
#include <dirent.h>
2021-02-22 16:52:51 +01: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
{
FFvaluestore valuestore ;
2021-03-19 20:57:07 +01:00
FFstrbuf structure ;
2021-04-07 17:36:03 +02:00
bool multithreading ;
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
2021-03-21 11:18:06 +01:00
printf ( "The default is something like \" %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 )
fputs ( FASTFETCH_DATATEXT_HELP , stdout );
else if ( strcasecmp ( command , "c" ) == 0 || strcasecmp ( command , "color" ) == 0 )
fputs ( FASTFETCH_DATATEXT_HELP_COLOR , stdout );
2021-03-21 11:18:06 +01:00
else if ( strcasecmp ( command , "format" ) == 0 )
2021-10-22 21:53:29 +02:00
fputs ( FASTFETCH_DATATEXT_HELP_FORMAT , stdout );
else if ( strcasecmp ( command , "load-config" ) == 0 || strcasecmp ( command , "loadconfig" ) == 0 || strcasecmp ( command , "config" ) == 0 )
fputs ( FASTFETCH_DATATEXT_HELP_CONFIG , stdout );
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
{
2021-05-14 16:03:19 +02:00
constructAndPrintCommandHelpFormat ( "host" , "{2} {3}" , 3 ,
2021-04-03 11:39:59 +02:00
"Host family" ,
"Host name" ,
"Host 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-02-12 12:13:02 +01:00
constructAndPrintCommandHelpFormat ( "packages" , "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (xps), {8}, (flatpak), {9} (snap)" , 9 ,
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" ,
2021-06-08 20:01:29 +02:00
"Number of xbps packages" ,
2021-04-28 19:45:43 +02:00
"Number of flatpak packages" ,
2022-02-12 12:13:02 +01:00
"Number of snap 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
);
}
2021-03-11 22:15:48 +01:00
else if ( strcasecmp ( command , "resolution-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "resolution" , "{}x{} @ {}Hz" , 3 ,
"Screen width" ,
"Screen height" ,
"Screen refresh rate"
);
}
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
{
2021-05-23 19:40:34 +02:00
constructAndPrintCommandHelpFormat ( "font" , "{5} [Plasma], {21}" , 21 ,
"Plasma raw" ,
2021-04-05 19:25:34 +02:00
"Plasma name" ,
"Plasma size" ,
2021-05-23 19:40:34 +02:00
"Plasma styles" ,
"Plasma pretty" ,
"GTK2 raw" ,
2021-04-05 19:25:34 +02:00
"GTK2 name" ,
"GTK2 size" ,
2021-05-23 19:40:34 +02:00
"GTK2 styles" ,
"GTK2 pretty" ,
"GTK3 raw" ,
2021-04-05 19:25:34 +02:00
"GTK3 name" ,
"GTK3 size" ,
2021-05-23 19:40:34 +02:00
"GTK3 styles" ,
"GTK3 pretty" ,
"GTK4 raw" ,
2021-04-05 19:25:34 +02:00
"GTK4 name" ,
"GTK4 size" ,
2021-05-23 19:40:34 +02:00
"GTK4 styles" ,
"GTK4 pretty" ,
"GTK2/3/4 pretty"
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
{
constructAndPrintCommandHelpFormat ( "terminal" , "{3}" , 3 ,
"Terminal process name" ,
2021-06-14 23:22:14 +02:00
"Terminal path with exe name" ,
"Terminal exe name"
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
{
2021-05-23 19:40:34 +02:00
constructAndPrintCommandHelpFormat ( "terminal-font" , "{5}" , 5 ,
"Terminal font raw" ,
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"
"Terminal font pretty"
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
{
2021-06-16 11:28:33 +02:00
constructAndPrintCommandHelpFormat ( "cpu" , "{2} ({7}) @ {14}GHz" , 14 ,
2021-04-03 11:39:59 +02:00
"CPU name" ,
"Prettified CPU name" ,
"CPU Vendor name (Vendor ID)" ,
"CPU logical core count online" ,
"CPU logical core count configured" ,
"CPU physical core count" ,
2021-04-15 18:59:26 +02:00
"Always set core count" ,
2021-04-03 11:39:59 +02:00
"frequency bios limit" ,
"frequency scaling max" ,
"frequency scaling min" ,
"frequency info max" ,
2021-04-03 21:51:50 +02:00
"frequency info min" ,
2021-06-16 11:28:33 +02:00
"frequeny from /proc/cpuinfo" ,
"most accurate frequeny"
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
{
2022-01-12 18:57:35 +01:00
constructAndPrintCommandHelpFormat ( "gpu" , "{2} {4}" , 5 ,
2021-04-03 11:39:59 +02:00
"GPU vendor" ,
2021-05-05 19:31:58 +02:00
"GPU vendor pretty" ,
2021-05-07 17:10:22 +02:00
"GPU name" ,
2022-01-12 18:57:35 +01:00
"GPU name pretty" ,
"GPU driver"
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
{
constructAndPrintCommandHelpFormat ( "memory" , "{}MiB / {}MiB ({}%)" , 3 ,
"Used memory" ,
"Total memory" ,
"Used memory percentage"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "disk-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "disk" , "{}GB / {}GB ({4}%)" , 4 ,
"Used disk space" ,
"Total disk space" ,
"Number of files" ,
"Used disk space percentage"
);
}
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"
);
}
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-02-13 23:51:13 +01:00
else if ( strcasecmp ( command , "player-format" ) == 0 )
{
2022-03-22 18:59:04 +01:00
constructAndPrintCommandHelpFormat ( "player" , "{}" , 3 ,
"Pretty player name" ,
"Player name" ,
"DBus bus name"
2022-02-13 23:51:13 +01:00
);
}
else if ( strcasecmp ( command , "song-format" ) == 0 )
{
2022-03-23 15:43:30 +01:00
constructAndPrintCommandHelpFormat ( "song" , "{3} - {4} - {1}" , 5 ,
"Song name pretty" ,
2022-02-13 23:51:13 +01:00
"Song name" ,
"Artist name" ,
2022-03-22 18:59:04 +01:00
"Album name" ,
"Song url"
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" ,
"hout with leading zero" ,
"hour 12h format" ,
"hour 12h format with leading zero" ,
"minute" ,
"minute with leading zero" ,
"second" ,
"second with leading zero"
);
}
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
}
2021-04-25 11:48:25 +02:00
static inline void listAvailablePresetsFromFolder ( FFstrbuf * folder , uint8_t indentation , const char * folderName )
{
DIR * dir = opendir ( folder -> chars );
if ( dir == NULL )
return ;
uint32_t folderLength = folder -> length ;
if ( folderName != NULL )
printf ( "%s/ \n " , folderName );
struct dirent * entry ;
while (( entry = readdir ( dir )) != NULL )
{
if ( entry -> d_type == DT_DIR )
{
if ( strcmp ( entry -> d_name , "." ) == 0 || strcmp ( entry -> d_name , ".." ) == 0 )
continue ;
ffStrbufAppendS ( folder , entry -> d_name );
ffStrbufAppendC ( folder , '/' );
2022-01-22 23:01:09 +01:00
listAvailablePresetsFromFolder ( folder , ( uint8_t ) ( indentation + 1 ), entry -> d_name );
2021-04-25 11:48:25 +02:00
ffStrbufSubstrBefore ( folder , folderLength );
continue ;
}
for ( uint8_t i = 0 ; i < indentation ; i ++ )
fputs ( " | " , stdout );
puts ( entry -> d_name );
}
closedir ( dir );
}
static inline void listAvailablePresets ( FFinstance * instance )
{
FFstrbuf folder ;
ffStrbufInitA ( & folder , 64 );
ffStrbufSetS ( & folder , instance -> state . passwd -> pw_dir );
ffStrbufAppendS ( & folder , "/.local/share/fastfetch/presets/" );
listAvailablePresetsFromFolder ( & folder , 0 , NULL );
2022-04-10 15:07:52 +02:00
ffStrbufSetS ( & folder , FASTFETCH_TARGET_DIR_USR "/share/fastfetch/presets/" );
2021-04-25 11:48:25 +02:00
listAvailablePresetsFromFolder ( & folder , 0 , NULL );
2021-04-25 15:07:31 +02:00
ffStrbufDestroy ( & folder );
2021-04-25 11:48:25 +02:00
}
static void parseOption ( FFinstance * instance , FFdata * data , const char * key , const char * value );
static void parseConfigFile ( FFinstance * instance , FFdata * data , FILE * file )
{
char * lineStart = NULL ;
size_t len = 0 ;
ssize_t read ;
FFstrbuf line ;
2021-11-17 10:59:31 +01:00
ffStrbufInitA ( & line , 256 ); //The default structure line needs this size
2021-04-25 11:48:25 +02:00
while (( read = getline ( & lineStart , & len , file )) != - 1 )
{
ffStrbufSetS ( & line , lineStart );
ffStrbufTrimRight ( & line , '\n' );
ffStrbufTrim ( & line , ' ' );
if ( line . length == 0 || line . chars [ 0 ] == '#' )
continue ;
uint32_t firstSpace = ffStrbufFirstIndexC ( & line , ' ' );
if ( firstSpace >= line . length )
{
parseOption ( instance , data , line . chars , NULL );
continue ;
}
2021-05-15 08:39:20 +02:00
//Separate key and value by simply replacing the first space with a \0
2021-04-25 11:48:25 +02:00
char * valueStart = & line . chars [ firstSpace ];
* valueStart = '\0' ;
++ valueStart ;
2021-05-15 08:39:20 +02:00
//Trim whitespace at beginning of value
2021-04-25 11:48:25 +02:00
while ( * valueStart == ' ' )
++ valueStart ;
//If we want whitespace in values, we need to quote it. This is done to keep consistency with shell.
if ( * valueStart == '"' )
{
char * last = line . chars + line . length - 1 ;
if ( * last == '"' )
{
++ valueStart ;
* last = '\0' ;
-- line . length ;
}
}
parseOption ( instance , data , line . chars , valueStart );
}
ffStrbufDestroy ( & line );
if ( lineStart != NULL )
free ( lineStart );
}
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 );
}
FILE * file = fopen ( value , "r" );
if ( file != NULL )
{
parseConfigFile ( instance , data , file );
fclose ( file );
return ;
}
FFstrbuf filename ;
ffStrbufInitA ( & filename , 64 );
ffStrbufAppendS ( & filename , instance -> state . passwd -> pw_dir );
ffStrbufAppendS ( & filename , "/.local/share/fastfetch/presets/" );
ffStrbufAppendS ( & filename , value );
file = fopen ( filename . chars , "r" );
if ( file != NULL )
{
parseConfigFile ( instance , data , file );
fclose ( file );
return ;
}
2022-04-10 15:07:52 +02:00
ffStrbufSetS ( & filename , FASTFETCH_TARGET_DIR_USR "/share/fastfetch/presets/" );
2021-04-25 11:48:25 +02:00
ffStrbufAppendS ( & filename , value );
file = fopen ( filename . chars , "r" );
if ( file != NULL )
{
parseConfigFile ( instance , data , file );
fclose ( file );
return ;
}
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
}
2021-12-20 12:12:55 +01:00
static void optionParseColor ( const char * key , const char * value , FFstrbuf * buffer )
{
optionCheckString ( key , value , buffer );
static const char reset [] = "reset_" ;
static const char bright [] = "bright_" ;
static const char black [] = "black" ;
static const char red [] = "red" ;
static const char green [] = "green" ;
static const char yellow [] = "yellow" ;
static const char blue [] = "blue" ;
static const char magenta [] = "magenta" ;
static const char cyan [] = "cyan" ;
static const char white [] = "white" ;
while ( * value != '\0' )
{
if ( strncasecmp ( value , reset , sizeof ( reset ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "0;" );
value += sizeof ( reset ) - 1 ;
}
else if ( strncasecmp ( value , bright , sizeof ( bright ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "1;" );
value += sizeof ( bright ) - 1 ;
}
else if ( strncasecmp ( value , black , sizeof ( black ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "30" );
value += sizeof ( black ) - 1 ;
}
else if ( strncasecmp ( value , red , sizeof ( red ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "31" );
value += sizeof ( red ) - 1 ;
}
else if ( strncasecmp ( value , green , sizeof ( green ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "32" );
value += sizeof ( green ) - 1 ;
}
else if ( strncasecmp ( value , yellow , sizeof ( yellow ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "33" );
value += sizeof ( yellow ) - 1 ;
}
else if ( strncasecmp ( value , blue , sizeof ( blue ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "34" );
value += sizeof ( blue ) - 1 ;
}
else if ( strncasecmp ( value , magenta , sizeof ( magenta ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "35" );
value += sizeof ( magenta ) - 1 ;
}
else if ( strncasecmp ( value , cyan , sizeof ( cyan ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "36" );
value += sizeof ( cyan ) - 1 ;
}
else if ( strncasecmp ( value , white , sizeof ( white ) - 1 ) == 0 )
{
ffStrbufAppendS ( buffer , "37" );
value += sizeof ( white ) - 1 ;
}
else
{
ffStrbufAppendC ( buffer , * value );
++ value ;
}
}
}
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 ;
}
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
{
2022-03-24 18:56:44 +01:00
puts ( "fastfetch " FASTFETCH_PROJECT_VERSION "" FASTFETCH_PROJECT_VERSION_TWEAK );
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 );
}
2021-10-23 14:59:11 +02:00
else if ( strcasecmp ( key , "--print-config" ) == 0 )
2021-03-03 19:59:39 +01:00
{
2021-10-22 21:53:29 +02:00
fputs ( FASTFETCH_DATATEXT_CONFIG , stdout );
2021-03-03 19:59:39 +01:00
exit ( 0 );
}
2021-10-23 14:59:11 +02:00
else if ( strcasecmp ( key , "--print-structure" ) == 0 )
2021-03-27 19:26:58 +01:00
{
2021-10-23 14:59:11 +02:00
puts ( FASTFETCH_DATATEXT_STRUCTURE );
2021-03-27 19:26:58 +01:00
exit ( 0 );
}
2021-10-23 14:59:11 +02:00
else if ( strcasecmp ( key , "--list-modules" ) == 0 )
2021-03-27 19:26:58 +01:00
{
2021-10-22 21:53:29 +02:00
fputs ( FASTFETCH_DATATEXT_MODULES , stdout );
2021-03-27 19:26:58 +01:00
exit ( 0 );
}
2021-10-23 14:59:11 +02:00
else if ( strcasecmp ( key , "--list-presets" ) == 0 )
2021-04-25 11:48:25 +02:00
{
listAvailablePresets ( instance );
exit ( 0 );
}
2021-10-23 14:59:11 +02:00
else if ( strcasecmp ( key , "--list-features" ) == 0 )
2021-10-19 18:44:59 +02:00
{
2022-02-13 23:51:13 +01:00
ffListFeatures ();
2021-10-19 18:44:59 +02:00
exit ( 0 );
}
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "--list-logos" ) == 0 )
2021-03-03 19:59:39 +01:00
{
2022-04-02 14:35:43 +02:00
ffListBuiltinLogos ();
exit ( 0 );
2021-03-05 23:00:28 +01:00
}
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "--list-logos-autocompletion" ) == 0 )
2021-03-03 19:59:39 +01:00
{
2022-04-02 14:35:43 +02:00
ffListBuiltinLogosAutocompletion ();
exit ( 0 );
2021-03-03 19:59:39 +01:00
}
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "--print-logos" ) == 0 )
2021-03-03 19:59:39 +01:00
{
2022-04-02 14:35:43 +02:00
ffPrintBuiltinLogos ( instance );
exit ( 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
else if ( strcasecmp ( key , "-r" ) == 0 || strcasecmp ( key , "--recache" ) == 0 )
{
2022-04-11 18:54:56 +02:00
//Set cacheSave as well, because the user expects the values to be cached when expliciting using --recache
2021-03-11 19:40:46 +01:00
instance -> config . recache = optionParseBoolean ( value );
2021-03-07 20:35:17 +01:00
instance -> config . cacheSave = instance -> config . recache ;
2021-03-06 11:28:38 +01:00
}
2021-04-18 19:23:54 +02:00
else if ( strcasecmp ( key , "--nocache" ) == 0 )
{
instance -> config . recache = optionParseBoolean ( value );
instance -> config . cacheSave = false ;
}
2021-04-25 11:48:25 +02:00
else if ( strcasecmp ( key , "--load-config" ) == 0 )
optionParseConfigFile ( instance , data , key , value );
2021-04-07 17:36:03 +02:00
else if ( strcasecmp ( key , "--multithreading" ) == 0 )
data -> multithreading = optionParseBoolean ( value );
2021-05-09 21:41:17 +02:00
else if ( strcasecmp ( key , "--allow-slow-operations" ) == 0 )
instance -> config . allowSlowOperations = optionParseBoolean ( value );
2022-04-02 14:35:43 +02:00
////////////////
//Logo options//
////////////////
else if ( strcasecmp ( key , "-l" ) == 0 || strcasecmp ( key , "--logo" ) == 0 )
2022-04-22 15:49:50 +02:00
optionParseString ( key , value , & instance -> config . logoSource );
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "--logo-type" ) == 0 )
{
if ( value == NULL )
{
fprintf ( stderr , "Error: usage: %s <type> \n " , key );
exit ( 476 );
}
if ( strcasecmp ( value , "auto" ) == 0 )
instance -> config . logoType = FF_LOGO_TYPE_AUTO ;
else if ( strcasecmp ( value , "builtin" ) == 0 )
instance -> config . logoType = FF_LOGO_TYPE_BUILTIN ;
else if ( strcasecmp ( value , "file" ) == 0 )
instance -> config . logoType = FF_LOGO_TYPE_FILE ;
else if ( strcasecmp ( value , "raw" ) == 0 )
instance -> config . logoType = FF_LOGO_TYPE_RAW ;
2022-04-06 14:02:05 +02:00
else if ( strcasecmp ( value , "sixel" ) == 0 )
instance -> config . logoType = FF_LOGO_TYPE_SIXEL ;
2022-04-13 23:04:42 +02:00
else if ( strcasecmp ( value , "kitty" ) == 0 )
instance -> config . logoType = FF_LOGO_TYPE_KITTY ;
2022-04-28 19:15:46 +02:00
else if ( strcasecmp ( value , "chafa" ) == 0 )
instance -> config . logoType = FF_LOGO_TYPE_CHAFA ;
2022-04-02 14:35:43 +02:00
else
{
fprintf ( stderr , "Error: unknown logo type: %s \n " , value );
exit ( 478 );
}
}
else if ( strncasecmp ( key , "--logo-color-" , 13 ) == 0 && 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 ;
//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 . logoColors [ index ]);
}
2022-04-06 14:02:05 +02:00
else if ( strcasecmp ( key , "--logo-width" ) == 0 )
instance -> config . logoWidth = optionParseUInt32 ( key , value );
2022-04-02 14:35:43 +02:00
else if ( strcasecmp ( key , "--logo-padding" ) == 0 )
{
uint32_t padding = optionParseUInt32 ( key , value );
instance -> config . logoPaddingLeft = padding ;
instance -> config . logoPaddingRight = padding ;
}
else if ( strcasecmp ( key , "--logo-padding-left" ) == 0 )
instance -> config . logoPaddingLeft = optionParseUInt32 ( key , value );
else if ( strcasecmp ( key , "--logo-padding-right" ) == 0 )
instance -> config . logoPaddingRight = optionParseUInt32 ( key , value );
else if ( strcasecmp ( key , "--logo-print-remaining" ) == 0 )
instance -> config . logoPrintRemaining = optionParseBoolean ( value );
2022-04-06 14:54:39 +02:00
else if ( strcasecmp ( key , "--sixel" ) == 0 )
{
2022-04-22 15:49:50 +02:00
optionParseString ( key , value , & instance -> config . logoSource );
2022-04-06 14:54:39 +02:00
instance -> config . logoType = FF_LOGO_TYPE_SIXEL ;
}
2022-04-13 23:04:42 +02:00
else if ( strcasecmp ( key , "--kitty" ) == 0 )
{
2022-04-22 15:49:50 +02:00
optionParseString ( key , value , & instance -> config . logoSource );
2022-04-13 23:04:42 +02:00
instance -> config . logoType = FF_LOGO_TYPE_KITTY ;
}
2022-04-22 15:49:50 +02:00
else if ( strcasecmp ( key , "--file" ) == 0 )
{
optionCheckString ( key , value , & instance -> config . logoSource );
instance -> config . logoType = FF_LOGO_TYPE_FILE ;
}
else if ( strcasecmp ( key , "--raw" ) == 0 )
{
optionParseString ( key , value , & instance -> config . logoSource );
instance -> config . logoType = FF_LOGO_TYPE_RAW ;
}
2022-04-28 19:15:46 +02:00
else if ( strcasecmp ( key , "--chafa" ) == 0 )
{
optionParseString ( key , value , & instance -> config . logoSource );
instance -> config . logoType = FF_LOGO_TYPE_CHAFA ;
}
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 );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "-c" ) == 0 || strcasecmp ( key , "--color" ) == 0 )
2022-04-02 14:35:43 +02:00
optionParseColor ( key , value , & instance -> config . mainColor );
else if ( strcasecmp ( key , "--set" ) == 0 )
{
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' ;
ffValuestoreSet ( & data -> valuestore , value , separator + 1 );
}
////////////////////////
//Format + Key options//
////////////////////////
2021-03-12 10:17:49 +01:00
else if ( strcasecmp ( key , "--os-format" ) == 0 )
2021-03-19 20:57:07 +01:00
optionParseString ( key , value , & instance -> config . osFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--os-key" ) == 0 )
optionParseString ( key , value , & instance -> config . osKey );
2021-03-12 12:16:41 +01:00
else if ( strcasecmp ( key , "--host-format" ) == 0 )
2021-03-19 20:57:07 +01:00
optionParseString ( key , value , & instance -> config . hostFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--host-key" ) == 0 )
optionParseString ( key , value , & instance -> config . hostKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--kernel-format" ) == 0 )
optionParseString ( key , value , & instance -> config . kernelFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--kernel-key" ) == 0 )
optionParseString ( key , value , & instance -> config . kernelKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--uptime-format" ) == 0 )
optionParseString ( key , value , & instance -> config . uptimeFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--uptime-key" ) == 0 )
optionParseString ( key , value , & instance -> config . uptimeKey );
2021-10-18 22:38:00 +08:00
else if ( strcasecmp ( key , "--processes-format" ) == 0 )
optionParseString ( key , value , & instance -> config . processesFormat );
else if ( strcasecmp ( key , "--processes-key" ) == 0 )
optionParseString ( key , value , & instance -> config . processesKey );
2021-03-11 19:40:46 +01:00
else if ( strcasecmp ( key , "--packages-format" ) == 0 )
2021-03-19 20:57:07 +01:00
optionParseString ( key , value , & instance -> config . packagesFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--packages-key" ) == 0 )
optionParseString ( key , value , & instance -> config . packagesKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--shell-format" ) == 0 )
optionParseString ( key , value , & instance -> config . shellFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--shell-key" ) == 0 )
optionParseString ( key , value , & instance -> config . shellKey );
2021-03-11 22:15:48 +01:00
else if ( strcasecmp ( key , "--resolution-format" ) == 0 )
2021-03-19 20:57:07 +01:00
optionParseString ( key , value , & instance -> config . resolutionFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--resolution-key" ) == 0 )
optionParseString ( key , value , & instance -> config . resolutionKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--de-format" ) == 0 )
optionParseString ( key , value , & instance -> config . deFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--de-key" ) == 0 )
optionParseString ( key , value , & instance -> config . deKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--wm-format" ) == 0 )
optionParseString ( key , value , & instance -> config . wmFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--wm-key" ) == 0 )
optionParseString ( key , value , & instance -> config . wmKey );
2021-04-03 23:10:14 +02:00
else if ( strcasecmp ( key , "--wm-theme-format" ) == 0 )
optionParseString ( key , value , & instance -> config . wmThemeFormat );
else if ( strcasecmp ( key , "--wm-theme-key" ) == 0 )
optionParseString ( key , value , & instance -> config . wmThemeKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--theme-format" ) == 0 )
optionParseString ( key , value , & instance -> config . themeFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--theme-key" ) == 0 )
optionParseString ( key , value , & instance -> config . themeKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--icons-format" ) == 0 )
optionParseString ( key , value , & instance -> config . iconsFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--icons-key" ) == 0 )
optionParseString ( key , value , & instance -> config . iconsKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--font-format" ) == 0 )
optionParseString ( key , value , & instance -> config . fontFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--font-key" ) == 0 )
optionParseString ( key , value , & instance -> config . fontKey );
2021-06-20 21:04:55 +02:00
else if ( strcasecmp ( key , "--cursor-key" ) == 0 )
optionParseString ( key , value , & instance -> config . cursorKey );
else if ( strcasecmp ( key , "--cursor-format" ) == 0 )
optionParseString ( key , value , & instance -> config . cursorFormat );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--terminal-format" ) == 0 )
optionParseString ( key , value , & instance -> config . terminalFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--terminal-key" ) == 0 )
optionParseString ( key , value , & instance -> config . terminalKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--terminal-font-format" ) == 0 )
optionParseString ( key , value , & instance -> config . termFontFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--terminal-font-key" ) == 0 )
optionParseString ( key , value , & instance -> config . termFontKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--cpu-format" ) == 0 )
optionParseString ( key , value , & instance -> config . cpuFormat );
2021-11-24 16:16:25 +08:00
else if ( strcasecmp ( key , "--cpu-usage-format" ) == 0 )
optionParseString ( key , value , & instance -> config . cpuUsageFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--cpu-key" ) == 0 )
optionParseString ( key , value , & instance -> config . cpuKey );
2021-11-24 16:16:25 +08:00
else if ( strcasecmp ( key , "--cpu-usage-key" ) == 0 )
optionParseString ( key , value , & instance -> config . cpuUsageKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--gpu-format" ) == 0 )
optionParseString ( key , value , & instance -> config . gpuFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--gpu-key" ) == 0 )
optionParseString ( key , value , & instance -> config . gpuKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--memory-format" ) == 0 )
optionParseString ( key , value , & instance -> config . memoryFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--memory-key" ) == 0 )
optionParseString ( key , value , & instance -> config . memoryKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--disk-format" ) == 0 )
optionParseString ( key , value , & instance -> config . diskFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--disk-key" ) == 0 )
optionParseString ( key , value , & instance -> config . diskKey );
2021-03-04 20:49:12 +01:00
else if ( strcasecmp ( key , "--battery-format" ) == 0 )
2021-03-19 20:57:07 +01:00
optionParseString ( key , value , & instance -> config . batteryFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--battery-key" ) == 0 )
optionParseString ( key , value , & instance -> config . batteryKey );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--locale-format" ) == 0 )
optionParseString ( key , value , & instance -> config . localeFormat );
2021-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--locale-key" ) == 0 )
optionParseString ( key , value , & instance -> config . localeKey );
2021-10-17 12:42:15 +08:00
else if ( strcasecmp ( key , "--local-ip-key" ) == 0 )
optionParseString ( key , value , & instance -> config . localIpKey );
else if ( strcasecmp ( key , "--local-ip-format" ) == 0 )
optionParseString ( key , value , & instance -> config . localIpFormat );
2022-01-10 20:20:18 +01:00
else if ( strcasecmp ( key , "--public-ip-key" ) == 0 )
optionParseString ( key , value , & instance -> config . publicIpKey );
else if ( strcasecmp ( key , "--public-ip-format" ) == 0 )
optionParseString ( key , value , & instance -> config . publicIpFormat );
2022-02-13 23:51:13 +01:00
else if ( strcasecmp ( key , "--player-key" ) == 0 )
optionParseString ( key , value , & instance -> config . playerKey );
else if ( strcasecmp ( key , "--player-format" ) == 0 )
optionParseString ( key , value , & instance -> config . playerFormat );
else if ( strcasecmp ( key , "--song-key" ) == 0 )
optionParseString ( key , value , & instance -> config . songKey );
else if ( strcasecmp ( key , "--song-format" ) == 0 )
optionParseString ( key , value , & instance -> config . songFormat );
2022-02-25 13:30:37 +01:00
else if ( strcasecmp ( key , "--datetime-key" ) == 0 )
optionParseString ( key , value , & instance -> config . dateTimeKey );
else if ( strcasecmp ( key , "--datetime-format" ) == 0 )
optionParseString ( key , value , & instance -> config . dateTimeFormat );
else if ( strcasecmp ( key , "--date-key" ) == 0 )
optionParseString ( key , value , & instance -> config . dateKey );
else if ( strcasecmp ( key , "--date-format" ) == 0 )
optionParseString ( key , value , & instance -> config . dateFormat );
else if ( strcasecmp ( key , "--time-key" ) == 0 )
optionParseString ( key , value , & instance -> config . timeKey );
else if ( strcasecmp ( key , "--time-format" ) == 0 )
optionParseString ( key , value , & instance -> config . timeFormat );
2022-04-02 14:35:43 +02:00
///////////////////
//Library options//
///////////////////
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--lib-PCI" ) == 0 )
optionParseString ( key , value , & instance -> config . libPCI );
2021-11-13 18:25:35 +01:00
else if ( strcasecmp ( key , "--lib-vulkan" ) == 0 )
optionParseString ( key , value , & instance -> config . libVulkan );
2022-01-05 14:40:57 +01:00
else if ( strcasecmp ( key , "--lib-wayland" ) == 0 )
optionParseString ( key , value , & instance -> config . libWayland );
else if ( strcasecmp ( key , "--lib-xcb-randr" ) == 0 )
2022-01-10 20:20:18 +01:00
optionParseString ( key , value , & instance -> config . libXcbRandr );
2022-01-05 14:40:57 +01:00
else if ( strcasecmp ( key , "--lib-xcb" ) == 0 )
optionParseString ( key , value , & instance -> config . libXcb );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--lib-Xrandr" ) == 0 )
optionParseString ( key , value , & instance -> config . libXrandr );
2022-01-05 14:40:57 +01:00
else if ( strcasecmp ( key , "--lib-X11" ) == 0 )
optionParseString ( key , value , & instance -> config . libX11 );
2021-05-02 18:52:42 +02:00
else if ( strcasecmp ( key , "--lib-gio" ) == 0 )
optionParseString ( key , value , & instance -> config . libGIO );
2021-04-05 23:42:07 +02:00
else if ( strcasecmp ( key , "--lib-DConf" ) == 0 )
optionParseString ( key , value , & instance -> config . libDConf );
2022-02-13 23:51:13 +01:00
else if ( strcasecmp ( key , "--lib-dbus" ) == 0 )
optionParseString ( key , value , & instance -> config . libDBus );
2021-05-11 20:06:17 +02:00
else if ( strcasecmp ( key , "--lib-XFConf" ) == 0 )
optionParseString ( key , value , & instance -> config . libXFConf );
2021-11-06 19:31:28 +08:00
else if ( strcasecmp ( key , "--lib-rpm" ) == 0 )
optionParseString ( key , value , & instance -> config . librpm );
2022-04-06 14:02:05 +02:00
else if ( strcasecmp ( key , "--lib-imagemagick" ) == 0 )
optionParseString ( key , value , & instance -> config . libImageMagick );
2022-04-14 15:11:14 +02:00
else if ( strcasecmp ( key , "--lib-z" ) == 0 )
optionParseString ( key , value , & instance -> config . libZ );
2022-04-28 19:15:46 +02:00
else if ( strcasecmp ( key , "--lib-chafa" ) == 0 )
optionParseString ( key , value , & instance -> config . libChafa );
2022-04-02 14:35:43 +02:00
//////////////////
//Module options//
//////////////////
2021-03-28 15:38:52 +02:00
else if ( strcasecmp ( key , "--disk-folders" ) == 0 )
optionParseString ( key , value , & instance -> config . diskFolders );
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 );
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-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-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-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
{
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
}
}
2021-04-25 11:48:25 +02:00
static void parseDefaultConfigFile ( FFinstance * instance , FFdata * data )
2021-03-03 19:59:39 +01:00
{
2021-05-07 14:55:43 +02:00
FFstrbuf * filename = ffListGet ( & instance -> state . configDirs , 0 );
uint32_t filenameLength = filename -> length ;
2021-03-03 19:59:39 +01:00
2021-05-15 08:39:20 +02:00
mkdir ( filename -> chars , S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH ); //I hope everybody has a config folder, but who knows
2021-03-27 18:14:19 +01:00
2021-05-07 14:55:43 +02:00
ffStrbufAppendS ( filename , "/fastfetch/" );
mkdir ( filename -> chars , S_IRWXU | S_IRGRP | S_IROTH );
2021-03-03 19:59:39 +01:00
2021-05-07 14:55:43 +02:00
ffStrbufAppendS ( filename , "config.conf" );
2021-03-03 19:59:39 +01:00
2022-02-12 22:30:57 +01:00
FILE * file = fopen ( filename -> chars , "r" );
if ( file != NULL )
2021-03-03 19:59:39 +01:00
{
2022-02-12 22:30:57 +01:00
parseConfigFile ( instance , data , file );
fclose ( file );
ffStrbufSubstrBefore ( filename , filenameLength );
return ;
2021-03-03 19:59:39 +01:00
}
2022-02-12 22:30:57 +01:00
file = fopen ( filename -> chars , "w" );
if ( file != NULL )
2021-03-27 14:22:08 +01:00
{
2022-02-12 22:30:57 +01:00
fputs ( FASTFETCH_DATATEXT_CONFIG , file );
fclose ( file );
2021-02-27 20:31:54 +01:00
}
2021-05-07 14:55:43 +02:00
ffStrbufSubstrBefore ( filename , filenameLength );
2021-03-03 19:59:39 +01:00
}
static void parseArguments ( FFinstance * instance , FFdata * data , int argc , const char ** argv )
{
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 ], "--offsetx" ) != 0 && // --offsetx allows negative values
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 )
{
const char * setValue = ffValuestoreGet ( & data -> valuestore , line );
if ( setValue != NULL )
{
ffPrintCustom ( instance , line , setValue );
return ;
}
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 );
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 );
else if ( strcasecmp ( line , "resolution" ) == 0 )
ffPrintResolution ( instance );
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 );
else if ( strcasecmp ( line , "disk" ) == 0 )
ffPrintDisk ( instance );
else if ( strcasecmp ( line , "battery" ) == 0 )
ffPrintBattery ( instance );
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-02-13 23:51:13 +01:00
else if ( strcasecmp ( line , "player" ) == 0 )
ffPrintPlayer ( instance );
else if ( strcasecmp ( line , "song" ) == 0 )
ffPrintSong ( 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 );
else
2021-04-15 18:59:26 +02:00
ffPrintError ( instance , line , 0 , NULL , NULL , 0 , "<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 ;
ffValuestoreInit ( & data . valuestore );
ffStrbufInitA ( & data . structure , 256 );
data . multithreading = true ;
2021-03-27 18:14:19 +01:00
2021-12-07 17:20:11 +01:00
parseDefaultConfigFile ( & instance , & data );
parseArguments ( & instance , & data , argc , argv );
2021-06-17 13:49:25 +02:00
2021-12-07 17:20:11 +01:00
//Start detection threads
if ( data . multithreading )
ffStartDetectionThreads ( & instance );
2021-04-07 17:36:03 +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 )
ffStrbufSetS ( & data . structure , FASTFETCH_DATATEXT_STRUCTURE );
2021-04-07 17:36:03 +02:00
2021-12-07 17:20:11 +01:00
ffStart ( & instance );
2021-03-03 19:59:39 +01:00
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
2021-12-07 17:20:11 +01:00
parseStructureCommand ( & instance , & data , data . structure . chars + startIndex );
2021-03-03 19:59:39 +01:00
2021-12-07 17:20:11 +01:00
startIndex = colonIndex + 1 ;
}
2021-03-03 19:59:39 +01:00
2021-12-07 17:20:11 +01:00
ffFinish ( & instance );
2021-02-18 22:25:36 +01:00
}