ap

An audio player suited to my tastes
Log | Files | Refs | README | LICENSE

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:
Maps/Makefile | 2+-
Maps/aps.c | 2+-
Daps/asplit.c | 42------------------------------------------
Daps/asplit.h | 1-
Maps/split.c | 87+++++++++++++++++++++++++++----------------------------------------------------
Maps/split.h | 3++-
Mlib/ap/quote.c | 55++++++++++++++++++++++++++++++++-----------------------
Mlib/ap/quote.h | 2+-
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));