tree-wide: extend verbs functions with extra per-verb data parameter

We often have a pattern where the same verb function is used for
multiple actions. This leads to an antipattern where we figure out what
action needs to be taken from argv[0] multiple times: often once in
parse_argv() to figure out what options are allowed, then once again
implicitly in dispatch_verb(), and then again in the action verb itself.
Let's allow passing a parameter into the verb to simplify this.

This matches a pattern we have in conf-parser.h, where we have both
void *userdata (more global) and void *data (per-config item). Here,
I opted for uintptr_t userdata. It seems that most of the time we'll
want to just pass an enum value. This works OK with no casts. I also
tried a void* and union. In both cases, much more boilerplate is needed:
either a cast or a macro to help avoid compiler warnings. uintptr_t
seems generic enough to cover foreseeable usecases with no fuss.

This is a noop refactoring. See next commit for an example.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-03-18 10:28:47 +00:00
committed by Luca Boccassi
parent 9e8babc8ab
commit 31ddd87da0
216 changed files with 745 additions and 573 deletions
+9 -6
View File
@@ -26,7 +26,7 @@ static char **arg_path = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_path, strv_freep);
static int help(int argc, char *argv[], void *userdata) {
static int help(void) {
_cleanup_free_ char *link = NULL;
int r;
@@ -54,6 +54,10 @@ static int help(int argc, char *argv[], void *userdata) {
return 0;
}
static int verb_help(int argc, char *argv[], uintptr_t _data, void *userdata) {
return help();
}
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_PATH = 0x100,
@@ -76,8 +80,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
case 'h':
help(0, NULL, NULL);
return 0;
return help();
case ARG_VERSION:
return version();
@@ -335,7 +338,7 @@ static int make_bad(const char *prefix, uint64_t done, const char *suffix, char
return 0;
}
static int verb_status(int argc, char *argv[], void *userdata) {
static int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL;
uint64_t left, done;
int r;
@@ -441,7 +444,7 @@ static int rename_in_dir_idempotent(int fd, const char *from, const char *to) {
return 1;
}
static int verb_set(int argc, char *argv[], void *userdata) {
static int verb_set(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL;
const char *target, *source1, *source2;
uint64_t left, done;
@@ -547,7 +550,7 @@ exists:
static int run(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
{ "help", VERB_ANY, VERB_ANY, 0, verb_help },
{ "status", VERB_ANY, 1, VERB_DEFAULT, verb_status },
{ "good", VERB_ANY, 1, 0, verb_set },
{ "bad", VERB_ANY, 1, 0, verb_set },