commit: 4f904704681567ff4301048c965a73d5d5f366b3
Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Dec 9 10:58:40 2025 +0000
Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Tue Dec 9 10:58:40 2025 +0000
URL: https://gitweb.gentoo.org/proj/steve.git/commit/?id=4f904704
Make stevie's argument parsing less cursed
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
stevie.cxx | 68 ++++++++++++++++++++++++++++++--------------------------------
1 file changed, 33 insertions(+), 35 deletions(-)
diff --git a/stevie.cxx b/stevie.cxx
index 46769a6..12f6043 100644
--- a/stevie.cxx
+++ b/stevie.cxx
@@ -162,16 +162,27 @@ static const struct option stevie_long_opts[] = {
static const char *stevie_short_opts = "+hVtjJ:lL:mM:";
+typedef std::vector<
+ std::pair<unsigned long, std::variant<int64_t, double>>
+> stevie_action_vector;
+
+static bool stevie_add_set_long_action(
+ stevie_action_vector *actions,
+ unsigned long ioctl_num)
+{
+}
+
int main(int argc, char **argv)
{
const char *jobserver_path = "/dev/steve";
int opt;
- std::vector<std::pair<unsigned long, std::variant<int64_t, double>>>
actions;
+ stevie_action_vector actions;
while ((opt = getopt_long(argc, argv, stevie_short_opts,
stevie_long_opts, nullptr)) != -1) {
- unsigned long ioctl_num = 0;
- std::variant<int64_t, double> ioctl_val = 0;
+ long long_arg;
+ double double_arg;
+
switch (opt) {
case 'h':
std::print(stevie_usage, argv[0]);
@@ -183,55 +194,42 @@ int main(int argc, char **argv)
jobserver_path = optarg;
break;
case 't':
- ioctl_num = STEVE_IOC_GET_TOKENS;
+ actions.emplace_back(STEVE_IOC_GET_TOKENS, 0);
break;
case 'j':
- ioctl_num = STEVE_IOC_GET_JOBS;
+ actions.emplace_back(STEVE_IOC_GET_JOBS, 0);
break;
case 'J':
- ioctl_num = STEVE_IOC_SET_JOBS;
+ if (!arg_to_long(optarg, &long_arg)) {
+ std::print(stderr, "invalid --set-jobs value:
{}\n", optarg);
+ return 1;
+ }
+ actions.emplace_back(STEVE_IOC_SET_JOBS, long_arg);
break;
case 'l':
- ioctl_num = STEVE_IOC_GET_LOAD_AVG;
- ioctl_val = 0.0;
+ actions.emplace_back(STEVE_IOC_GET_LOAD_AVG, 0.0);
break;
case 'L':
- ioctl_num = STEVE_IOC_SET_LOAD_AVG;
- ioctl_val = 0.0;
+ if (!arg_to_double(optarg, &double_arg) || double_arg <
1) {
+ std::print(stderr, "invalid --set-load-average
value (must be >=1): {}\n", optarg);
+ return 1;
+ }
+ actions.emplace_back(STEVE_IOC_SET_LOAD_AVG,
double_arg);
break;
case 'm':
- ioctl_num = STEVE_IOC_GET_MIN_JOBS;
+ actions.emplace_back(STEVE_IOC_GET_MIN_JOBS, 0);
break;
case 'M':
- ioctl_num = STEVE_IOC_SET_MIN_JOBS;
+ if (!arg_to_long(optarg, &long_arg)) {
+ std::print(stderr, "invalid --set-min-jobs
value: {}\n", optarg);
+ return 1;
+ }
+ actions.emplace_back(STEVE_IOC_SET_MIN_JOBS, long_arg);
break;
default:
std::print(stderr, stevie_usage, argv[0]);
return 1;
}
-
- if (ioctl_num != 0) {
- if (STEVE_IOC_IS_GET(ioctl_num)) {
- actions.emplace_back(ioctl_num, ioctl_val);
- } else if (STEVE_IOC_IS_SET(ioctl_num)) {
- if (double *dval =
std::get_if<double>(&ioctl_val)) {
- if (!arg_to_double(optarg, dval) ||
*dval < 1) {
- std::print(stderr, "invalid
load average value (must be >=1): {}\n", optarg);
- return 1;
- }
- } else if
(std::holds_alternative<int64_t>(ioctl_val)) {
- long long_arg;
- if (!arg_to_long(optarg, &long_arg)) {
- std::print(stderr, "invalid
value: {}\n", optarg);
- return 1;
- }
- ioctl_val = long_arg;
- } else
- assert(0 && "not reached");
- actions.emplace_back(ioctl_num, ioctl_val);
- } else
- assert(0 && "not reached");
- }
}
if (actions.empty() && !argv[optind]) {