Initial commit. Works.
Makefile copied from pokemath project Reads two files from sysfs: charge_now and charge_full under BAT0, then divides them using float math. Output is guaranteed to be stable across major versions. Supported options: -v gives verbose output for debugging purposes -h shows help text and exits -t gives terse output Known issues: The path to charge_now and charge_full is hard-coded. This utility will not work with batteries that do not happen to be named BAT0. The float value given by this program is not actually a percentage. TODO: Move help text #defines into a header file Add support to traverse /sys/class/power_supply and locate batteries Possibly add support to store default battery paths in /etc/battery_percent.conf DISCLAIMER: This program is already too overcomplicated and shows no signs of slowing down.
This commit is contained in:
commit
50fdb142dd
58
Makefile
Normal file
58
Makefile
Normal file
@ -0,0 +1,58 @@
|
||||
#NEWPROJECT requires refactor.sh main.c
|
||||
# Taken from https://stackoverflow.com/questions/30573481/how-to-write-a-makefile-with-separate-source-and-header-directories
|
||||
|
||||
SRCDIR := sources
|
||||
MAINDIR := $(SRCDIR)/main
|
||||
INCDIR := include
|
||||
OBJDIR := objects
|
||||
MAINOD := $(OBJDIR)/main
|
||||
BINDIR := build
|
||||
|
||||
REFACTOR := refactor.h
|
||||
|
||||
HEADERS := $(wildcard $(INCDIR)/*.h)
|
||||
|
||||
MAINS := $(wildcard $(MAINDIR)/*.c)
|
||||
MAINOBJS := $(patsubst $(MAINDIR)/%.c, $(MAINOD)/%.o, $(MAINS))
|
||||
|
||||
TARGETS := $(patsubst $(MAINDIR)/%.c, $(BINDIR)/%, $(MAINS))
|
||||
|
||||
SOURCES := $(wildcard $(SRCDIR)/*.c)
|
||||
|
||||
OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SOURCES))
|
||||
|
||||
CPPFLAGS := -Iinclude -MMD -MP
|
||||
CFLAGS := -Wall -Werror -Wpedantic
|
||||
LDFLAGS := #-Lmath or whatever
|
||||
LDLIBS := #-lm or whatever
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(TARGETS)
|
||||
@echo $(TARGETS)
|
||||
|
||||
refactor:
|
||||
./refactor.sh
|
||||
|
||||
$(TARGETS): $(OBJECTS) $(MAINOBJS) | $(BINDIR) $(OBJDIR) $(MAINOD)
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) $(patsubst $(BINDIR)/%, $(MAINOD)/%.o, $@) $(LDLIBS) -o $@
|
||||
|
||||
$(BINDIR) $(OBJDIR) $(MAINOD):
|
||||
mkdir --parents $@
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(HEADERS) | $(OBJDIR)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(MAINOD)/%.o: $(MAINDIR)/%.c $(HEADERS) | $(MAINOD)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) -rv $(BINDIR) $(OBJDIR)
|
||||
|
||||
# Honestly still not sure what this directive does.
|
||||
# It's an include directive, which processes all .d files that correspond to members of $(OBJ),
|
||||
# with the hyphen in front meaning that it suppresses/ignores errors (from nonexistent .d files)
|
||||
# Seems to be included under the stipulation that GNU make will auto-generate .d files based on
|
||||
# a given file's #include directives?
|
||||
# https://stackoverflow.com/questions/19114410/what-is-d-file-after-building-with-make
|
||||
-include $(OBJ:.o=.d)
|
86
sources/main/battery.c
Normal file
86
sources/main/battery.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CHARGE_NOW_PATH "/sys/class/power_supply/BAT0/charge_now"
|
||||
#define CHARGE_FULL_PATH "/sys/class/power_supply/BAT0/charge_full"
|
||||
#define VERSION "v0.0"
|
||||
#define TITLE "Battery Percentage, by Catluck Kettlemerry"
|
||||
#define PROGNAME "battery_percentage"
|
||||
#define USAGE0 "Usage: "
|
||||
#define USAGE1 "[option]"
|
||||
#define OPTIONS0 "Options:"
|
||||
#define OPTIONS1 "\t-v run verbosely"
|
||||
#define OPTIONS2 "\t-h show help and exit"
|
||||
#define OPTIONS3 "\t-t provide terse output"
|
||||
|
||||
int run_verbose = 0;
|
||||
int run_terse = 0;
|
||||
|
||||
void print_help(void){
|
||||
printf("%s %s\n", TITLE, VERSION);
|
||||
printf("%s %s %s\n", USAGE0, PROGNAME, USAGE1);
|
||||
printf("%s\n%s\n%s\n%s\n", OPTIONS0, OPTIONS1, OPTIONS2, OPTIONS3);
|
||||
}
|
||||
|
||||
int main(int argc, char *const argv[]){
|
||||
|
||||
int opt;
|
||||
while((opt = getopt(argc, argv, "vht")) != -1) {
|
||||
switch(opt){
|
||||
case 'v':
|
||||
run_verbose = 1;
|
||||
break;
|
||||
case 'h':
|
||||
print_help();
|
||||
return 0;
|
||||
case 't':
|
||||
run_terse = 1;
|
||||
break;
|
||||
default:
|
||||
printf("Literally how could you pass an unspecified argument to this program");
|
||||
}
|
||||
}
|
||||
|
||||
FILE * fd_now = fopen(CHARGE_NOW_PATH, "r");
|
||||
FILE * fd_full = fopen(CHARGE_FULL_PATH, "r");
|
||||
|
||||
int c_now;
|
||||
int c_full;
|
||||
|
||||
int vals_read = fscanf(fd_now, "%d", &c_now);
|
||||
if(vals_read != 1){
|
||||
if(errno != 0){
|
||||
perror("Error reading full battery charge: ");
|
||||
} else if(vals_read == EOF){
|
||||
printf("End-of-file reached while reading current battery charge(?)");
|
||||
} else {
|
||||
printf("Invalid number of arguments (%d) returned while reading full battery charge", vals_read);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
vals_read = fscanf(fd_full, "%d", &c_full);
|
||||
if(vals_read != 1){
|
||||
if(errno != 0){
|
||||
perror("Error reading full battery charge: ");
|
||||
} else if(vals_read == EOF){
|
||||
printf("End-of-file reached while reading full battery charge(?)");
|
||||
} else {
|
||||
printf("Invalid number of arguments (%d) returned while reading full battery charge", vals_read);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(run_verbose){
|
||||
printf("Current charge: %d\n", c_now);
|
||||
printf("Full charge: %d\n", c_full);
|
||||
}
|
||||
|
||||
if(!run_terse) {
|
||||
printf("Battery percentage: ");
|
||||
}
|
||||
float pct = ((float)c_now) / ((float)c_full);
|
||||
printf("%f\n", pct);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user