Commit: 097fda3f32942da2f4bbf8495c9dbb6c152fef58
Parent: 7bced14670d73a48fc528ab2cafd8a6ddf0e0b94
Author: Randy Palamar
Date: Tue, 24 Dec 2024 12:11:22 -0700
delete pscanf function
scanf in general is an awful function and reading strings with it
is completely inexcusable. This removes more pointless c-runtime
code.
Diffstat:
3 files changed, 57 insertions(+), 29 deletions(-)
diff --git a/blocks/linux/backlight.c b/blocks/linux/backlight.c
@@ -7,10 +7,7 @@ static BLOCK_UPDATE_FN(backlight_update)
return 0;
struct linux_backlight_data *lbd = b->user_data;
- i64 current;
- if (pscanf(lbd->brightness_path, "%ld", ¤t) != 1)
- current = 0;
-
+ i64 current = read_i64(lbd->brightness_path);
f32 percent = 100 * current / (f32)lbd->max_brightness + 0.5;
i64 len = snprintf(buffer, sizeof(buffer), "%d%%", (i32)percent);
buffer[len] = 0;
@@ -30,7 +27,8 @@ static BLOCK_INIT_FN(backlight_init)
stream_push_s8(&path, *(s8 *)b->arg);
size sidx = path.write_index;
stream_push_s8(&path, s8("/max_brightness"));
- if (pscanf(stream_ensure_c_str(&path), "%ld", &lbd->max_brightness) != 1)
+ lbd->max_brightness = read_i64(stream_ensure_c_str(&path));
+ if (!lbd->max_brightness)
die("backlight_init: failed to read max brightness\n");
path.write_index = sidx;
diff --git a/blocks/linux/battery_info.c b/blocks/linux/battery_info.c
@@ -19,7 +19,6 @@ static BLOCK_UPDATE_FN(battery_info_update)
char *pre = ba->pre ? ba->pre : "";
char *suf = ba->suf ? ba->suf : "";
- char state[12];
i32 h, m;
i64 power_now, energy_now;
@@ -28,24 +27,26 @@ static BLOCK_UPDATE_FN(battery_info_update)
size sidx = lbd->path_base.write_index;
stream_push_s8(&lbd->path_base, s8("/energy_now"));
- if (pscanf(stream_ensure_c_str(&lbd->path_base), "%ld", &energy_now) != 1)
- energy_now = 0;
+ energy_now = read_i64(stream_ensure_c_str(&lbd->path_base));
lbd->path_base.write_index = sidx;
f32 percent = (100 * energy_now / (f64)lbd->energy_full) + 0.5;
b32 warn = percent < ba->thres;
+ char state_buffer[16] = {0};
stream_push_s8(&lbd->path_base, s8("/status"));
- if (pscanf(stream_ensure_c_str(&lbd->path_base), "%12s", &state) != 1)
- snprintf(state, sizeof(state), "Unknown");
+ s8 state = s8_trim_space(read_s8(stream_ensure_c_str(&lbd->path_base),
+ (s8){.len = sizeof(state_buffer),
+ .data = (u8 *)state_buffer}));
+ if (state.len <= 0) state = s8("Unknown");
lbd->path_base.write_index = sidx;
/* NOTE(rnp): proper devices use negative power to indicate discharging but that
* is not always the case. The status string can mostly be trusted */
- if (!strcmp(state, "Discharging")) {
+ if (s8_equal(state, s8("Discharging"))) {
stream_push_s8(&lbd->path_base, s8("/power_now"));
- if (pscanf(stream_ensure_c_str(&lbd->path_base), "%ld", &power_now) != 1)
- power_now = 1;
+ power_now = read_i64(stream_ensure_c_str(&lbd->path_base));
+ if (!power_now) power_now = 1;
lbd->path_base.write_index = sidx;
timeleft = energy_now / (f64)ABS(power_now);
@@ -57,7 +58,7 @@ static BLOCK_UPDATE_FN(battery_info_update)
buffer[len] = 0;
} else {
i64 len = snprintf(buffer, sizeof(buffer), "%s%d%% (%s)%s", warn? pre : "",
- (i32)percent, state, warn? suf : "");
+ (i32)percent, (char *)state.data, warn? suf : "");
buffer[len] = 0;
}
b->len = snprintf(b->data, sizeof(b->data), b->fmt, buffer);
@@ -89,7 +90,8 @@ static BLOCK_INIT_FN(battery_info_init)
stream_push_s8(&lbd->path_base, ba->bat);
size sidx = lbd->path_base.write_index;
stream_push_s8(&lbd->path_base, s8("/energy_full"));
- if (pscanf(stream_ensure_c_str(&lbd->path_base), "%ld", &lbd->energy_full) != 1)
+ lbd->energy_full = read_i64(stream_ensure_c_str(&lbd->path_base));
+ if (!lbd->energy_full)
die("battery_info_init: failed to read battery capacity\n");
lbd->path_base.write_index = sidx;
diff --git a/status.c b/status.c
@@ -12,9 +12,12 @@
#include <X11/Xlib.h>
#define ABS(a) ((a) < 0 ? -(a) : (a))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a))
#define BLOCKLEN 128
+#define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\t')
+
#define TICK_RATE_SECONDS 1
#define TICK_RATE_NANOSECONDS 0
@@ -101,6 +104,8 @@ static FileWatch file_watches;
static i32 dflag;
+i64 strtol(const char *, char **, i32);
+
static void
die(const char *errstr, ...)
{
@@ -131,22 +136,26 @@ timer_update(f32 *timer, f32 interval, f32 dt)
return result;
}
-static int
-pscanf(const char *path, const char *fmt, ...)
+static s8
+read_s8(char *path, s8 buffer)
{
- FILE *fp;
- va_list ap;
- int ret;
-
- if (!(fp = fopen(path, "r")))
- return -1;
-
- va_start(ap, fmt);
- ret = vfscanf(fp, fmt, ap);
- va_end(ap);
- fclose(fp);
+ i32 fd = open(path, O_RDONLY);
+ buffer.len = read(fd, buffer.data, buffer.len);
+ close(fd);
+ return buffer;
+}
- return (ret == EOF) ? -1 : ret;
+static i64
+read_i64(char *path)
+{
+ i64 result = 0;
+ char buffer[64];
+ s8 str = read_s8(path, (s8){.len = sizeof(buffer), .data = (u8 *)buffer});
+ if (str.len > 0) {
+ buffer[MIN(str.len, sizeof(buffer) - 1)] = 0;
+ result = strtol(buffer, 0, 10);
+ }
+ return result;
}
static void *
@@ -174,6 +183,25 @@ alloc_(Arena *a, size len, size align, size count)
return mem_clear(p, 0, count * len);
}
+static b32
+s8_equal(s8 a, s8 b)
+{
+ b32 result = a.len == b.len;
+ if (result) {
+ for (size i = 0; i < a.len; i++)
+ result &= a.data[i] == b.data[i];
+ }
+ return result;
+}
+
+static s8
+s8_trim_space(s8 a)
+{
+ while (a.len > 0 && ISSPACE(a.data[0])) { a.len--; a.data++; }
+ while (a.len > 0 && ISSPACE(a.data[a.len - 1])) { a.len--; }
+ return a;
+}
+
static Stream
stream_alloc(Arena *a, size capacity)
{