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 LIBS := xcb-atom
PREFIX := /usr/local 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 += -DBINARY=\"$(BIN)\" -D_POSIX_C_SOURCE=200809L
CFLAGS += -Wall -Wpedantic -Wextra -Wswitch-enum CFLAGS += -Wall -Wpedantic -Wextra -Wswitch-enum
CFLAGS += $(shell pkg-config --cflags $(LIBS)) CFLAGS += $(shell pkg-config --cflags $(LIBS))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,6 +14,20 @@
#include "config.h" #include "config.h"
#include "util.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) { int block_init(block *const block) {
if (pipe(block->pipe) != 0) { if (pipe(block->pipe) != 0) {
(void)fprintf(stderr, (void)fprintf(stderr,
@ -22,8 +36,6 @@ int block_init(block *const block) {
return 1; return 1;
} }
block->fork_pid = -1;
return 0; return 0;
} }

View File

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

View File

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

View File

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

View File

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

View File

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