commit 7d7ddd0a3b49aa95c36c985c0badeaae55f789f4
parent 7095779d2fa0d126b2eb2f36eeab0969d3b9feec
Author: Jacob R. Edwards <n/a>
Date: Mon, 3 Oct 2022 13:36:04 -0700
Improve the library's unquoting function
Previously the library's unquoting function was practically unusable,
so another one was written for the server. This was obviously a
terrible solution; now the library's unquote function has the
flexibility to be suitable for any need and the server's unquote
function is no longer.
Diffstat:
8 files changed, 67 insertions(+), 127 deletions(-)
diff --git a/aps/Makefile b/aps/Makefile
@@ -1,5 +1,5 @@
name = aps
-src = aps.c arg.c asplit.c bug.c command.c find.c log.c main.c player.c \
+src = aps.c arg.c bug.c command.c find.c log.c main.c player.c \
queue.c response.c split.c
inc = ${src:.c=.h} util.h
ldlibs = ../lib/ap/libap.a
diff --git a/aps/aps.c b/aps/aps.c
@@ -31,12 +31,12 @@
#include "aps.h"
#include "arg.h"
-#include "asplit.h"
#include "bug.h"
#include "command.h"
#include "find.h"
#include "log.h"
#include "queue.h"
+#include "split.h"
#include "util.h"
struct aps *
diff --git a/aps/asplit.c b/aps/asplit.c
@@ -1,42 +0,0 @@
-/*
- * Copyright 2021 Jacob R. Edwards
- *
- * ap -- audio player
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "split.h"
-
-char **
-asplit(char *s, int (*issep)(int))
-{
- char **args, *copy;
- unsigned int len;
-
- copy = strdup(s);
- if (copy == NULL)
- return NULL;
- len = split(NULL, 0, copy, issep);
- free(copy);
-
- args = calloc(++len, sizeof(*args));
- if (args == NULL)
- return NULL;
- split(args, len, s, issep);
- return args;
-}
diff --git a/aps/asplit.h b/aps/asplit.h
@@ -1 +0,0 @@
-char **asplit(char *, int (*)(int));
diff --git a/aps/split.c b/aps/split.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 Jacob R. Edwards
+ * Copyright 2021, 2022 Jacob R. Edwards
*
* ap -- audio player
*
@@ -17,76 +17,49 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <string.h>
-
#include "util.h"
-char *
-spanwhile(char *s, int (*func)(int))
-{
- while (*s && func(*s))
- ++s;
- return s;
-}
-
-char *
-spanwhilenot(char *s, int (*func)(int))
-{
- while (*s && !func(*s))
- ++s;
- return s;
-}
-
-/* Unquoting should probably done in only one place... */
-char *
-unquote(char **sp, int (*issep)(int))
-{
- char *start;
-
- start = spanwhile(*sp, issep);
- if (*start == '\0')
- return NULL;
-
- if (*start != '\'') {
- *sp = spanwhilenot(start, issep);
- if (**sp != '\0') {
- **sp = 0;
- ++*sp;
- }
- return start;
- }
-
- *sp = ++start;
- if (*start == '\0')
- return NULL;
-
- for (; **sp; ++*sp) {
- if (**sp == '\'') {
- if ((*sp)[1] != '\'') {
- **sp = 0;
- ++*sp;
- return start;
- }
- /* NOTE: only up to the next argument MUST be moved */
- memmove(*sp, *sp + 1, strlen(*sp));
- }
- }
+#include <ap/quote.h>
- return start;
-}
+#include <stdlib.h>
+#include <string.h>
-unsigned int
+int
split(char **ap, unsigned int len, char *s, int (*sep)(int))
{
char *p;
unsigned int i;
- for (i = 0; (p = unquote(&s, sep)); ++i) {
+ for (i = 0; (p = apunquote(&s, sep)) && p[0]; ++i) {
if (i < len)
ap[i] = p;
}
+ if (!p)
+ return -1;
if (len)
ap[MIN(len - 1, i)] = NULL;
return i;
}
+
+char **
+asplit(char *s, int (*issep)(int))
+{
+ char **args, *copy;
+ int len;
+
+ copy = strdup(s);
+ if (copy == NULL)
+ return NULL;
+ len = split(NULL, 0, copy, issep);
+ free(copy);
+
+ if (len < 0)
+ return NULL;
+
+ args = calloc(++len, sizeof(*args));
+ if (args == NULL)
+ return NULL;
+ split(args, len, s, issep);
+ return args;
+}
diff --git a/aps/split.h b/aps/split.h
@@ -1 +1,2 @@
-unsigned int split(char **, unsigned int, char *, int (*)(int));
+int split(char **, unsigned int, char *, int (*)(int));
+char **asplit(char *, int (*)(int));
diff --git a/lib/ap/quote.c b/lib/ap/quote.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 Jacob R. Edwards
+ * Copyright 2021, 2022 Jacob R. Edwards
*
* ap -- audio player
*
@@ -59,32 +59,41 @@ apquote(char *s, int (*needquote)(int))
}
char *
-apunquote(char *s)
+apunquote(char **sp, int (*issep)(int))
{
- size_t i;
- char *buf, *bufp;
+ char *s, *p;
+ int quoted;
+ size_t len;
- if (s[0] != '\'')
- return strdup(s);
+ if (!issep)
+ issep = isspace;
- bufp = buf = malloc(strlen(s));
- if (buf == NULL)
- return NULL;
+ s = *sp;
+ while (s[0] && issep(s[0]))
+ ++s;
+ p = s;
+ len = strlen(p);
+
+ quoted = 0;
+ while (s[0] && (quoted || !issep(s[0]))) {
+ if (s[0] == '\'') {
+ if (!quoted)
+ quoted = 1;
+ else if (s[1] == '\'')
+ ++s;
+ else
+ quoted = 0;
+ memmove(s, s + 1, (len + 1) - (s - p));
+ } else
+ ++s;
+ }
- for (i = 1; s[i]; ++i, ++bufp) {
- if (s[i] == '\'') {
- ++i;
- if (s[i] == '\0') {
- *bufp = '\0';
- return buf;
- }
- if (s[i] != '\'')
- break;
- }
- *bufp = s[i];
+ if (quoted) {
+ errno = EINVAL;
+ return NULL;
}
- free(buf);
- errno = EINVAL;
- return NULL;
+ s[0] = '\0';
+ *sp = s + 1;
+ return p;
}
diff --git a/lib/ap/quote.h b/lib/ap/quote.h
@@ -1,2 +1,2 @@
char *apquote(char *, int (*)(int));
-char *apunquote(char *);
+char *apunquote(char **, int (*)(int));