Get rid of all global variables

This commit is contained in:
Utkarsh Verma 2023-10-25 20:00:08 +05:30
parent bc84d094cd
commit 10f7d9b8db
No known key found for this signature in database
GPG Key ID: 7A4885A7162BDF20
13 changed files with 121 additions and 69 deletions

View File

@ -9,7 +9,7 @@ VERBOSE := 0
LIBS := xcb-atom
PREFIX := /usr/local
CFLAGS := -Ofast -I. -I$(INC_DIR)
CFLAGS := -Ofast -I. -I$(INC_DIR) -std=c99
CFLAGS += -DBINARY=\"$(BIN)\" -D_POSIX_C_SOURCE=200809L
CFLAGS += -Wall -Wpedantic -Wextra -Wswitch-enum
CFLAGS += $(shell pkg-config --cflags $(LIBS))

View File

@ -17,6 +17,8 @@ typedef struct {
pid_t fork_pid;
} block;
block block_new(const char *const command, const unsigned int interval,
const int signal);
int block_init(block *const block);
int block_deinit(block *const block);
int block_execute(block *const block, const uint8_t button);

View File

@ -2,13 +2,12 @@
#include <signal.h>
#include "block.h"
#include "config.h"
#include "util.h"
#define REFRESH_SIGNAL SIGUSR1
// Utilise C's adjacent string concatenation to count the number of blocks.
#define X(...) "."
extern block blocks[LEN(BLOCKS(X)) - 1];
enum { BLOCK_COUNT = LEN(BLOCKS(X)) - 1 };
#undef X
#define REFRESH_SIGNAL SIGUSR1

View File

@ -2,19 +2,27 @@
#include <bits/types/sigset_t.h>
#include "block.h"
#include "timer.h"
typedef sigset_t signal_set;
typedef int (*signal_refresh_callback)(void);
typedef int (*signal_timer_callback)(timer* const timer);
typedef int (*signal_refresh_callback)(block* const blocks,
const unsigned short block_count);
typedef int (*signal_timer_callback)(block* const blocks,
const unsigned short block_code,
timer* const timer);
typedef struct {
int fd;
const signal_refresh_callback refresh_callback;
const signal_timer_callback timer_callback;
block* const blocks;
const unsigned short block_count;
} signal_handler;
signal_handler signal_handler_new(
block* const blocks, const unsigned short block_count,
const signal_refresh_callback refresh_callback,
const signal_timer_callback timer_callback);
int signal_handler_init(signal_handler* const handler);

View File

@ -10,16 +10,19 @@
typedef struct {
#define STATUS_LENGTH \
((LEN(blocks) * (MEMBER_LENGTH(block, output) - 1) + CLICKABLE_BLOCKS) + \
(LEN(blocks) - 1 + LEADING_DELIMITER + TRAILING_DELIMITER) * \
((BLOCK_COUNT * (MEMBER_LENGTH(block, output) - 1) + CLICKABLE_BLOCKS) + \
(BLOCK_COUNT - 1 + LEADING_DELIMITER + TRAILING_DELIMITER) * \
(LEN(DELIMITER) - 1) + \
1)
char current[STATUS_LENGTH];
char previous[STATUS_LENGTH];
#undef STATUS_LENGTH
const block* const blocks;
const unsigned short block_count;
} status;
status status_new(void);
status status_new(const block* const blocks, const unsigned short block_count);
bool status_update(status* const status);
int status_write(const status* const status, const bool is_debug_mode,
x11_connection* const connection);

View File

@ -2,6 +2,8 @@
#include <signal.h>
#include "block.h"
#define TIMER_SIGNAL SIGALRM
typedef struct {
@ -10,5 +12,5 @@ typedef struct {
const unsigned int reset_value;
} timer;
timer timer_new(void);
timer timer_new(const block *const blocks, const unsigned short block_count);
int timer_arm(timer *const timer);

View File

@ -3,11 +3,11 @@
#include <stdbool.h>
#include <sys/poll.h>
#include "block.h"
#include "main.h"
#include "util.h"
typedef enum {
SIGNAL_FD = LEN(blocks),
SIGNAL_FD = BLOCK_COUNT,
WATCHER_FD_COUNT,
} watcher_fd_index;
@ -15,8 +15,13 @@ typedef struct pollfd watcher_fd;
typedef struct {
watcher_fd fds[WATCHER_FD_COUNT];
const block *const blocks;
const unsigned short block_count;
} watcher;
watcher watcher_new(const block *const blocks,
const unsigned short block_count);
int watcher_init(watcher *const watcher, const int signal_fd);
int watcher_poll(watcher *const watcher, const int timeout_ms);
bool watcher_fd_is_readable(const watcher_fd *const watcher_fd);

View File

@ -14,6 +14,20 @@
#include "config.h"
#include "util.h"
block block_new(const char *const command, const unsigned int interval,
const int signal) {
block block = {
.command = command,
.interval = interval,
.signal = signal,
.output = {[0] = '\0'},
.fork_pid = -1,
};
return block;
}
int block_init(block *const block) {
if (pipe(block->pipe) != 0) {
(void)fprintf(stderr,
@ -22,8 +36,6 @@ int block_init(block *const block) {
return 1;
}
block->fork_pid = -1;
return 0;
}

View File

@ -13,18 +13,8 @@
#include "watcher.h"
#include "x11.h"
#define BLOCK(cmd, period, sig) \
{ \
.command = cmd, \
.interval = period, \
.signal = sig, \
},
block blocks[] = {BLOCKS(BLOCK)};
#undef BLOCK
static int init_blocks(void) {
for (unsigned short i = 0; i < LEN(blocks); ++i) {
static int init_blocks(block *const blocks, const unsigned short block_count) {
for (unsigned short i = 0; i < block_count; ++i) {
block *const block = &blocks[i];
if (block_init(block) != 0) {
return 1;
@ -34,8 +24,9 @@ static int init_blocks(void) {
return 0;
}
static int deinit_blocks(void) {
for (unsigned short i = 0; i < LEN(blocks); ++i) {
static int deinit_blocks(block *const blocks,
const unsigned short block_count) {
for (unsigned short i = 0; i < block_count; ++i) {
block *const block = &blocks[i];
if (block_deinit(block) != 0) {
return 1;
@ -45,8 +36,10 @@ static int deinit_blocks(void) {
return 0;
}
static int execute_blocks(const unsigned int time) {
for (unsigned short i = 0; i < LEN(blocks); ++i) {
static int execute_blocks(block *const blocks,
const unsigned short block_count,
const unsigned int time) {
for (unsigned short i = 0; i < block_count; ++i) {
block *const block = &blocks[i];
if (!block_must_run(block, time)) {
continue;
@ -60,8 +53,9 @@ static int execute_blocks(const unsigned int time) {
return 0;
}
static int trigger_event(timer *const timer) {
if (execute_blocks(timer->time) != 0) {
static int trigger_event(block *const blocks, const unsigned short block_count,
timer *const timer) {
if (execute_blocks(blocks, block_count, timer->time) != 0) {
return 1;
}
@ -72,30 +66,32 @@ static int trigger_event(timer *const timer) {
return 0;
}
static int refresh_callback(void) {
if (execute_blocks(0) != 0) {
static int refresh_callback(block *const blocks,
const unsigned short block_count) {
if (execute_blocks(blocks, block_count, 0) != 0) {
return 1;
}
return 0;
}
static int event_loop(const bool is_debug_mode,
static int event_loop(block *const blocks, const unsigned short block_count,
const bool is_debug_mode,
x11_connection *const connection,
signal_handler *const signal_handler) {
timer timer = timer_new();
timer timer = timer_new(blocks, block_count);
// Kickstart the event loop with an initial execution.
if (trigger_event(&timer) != 0) {
if (trigger_event(blocks, block_count, &timer) != 0) {
return 1;
}
watcher watcher;
watcher watcher = watcher_new(blocks, block_count);
if (watcher_init(&watcher, signal_handler->fd) != 0) {
return 1;
}
status status = status_new();
status status = status_new(blocks, block_count);
bool is_alive = true;
while (is_alive) {
const int event_count = watcher_poll(&watcher, -1);
@ -147,20 +143,26 @@ int main(const int argc, const char *const argv[]) {
return 1;
}
#define BLOCK(command, interval, signal) block_new(command, interval, signal),
block blocks[BLOCK_COUNT] = {BLOCKS(BLOCK)};
#undef BLOCK
const unsigned short block_count = LEN(blocks);
int status = 0;
if (init_blocks() != 0) {
if (init_blocks(blocks, block_count) != 0) {
status = 1;
goto x11_close;
}
signal_handler signal_handler =
signal_handler_new(refresh_callback, trigger_event);
signal_handler signal_handler = signal_handler_new(
blocks, block_count, refresh_callback, trigger_event);
if (signal_handler_init(&signal_handler) != 0) {
status = 1;
goto deinit_blocks;
}
if (event_loop(cli_args.is_debug_mode, connection, &signal_handler) != 0) {
if (event_loop(blocks, block_count, cli_args.is_debug_mode, connection,
&signal_handler) != 0) {
status = 1;
}
@ -169,7 +171,7 @@ int main(const int argc, const char *const argv[]) {
}
deinit_blocks:
if (deinit_blocks() != 0) {
if (deinit_blocks(blocks, block_count) != 0) {
status = 1;
}

View File

@ -11,16 +11,19 @@
#include "block.h"
#include "main.h"
#include "timer.h"
#include "util.h"
typedef struct signalfd_siginfo signal_info;
signal_handler signal_handler_new(
block *const blocks, const unsigned short block_count,
const signal_refresh_callback refresh_callback,
const signal_timer_callback timer_callback) {
signal_handler handler = {
.refresh_callback = refresh_callback,
.timer_callback = timer_callback,
.blocks = blocks,
.block_count = block_count,
};
return handler;
@ -40,9 +43,9 @@ int signal_handler_init(signal_handler *const handler) {
(void)sigaddset(&set, SIGINT);
(void)sigaddset(&set, SIGTERM);
for (unsigned short i = 0; i < LEN(blocks); ++i) {
const block *const block = &blocks[i];
if (blocks->signal > 0) {
for (unsigned short i = 0; i < handler->block_count; ++i) {
const block *const block = &handler->blocks[i];
if (block->signal > 0) {
if (sigaddset(&set, SIGRTMIN + block->signal) != 0) {
(void)fprintf(
stderr,
@ -75,6 +78,7 @@ int signal_handler_deinit(signal_handler *const handler) {
if (close(handler->fd) != 0) {
(void)fprintf(stderr,
"error: could not close signal file descriptor\n");
return 1;
}
return 0;
@ -91,12 +95,14 @@ int signal_handler_process(signal_handler *const handler, timer *const timer) {
const int signal = (int)info.ssi_signo;
switch (signal) {
case TIMER_SIGNAL:
if (handler->timer_callback(timer) != 0) {
if (handler->timer_callback(handler->blocks, handler->block_count,
timer) != 0) {
return 1;
}
return 0;
case REFRESH_SIGNAL:
if (handler->refresh_callback() != 0) {
if (handler->refresh_callback(handler->blocks,
handler->block_count) != 0) {
return 1;
}
return 0;
@ -106,8 +112,8 @@ int signal_handler_process(signal_handler *const handler, timer *const timer) {
return 1;
}
for (unsigned short i = 0; i < LEN(blocks); ++i) {
block *const block = blocks + i;
for (unsigned short i = 0; i < handler->block_count; ++i) {
block *const block = &handler->blocks[i];
if (block->signal == signal - SIGRTMIN) {
const uint8_t button = (uint8_t)info.ssi_int;
block_execute(block, button);

View File

@ -6,18 +6,20 @@
#include "block.h"
#include "config.h"
#include "main.h"
#include "util.h"
#include "x11.h"
static bool has_status_changed(const status *const status) {
return strcmp(status->current, status->previous) != 0;
}
status status_new(void) {
status status_new(const block *const blocks,
const unsigned short block_count) {
status status = {
.current = {[0] = '\0'},
.previous = {[0] = '\0'},
.blocks = blocks,
.block_count = block_count,
};
return status;
@ -27,8 +29,8 @@ bool status_update(status *const status) {
(void)strcpy(status->previous, status->current);
status->current[0] = '\0';
for (unsigned short i = 0; i < LEN(blocks); ++i) {
const block *const block = &blocks[i];
for (unsigned short i = 0; i < status->block_count; ++i) {
const block *const block = &status->blocks[i];
if (strlen(block->output) > 0) {
#if LEADING_DELIMITER

View File

@ -5,13 +5,13 @@
#include <unistd.h>
#include "block.h"
#include "main.h"
#include "util.h"
static unsigned int compute_tick(void) {
static unsigned int compute_tick(const block *const blocks,
const unsigned short block_count) {
unsigned int tick = 0;
for (unsigned short i = 0; i < LEN(blocks); ++i) {
for (unsigned short i = 0; i < block_count; ++i) {
const block *const block = &blocks[i];
tick = gcd(block->interval, tick);
}
@ -19,10 +19,11 @@ static unsigned int compute_tick(void) {
return tick;
}
static unsigned int compute_reset_value(void) {
static unsigned int compute_reset_value(const block *const blocks,
const unsigned short block_count) {
unsigned int reset_value = 1;
for (unsigned short i = 0; i < LEN(blocks); ++i) {
for (unsigned short i = 0; i < block_count; ++i) {
const block *const block = &blocks[i];
reset_value = MAX(block->interval, reset_value);
}
@ -30,11 +31,11 @@ static unsigned int compute_reset_value(void) {
return reset_value;
}
timer timer_new(void) {
timer timer_new(const block *const blocks, const unsigned short block_count) {
timer timer = {
.time = 0,
.tick = compute_tick(),
.reset_value = compute_reset_value(),
.tick = compute_tick(blocks, block_count),
.reset_value = compute_reset_value(blocks, block_count),
};
return timer;

View File

@ -5,9 +5,19 @@
#include <stdio.h>
#include <sys/poll.h>
#include "main.h"
#include "block.h"
#include "util.h"
watcher watcher_new(const block* const blocks,
const unsigned short block_count) {
watcher watcher = {
.blocks = blocks,
.block_count = block_count,
};
return watcher;
}
int watcher_init(watcher* const watcher, const int signal_fd) {
if (signal_fd == -1) {
fprintf(stderr,
@ -19,8 +29,8 @@ int watcher_init(watcher* const watcher, const int signal_fd) {
fd->fd = signal_fd;
fd->events = POLLIN;
for (unsigned short i = 0; i < LEN(blocks); ++i) {
const int block_fd = blocks[i].pipe[READ_END];
for (unsigned short i = 0; i < watcher->block_count; ++i) {
const int block_fd = watcher->blocks[i].pipe[READ_END];
if (block_fd == -1) {
fprintf(
stderr,