2021-02-18 22:25:36 +01:00
#include "fastfetch.h"
2021-03-03 19:59:39 +01:00
#include "util/FFvaluestore.h"
2021-02-18 22:25:36 +01:00
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-04-03 23:10:14 +02:00
#define FASTFETCH_DEFAULT_STRUCTURE "Title:Seperator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Locale:Break:Colors"
2021-03-03 19:59:39 +01:00
#define FASTFETCH_DEFAULT_CONFIG \
2021-03-19 20:57:07 +01:00
"# Fastfetch configuration\n" \
"# Put arguments here to make them permanently (one per line). \n" \
"# Direct arguments will overwrite the corresponding ones in this files\n" \
"# Each line is whitespace trimmed on beginn and end.\n" \
"# Empty lines or lines starting with # are ignored.\n" \
"# There are more arguments possible than listed here, take a look at fastfetch --help!\n" \
"# This version of the file was shipped with "FASTFETCH_PROJECT_VERSION".\n" \
"# Use fastfetch --print-default-config > ~/.config/fastfetch/config.conf to generate a new one with current defaults.\n"
2021-03-03 19:59:39 +01:00
//Things only needed by fastfetch
typedef struct FFdata
{
FFvaluestore valuestore ;
2021-03-19 20:57:07 +01:00
FFstrbuf structure ;
FFstrbuf logoName ;
2021-04-07 17:36:03 +02:00
bool multithreading ;
2021-03-03 19:59:39 +01:00
} FFdata ;
2021-03-11 19:40:46 +01:00
static inline void printHelp ()
2021-02-19 16:23:41 +01:00
{
puts (
2021-03-03 21:03:12 +01:00
"Usage: fastfetch <options> \n "
2021-02-20 19:32:57 +01:00
" \n "
2021-03-03 21:03:12 +01:00
"Informative options: \n "
2021-03-27 19:26:58 +01:00
" -h, --help: shows this message and exits \n "
" -h <command>, --help <command>: shows help for a specific command and exits \n "
" -v --version: prints the version of fastfetch and exits \n "
" --list-logos: list available logos and exits \n "
" --print-logos: shows available logos and exits \n "
" --print-default-config: prints the default config and exits \n "
" --print-default-structure: prints the default stucture and exits \n "
" --print-available-modules: prints a list of available modules and exits \n "
2021-04-25 11:48:25 +02:00
" --print-available-presets: list presets fastfetch knows about. They can be loaded with --load-config. (+) \n "
2021-03-03 21:03:12 +01:00
" \n "
"General options: \n "
2021-03-27 19:26:58 +01:00
" --structure <structure>: sets the structure of the fetch. Must be a colon seperated list of keys. Use --print-available-modules to show the default \n "
2021-03-19 21:23:15 +01:00
" --set <key=value>: hard set the value of an key \n "
" -c <color>, --color <color>: sets the color of the keys. Must be a linux console color code (+) \n "
2021-03-21 17:02:31 +01:00
" --spacing <width>: sets the distance between logo and text \n "
2021-03-19 21:23:15 +01:00
" -s <str>, --seperator <str>: sets the seperator between key and value. Default is a colon with a space \n "
" -x <offset>, --offsetx <offset>: sets the x offset. Can be negative to cut the logo, but no more than logo width. \n "
" --show-errors <?value>: print occuring errors \n "
2021-04-18 19:23:54 +02:00
" -r <?value> --recache <?value>: generate new cached values \n "
" --nocache <?value>: dont use cached values, but also dont overwrite existing ones \n "
2021-03-19 21:23:15 +01:00
" --print-remaining-logo <?value>: print the remaining logo, if it is higher than the number of lines shown \n "
2021-04-07 17:36:03 +02:00
" --multithreading <?value>: use multiple threads to calculate values \n "
2021-04-25 11:48:25 +02:00
" --load-config <file>: load a config file (+) \n "
2021-03-03 19:59:39 +01:00
" \n "
2021-03-03 21:03:12 +01:00
"Logo options: \n "
2021-03-05 23:00:28 +01:00
" -l <name>, --logo <name>: sets the shown logo. Also changes the main color accordingly \n "
" --color-logo <?value>: if set to false, the logo will be black / white \n "
2021-03-03 21:03:12 +01:00
" \n "
2021-03-19 20:57:07 +01:00
"Format options: Provide the format string for custom output (+) \n "
" --os-format <format> \n "
" --host-format <format> \n "
" --kernel-format <format> \n "
" --uptime-format <format> \n "
" --packages-format <format> \n "
" --shell-format <format> \n "
" --resolution-format <format> \n "
" --de-format <format> \n "
" --wm-format <format> \n "
2021-04-03 23:10:14 +02:00
" --wm-theme-format <format> \n "
2021-03-19 20:57:07 +01:00
" --theme-format <format> \n "
" --icons-format <format> \n "
" --font-format <format> \n "
" --terminal-format <format> \n "
" --terminal-font-format <format> \n "
" --cpu-format <format> \n "
" --gpu-format <format> \n "
" --memory-format <format> \n "
" --disk-format <format> \n "
" --battery-format <format> \n "
" --locale-format <format> \n "
2021-03-06 11:28:38 +01:00
" \n "
2021-04-03 11:39:59 +02:00
"Key options: Provide a custom key for an output \n "
" --os-key <key> \n "
" --host-key <key> \n "
" --kernel-key <key> \n "
2021-04-03 23:10:14 +02:00
" --uptime-key <key> \n "
" --packages-key <key> \n "
" --shell-key <key> \n "
2021-04-22 21:41:42 +02:00
" --resolution-key <key>: takes the resolution index as argument \n "
2021-04-03 23:10:14 +02:00
" --de-key <key> \n "
" --wm-key <key> \n "
" --wm-theme-key <key> \n "
" --theme-key <key> \n "
" --icons-key <key> \n "
" --font-key <key> \n "
" --terminal-key <key> \n "
" --terminal-font-key <key> \n "
" --cpu-key <key> \n "
" --gpu-key <key>: takes the gpu index as format argument \n "
" --memory-key <key> \n "
" --disk-key <key>: takes the mount path as format argument \n "
" --battery-key <key>: takes the battery index as format argument \n "
" --locale-key <key> \n "
2021-04-03 11:39:59 +02:00
" \n "
2021-03-19 20:57:07 +01:00
"Library optins: Set the path of a library to load \n "
" --lib-PCI <path> \n "
2021-03-21 11:18:06 +01:00
" --lib-X11 <path> \n "
" --lib-Xrandr <path> \n "
2021-04-05 23:42:07 +02:00
" --lib-DConf <path> \n "
2021-04-16 16:49:33 +02:00
" --lib-wayland <path> \n "
2021-04-03 11:39:59 +02:00
" \n "
2021-03-28 15:38:52 +02:00
"Module specific options: \n "
" --disk-folders <folders>: A colon seperated list of folder paths for the disk output. Default is \" /:/home \"\n "
2021-04-24 13:05:43 +02:00
" --battery-dir <folder>: The directory were the battery folders are in. Standard: /sys/class/power_supply/ \n "
2021-03-03 21:03:12 +01:00
" \n "
2021-04-05 23:42:07 +02:00
"Parsing is not case sensetive. E.g. \" --lib-PCI \" is equal to \" --Lib-Pci \"\n "
2021-03-03 19:59:39 +01:00
"If an value starts with an ?, it is optional. \" true \" will be used if not set. \n "
2021-03-03 21:03:12 +01:00
"An (+) at the end indicates that more help can be printed with --help <option> \n "
2021-03-03 19:59:39 +01:00
"All options can be make permanent in $XDG_CONFIG_HOME/fastfetch/config.conf"
2021-02-19 16:23:41 +01:00
);
}
2021-03-04 20:49:12 +01:00
static inline void printCommandHelpColor ()
2021-02-20 19:32:57 +01:00
{
puts (
"usage: fastfetch --color <color> \n "
" \n "
"<color> must be a color encoding for linux terminals. It is inserted between \" ESC[ \" and \" m \" . \n "
2021-04-25 09:13:18 +02:00
"Infos about them can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters. \n "
2021-02-20 19:32:57 +01:00
"Examples: \n "
" \" --color 35 \" : sets the color to pink \n "
" \" --color 4;92 \" : sets the color to bright Green with underline \n "
" \" --color 5;104 \" : blinking text on a blue background \n "
2021-02-20 20:00:06 +01:00
"If no color is set, the main color of the logo will be used. \n "
2021-02-20 19:32:57 +01:00
);
}
2021-03-21 11:18:06 +01:00
static inline void printCommandHelpFormat ()
2021-03-12 10:17:49 +01:00
{
puts (
2021-03-21 11:18:06 +01:00
"A format string is string that contains placeholder for values. \n "
"These placeholders beginn with a '{', contain the index of the value and end with a '}'. \n "
"For example the format string \" Values: {1} ({2}) \" , with the values \" First \" and \" My second val \" , will produce \" Values: First (My second val) \" . \n "
"The format string can contain placeholdes in any oder and multiple occurences. \n "
"To include spaces when setting from command line, surround the whole string with double quotes ( \" ). \n "
" \n "
"If the value index is missing, meaning the placeholder is \" {} \" , an internal counter sets the value index. \n "
"This means, that the format string \" Values: {1} ({2}) \" is equivalent to \" Values: {} ({}) \" . \n "
"Note that this counter only counts empty placeholders, so the format string \" {2} {} {} \" will contain the second value, then the first, and then again the second. \n "
" \n "
"To make formatting easier, a double open curly brace ( \" {{ \" ) will be printed as a single open curly brace and not counted as the beginn of a placeholder. \n "
"If a value index is missformatted or wants a non existing value, it will be printed as is, with the curly braces around it. \n "
2021-04-24 21:42:48 +02:00
"If the last placeholder isn't closed, it will be treated like it was at the end of the format string. \n "
" \n "
"To only print something if a variable is set use \" {?<index>} ... {?} \" . \n "
"For example to only print a second value if it is set use \" {?2} Second value: {2}{?} \" . \n "
"If a \" {?} \" is found without an opener, it is printed as is. \n "
" \n "
"To only print something if a variable is not set, do the same as with if, just replace every '?' with a '!'. \n "
"For example to print a fallback for a second value if it is not set use \" {?2}{2}{?}{/2}Second value fallback{/} \" . \n "
" \n "
"There is a special variable set if an error occured during detection, you can access it with \" {e} \" , \" {error} \" or \" {0} \" . \n "
"You can use ifs and not ifs with it like with an index, for example use \" {?e}some text{?} \" to print an text if an error occurred. \n "
" \n "
"To stop formating at any point in the format string, use \" {-} \" . \n "
"For example to print an error instead of the normal output if it occured, prefix the format string with \" {?e}{e}{-}{?}... \" . \n "
2021-03-21 11:18:06 +01:00
" \n "
2021-04-25 09:13:18 +02:00
"To print something with color, start a placeholder with a '#' and then the linux terminal color encoding. \n "
" \"\\ 033[ \" at the start and a 'm' at the end is automatically added, so don't do that. \n "
"A \" {#} \" is equivalent to a \" {#0} \" and resets everything to normal. \n "
"For example to print something pink and underline use \" {#4;35}...{#} \" . \n "
"If not in a format string, fastfetch wraps errors with \" {#1;31}error{#} \" , so you might want to do that to if you show errors. \n "
"Information about what the numbers mean can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters. \n "
"Which escape codes are supported and how they look like is defined by your terminal. \n "
" \n "
2021-03-27 15:39:56 +01:00
"If an format string evaluates to an empty value, the whole line in the output will be discarded. \n "
"You can therefore use --host-format \" \" to disable host output. \n "
"Note that --host-format \"\" would evaluate as not set, and therefore use the built in host format \n "
2021-04-24 21:42:48 +02:00
"This can be used to print nothing if an error occured: prefix the format string with \" {?e}{-}{?}... \" . \n "
2021-03-27 15:39:56 +01:00
" \n "
2021-03-21 11:18:06 +01:00
"Format string is also the way to go to set a fixed value, just use one without placeholders. \n "
"For example when running in headless mode you could use \" --resolution-format \" Preferred \" ."
2021-03-19 20:57:07 +01:00
);
}
2021-04-25 11:48:25 +02:00
static inline void printCommandHelpLoadConfig ()
2021-03-27 19:26:58 +01:00
{
puts (
2021-04-25 11:48:25 +02:00
"usage: fastfetch --load-config <file> \n "
2021-03-27 19:26:58 +01:00
" \n "
2021-04-25 11:48:25 +02:00
"Loads a config file. A config file contains one flag per line. Empty lines or lines starting with # are ignored. \n "
"If the file is relative it looks in the following order: \n "
" - relative to the current working directory \n "
" - relative to ~/.local/share/fastfetch/presets/ \n "
" - relative to /usr/share/fastfetch/presets/ \n "
"Fastfetch provides some default presets. List them with --print-available-presets. \n "
"Note that this will only print presets fastfetch knows about and not every possible one."
2021-03-27 19:26:58 +01:00
);
}
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 \" ." );
puts ( "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-03-04 20:49:12 +01:00
if ( strcasecmp ( command , "c" ) == 0 || strcasecmp ( command , "color" ) == 0 )
2021-02-20 19:32:57 +01:00
printCommandHelpColor ();
2021-03-21 11:18:06 +01:00
else if ( strcasecmp ( command , "format" ) == 0 )
printCommandHelpFormat ();
2021-04-25 11:48:25 +02:00
else if ( strcasecmp ( command , "load-config" ) == 0 )
printCommandHelpLoadConfig ();
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 ,
"System name, typically just Linux" ,
"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
{
constructAndPrintCommandHelpFormat ( "host" , "{} {} {}" , 3 ,
"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-03-11 19:40:46 +01:00
else if ( strcasecmp ( command , "packages-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
constructAndPrintCommandHelpFormat ( "packages" , "{2} (pacman), {3} (flatpak)" , 3 ,
"Number of all packages" ,
"Number of pacman packages" ,
"Number of flatpak packages"
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "shell-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2021-04-18 15:19:21 +02:00
constructAndPrintCommandHelpFormat ( "shell" , "{2} {4}" , 4 ,
2021-04-03 11:39:59 +02:00
"Shell path (without name)" ,
2021-04-18 15:19:21 +02:00
"Shell name" ,
"Shell version raw" ,
"Shell version pretty"
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
{
constructAndPrintCommandHelpFormat ( "de" , "{} {} ({})" , 3 ,
2021-04-25 21:32:35 +02:00
"Session desktop" ,
"Session name" ,
"Session 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
{
2021-04-25 21:32:35 +02: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-04-05 19:25:34 +02:00
constructAndPrintCommandHelpFormat ( "font" , "{4}, {17}" , 17 ,
"Plasma as in resource file" ,
"Plasma name" ,
"Plasma size" ,
"Plasma name and size pretty together" ,
"GTK2 as in resource file" ,
"GTK2 name" ,
"GTK2 size" ,
"GTK2 name and size pretty together" ,
"GTK3 as in resource file" ,
"GTK3 name" ,
"GTK3 size" ,
"GTK3 name and size pretty together" ,
"GTK4 as in resource file" ,
"GTK4 name" ,
"GTK4 size" ,
"GTK4 name and size pretty together" ,
"GTK 2/3/4 name and size pretty together"
2021-04-03 11:39:59 +02:00
);
}
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 executable name" ,
"Terminal process name" ,
"Terminal name"
);
}
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-04-05 19:25:34 +02:00
constructAndPrintCommandHelpFormat ( "terminal-font" , "{4}" , 4 ,
"Terminal font as in resource file" ,
"Terminal font name" ,
"Termianl font size" ,
"Terminal font name and size pretty together"
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-04-03 21:51:50 +02:00
constructAndPrintCommandHelpFormat ( "cpu" , "{2} ({7}) @ {13}GHz" , 13 ,
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" ,
"Always set frequeny"
2021-04-03 11:39:59 +02:00
);
}
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( command , "gpu-format" ) == 0 )
2021-04-03 11:39:59 +02:00
{
2021-04-15 18:59:26 +02:00
constructAndPrintCommandHelpFormat ( "gpu" , "{2} {3}" , 3 ,
2021-04-03 11:39:59 +02:00
"GPU vendor" ,
2021-04-15 18:59:26 +02:00
"GPU vendor pretty"
2021-04-03 11:39:59 +02:00
"GPU name"
);
}
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
{
constructAndPrintCommandHelpFormat ( "battery" , "{} {} ({}) [{}%; {}]" , 5 ,
"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"
);
}
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 printAvailableModules ()
{
puts (
"Battery \n "
"Break \n "
"Colors \n "
"CPU \n "
"DE \n "
"Disk \n "
"Font \n "
"GPU \n "
"Host \n "
"Icons \n "
"Kernel \n "
"Locale \n "
"Memory \n "
"OS \n "
"Packages \n "
"Resolution \n "
"Seperator \n "
"Shell \n "
"Terminal \n "
"TerminalFont \n "
"Theme \n "
"Title \n "
"Uptime \n "
"WM \n "
"WMTheme \n "
" \n "
"+ Additional defined by --set"
);
}
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 , '/' );
listAvailablePresetsFromFolder ( folder , indentation + 1 , entry -> d_name );
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 );
ffStrbufSetS ( & folder , "/usr/share/fastfetch/presets/" );
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 ;
ffStrbufInitA ( & line , 128 ); //The default structure line needs this size
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 );
ffStrbufDestroy ( & line );
continue ;
}
//Seperate key and value by simply replacing the first space with a \0
char * valueStart = & line . chars [ firstSpace ];
* valueStart = '\0' ;
++ valueStart ;
//Trim whitespace at beginn of value
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 ;
}
ffStrbufSetS ( & filename , "/usr/share/fastfetch/presets/" );
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-03-11 19:40:46 +01:00
static inline bool optionParseBoolean ( const char * str )
2021-02-27 20:31:54 +01:00
{
2021-03-07 20:35:17 +01:00
if ( str == NULL )
return true ;
return (
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-03-19 20:57:07 +01:00
static inline void optionParseString ( 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-04-03 11:39:59 +02:00
ffStrbufEnsureCapacity ( buffer , 64 ); //This is not needed as ffStrbufSetS will resize capacity if needed, but giving an higher start should improve performance
2021-03-19 20:57:07 +01:00
ffStrbufSetS ( buffer , value );
2021-02-27 20:31:54 +01:00
}
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
{
2021-03-03 19:59:39 +01:00
if ( strcasecmp ( key , "-h" ) == 0 || strcasecmp ( key , "--help" ) == 0 )
{
if ( value == NULL )
printHelp ();
else
printCommandHelp ( value );
exit ( 0 );
}
else if ( strcasecmp ( key , "-v" ) == 0 || strcasecmp ( key , "--version" ) == 0 )
{
2021-03-05 21:49:13 +01:00
puts ( FASTFETCH_PROJECT_NAME " " FASTFETCH_PROJECT_VERSION );
2021-03-03 19:59:39 +01:00
exit ( 0 );
}
else if ( strcasecmp ( key , "--list-logos" ) == 0 )
{
ffListLogos ();
exit ( 0 );
}
else if ( strcasecmp ( key , "--print-logos" ) == 0 )
{
ffPrintLogos ( instance -> config . colorLogo );
exit ( 0 );
}
else if ( strcasecmp ( key , "--print-default-config" ) == 0 )
{
puts ( FASTFETCH_DEFAULT_CONFIG );
exit ( 0 );
}
2021-03-27 19:26:58 +01:00
else if ( strcasecmp ( key , "--print-default-structure" ) == 0 )
{
puts ( FASTFETCH_DEFAULT_STRUCTURE );
exit ( 0 );
}
else if ( strcasecmp ( key , "--print-available-modules" ) == 0 )
{
printAvailableModules ();
exit ( 0 );
}
2021-04-25 11:48:25 +02:00
else if ( strcasecmp ( key , "--print-available-presets" ) == 0 )
{
listAvailablePresets ( instance );
exit ( 0 );
}
2021-03-21 17:02:31 +01:00
else if ( strcasecmp ( key , "--spacing" ) == 0 )
2021-03-03 19:59:39 +01:00
{
if ( value == NULL )
{
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: usage: %s <width> \n " , key );
2021-03-05 23:00:28 +01:00
exit ( 404 );
2021-03-03 19:59:39 +01:00
}
2021-03-21 17:02:31 +01:00
if ( sscanf ( value , "%hd" , & instance -> config . logo_spacing ) != 1 )
2021-03-03 19:59:39 +01:00
{
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: couldn't parse %s to uint16_t \n " , value );
2021-03-05 23:00:28 +01:00
exit ( 405 );
}
}
2021-03-03 19:59:39 +01:00
else if ( strcasecmp ( key , "-x" ) == 0 || strcasecmp ( key , "--offsetx" ) == 0 )
{
if ( value == NULL )
{
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: usage: %s <offset> \n " , key );
2021-03-05 23:00:28 +01:00
exit ( 408 );
2021-03-03 19:59:39 +01:00
}
if ( sscanf ( value , "%hi" , & instance -> config . offsetx ) != 1 )
{
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: couldn't parse %s to int16_t \n " , value );
2021-03-05 23:00:28 +01:00
exit ( 409 );
2021-03-03 19:59:39 +01:00
}
}
else if ( strcasecmp ( key , "--set" ) == 0 )
{
if ( value == NULL )
{
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: usage: %s <key=value> \n " , key );
2021-03-05 23:00:28 +01:00
exit ( 411 );
2021-03-03 19:59:39 +01:00
}
char * seperator = strchr ( value , '=' );
2021-03-05 23:00:28 +01:00
if ( seperator == NULL )
{
2021-04-03 11:39:59 +02:00
fprintf ( stderr , "Error: usage: %s <key=value>, '=' missing \n " , key );
2021-03-05 23:00:28 +01:00
exit ( 412 );
}
2021-03-03 19:59:39 +01:00
* seperator = '\0' ;
ffValuestoreSet ( & data -> valuestore , value , seperator + 1 );
}
else if ( strcasecmp ( key , "-r" ) == 0 || strcasecmp ( key , "--recache" ) == 0 )
{
2021-03-27 18:14:19 +01:00
//Set cacheSave as well, beacuse 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-03-07 20:35:17 +01:00
else if ( strcasecmp ( key , "--show-errors" ) == 0 )
2021-03-11 19:40:46 +01:00
instance -> config . showErrors = optionParseBoolean ( value );
2021-03-07 20:35:17 +01:00
else if ( strcasecmp ( key , "--color-logo" ) == 0 )
2021-03-11 19:40:46 +01:00
instance -> config . colorLogo = optionParseBoolean ( value );
2021-03-19 21:23:15 +01:00
else if ( strcasecmp ( key , "--print-remaining-logo" ) == 0 )
instance -> config . printRemainingLogo = optionParseBoolean ( value );
2021-04-07 17:36:03 +02:00
else if ( strcasecmp ( key , "--multithreading" ) == 0 )
data -> multithreading = optionParseBoolean ( value );
2021-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--structure" ) == 0 )
optionParseString ( key , value , & data -> structure );
else if ( strcasecmp ( key , "-l" ) == 0 || strcasecmp ( key , "--logo" ) == 0 )
optionParseString ( key , value , & data -> logoName );
else if ( strcasecmp ( key , "-s" ) == 0 || strcasecmp ( key , "--seperator" ) == 0 )
optionParseString ( key , value , & instance -> config . seperator );
else if ( strcasecmp ( key , "-c" ) == 0 || strcasecmp ( key , "--color" ) == 0 )
optionParseString ( key , value , & instance -> config . color );
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-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-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-04-03 11:39:59 +02:00
else if ( strcasecmp ( key , "--cpu-key" ) == 0 )
optionParseString ( key , value , & instance -> config . cpuKey );
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-03-19 20:57:07 +01:00
else if ( strcasecmp ( key , "--lib-PCI" ) == 0 )
optionParseString ( key , value , & instance -> config . libPCI );
else if ( strcasecmp ( key , "--lib-X11" ) == 0 )
optionParseString ( key , value , & instance -> config . libX11 );
else if ( strcasecmp ( key , "--lib-Xrandr" ) == 0 )
optionParseString ( key , value , & instance -> config . libXrandr );
2021-04-05 23:42:07 +02:00
else if ( strcasecmp ( key , "--lib-DConf" ) == 0 )
optionParseString ( key , value , & instance -> config . libDConf );
2021-04-16 16:49:33 +02:00
else if ( strcasecmp ( key , "--lib-wayland" ) == 0 )
optionParseString ( key , value , & instance -> config . libWayland );
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-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-04-03 12:14:25 +02:00
FFstrbuf filename ;
ffStrbufInitA ( & filename , 64 );
2021-03-03 19:59:39 +01:00
const char * xdgConfig = getenv ( "XDG_CONFIG_HOME" );
if ( xdgConfig == NULL )
{
2021-03-27 18:35:30 +01:00
ffStrbufAppendS ( & filename , instance -> state . passwd -> pw_dir );
ffStrbufAppendS ( & filename , "/.config" );
2021-03-03 19:59:39 +01:00
}
else
{
2021-03-27 18:35:30 +01:00
ffStrbufAppendS ( & filename , xdgConfig );
2021-03-03 19:59:39 +01:00
}
2021-03-27 18:35:30 +01:00
mkdir ( filename . chars , S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH ); //I hope everybody has a config folder but whow knews
2021-03-27 18:14:19 +01:00
2021-03-27 18:35:30 +01:00
ffStrbufAppendS ( & filename , "/fastfetch/" );
mkdir ( filename . chars , S_IRWXU | S_IRGRP | S_IROTH );
2021-03-03 19:59:39 +01:00
2021-03-27 18:35:30 +01:00
ffStrbufAppendS ( & filename , "config.conf" );
2021-03-03 19:59:39 +01:00
2021-03-27 18:35:30 +01:00
if ( access ( filename . chars , F_OK ) != 0 )
2021-03-03 19:59:39 +01:00
{
2021-03-27 18:35:30 +01:00
FILE * file = fopen ( filename . chars , "w" );
2021-04-25 11:48:25 +02:00
if ( file == NULL )
{
ffStrbufDestroy ( & filename );
return ;
}
2021-03-03 19:59:39 +01:00
fputs ( FASTFETCH_DEFAULT_CONFIG , file );
fclose ( file );
}
2021-04-25 11:48:25 +02:00
else
2021-03-27 14:22:08 +01:00
{
2021-04-25 11:48:25 +02:00
FILE * file = fopen ( filename . chars , "r" );
if ( file == NULL )
2021-03-28 20:09:29 +02:00
{
2021-04-25 11:48:25 +02:00
ffStrbufDestroy ( & filename );
return ;
2021-03-03 19:59:39 +01:00
}
2021-03-27 14:22:08 +01:00
2021-04-25 11:48:25 +02:00
parseConfigFile ( instance , data , file );
fclose ( file );
2021-02-27 20:31:54 +01:00
}
2021-03-27 18:35:30 +01:00
ffStrbufDestroy ( & filename );
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 ++ )
{
if ( i == argc - 1 || argv [ i + 1 ][ 0 ] == '-' )
{
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-03 19:59:39 +01:00
static void applyData ( FFinstance * instance , FFdata * data )
{
//We must do this after parsing all options because of color options
2021-03-23 19:48:52 +01:00
if ( data -> logoName . length == 0 )
2021-04-22 21:41:42 +02:00
ffLoadLogo ( instance );
2021-03-03 19:59:39 +01:00
else
2021-03-19 20:57:07 +01:00
ffLoadLogoSet ( & instance -> config , data -> logoName . chars );
2021-03-03 19:59:39 +01:00
//This must be done after loading the logo
2021-03-23 19:48:52 +01:00
if ( instance -> config . color . length == 0 )
2021-03-19 20:57:07 +01:00
ffStrbufSetS ( & instance -> config . color , instance -> config . logo . color );
}
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 );
else if ( strcasecmp ( line , "seperator" ) == 0 )
ffPrintSeperator ( instance );
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 );
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 );
else if ( strcasecmp ( line , "terminal" ) == 0 )
ffPrintTerminal ( instance );
else if ( strcasecmp ( line , "terminalfont" ) == 0 )
ffPrintTerminalFont ( instance );
else if ( strcasecmp ( line , "cpu" ) == 0 )
ffPrintCPU ( instance );
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 );
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
}
static void run ( FFinstance * instance , FFdata * data )
{
2021-04-07 17:36:03 +02:00
if ( data -> multithreading )
ffStartCalculationThreads ( instance );
2021-03-23 19:48:52 +01:00
if ( data -> structure . length == 0 )
2021-03-19 20:57:07 +01:00
ffStrbufSetS ( & data -> structure , FASTFETCH_DEFAULT_STRUCTURE );
2021-03-27 18:14:19 +01:00
2021-03-28 20:09:29 +02:00
uint32_t lastIndex = 0 ;
while ( lastIndex < data -> structure . length )
2021-03-03 19:59:39 +01:00
{
2021-03-28 20:09:29 +02:00
uint32_t colonIndex = ffStrbufFirstIndexAfterC ( & data -> structure , lastIndex , ':' );
data -> structure . chars [ colonIndex ] = '\0' ;
2021-03-27 18:14:19 +01:00
2021-03-28 20:09:29 +02:00
parseStructureCommand ( instance , data , data -> structure . chars + lastIndex );
2021-03-27 18:14:19 +01:00
2021-03-28 20:09:29 +02:00
lastIndex = colonIndex + 1 ;
2021-03-03 19:59:39 +01:00
}
2021-04-07 17:36:03 +02:00
ffFinish ( instance );
}
static void initData ( FFdata * data )
{
ffValuestoreInit ( & data -> valuestore );
ffStrbufInitA ( & data -> structure , 256 );
ffStrbufInit ( & data -> logoName );
data -> multithreading = true ;
2021-03-03 19:59:39 +01:00
}
int main ( int argc , const char ** argv )
2021-02-22 13:45:14 +01:00
{
2021-02-27 18:30:05 +01:00
FFinstance instance ;
2021-04-09 14:07:05 +02:00
ffInitInstance ( & instance );
2021-03-03 19:59:39 +01:00
FFdata data ;
2021-04-07 17:36:03 +02:00
initData ( & data );
2021-03-03 19:59:39 +01:00
2021-04-25 11:48:25 +02:00
parseDefaultConfigFile ( & instance , & data );
2021-03-03 19:59:39 +01:00
parseArguments ( & instance , & data , argc , argv );
2021-03-05 23:26:05 +01:00
applyData ( & instance , & data ); //Here we do things that need to be done after parsing all options
2021-03-03 19:59:39 +01:00
run ( & instance , & data );
2021-02-18 22:25:36 +01:00
}