Skip to content
This repository was archived by the owner on Apr 28, 2021. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
142a6b4
Add function to replace substrings
dwzg Apr 23, 2020
0061363
Add configurable way to replace strings of CPU and GPU model
dwzg Apr 24, 2020
c0e59cc
Improve function for substring replacement
dwzg Apr 24, 2020
011d98e
Rename struct for string modification to reflect new function
dwzg Apr 24, 2020
ad0b668
Add fallback method for CPU frequency
dwzg Apr 25, 2020
f8fd070
Fix check of wrong file pointer
dwzg Apr 28, 2020
30bf30d
Merge remote-tracking branch 'upstream/master' into fallback_cpufreq
dwzg Apr 28, 2020
de9a199
Fix bug in frequency precision detection code
dwzg Apr 28, 2020
d554a74
Remove unnecessary newlines
dwzg Apr 28, 2020
6ea3250
Merge remote-tracking branch 'upstream/master' into replace_substring
dwzg Apr 28, 2020
02120c7
Return stolen newline
dwzg Apr 28, 2020
d23cf6a
Merge pull request #51 from dwzg/fallback_cpufreq
ss7m Apr 29, 2020
6b45321
Add ability to switch CPU frequency unit to MHz for < 1 GHz
dwzg Apr 26, 2020
b3c1ae5
Improve code and fix a bug
dwzg May 1, 2020
f1f8a7e
Merge pull request #53 from dwzg/freq_mhz
ss7m May 1, 2020
6eba614
Merge remote-tracking branch 'upstream/master' into replace_substring
dwzg May 1, 2020
61d9bff
Add string length check in replace_substring()
dwzg May 1, 2020
a1c5ec7
Make get_terminal get the actual tty name
dwzg Apr 24, 2020
69605e2
Merge pull request #54 from dwzg/tty_name
ss7m May 1, 2020
fdab2c5
added fallback for get_host
ss7m May 1, 2020
af6f3a7
Update README.md with performance information
May 1, 2020
9544cfe
Merge pull request #57 from Titaniumtown/patch-1
ss7m May 2, 2020
ea70303
Update README
dwzg May 3, 2020
cbbe1a7
Merge pull request #41 from dwzg/replace_substring
ss7m May 3, 2020
03e7bd7
get_cpu returns empty string when model name isn't present
ss7m May 4, 2020
92b105a
Add get_battery_percentage() to header
srithon May 8, 2020
4dbac17
Add battery to config, fix spacing
srithon May 8, 2020
b361dbc
Implement get_battery_percentage() function
srithon May 8, 2020
02e0d68
Add battery status after percentage
srithon May 8, 2020
948f29c
Add panic if battery cannot be opened
srithon May 8, 2020
aadf25f
Add % symbol and cut down # of strcat's
srithon May 8, 2020
10a23a9
Add comment showing output of function
srithon May 8, 2020
274410c
Write script for finding battery path
srithon May 8, 2020
ab2d043
Call battery config script in Makefile
srithon May 8, 2020
33285a9
Include battery config and replace hardcoded refs
srithon May 8, 2020
4007c41
Reduce file read sizes in get_battery_percentage
srithon May 8, 2020
5084173
Add remove_newline function that returns length of string
srithon May 8, 2020
4882940
Optimize battery function by using length of strings for strcat
srithon May 8, 2020
fd9f29e
Get rid of the second buffer in battery function
srithon May 8, 2020
883c58a
Pass battery path directly to compiler
srithon May 9, 2020
721972f
Remove unnecessary "-1" argument
srithon May 9, 2020
31e0067
Move battery_config.sh to config_scripts folder
srithon May 9, 2020
c7022eb
Revert "Get rid of the second buffer in battery function"
srithon May 8, 2020
13e2058
Revert "Optimize battery function by using length of strings for strcat"
srithon May 8, 2020
964ca21
Use scanf/sprintf approach rather than micromanaging buffers
srithon May 9, 2020
b7c58a5
Merge pull request #61 from srithon/master
ss7m May 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ clean:
rm -f paleofetch $(CACHE)/paleofetch

paleofetch: paleofetch.c paleofetch.h config.h
$(CC) paleofetch.c -o paleofetch $(CFLAGS)
$(eval battery_path := $(shell ./config_scripts/battery_config.sh))
$(CC) paleofetch.c -o paleofetch $(CFLAGS) -D $(battery_path)
strip paleofetch

install: paleofetch
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ paleofetch
A rewrite of [neofetch](https://github.com/dylanaraps/neofetch) in C.
Currently only supports Linux and Xorg.


Why use paleofetch over neofetch?
-----------------------------------------
One major reason is the performance improvement. For example: neofetch finishes running after about 222 milliseconds where as paleofetch can finish running in a blazing fast 3 milliseconds.

Note: this testing occured on only 1 computer, it's not a good representation on the performance benefit you may gain.


Example output:

![example output](example.png)
Expand Down Expand Up @@ -77,6 +85,15 @@ The booleans in `CONFIG` tell paleofetch whether you want to cache an entry.
When cached, paleofetch will save the value and not recompute it whenever you run paleofetch
(unless you specify the `--recache` option).

The CPU and GPU name can be configured as well. This is done under the CPU_CONFIG and GPU_CONFIG section
in the config.h file. Two macros are provided to customize and tidy up the model names:

* `REMOVE(string)`: removes the first occurence of `string`
* `REPLACE(string1, string2)`: replaces the first occurence of `string1` with `string2`

Don't forget to run paleofetch with the --recache flag after compiling it with your new
configuration, otherwise it will still show the old name for already cached entries.

FAQ
---

Expand Down
29 changes: 15 additions & 14 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,29 @@

#define CONFIG \
{ \
/* name function cached */\
{ "", get_title, false }, \
{ "", get_bar, false }, \
{ "OS: ", get_os, true }, \
{ "Host: ", get_host, true }, \
{ "Kernel: ", get_kernel, true }, \
{ "Uptime: ", get_uptime, false }, \
/* name function cached */\
{ "", get_title, false }, \
{ "", get_bar, false }, \
{ "OS: ", get_os, true }, \
{ "Host: ", get_host, true }, \
{ "Kernel: ", get_kernel, true }, \
{ "Uptime: ", get_uptime, false }, \
{ "Battery: ", get_battery_percentage, false }, \
SPACER \
{ "Packages: ", get_packages_pacman, false }, \
{ "Shell: ", get_shell, false }, \
{ "Resolution: ", get_resolution, false }, \
{ "Terminal: ", get_terminal, false }, \
SPACER \
{ "CPU: ", get_cpu, true }, \
{ "GPU: ", get_gpu1, true }, \
{ "Memory: ", get_memory, false }, \
{ "CPU: ", get_cpu, true }, \
{ "GPU: ", get_gpu1, true }, \
{ "Memory: ", get_memory, false }, \
SPACER \
{ "", get_colors1, false }, \
{ "", get_colors2, false }, \
{ "", get_colors1, false }, \
{ "", get_colors2, false }, \
}

#define CPU_REMOVE \
#define CPU_CONFIG \
{ \
REMOVE("(R)"), \
REMOVE("(TM)"), \
Expand All @@ -36,7 +37,7 @@
REMOVE("CPU"), \
}

#define GPU_REMOVE \
#define GPU_CONFIG \
{ \
REMOVE("Corporation"), \
}
5 changes: 5 additions & 0 deletions config_scripts/battery_config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

BATTERY_DIRECTORY=`ls /sys/class/power_supply | grep -i "^bat" | head -n 1`

echo "BATTERY_DIRECTORY='\"/sys/class/power_supply/$BATTERY_DIRECTORY\"'"
190 changes: 145 additions & 45 deletions paleofetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ struct conf {

struct {
char *substring;
char *repl_str;
size_t length;
} cpu_remove[] = CPU_REMOVE, gpu_remove[] = GPU_REMOVE;
size_t repl_len;
} cpu_config[] = CPU_CONFIG, gpu_config[] = GPU_CONFIG;

Display *display;
struct statvfs file_stats;
Expand All @@ -55,6 +57,17 @@ void remove_newline(char *s) {
*s = '\0';
}

/*
* Replaces the first newline character with null terminator
* and returns the length of the string
*/
int remove_newline_get_length(char *s) {
int i;
for (i = 0; *s != '\0' && *s != '\n'; s++, i++);
*s = '\0';
return i;
}

/*
* Cleans up repeated spaces in a string
* Trim spaces at the front of a string
Expand Down Expand Up @@ -89,6 +102,26 @@ void remove_substring(char *str, const char* substring, size_t len) {
while(*(sub+(++i)) != '\0');
}

/*
* Replaces the first sub_len characters of sub_str from str
* with the first repl_len characters of repl_str
*/
void replace_substring(char *str, const char *sub_str, const char *repl_str, size_t sub_len, size_t repl_len) {
char buffer[BUF_SIZE / 2];
char *start = strstr(str, sub_str);
if (start == NULL) return; // substring not found

/* check if we have enough space for new substring */
if (strlen(str) - sub_len + repl_len >= BUF_SIZE / 2) {
status = -1;
halt_and_catch_fire("new substring too long to replace");
}

strcpy(buffer, start + sub_len);
strncpy(start, repl_str, repl_len);
strcpy(start + repl_len, buffer);
}

static char *get_title() {
// reduce the maximum size for these, so that we don't over-fill the title string
char hostname[BUF_SIZE / 3];
Expand Down Expand Up @@ -145,36 +178,36 @@ static char *get_kernel() {
}

static char *get_host() {
FILE *product_name = fopen("/sys/devices/virtual/dmi/id/product_name", "r");

if(product_name == NULL) {
status = -1;
halt_and_catch_fire("unable to open product name file");
char *host = malloc(BUF_SIZE), buffer[BUF_SIZE/2];
FILE *product_name, *product_version, *model;

if((product_name = fopen("/sys/devices/virtual/dmi/id/product_name", "r")) != NULL) {
if((product_version = fopen("/sys/devices/virtual/dmi/id/product_version", "r")) != NULL) {
fread(host, 1, BUF_SIZE/2, product_name);
remove_newline(host);
strcat(host, " ");
fread(buffer, 1, BUF_SIZE/2, product_version);
remove_newline(buffer);
strcat(host, buffer);
fclose(product_version);
} else {
fclose(product_name);
goto model_fallback;
}
fclose(product_name);
return host;
}

char *host = malloc(BUF_SIZE);
fread(host, 1, BUF_SIZE, product_name);
fclose(product_name);

FILE *product_version = fopen("/sys/devices/virtual/dmi/id/product_version", "r");

if(product_version == NULL) {
status = -1;
halt_and_catch_fire("unable to open product version file");
model_fallback:
if((model = fopen("/sys/firmware/devicetree/base/model", "r")) != NULL) {
fread(host, 1, BUF_SIZE, model);
remove_newline(host);
return host;
}

char version[BUF_SIZE];

fread(version, 1, BUF_SIZE, product_version);
fclose(product_version);

remove_newline(host);
remove_newline(version);

strcat(host, " ");
strcat(host, version);

return host;
status = -1;
halt_and_catch_fire("unable to get host");
return NULL;
}

static char *get_uptime() {
Expand All @@ -199,6 +232,37 @@ static char *get_uptime() {
return uptime;
}

// returns "<Battery Percentage>% [<Charging | Discharging | Unknown>]"
// Credit: allisio - https://gist.github.com/allisio/1e850b93c81150124c2634716fbc4815
static char *get_battery_percentage() {
int battery_capacity;
FILE *capacity_file, *status_file;
char battery_status[12] = "Unknown";

if ((capacity_file = fopen(BATTERY_DIRECTORY "/capacity", "r")) == NULL) {
status = ENOENT;
halt_and_catch_fire("Unable to get battery information");
}

fscanf(capacity_file, "%d", &battery_capacity);
fclose(capacity_file);

if ((status_file = fopen(BATTERY_DIRECTORY "/status", "r")) != NULL) {
fscanf(status_file, "%s", battery_status);
fclose(status_file);
}

// max length of resulting string is 19
// one byte for padding incase there is a newline
// 100% [Discharging]
// 1234567890123456789
char *battery = malloc(20);

snprintf(battery, 20, "%d%% [%s]", battery_capacity, battery_status);

return battery;
}

static char *get_packages(const char* dirname, const char* pacname, int num_extraneous) {
int num_packages = 0;
DIR * dirp;
Expand Down Expand Up @@ -326,6 +390,10 @@ static char *get_terminal() {
} else {
terminal_fallback:
strncpy(terminal, getenv("TERM"), BUF_SIZE); /* fallback to old method */
/* in tty, $TERM is simply returned as "linux"; in this case get actual tty name */
if (strcmp(terminal, "linux") == 0) {
strncpy(terminal, ttyname(STDIN_FILENO), BUF_SIZE);
}
}

return terminal;
Expand All @@ -343,6 +411,7 @@ static char *get_cpu() {
size_t len; /* unused */
int num_cores = 0, cpu_freq, prec = 3;
double freq;
char freq_unit[] = "GHz";

/* read the model name into cpu_model, and increment num_cores every time model name is found */
while(getline(&line, &len, cpuinfo) != -1) {
Expand All @@ -352,40 +421,67 @@ static char *get_cpu() {
fclose(cpuinfo);

FILE *cpufreq = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
line = NULL;

if (cpufreq == NULL) {
status = -1;
halt_and_catch_fire("Unable to open cpufreq");
if (cpufreq != NULL) {
if (getline(&line, &len, cpufreq) != -1) {
sscanf(line, "%d", &cpu_freq);
cpu_freq /= 1000; // convert kHz to MHz
} else {
fclose(cpufreq);
free(line);
goto cpufreq_fallback;
}
} else {
cpufreq_fallback:
cpufreq = fopen("/proc/cpuinfo", "r"); /* read from cpu info */
if (cpufreq == NULL) {
status = -1;
halt_and_catch_fire("Unable to open cpuinfo");
}

while (getline(&line, &len, cpufreq) != -1) {
if (sscanf(line, "cpu MHz : %lf", &freq) > 0) break;
}

cpu_freq = (int) freq;
}

line = NULL;
free(line);
fclose(cpufreq);

if (getline(&line, &len, cpufreq) != -1) {
sscanf(line, "%d", &cpu_freq);
cpu_freq /= 1000; // convert kHz to MHz
if (cpu_freq < 1000) {
freq = (double) cpu_freq;
freq_unit[0] = 'M'; // make MHz from GHz
prec = 0; // show frequency as integer value
} else {
freq = cpu_freq / 1000.0; // convert MHz to GHz and cast to double

while (cpu_freq % 10 == 0) {
--prec;
cpu_freq /= 10;
}
if (prec == 0) prec = 1; // we don't want zero decimal places
} else {
freq = 0.0; // cpuinfo_max_freq not available?
}

free(line);
fclose(cpufreq);
if (prec == 0) prec = 1; // we don't want zero decimal places
}

/* remove unneeded information */
for (int i = 0; i < COUNT(cpu_remove); ++i) {
remove_substring(cpu_model, cpu_remove[i].substring, cpu_remove[i].length);
for (int i = 0; i < COUNT(cpu_config); ++i) {
if (cpu_config[i].repl_str == NULL) {
remove_substring(cpu_model, cpu_config[i].substring, cpu_config[i].length);
} else {
replace_substring(cpu_model, cpu_config[i].substring, cpu_config[i].repl_str, cpu_config[i].length, cpu_config[i].repl_len);
}
}

char *cpu = malloc(BUF_SIZE);
snprintf(cpu, BUF_SIZE, "%s (%d) @ %.*fGHz", cpu_model, num_cores, prec, freq);
snprintf(cpu, BUF_SIZE, "%s (%d) @ %.*f%s", cpu_model, num_cores, prec, freq, freq_unit);
free(cpu_model);

truncate_spaces(cpu);

if(num_cores == 0)
*cpu = '\0';
return cpu;
}

Expand Down Expand Up @@ -424,8 +520,12 @@ static char *find_gpu(int index) {
pci_cleanup(pacc);

/* remove unneeded information */
for (int i = 0; i < COUNT(gpu_remove); ++i) {
remove_substring(gpu, gpu_remove[i].substring, gpu_remove[i].length);
for (int i = 0; i < COUNT(gpu_config); ++i) {
if (gpu_config[i].repl_str == NULL) {
remove_substring(gpu, gpu_config[i].substring, gpu_config[i].length);
} else {
replace_substring(gpu, gpu_config[i].substring, gpu_config[i].repl_str, gpu_config[i].length, gpu_config[i].repl_len);
}
}

truncate_spaces(gpu);
Expand Down
4 changes: 3 additions & 1 deletion paleofetch.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ static char *get_title(),
*get_kernel(),
*get_host(),
*get_uptime(),
*get_battery_percentage(),
*get_packages_pacman(),
*get_shell(),
*get_resolution(),
Expand All @@ -22,4 +23,5 @@ static char *get_title(),
*spacer();

#define SPACER {"", spacer, false},
#define REMOVE(A) { (A), sizeof(A) - 1}
#define REMOVE(A) { (A), NULL, sizeof(A) - 1 , 0 }
#define REPLACE(A, B) { (A), (B), sizeof(A) - 1, sizeof(B) - 1 }