Files
fastfetch/src/fastfetch.c
T

1073 lines
40 KiB
C
Raw Normal View History

2021-02-18 22:25:36 +01:00
#include "fastfetch.h"
#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"
#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"
//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;
} 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"
"\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"
" --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"
"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"
"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"
"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"
"\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 (
strcasecmp(str, "true") == 0 ||
strcasecmp(str, "yes") == 0 ||
2021-04-07 17:36:03 +02:00
strcasecmp(str, "on") == 0 ||
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
}
static void parseOption(FFinstance* instance, FFdata* data, const char* key, const char* value)
2021-02-27 20:31:54 +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);
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)
{
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-21 17:02:31 +01:00
if(sscanf(value, "%hd", &instance->config.logo_spacing) != 1)
{
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);
}
}
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);
}
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);
}
}
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);
}
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);
}
*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);
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-04-25 11:48:25 +02:00
static void parseDefaultConfigFile(FFinstance* instance, FFdata* data)
{
2021-04-03 12:14:25 +02:00
FFstrbuf filename;
ffStrbufInitA(&filename, 64);
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");
}
else
{
2021-03-27 18:35:30 +01:00
ffStrbufAppendS(&filename, xdgConfig);
}
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-27 18:35:30 +01:00
ffStrbufAppendS(&filename, "config.conf");
2021-03-27 18:35:30 +01:00
if(access(filename.chars, F_OK) != 0)
{
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;
}
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-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);
}
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
}
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)
ffLoadLogo(instance);
else
2021-03-19 20:57:07 +01:00
ffLoadLogoSet(&instance->config, data->logoName.chars);
//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>");
}
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-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-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;
}
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);
FFdata data;
2021-04-07 17:36:03 +02:00
initData(&data);
2021-04-25 11:48:25 +02:00
parseDefaultConfigFile(&instance, &data);
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
run(&instance, &data);
2021-02-18 22:25:36 +01:00
}