ap

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

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:
Maps/aps.c | 23++++++++++++++++++++++-
Maps/aps.h | 3++-
Maps/command.c | 167++++++++++++++++++++++++++++++++++++-------------------------------------------
Maps/command.h | 30+++++++++++++++---------------
Maps/find.c | 42+++++++++---------------------------------
Maps/find.h | 8+-------
Maps/main.c | 34++++++++++++++++++----------------
Maps/match.c | 11-----------
Maps/match.h | 1-
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);