From eca60cc8a687856d5387c1a0e3edece95150231c Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Sun, 2 May 2021 11:05:28 +0200
Subject: [PATCH] CMD: Define macros to help manipulate the arguments in the
 {argc,argv} form

---
 inc/lektor/cmd.h | 13 +++++++++++++
 src/base/cmd.c   | 20 ++++++--------------
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h
index b37d64fe..c1890987 100644
--- a/inc/lektor/cmd.h
+++ b/inc/lektor/cmd.h
@@ -34,6 +34,19 @@ struct cmd_args {
     const char **argv; /* An array of argument passed.     */
 };
 
+#define CMD_ARGS_FROM(argc, argv)                                                                                      \
+    {                                                                                                                  \
+        .argc = (argc), .argv = (argv)                                                                                 \
+    }
+#define CMD_ARGS_NEXT_FROM(argc, argv)                                                                                 \
+    {                                                                                                                  \
+        .argc = argc - 1, .argv = (const char **)&(argv[1]),                                                           \
+    }
+#define CMD_ARGS_NEXT(args)                                                                                            \
+    {                                                                                                                  \
+        .argc = (args).argc - 1, .argv = (args).argv + 1,                                                              \
+    }
+
 /* Callback to call on command, takes the arguments */
 typedef void (*cmd_callback)(struct cmd_args *);
 
diff --git a/src/base/cmd.c b/src/base/cmd.c
index 2b3fae4e..363afa4d 100644
--- a/src/base/cmd.c
+++ b/src/base/cmd.c
@@ -119,7 +119,7 @@ cmd_parse_env(struct cmd_env *env, int *argc, const char ***argv)
 EXIT_FUNCTION
 cmd_parse(struct cmd_opt *opts, int argc, const char **argv)
 {
-    int count = 0, is_ok, offset = 0;
+    int count            = 0, is_ok;
     struct cmd_opt *it   = opts;
     cmd_callback call[2] = { NULL, NULL };
 
@@ -128,11 +128,10 @@ cmd_parse(struct cmd_opt *opts, int argc, const char **argv)
         goto help;
 
     /* Find the command */
-    while (it && it->name) {
+    FOR_EACH_FLAT_LIST_ITEM (it, name) {
         is_ok       = (!strncasecmp(argv[0], it->name, strlen(argv[0])));
         call[is_ok] = it->call;
         count += is_ok;
-        it = opts + (++offset);
     }
 
     /* Now search for a unique match */
@@ -142,22 +141,15 @@ cmd_parse(struct cmd_opt *opts, int argc, const char **argv)
     if (!call[1] || count == 0)
         goto not_found;
 
-    struct cmd_args arguments = {
-        .argc = argc - 1,
-        .argv = (const char **)&(argv[1]),
-    };
-
     /* This call should exit. */
+    struct cmd_args arguments = CMD_ARGS_NEXT_FROM(argc, argv);
     call[1](&arguments);
-    exit(EXIT_FAILURE);
+    abort();
 
 not_found:
     /* The default function */
     if (!it->name && it->call) {
-        struct cmd_args arguments = {
-            .argc = argc,
-            .argv = (const char **)argv,
-        };
+        struct cmd_args arguments = CMD_ARGS_FROM(argc, argv);
         it->call(&arguments);
     }
 
@@ -169,5 +161,5 @@ help:
 
 not_exclusive:
     LOG_ERROR("COMMAND", "Failed to determine option, '%s' not exclusive", argv[0]);
-    exit(EXIT_FAILURE);
+    abort();
 }
-- 
GitLab