• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eclipse-bluechi / bluechi / 16142519133

08 Jul 2025 11:56AM UTC coverage: 74.418% (-8.0%) from 82.434%
16142519133

push

github

engelmi
Added epel10 target for copr_build via packit

Signed-off-by: Michael Engel <mengel@redhat.com>

5117 of 6876 relevant lines covered (74.42%)

870.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.67
/src/libbluechi/cli/command.c
1
/*
2
 * Copyright Contributors to the Eclipse BlueChi project
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
#include "command.h"
7

8
#include "libbluechi/common/parse-util.h"
9
#include "libbluechi/common/string-util.h"
10

11
Command *new_command() {
71✔
12
        _cleanup_command_ Command *command = malloc0(sizeof(Command));
142✔
13
        if (command == NULL) {
71✔
14
                return NULL;
15
        }
16

17
        command->ref_count = 1;
71✔
18
        command->op = NULL;
71✔
19
        command->opargc = 0;
71✔
20
        command->opargv = NULL;
71✔
21
        command->is_help = false;
71✔
22

23
        LIST_HEAD_INIT(command->command_options);
71✔
24

25
        return steal_pointer(&command);
71✔
26
}
27

28
void command_unref(Command *command) {
71✔
29
        command->ref_count--;
71✔
30
        if (command->ref_count != 0) {
71✔
31
                return;
32
        }
33

34
        CommandOption *option = NULL;
71✔
35
        CommandOption *next_option = NULL;
71✔
36
        LIST_FOREACH_SAFE(options, option, next_option, command->command_options) {
95✔
37
                command_option_free(option);
24✔
38
        }
39

40
        free_and_null(command);
71✔
41
}
42

43
int command_execute(Command *command, void *userdata) {
65✔
44
        const Method *method = command->method;
65✔
45
        if (command->is_help) {
65✔
46
                method->usage();
1✔
47
                return 0;
1✔
48
        }
49
        if (command->opargc < method->min_args) {
64✔
50
                fprintf(stderr, "Too few arguments for method %s\n", method->name);
1✔
51
                return -EINVAL;
1✔
52
        }
53
        if (command->opargc > method->max_args) {
63✔
54
                fprintf(stderr, "Too many arguments for method %s\n", method->name);
1✔
55
                return -EINVAL;
1✔
56
        }
57
        CommandOption *opt = NULL;
62✔
58
        LIST_FOREACH(options, opt, command->command_options) {
76✔
59
                if (!(opt->option_type->option_flag & method->supported_options)) {
14✔
60
                        fprintf(stderr,
×
61
                                "Unsupported option '%s' for method '%s'\n",
62
                                opt->option_type->option_long,
×
63
                                method->name);
×
64
                        return -EINVAL;
×
65
                }
66
        }
67

68
        return method->dispatch(command, userdata);
62✔
69
}
70

71
void command_option_free(CommandOption *option) {
24✔
72
        free_and_null(option->value);
24✔
73
        free_and_null(option);
24✔
74
}
24✔
75

76
char *command_get_option(Command *command, int key) {
28✔
77
        CommandOption *option = NULL;
28✔
78
        LIST_FOREACH(options, option, command->command_options) {
48✔
79
                if (key == option->key) {
30✔
80
                        return option->value;
10✔
81
                }
82
        }
83
        return NULL;
84
}
85

86
int command_get_option_long(Command *command, int key, long *ret) {
16✔
87
        const char *opt = command_get_option(command, key);
16✔
88
        long val = 0;
16✔
89
        if (opt != NULL && !streq(opt, "") && !parse_long(opt, &val)) {
16✔
90
                return -EINVAL;
16✔
91
        }
92
        *ret = val;
15✔
93
        return 0;
15✔
94
}
95

96
bool command_flag_exists(Command *command, int key) {
22✔
97
        CommandOption *option = NULL;
22✔
98
        LIST_FOREACH(options, option, command->command_options) {
27✔
99
                if (key == option->key) {
15✔
100
                        return true;
101
                }
102
        }
103
        return false;
104
}
105

106
int command_add_option(Command *command, int key, char *value, const OptionType *option_type) {
24✔
107
        _cleanup_command_option_ CommandOption *opt = malloc0(sizeof(CommandOption));
48✔
108
        if (opt == NULL) {
24✔
109
                return -ENOMEM;
110
        }
111

112
        opt->key = key;
24✔
113
        if (value != NULL) {
24✔
114
                opt->is_flag = false;
11✔
115
                opt->value = strdup(value);
11✔
116
                if (opt->value == NULL) {
11✔
117
                        return -ENOMEM;
×
118
                }
119
        } else {
120
                opt->is_flag = true;
13✔
121
                opt->value = NULL;
13✔
122
        }
123
#pragma GCC diagnostic push
124
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
125
        opt->option_type = option_type;
24✔
126

127
        LIST_APPEND(options, command->command_options, steal_pointer(&opt));
26✔
128
#pragma GCC diagnostic pop
129

130
        return 0;
131
}
132

133
const OptionType *get_option_type(const OptionType option_types[], int option_short) {
18✔
134
        assert(option_types);
18✔
135

136
        for (size_t i = 0; option_types[i].option_flag; i++) {
60✔
137
                if (option_short == option_types[i].option_short) {
58✔
138
                        return option_types + i;
139
                }
140
        }
141
        return NULL;
142
}
143

144
const Method *methods_get_method(char *name, const Method methods[]) {
65✔
145
        assert(methods);
65✔
146
        if (name == NULL) {
65✔
147
                return NULL;
148
        }
149

150
        for (size_t i = 0; methods[i].dispatch; i++) {
465✔
151
                if (streq(name, methods[i].name)) {
464✔
152
                        return methods + i;
153
                }
154
        }
155

156
        return NULL;
157
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc