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]) {

Reply via email to