commit a33ea46f91b216961b7897b0e0618f0d6411b368
parent 5cd7ee48896ba1c89a6845187509f9f8437de186
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date:   Tue, 20 Jul 2021 18:57:48 -0700
Improve split()
Instead of returning -1 when the given array doesn't have enough
space, return how many elements would have been written if the array
was large enough (like snprintf(3)).
Diffstat:
4 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/aps/aps.c b/aps/aps.c
@@ -186,26 +186,25 @@ aps_read(struct aps *aps, int s)
 int
 aps_command(struct aps *aps, int s)
 {
+	char *(*com)(struct aps *, int, int, char **);
+	char *argv[AP_ARGV_MAX];
 	char *next;
 	char *status;
 	struct buf *buf;
-        char *argv[AP_ARGV_MAX];
-        int i;
-        int len;
-	char *(*com)(struct aps *, int, int, char **);
+	unsigned int i;
+	unsigned int len;
 
 	if ((next = aps_read(aps, s)) == NULL)
 		return 0;
 
 	buf = aps->clients[s].request;
-
 	len = split(argv, LEN(argv), buf->data, AP_ARG_SEPS);
 	if (len == 0)
 		return respfinish(aps, s, "No command");
-	if (len < 0)
+	if (len >= LEN(argv))
 		return respfinish(aps, s, strerror(E2BIG));
 
-        for (com = NULL, i = 0; com == NULL && i < aps->ncoms; ++i)
+	for (com = NULL, i = 0; com == NULL && i < aps->ncoms; ++i)
 		if (strcmp(*argv, aps->coms[i].name) == 0)
 			com = aps->coms[i].func;
 
@@ -218,5 +217,5 @@ aps_command(struct aps *aps, int s)
 	memmove(buf->data, buf->data + len, buf->len - len);
 	buf->len -= len;
 
-        return respfinish(aps, s, status);
+	return respfinish(aps, s, status);
 }
diff --git a/aps/split.c b/aps/split.c
@@ -18,19 +18,20 @@
 
 #include <string.h>
 
-int
-split(char **ap, int len, char *s, char *sep)
+#include "util.h"
+
+unsigned int
+split(char **ap, unsigned int len, char *s, char *sep)
 {
-	char **ap0;
+	char *p;
+	unsigned int i;
 
-	ap0 = ap;
-        while ((*ap = strsep(&s, sep))) {
-                if (**ap) {
-			if (ap - ap0 >= len)
-				return -1;
-			++ap;
-		}
-        }
+	for (i = 0; (p = strsep(&s, sep)); ++i) {
+		if (i < len)
+			ap[i] = p;
+	}
 
-        return ap - ap0;
+	if (len)
+		ap[MIN(len - 1, i)] = NULL;
+        return i;
 }
diff --git a/aps/split.h b/aps/split.h
@@ -1 +1 @@
-int	split(char **, int, char *, char *);
+unsigned int	split(char **, unsigned int, char *, char *);
diff --git a/aps/util.h b/aps/util.h
@@ -1,6 +1,9 @@
 #include "bug.h"
 
 #define LEN(X) (sizeof(X) / sizeof(*X))
+
 #define MAX(A,B) (A > B ? A : B)
+#define MIN(A,B) (A < B ? A : B)
+
 #define ASSERT(EXP) ((EXP) ? 0 : BUG(#EXP))
 #define BUG(WHY) (bug(__FILE__, __LINE__, WHY))