make tog(1) command argument optional
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
diff --git a/tog/tog.c b/tog/tog.c
index 66799db..2b977a1 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -42,11 +42,11 @@ enum tog_view_id {
};
struct tog_cmd {
- const char *cmd_name;
+ const char *name;
const struct got_error *(*cmd_main)(int, char *[]);
void (*cmd_usage)(void);
enum tog_view_id view;
- const char *cmd_descr;
+ const char *descr;
};
__dead void usage(void);
@@ -436,21 +436,43 @@ usage(void)
{
int i;
- fprintf(stderr, "usage: %s [-h] command [arg ...]\n\n"
+ fprintf(stderr, "usage: %s [-h] [command] [arg ...]\n\n"
"Available commands:\n", getprogname());
for (i = 0; i < nitems(tog_commands); i++) {
struct tog_cmd *cmd = &tog_commands[i];
- fprintf(stderr, " %s: %s\n", cmd->cmd_name, cmd->cmd_descr);
+ fprintf(stderr, " %s: %s\n", cmd->name, cmd->descr);
}
exit(1);
}
+static char **
+make_argv(const char *arg0, const char *arg1)
+{
+ char **argv;
+ int argc = (arg1 == NULL ? 1 : 2);
+
+ argv = calloc(argc, sizeof(char *));
+ if (argv == NULL)
+ err(1, "calloc");
+ argv[0] = strdup(arg0);
+ if (argv[0] == NULL)
+ err(1, "calloc");
+ if (arg1) {
+ argv[1] = strdup(arg1);
+ if (argv[1] == NULL)
+ err(1, "calloc");
+ }
+
+ return argv;
+}
+
int
main(int argc, char *argv[])
{
const struct got_error *error = NULL;
struct tog_cmd *cmd = NULL;
int ch, hflag = 0;
+ char **cmd_argv = NULL;
setlocale(LC_ALL, "");
@@ -468,14 +490,19 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
optind = 0;
+ optreset = 1;
- if (argc == 0)
+ if (argc == 0) {
+ /* Build an argument vector which runs a default command. */
cmd = &tog_commands[0];
- else {
+ cmd_argv = make_argv(cmd->name, NULL);
+ argc = 1;
+ } else {
int i;
+ /* Did the user specific a command? */
for (i = 0; i < nitems(tog_commands); i++) {
- if (strncmp(tog_commands[i].cmd_name, argv[0],
+ if (strncmp(tog_commands[i].name, argv[0],
strlen(argv[0])) == 0) {
cmd = &tog_commands[i];
if (hflag)
@@ -484,9 +511,25 @@ main(int argc, char *argv[])
}
}
if (cmd == NULL) {
- fprintf(stderr, "%s: unknown command '%s'\n",
- getprogname(), argv[0]);
- return 1;
+ /* Did the user specify a repository? */
+ char *repo_path = realpath(argv[0], NULL);
+ if (repo_path) {
+ struct got_repository *repo;
+ error = got_repo_open(&repo, repo_path);
+ if (error == NULL)
+ got_repo_close(repo);
+ } else
+ error = got_error(GOT_ERR_NOT_GIT_REPO);
+ if (error) {
+ free(repo_path);
+ fprintf(stderr, "%s: unknown command '%s'\n",
+ getprogname(), argv[0]);
+ return 1;
+ }
+ cmd = &tog_commands[0];
+ cmd_argv = make_argv(cmd->name, repo_path);
+ argc = 2;
+ free(repo_path);
}
}
@@ -496,11 +539,12 @@ main(int argc, char *argv[])
return 1;
}
- error = cmd->cmd_main(argc, argv);
+ error = cmd->cmd_main(argc, cmd_argv ? cmd_argv : argv);
if (error)
goto done;
done:
endwin();
+ free(cmd_argv);
if (error)
fprintf(stderr, "%s: %s\n", getprogname(), error->msg);
return 0;