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

eclipse-bluechi / bluechi / 15045056381

15 May 2025 12:33PM UTC coverage: 37.505% (-44.9%) from 82.405%
15045056381

Pull #1072

github

web-flow
Merge b13cd68af into 04834083b
Pull Request #1072: Prevent tmt from pruning coverage files

1888 of 5034 relevant lines covered (37.5%)

23.81 hits per line

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

93.59
/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() {
8✔
12
        _cleanup_command_ Command *command = malloc0(sizeof(Command));
16✔
13
        if (command == NULL) {
8✔
14
                return NULL;
15
        }
16

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

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

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

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

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

40
        free_and_null(command);
8✔
41
}
42

43
int command_execute(Command *command, void *userdata) {
4✔
44
        const Method *method = command->method;
4✔
45
        if (command->is_help) {
4✔
46
                method->usage();
1✔
47
                return 0;
1✔
48
        }
49
        if (command->opargc < method->min_args) {
3✔
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) {
2✔
54
                fprintf(stderr, "Too many arguments for method %s\n", method->name);
1✔
55
                return -EINVAL;
1✔
56
        }
57
        CommandOption *opt = NULL;
1✔
58
        LIST_FOREACH(options, opt, command->command_options) {
1✔
59
                if (!(opt->option_type->option_flag & method->supported_options)) {
×
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);
1✔
69
}
70

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

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

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

96
bool command_flag_exists(Command *command, int key) {
3✔
97
        CommandOption *option = NULL;
3✔
98
        LIST_FOREACH(options, option, command->command_options) {
8✔
99
                if (key == option->key) {
7✔
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) {
10✔
107
        _cleanup_command_option_ CommandOption *opt = malloc0(sizeof(CommandOption));
20✔
108
        if (opt == NULL) {
10✔
109
                return -ENOMEM;
110
        }
111

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

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

130
        return 0;
131
}
132

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

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

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

150
        for (size_t i = 0; methods[i].dispatch; i++) {
6✔
151
                if (streq(name, methods[i].name)) {
5✔
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