ani.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "scaffold.h"
#include "macros.h"
#include "repository.h"
#include "dir.h"
#include "commands.h"
#define NEED_REPO_DIR (1 << 0)
const char ani_usage_string[] =
"usage: ani <command>\n"
"\n"
"Commands\n"
" init Initialize empty repository\n"
" change Show information about a particular change\n"
" pristine Show information about the repository database\n";
/* List of builtin commands, by name and the function to invoke */
struct cmd {
const char *name;
int (*fn)(int, const char **, struct repository *);
unsigned int flags;
};
static struct cmd commands[] = {
{ "init", cmd_init, 0 },
{ "change", cmd_change, NEED_REPO_DIR },
{ "pristine", cmd_pristine, NEED_REPO_DIR },
};
/**
* Print usage string and exit.
*/
static void
usage()
{
printf("%s", ani_usage_string);
exit(0);
}
static struct cmd *
find_cmd(const char *s)
{
long unsigned int i;
struct cmd *p;
for (i = 0; i < ARRAY_SIZE(commands); i++) {
p = commands + i;
if (!strcmp(s, p->name))
return p;
}
return NULL;
}
static int
cmd_main(int argc, const char *argv[])
{
const char *cmd_name;
char *pijul_dir = NULL;
struct repository repo = { 0 };
struct cmd *command;
int ret;
cmd_name = *++argv;
--argc;
command = find_cmd(cmd_name);
if (command == NULL) {
fprintf(stderr,
"ani: '%s' is not an ani command. See 'ani -h'\n",
cmd_name);
return -1;
}
if (command->flags & NEED_REPO_DIR) {
pijul_dir = find_dotpijul();
if (!pijul_dir)
die("no Pijul repository found");
repo.path = pijul_dir;
}
ret = (command->fn)(argc, argv, &repo);
if (pijul_dir)
free(pijul_dir);
return ret;
}
int
main(int argc, const char *argv[])
{
if (argc == 1)
usage();
return cmd_main(argc, argv);
}