commit 948b7c9af394c10f51d83c90135f313f73c0c521
parent 1fa9cce85c6e089665d08ec4dfa415d97fc6c8e0
Author: Jacob R. Edwards <n/a>
Date: Sat, 11 Dec 2021 14:26:25 -0800
Simplify many commands and functions
Major changes include:
- Command functions are now prefixed by com_ instead of aps_.
- The find function takes only one pattern, and it's given directly
to match()
- Remove the next pattern
Diffstat:
9 files changed, 143 insertions(+), 176 deletions(-)
diff --git a/aps/aps.c b/aps/aps.c
@@ -31,6 +31,7 @@
#include "asplit.h"
#include "bug.h"
#include "command.h"
+#include "find.h"
#include "log.h"
#include "queue.h"
#include "util.h"
@@ -84,7 +85,6 @@ aps_close(struct aps *aps)
aps_drop(aps, i);
apclose(aps->con);
- argfree(aps->next);
free(aps);
}
@@ -240,3 +240,24 @@ aps_errordrop(struct aps *aps, int fd, char *why)
aps_log(aps, ERROR, fd, why);
aps_drop(aps, fd);
}
+
+int
+aps_seek(struct aps *aps, struct item *(*incr)(struct item *), char *pattern)
+{
+ struct item *item;
+
+ item = find(aps->queue, aps->queue, incr, pattern);
+ if (item == NULL)
+ return 1;
+ if (queue_set(aps, item))
+ return 1;
+ return 0;
+}
+
+int
+aps_play(struct aps *aps, struct item *item)
+{
+ if (queue_set(aps, item))
+ return 1;
+ return pplay(aps->player, item->path);
+}
diff --git a/aps/aps.h b/aps/aps.h
@@ -11,7 +11,6 @@ struct client {
};
struct aps {
- char **next;
int close;
int loglevel;
int nfds;
@@ -34,3 +33,5 @@ int aps_update(struct aps *);
char *aps_read(struct aps *, int);
int aps_command(struct aps *, int);
void aps_errordrop(struct aps *, int, char *);
+int aps_seek(struct aps *, struct item *(*)(struct item *), char *);
+int aps_play(struct aps *, struct item *);
diff --git a/aps/command.c b/aps/command.c
@@ -28,40 +28,15 @@
#include "aps.h"
#include "arg.h"
#include "bug.h"
+#include "command.h"
#include "find.h"
#include "log.h"
+#include "match.h"
#include "queue.h"
#include "util.h"
-static char *enotfound = "No match";
-static char *eposition = "Empty queue";
-
-char *
-findset(struct aps *aps, char **patterns, unsigned int len, unsigned int flags)
-{
- struct item *item;
-
- item = find(aps->queue, aps->queue, patterns, len, FIND_NEXT | flags);
- if (item == NULL)
- return enotfound;
- if (queue_set(aps, item))
- return errstr;
- return NULL;
-}
-
-char *
-findplay(struct aps *aps, char **patterns, unsigned int len, unsigned int flags)
-{
- char *e;
-
- if ((e = findset(aps, patterns, len, flags)))
- return e;
- aps->player->state = OFF;
- return NULL;
-}
-
char *
-aps_add(struct aps *aps, int s, int argc, char **argv)
+com_add(struct aps *aps, int fd, int argc, char **argv)
{
int i;
@@ -73,69 +48,82 @@ aps_add(struct aps *aps, int s, int argc, char **argv)
}
char *
-aps_remove(struct aps *aps, int s, int argc, char **argv)
+com_remove(struct aps *aps, int fd, int argc, char **argv)
{
- struct item *item, *next;
+ struct item *item, *matched;
- if (!argc) {
- queue_remove(aps, aps->queue);
+ if ((item = aps->queue) == NULL)
return NULL;
- }
- item = aps->queue;
- while ((item = finddir(findnext, item, aps->queue, argv, argc, 0))) {
- next = findnext(item);
- if (next == item)
- next = NULL;
+ if (!argc) {
queue_remove(aps, item);
- item = next;
+ return NULL;
}
+ /*
+ * A messy solution, the whole item system should be
+ * reworked to make it easy.
+ */
+ matched = NULL;
+ do {
+ if (match(item->path, *argv)) {
+ if (matched)
+ queue_remove(aps, matched);
+ matched = item;
+ }
+ item = item->next;
+ } while (item != aps->queue);
+ if (matched)
+ queue_remove(aps, matched);
+
return NULL;
}
char *
-aps_list(struct aps *aps, int s, int argc, char **argv)
+com_list(struct aps *aps, int fd, int argc, char **argv)
{
struct item *item;
- if (!argc) {
- argv = aps->next;
- argc = arglen(argv);
- }
+ if ((item = aps->queue) == NULL)
+ return NULL;
- item = find(aps->queue, aps->queue, argv, argc, 0);
- while (item) {
- if (respadd(aps, s, item->path))
- return errstr;
- item = find(item, aps->queue, argv, argc, FIND_NEXT);
- }
+ do {
+ if (!argc || match(item->path, *argv))
+ if (respadd(aps, fd, item->path))
+ return errstr;
+ } while ((item = item->next) != aps->queue);
return NULL;
}
char *
-aps_seek(struct aps *aps, int s, int argc, char **argv)
+com_seek(struct aps *aps, int fd, int argc, char **argv)
{
- return findset(aps, argv, argc, 0);
+ if (!argc)
+ return "No pattern";
+ if (aps_seek(aps, findnext, *argv))
+ return errstr;
+ return NULL;
}
char *
-aps_play(struct aps *aps, int s, int argc, char **argv)
+com_play(struct aps *aps, int fd, int argc, char **argv)
{
- char *e;
+ char *err;
+
+ if (!aps->queue)
+ return "Empty queue";
+
+ if (argc && (err = com_seek(aps, fd, argc, argv)))
+ return err;
- if (argc && (e = aps_seek(aps, s, argc, argv)))
- return e;
- else if (aps->queue == NULL)
- return eposition;
if (pplay(aps->player, aps->queue->path))
return errstr;
return NULL;
}
char *
-aps_pause(struct aps *aps, int s, int argc, char **argv)
+com_pause(struct aps *aps, int fd, int argc, char **argv)
{
if (psuspend(aps->player))
return errstr;
@@ -143,7 +131,7 @@ aps_pause(struct aps *aps, int s, int argc, char **argv)
}
char *
-aps_stop(struct aps *aps, int s, int argc, char **argv)
+com_stop(struct aps *aps, int fd, int argc, char **argv)
{
if (pstop(aps->player))
return errstr;
@@ -151,7 +139,7 @@ aps_stop(struct aps *aps, int s, int argc, char **argv)
}
char *
-aps_toggle(struct aps *aps, int s, int argc, char **argv)
+com_toggle(struct aps *aps, int fd, int argc, char **argv)
{
if (ptoggle(aps->player))
return errstr;
@@ -159,38 +147,37 @@ aps_toggle(struct aps *aps, int s, int argc, char **argv)
}
char *
-aps_name(struct aps *aps, int s, int argc, char **argv)
+com_name(struct aps *aps, int fd, int argc, char **argv)
{
- struct item *item;
-
- item = find(aps->queue, aps->queue, argv, argc, 0);
- if (item == NULL)
- return enotfound;
-
- if (respadd(aps, s, item->path))
+ if (!aps->queue)
+ return "Empty queue";
+ if (respadd(aps, fd, aps->queue->path))
return errstr;
return NULL;
}
char *
-aps_next(struct aps *aps, int s, int argc, char **argv)
+com_next(struct aps *aps, int fd, int argc, char **argv)
{
- if (argc) {
- if (argsub(&aps->next, argv, argc) == NULL)
- return errstr;
- return NULL;
- }
- return findplay(aps, aps->next, arglen(aps->next), 0);
+ if (!aps->queue)
+ return "Empty queue";
+ if (aps_play(aps, aps->queue->next))
+ return errstr;
+ return NULL;
}
char *
-aps_previous(struct aps *aps, int s, int argc, char **argv)
+com_previous(struct aps *aps, int fd, int argc, char **argv)
{
- return findplay(aps, aps->next, arglen(aps->next), FIND_REVERSE);
+ if (!aps->queue)
+ return "Empty queue";
+ if (aps_play(aps, aps->queue->prev))
+ return errstr;
+ return NULL;
}
char *
-aps_status(struct aps *aps, int s, int argc, char **argv)
+com_status(struct aps *aps, int fd, int argc, char **argv)
{
char *status;
@@ -217,21 +204,18 @@ aps_status(struct aps *aps, int s, int argc, char **argv)
bug("impossible player state");
}
- if (respadd(aps, s, status))
+ if (respadd(aps, fd, status))
return errstr;
return NULL;
}
char *
-aps_loglevel(struct aps *aps, int s, int argc, char **argv)
+com_log(struct aps *aps, int fd, int argc, char **argv)
{
- int flip;
- int i;
- int level, mask;
-
- flip = (argc && strcmp(argv[0], "!") == 0);
+ int level, mask, flip, i;
level = 0;
+ flip = (argc && strcmp(argv[0], "!") == 0);
for (i = flip; i < argc; ++i) {
if ((mask = strlevel(argv[i])) < 0)
return "invalid log level";
@@ -243,7 +227,7 @@ aps_loglevel(struct aps *aps, int s, int argc, char **argv)
}
char *
-aps_player(struct aps *aps, int s, int argc, char **argv)
+com_player(struct aps *aps, int fd, int argc, char **argv)
{
char **ap;
struct player *new;
@@ -260,17 +244,18 @@ aps_player(struct aps *aps, int s, int argc, char **argv)
return NULL;
}
+ /* TODO: Send on a single line, quoted if required */
for (ap = aps->player->argv; *ap; ++ap)
- if (respadd(aps, s, *ap))
+ if (respadd(aps, fd, *ap))
return errstr;
return NULL;
}
+
char *
-aps_truncate(struct aps *aps, int fd, int argc, char **argv)
+com_truncate(struct aps *aps, int fd, int argc, char **argv)
{
while (aps->queue)
queue_remove(aps, aps->queue);
- return aps_add(aps, fd, argc, argv);
+ return com_add(aps, fd, argc, argv);
}
-
diff --git a/aps/command.h b/aps/command.h
@@ -3,18 +3,18 @@ struct command {
char *(*func)(struct aps *, int, int, char **);
};
-char *aps_add(struct aps *, int, int, char **);
-char *aps_remove(struct aps *, int, int, char **);
-char *aps_list(struct aps *, int, int, char **);
-char *aps_seek(struct aps *, int, int, char **);
-char *aps_play(struct aps *, int, int, char **);
-char *aps_pause(struct aps *, int, int, char **);
-char *aps_stop(struct aps *, int, int, char **);
-char *aps_toggle(struct aps *, int, int, char **);
-char *aps_name(struct aps *, int, int, char **);
-char *aps_next(struct aps *, int, int, char **);
-char *aps_previous(struct aps *, int, int, char **);
-char *aps_status(struct aps *, int, int, char **);
-char *aps_loglevel(struct aps *, int, int, char **);
-char *aps_player(struct aps *, int, int, char **);
-char *aps_truncate(struct aps *, int, int, char **);
+char *com_add(struct aps *, int, int, char **);
+char *com_remove(struct aps *, int, int, char **);
+char *com_list(struct aps *, int, int, char **);
+char *com_seek(struct aps *, int, int, char **);
+char *com_play(struct aps *, int, int, char **);
+char *com_pause(struct aps *, int, int, char **);
+char *com_stop(struct aps *, int, int, char **);
+char *com_toggle(struct aps *, int, int, char **);
+char *com_name(struct aps *, int, int, char **);
+char *com_next(struct aps *, int, int, char **);
+char *com_previous(struct aps *, int, int, char **);
+char *com_status(struct aps *, int, int, char **);
+char *com_log(struct aps *, int, int, char **);
+char *com_player(struct aps *, int, int, char **);
+char *com_truncate(struct aps *, int, int, char **);
diff --git a/aps/find.c b/aps/find.c
@@ -17,15 +17,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <errno.h>
-#include <string.h>
+#include <stddef.h>
#include "find.h"
#include "item.h"
#include "match.h"
-#define REV(ITEM) (ITEM == findnext ? findprev : findnext)
-
struct item *
findnext(struct item *item)
{
@@ -39,36 +36,15 @@ findprev(struct item *item)
}
struct item *
-finddir(struct item *(*incr)(struct item *), struct item *item, struct item *end,
- char **patterns, unsigned int len, unsigned int flags)
+find(struct item *start, struct item *stop, struct item *(*incr)(struct item *), char *pattern)
{
- if (flags & FIND_REVERSE)
- incr = REV(incr);
- if (flags & FIND_NEXT && (item == NULL || (item = incr(item)) == end))
- return NULL;
+ struct item *i;
- while (item && !multimatch(item->path, patterns, len)) {
- item = incr(item);
- if (item == end)
- item = NULL;
+ for (i = incr(start);; i = incr(i)) {
+ if (!pattern || match(i->path, pattern))
+ return i;
+ if (i == stop)
+ break;
}
-
- return item;
-}
-
-struct item *
-find(struct item *item, struct item *end, char **patterns, unsigned int len,
- unsigned int flags)
-{
- struct item *(*incr)(struct item *);
-
- incr = findnext;
- if (len && (strchr("+-", patterns[0][0]) && patterns[0][1] == '\0')) {
- if (patterns[0][0] == '-')
- incr = findprev;
- ++patterns;
- --len;
- }
-
- return finddir(incr, item, end, patterns, len, flags);
+ return NULL;
}
diff --git a/aps/find.h b/aps/find.h
@@ -1,9 +1,3 @@
-enum findflag {
- FIND_REVERSE = 1,
- FIND_NEXT = 2
-};
-
struct item *findnext(struct item *);
struct item *findprev(struct item *);
-struct item *finddir(struct item *(*)(struct item *), struct item *, struct item *, char **, unsigned int, unsigned int);
-struct item *find(struct item *, struct item *, char **, unsigned int, unsigned int);
+struct item *find(struct item *, struct item *, struct item *(*)(struct item *), char *);
diff --git a/aps/main.c b/aps/main.c
@@ -32,26 +32,28 @@
#include "aps.h"
#include "command.h"
#include "config.h"
+#include "find.h"
#include "log.h"
+#include "queue.h"
#include "util.h"
static struct aps *aps;
static struct command commands[] = {
- { "add", aps_add },
- { "list", aps_list },
- { "log", aps_loglevel },
- { "name", aps_name },
- { "next", aps_next },
- { "pause", aps_pause },
- { "play", aps_play },
- { "player", aps_player },
- { "previous", aps_previous },
- { "remove", aps_remove },
- { "seek", aps_seek },
- { "status", aps_status },
- { "stop", aps_stop },
- { "toggle", aps_toggle },
- { "truncate", aps_truncate }
+ { "add", com_add },
+ { "list", com_list },
+ { "log", com_log },
+ { "name", com_name },
+ { "next", com_next },
+ { "pause", com_pause },
+ { "play", com_play },
+ { "player", com_player },
+ { "previous", com_previous },
+ { "remove", com_remove },
+ { "seek", com_seek },
+ { "status", com_status },
+ { "stop", com_stop },
+ { "toggle", com_toggle },
+ { "truncate", com_truncate }
};
void
@@ -94,7 +96,7 @@ run(struct aps *aps)
while (!aps->close) {
if (aps->queue) {
if (aps->player->state == COMPLETE)
- aps_next(aps, -1, 0, NULL);
+ queue_set(aps, aps->queue->next);
if (aps->player->state == OFF)
pplay(aps->player, aps->queue->path);
}
diff --git a/aps/match.c b/aps/match.c
@@ -41,14 +41,3 @@ match(char *s, char *pattern)
++pattern;
return regmatch(s, pattern);
}
-
-int
-multimatch(char *s, char **patterns, unsigned int len)
-{
- int i;
-
- for (i = 0; i < len; ++i)
- if (match(s, patterns[i]))
- return 1;
- return len == 0;
-}
diff --git a/aps/match.h b/aps/match.h
@@ -1,2 +1 @@
int match(char *, char *);
-int multimatch(char *, char **, unsigned int);