Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions doc/vitunes.1
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@ section for a complete listing.
More detailed usage information and examples for each e-command can be
obtained by issuing:
.Dl $ vitunes -e help command-name
.Pp
Note that abbreviations are also supported.
That is, entering any non-ambiguous abbreviation of an e-command will also
execute the e-command.
.Bd -literal -offset indent
$ vitunes -e a ~/music
vitunes: Ambiguous e-command 'a'. Matches: add addurl
.Ed
.Sh RUN-TIME COMMANDS
Below is a listing of all run-time commands supported by
.Nm .
Expand All @@ -243,9 +251,7 @@ All commands are entered by typing ':' followed by the command name and any
parameters (just like in
.Xr vi 1 ).
.Pp
Note that abbreviations are also supported.
That is, entering any non-ambiguous abbreviation of a command name will also
execute the command.
As with e-commands, abbreviations are also supported.
.Bl -tag -width Ds
.It Pf : Ic bind Ar action Ar keycode
This will bind the action specified by
Expand Down
90 changes: 67 additions & 23 deletions ecmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@

#include "ecmd.h"

/* set of e-commands */
static const struct ecmd *ecmdtab[] = {
&ecmd_add,
&ecmd_addurl,
&ecmd_check,
&ecmd_flush,
&ecmd_help,
&ecmd_init,
&ecmd_rmfile,
&ecmd_tag,
&ecmd_update,
};
static const int ecmdtab_size = sizeof ecmdtab / sizeof ecmdtab[0];

static int
ecmd_parse(const struct ecmd *ecmd, int argc, char ***argv)
{
Expand Down Expand Up @@ -45,49 +59,79 @@ ecmd_parse(const struct ecmd *ecmd, int argc, char ***argv)
if (ecmd->args_upper >= 0 && argc > ecmd->args_upper)
return -1;

/* return updated (no name) number of arguments */
/* return updated number of arguments */
return argc;
}

static void
ecmd_print_ambiguous(const char *ecmd)
{
int i;

fprintf(stderr, "%s: Ambiguous e-command '%s'. Matches: ", progname, ecmd);
for (i = 0; i < ecmdtab_size; i++) {
if (strncmp(ecmd, ecmdtab[i]->name, strlen(ecmd)) != 0)
continue;
fprintf(stderr, "%s ", ecmdtab[i]->name);
}
fputs("\n", stderr);
}

const char *
ecmd_get_names(void)
{
static int i = 0;
const struct ecmd *ecmdp;

if (i == ecmdtab_size)
return (NULL);

ecmdp = ecmdtab[i++];
return (ecmdp->name);
}

int
ecmd_exec(const char *ecmd, int argc, char **argv)
{
/* set of e-commands */
static const struct ecmd *ecmdtab[] = {
&ecmd_add,
&ecmd_addurl,
&ecmd_check,
&ecmd_flush,
&ecmd_help,
&ecmd_init,
&ecmd_rmfile,
&ecmd_tag,
&ecmd_update,
};
static const int ecmdtab_size = sizeof ecmdtab / sizeof ecmdtab[0];
int i;
bool ambiguous = false;
int i;
const struct ecmd *ecmdp = NULL;

/* search for e-command (first by name and then by alias) */
/* search for e-command (first by name and then by abbreviation) */
for (i = 0; i < ecmdtab_size; i++) {
if (strcmp(ecmd, ecmdtab[i]->name) == 0)
/* exact match */
if (strcmp(ecmd, ecmdtab[i]->name) == 0) {
ecmdp = ecmdtab[i];
break;
if (ecmdtab[i]->alias != NULL && strcmp(ecmd, ecmdtab[i]->alias) == 0)
}
/* abbreviation match */
if (strncmp(ecmd, ecmdtab[i]->name, strlen(ecmd)) != 0)
continue;
if (ecmdp != NULL) {
ambiguous = true;
break;
}
ecmdp = ecmdtab[i];
}
/* not found; bail out */
if (i == ecmdtab_size) {
if (ecmdp == NULL) {
warnx("Unknown e-command '%s'. See 'vitunes -e help' for list.", ecmd);
return -1;
}
/* ambiguous e-command */
if (ambiguous) {
ecmd_print_ambiguous(ecmd);
return -1;
}

/* parse e-command arguments */
if ((argc = ecmd_parse(ecmdtab[i], argc, &argv)) == -1) {
fprintf(stderr, "usage: %s -e %s %s\n", progname, ecmdtab[i]->name,
ecmdtab[i]->usage != NULL ? ecmdtab[i]->usage : "");
if ((argc = ecmd_parse(ecmdp, argc, &argv)) == -1) {
fprintf(stderr, "usage: %s -e %s %s\n", progname, ecmdp->name,
ecmdp->usage != NULL ? ecmdp->usage : "");
return 1;
}

/* finally execute it */
ecmdtab[i]->exec(argc, argv);
ecmdp->exec(argc, argv);
return 0;
}
5 changes: 3 additions & 2 deletions ecmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define ECMD_H

#include <err.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
Expand All @@ -27,7 +28,6 @@

struct ecmd {
const char *name;
const char *alias; /* may be NULL */
const char *usage; /* may be NULL */
int args_lower; /* minimum number of arguments */
int args_upper; /* negative number means no limit */
Expand All @@ -46,6 +46,7 @@ extern const struct ecmd ecmd_rmfile;
extern const struct ecmd ecmd_tag;
extern const struct ecmd ecmd_update;

int ecmd_exec(const char *ecmd, int argc, char **argv);
const char *ecmd_get_names(void);
int ecmd_exec(const char *ecmd, int argc, char **argv);

#endif
2 changes: 1 addition & 1 deletion ecmd_add.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ecmd_add_exec(UNUSED int argc, char **argv)
}

const struct ecmd ecmd_add = {
"add", NULL,
"add",
"path [...]",
1, -1,
NULL,
Expand Down
2 changes: 1 addition & 1 deletion ecmd_addurl.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ ecmd_addurl_exec(UNUSED int argc, char **argv)
}

const struct ecmd ecmd_addurl = {
"addurl", NULL,
"addurl",
"URL|path",
1, 1,
NULL,
Expand Down
2 changes: 1 addition & 1 deletion ecmd_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ ecmd_check_exec(int argc, char **argv)
}

const struct ecmd ecmd_check = {
"check", NULL,
"check",
"-d | -r | -s path [...]",
1, -1,
ecmd_check_parse,
Expand Down
2 changes: 1 addition & 1 deletion ecmd_flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ ecmd_flush_exec(UNUSED int argc, UNUSED char **argv)
}

const struct ecmd ecmd_flush = {
"flush", NULL,
"flush",
"[-t format]",
0, 0,
ecmd_flush_parse,
Expand Down
33 changes: 11 additions & 22 deletions ecmd_help.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,19 @@
static void
ecmd_help_exec(UNUSED int argc, char **argv)
{
char *man_args[3];
char *man_args[3];
const char *name;

/* no help requested for a specific command, give a list of all e-cmds */
if (argc == 0) {
printf("\
The following is a list of e-commands supported by vitunes.\n\
Each command is executed by doing:\n\
$ vitunes -e COMMAND [args ...]\n\
The complete manual for each can be obtained by doing:\n\
$ vitunes -e help COMMAND\n\
The list of available commands are:\n\n\
Command Description\n\
------- ------------------------------------------------------------\n\
add Add files to the database.\n\
addurl Add URL (or non-file playable item) to the database.\n\
check Check files for meta-information.\n\
flush Output the contents of the database to stdout.\n\
help This command.\n\
init Initialize the media database.\n\
rm Remove a file or a URL from the database.\n\
rmfile Alias for \"rm\".\n\
tag Set the meta-information tags in media files.\n\
update Update all files in the database.\n\
");
printf("Available e-commands: ");
while ((name = ecmd_get_names()) != NULL)
printf("%s ", name);
puts("\n");
printf("Each is executed by doing:\n"
"$ vitunes -e e-command [...]\n"
"The complete manual for each can be obtained by doing:\n"
"$ vitunes -e help e-command\n");
return;
}

Expand All @@ -69,7 +58,7 @@ The list of available commands are:\n\n\
}

const struct ecmd ecmd_help = {
"help", NULL,
"help",
"[command]",
0, 1,
NULL,
Expand Down
2 changes: 1 addition & 1 deletion ecmd_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ ecmd_init_exec(UNUSED int argc, UNUSED char **argv)
}

const struct ecmd ecmd_init = {
"init", NULL,
"init",
NULL,
0, 0,
NULL,
Expand Down
2 changes: 1 addition & 1 deletion ecmd_rmfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ ecmd_rmfile_exec(UNUSED int argc, char **argv)
}

const struct ecmd ecmd_rmfile = {
"rmfile", "rm",
"rmfile",
"[-f] URL|path",
1, 1,
ecmd_rmfile_parse,
Expand Down
2 changes: 1 addition & 1 deletion ecmd_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ ecmd_tag_exec(int argc, char **argv)
}

const struct ecmd ecmd_tag = {
"tag", NULL,
"tag",
"[-A album] [-T track] [-a artist] [-c comment] [-g genre] [-t title]\n\
\t[-y year] path [...]",
1, -1,
Expand Down
2 changes: 1 addition & 1 deletion ecmd_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ ecmd_update_exec(UNUSED int argc, UNUSED char **argv)
}

const struct ecmd ecmd_update = {
"update", NULL,
"update",
"[-fs]",
0, 0,
ecmd_update_parse,
Expand Down