Unverified Commit dfea0713 by Patrick Steinhardt Committed by GitHub

Merge pull request #5272 from tiennou/examples/cli-ification

Various examples shape-ups
parents b63ad958 fe42557a
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES}) INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES})
FILE(GLOB LG2_SOURCES *.c) FILE(GLOB LG2_SOURCES *.c *.h)
ADD_EXECUTABLE(lg2 ${LG2_SOURCES}) ADD_EXECUTABLE(lg2 ${LG2_SOURCES})
SET_TARGET_PROPERTIES(lg2 PROPERTIES C_STANDARD 90) SET_TARGET_PROPERTIES(lg2 PROPERTIES C_STANDARD 90)
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
*/ */
#include "common.h" #include "common.h"
#include <assert.h>
/** /**
* The following example demonstrates how to add files with libgit2. * The following example demonstrates how to add files with libgit2.
...@@ -27,48 +26,50 @@ ...@@ -27,48 +26,50 @@
* -u/--update: update the index instead of adding to it. * -u/--update: update the index instead of adding to it.
*/ */
enum print_options { enum index_mode {
SKIP = 1, INDEX_NONE,
VERBOSE = 2, INDEX_ADD,
UPDATE = 4,
}; };
struct print_payload { struct index_options {
enum print_options options; int dry_run;
int verbose;
git_repository *repo; git_repository *repo;
enum index_mode mode;
int add_update;
}; };
/* Forward declarations for helpers */ /* Forward declarations for helpers */
static void parse_opts(int *options, int *count, int argc, char *argv[]); static void parse_opts(const char **repo_path, struct index_options *opts, struct args_info *args);
void init_array(git_strarray *array, int argc, char **argv);
int print_matched_cb(const char *path, const char *matched_pathspec, void *payload); int print_matched_cb(const char *path, const char *matched_pathspec, void *payload);
int lg2_add(git_repository *repo, int argc, char** argv) int lg2_add(git_repository *repo, int argc, char **argv)
{ {
git_index_matched_path_cb matched_cb = NULL; git_index_matched_path_cb matched_cb = NULL;
git_index *index; git_index *index;
git_strarray array = {0}; git_strarray array = {0};
int options = 0, count = 0; struct index_options options;
struct print_payload payload = {0}; struct args_info args = ARGS_INFO_INIT;
parse_opts(&options, &count, argc, argv); /* Parse the options & arguments. */
init_array(&array, argc-count, argv+count); parse_opts(NULL, &options, &args);
strarray_from_args(&array, &args);
/* Grab the repository's index. */
check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL); check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL);
/* Setup a callback if the requested options need it */ /* Setup a callback if the requested options need it */
if ((options & VERBOSE) || (options & SKIP)) { if (options.verbose || options.dry_run) {
matched_cb = &print_matched_cb; matched_cb = &print_matched_cb;
} }
/* Perform the requested action with the index and files */ options.repo = repo;
payload.options = options;
payload.repo = repo;
if (options & UPDATE) { /* Perform the requested action with the index and files */
git_index_update_all(index, &array, matched_cb, &payload); if (options.add_update) {
git_index_update_all(index, &array, matched_cb, &options);
} else { } else {
git_index_add_all(index, &array, 0, matched_cb, &payload); git_index_add_all(index, &array, 0, matched_cb, &options);
} }
/* Cleanup memory */ /* Cleanup memory */
...@@ -85,15 +86,14 @@ int lg2_add(git_repository *repo, int argc, char** argv) ...@@ -85,15 +86,14 @@ int lg2_add(git_repository *repo, int argc, char** argv)
*/ */
int print_matched_cb(const char *path, const char *matched_pathspec, void *payload) int print_matched_cb(const char *path, const char *matched_pathspec, void *payload)
{ {
struct print_payload p = *(struct print_payload*)(payload); struct index_options *opts = (struct index_options *)(payload);
int ret; int ret;
unsigned status; unsigned status;
(void)matched_pathspec; (void)matched_pathspec;
/* Get the file status */ /* Get the file status */
if (git_status_file(&status, p.repo, path)) { if (git_status_file(&status, opts->repo, path) < 0)
return -1; return -1;
}
if ((status & GIT_STATUS_WT_MODIFIED) || (status & GIT_STATUS_WT_NEW)) { if ((status & GIT_STATUS_WT_MODIFIED) || (status & GIT_STATUS_WT_NEW)) {
printf("add '%s'\n", path); printf("add '%s'\n", path);
...@@ -102,9 +102,8 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo ...@@ -102,9 +102,8 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo
ret = 1; ret = 1;
} }
if ((p.options & SKIP)) { if (opts->dry_run)
ret = 1; ret = 1;
}
return ret; return ret;
} }
...@@ -133,33 +132,39 @@ void print_usage(void) ...@@ -133,33 +132,39 @@ void print_usage(void)
exit(1); exit(1);
} }
static void parse_opts(int *options, int *count, int argc, char *argv[]) static void parse_opts(const char **repo_path, struct index_options *opts, struct args_info *args)
{ {
int i; if (args->argc <= 1)
print_usage();
for (i = 1; i < argc; ++i) { for (args->pos = 1; args->pos < args->argc; ++args->pos) {
if (argv[i][0] != '-') const char *curr = args->argv[args->pos];
break;
else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) if (curr[0] != '-') {
*options |= VERBOSE; if (!strcmp("add", curr)) {
else if (!strcmp(argv[i], "--dry-run") || !strcmp(argv[i], "-n")) opts->mode = INDEX_ADD;
*options |= SKIP; continue;
else if (!strcmp(argv[i], "--update") || !strcmp(argv[i], "-u")) } else if (opts->mode == INDEX_NONE) {
*options |= UPDATE; fprintf(stderr, "missing command: %s", curr);
else if (!strcmp(argv[i], "-h")) { print_usage();
break;
} else {
/* We might be looking at a filename */
break;
}
} else if (match_bool_arg(&opts->verbose, args, "--verbose") ||
match_bool_arg(&opts->dry_run, args, "--dry-run") ||
match_str_arg(repo_path, args, "--git-dir") ||
(opts->mode == INDEX_ADD && match_bool_arg(&opts->add_update, args, "--update"))) {
continue;
} else if (match_bool_arg(NULL, args, "--help")) {
print_usage(); print_usage();
break; break;
} else if (!strcmp(argv[i], "--")) { } else if (match_arg_separator(args)) {
i++;
break; break;
} else { } else {
fprintf(stderr, "Unsupported option %s.\n", argv[i]); fprintf(stderr, "Unsupported option %s.\n", curr);
print_usage(); print_usage();
} }
} }
if (argc <= i)
print_usage();
*count = i;
} }
#include "common.h"
#include "args.h"
size_t is_prefixed(const char *str, const char *pfx)
{
size_t len = strlen(pfx);
return strncmp(str, pfx, len) ? 0 : len;
}
int optional_str_arg(
const char **out, struct args_info *args, const char *opt, const char *def)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return 0;
if (!found[len]) {
if (args->pos + 1 == args->argc) {
*out = def;
return 1;
}
args->pos += 1;
*out = args->argv[args->pos];
return 1;
}
if (found[len] == '=') {
*out = found + len + 1;
return 1;
}
return 0;
}
int match_str_arg(
const char **out, struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return 0;
if (!found[len]) {
if (args->pos + 1 == args->argc)
fatal("expected value following argument", opt);
args->pos += 1;
*out = args->argv[args->pos];
return 1;
}
if (found[len] == '=') {
*out = found + len + 1;
return 1;
}
return 0;
}
static const char *match_numeric_arg(struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return NULL;
if (!found[len]) {
if (args->pos + 1 == args->argc)
fatal("expected numeric value following argument", opt);
args->pos += 1;
found = args->argv[args->pos];
} else {
found = found + len;
if (*found == '=')
found++;
}
return found;
}
int match_uint16_arg(
uint16_t *out, struct args_info *args, const char *opt)
{
const char *found = match_numeric_arg(args, opt);
uint16_t val;
char *endptr = NULL;
if (!found)
return 0;
val = (uint16_t)strtoul(found, &endptr, 0);
if (!endptr || *endptr != '\0')
fatal("expected number after argument", opt);
if (out)
*out = val;
return 1;
}
int match_uint32_arg(
uint32_t *out, struct args_info *args, const char *opt)
{
const char *found = match_numeric_arg(args, opt);
uint16_t val;
char *endptr = NULL;
if (!found)
return 0;
val = (uint32_t)strtoul(found, &endptr, 0);
if (!endptr || *endptr != '\0')
fatal("expected number after argument", opt);
if (out)
*out = val;
return 1;
}
static int match_int_internal(
int *out, const char *str, int allow_negative, const char *opt)
{
char *endptr = NULL;
int val = (int)strtol(str, &endptr, 10);
if (!endptr || *endptr != '\0')
fatal("expected number", opt);
else if (val < 0 && !allow_negative)
fatal("negative values are not allowed", opt);
if (out)
*out = val;
return 1;
}
int match_bool_arg(int *out, struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
if (!strcmp(found, opt)) {
*out = 1;
return 1;
}
if (!strncmp(found, "--no-", strlen("--no-")) &&
!strcmp(found + strlen("--no-"), opt + 2)) {
*out = 0;
return 1;
}
*out = -1;
return 0;
}
int is_integer(int *out, const char *str, int allow_negative)
{
return match_int_internal(out, str, allow_negative, NULL);
}
int match_int_arg(
int *out, struct args_info *args, const char *opt, int allow_negative)
{
const char *found = match_numeric_arg(args, opt);
if (!found)
return 0;
return match_int_internal(out, found, allow_negative, opt);
}
int match_arg_separator(struct args_info *args)
{
if (args->opts_done)
return 1;
if (strcmp(args->argv[args->pos], "--") != 0)
return 0;
args->opts_done = 1;
args->pos++;
return 1;
}
void strarray_from_args(git_strarray *array, struct args_info *args)
{
size_t i;
array->count = args->argc - args->pos;
array->strings = calloc(array->count, sizeof(char *));
assert(array->strings != NULL);
for (i = 0; args->pos < args->argc; ++args->pos) {
array->strings[i++] = args->argv[args->pos];
}
args->pos = args->argc;
}
#ifndef INCLUDE_examples_args_h__
#define INCLUDE_examples_args_h__
/**
* Argument-processing helper structure
*/
struct args_info {
int argc;
char **argv;
int pos;
int opts_done : 1; /**< Did we see a -- separator */
};
#define ARGS_INFO_INIT { argc, argv, 0, 0 }
#define ARGS_CURRENT(args) args->argv[args->pos]
/**
* Check if a string has the given prefix. Returns 0 if not prefixed
* or the length of the prefix if it is.
*/
extern size_t is_prefixed(const char *str, const char *pfx);
/**
* Match an integer string, returning 1 if matched, 0 if not.
*/
extern int is_integer(int *out, const char *str, int allow_negative);
/**
* Check current `args` entry against `opt` string. If it matches
* exactly, take the next arg as a string; if it matches as a prefix with
* an equal sign, take the remainder as a string; if value not supplied,
* default value `def` will be given. otherwise return 0.
*/
extern int optional_str_arg(
const char **out, struct args_info *args, const char *opt, const char *def);
/**
* Check current `args` entry against `opt` string. If it matches
* exactly, take the next arg as a string; if it matches as a prefix with
* an equal sign, take the remainder as a string; otherwise return 0.
*/
extern int match_str_arg(
const char **out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as uint16. If
* `opt` matches exactly, take the next arg as a uint16_t value; if `opt`
* is a prefix (equal sign optional), take the remainder of the arg as a
* uint16_t value; otherwise return 0.
*/
extern int match_uint16_arg(
uint16_t *out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as uint32. If
* `opt` matches exactly, take the next arg as a uint16_t value; if `opt`
* is a prefix (equal sign optional), take the remainder of the arg as a
* uint32_t value; otherwise return 0.
*/
extern int match_uint32_arg(
uint32_t *out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as int. If
* `opt` matches exactly, take the next arg as an int value; if it matches
* as a prefix (equal sign optional), take the remainder of the arg as a
* int value; otherwise return 0.
*/
extern int match_int_arg(
int *out, struct args_info *args, const char *opt, int allow_negative);
/**
* Check current `args` entry against a "bool" `opt` (ie. --[no-]progress).
* If `opt` matches positively, out will be set to 1, or if `opt` matches
* negatively, out will be set to 0, and in both cases 1 will be returned.
* If neither the positive or the negative form of opt matched, out will be -1,
* and 0 will be returned.
*/
extern int match_bool_arg(int *out, struct args_info *args, const char *opt);
/**
* Check if we're processing past the single -- separator
*/
extern int match_arg_separator(struct args_info *args);
/**
* Consume all remaining arguments in a git_strarray
*/
extern void strarray_from_args(git_strarray *array, struct args_info *args);
#endif
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* simulate the output of `git blame` and a few of its command line arguments. * simulate the output of `git blame` and a few of its command line arguments.
*/ */
struct opts { struct blame_opts {
char *path; char *path;
char *commitspec; char *commitspec;
int C; int C;
...@@ -28,14 +28,14 @@ struct opts { ...@@ -28,14 +28,14 @@ struct opts {
int end_line; int end_line;
int F; int F;
}; };
static void parse_opts(struct opts *o, int argc, char *argv[]); static void parse_opts(struct blame_opts *o, int argc, char *argv[]);
int lg2_blame(git_repository *repo, int argc, char *argv[]) int lg2_blame(git_repository *repo, int argc, char *argv[])
{ {
int line, break_on_null_hunk; int line, break_on_null_hunk;
git_object_size_t i, rawsize; git_object_size_t i, rawsize;
char spec[1024] = {0}; char spec[1024] = {0};
struct opts o = {0}; struct blame_opts o = {0};
const char *rawdata; const char *rawdata;
git_revspec revspec = {0}; git_revspec revspec = {0};
git_blame_options blameopts = GIT_BLAME_OPTIONS_INIT; git_blame_options blameopts = GIT_BLAME_OPTIONS_INIT;
...@@ -143,7 +143,7 @@ static void usage(const char *msg, const char *arg) ...@@ -143,7 +143,7 @@ static void usage(const char *msg, const char *arg)
} }
/** Parse the arguments. */ /** Parse the arguments. */
static void parse_opts(struct opts *o, int argc, char *argv[]) static void parse_opts(struct blame_opts *o, int argc, char *argv[])
{ {
int i; int i;
char *bare_args[3] = {0}; char *bare_args[3] = {0};
......
...@@ -102,27 +102,28 @@ static void show_tag(const git_tag *tag) ...@@ -102,27 +102,28 @@ static void show_tag(const git_tag *tag)
printf("\n%s\n", git_tag_message(tag)); printf("\n%s\n", git_tag_message(tag));
} }
enum { typedef enum {
SHOW_TYPE = 1, SHOW_TYPE = 1,
SHOW_SIZE = 2, SHOW_SIZE = 2,
SHOW_NONE = 3, SHOW_NONE = 3,
SHOW_PRETTY = 4 SHOW_PRETTY = 4
}; } catfile_mode;
/* Forward declarations for option-parsing helper */ /* Forward declarations for option-parsing helper */
struct opts { struct catfile_options {
const char *dir; const char *dir;
const char *rev; const char *rev;
int action; catfile_mode action;
int verbose; int verbose;
}; };
static void parse_opts(struct opts *o, int argc, char *argv[]);
static void parse_opts(struct catfile_options *o, int argc, char *argv[]);
/** Entry point for this command */ /** Entry point for this command */
int lg2_cat_file(git_repository *repo, int argc, char *argv[]) int lg2_cat_file(git_repository *repo, int argc, char *argv[])
{ {
struct opts o = { ".", NULL, 0, 0 }; struct catfile_options o = { ".", NULL, 0, 0 };
git_object *obj = NULL; git_object *obj = NULL;
char oidstr[GIT_OID_HEXSZ + 1]; char oidstr[GIT_OID_HEXSZ + 1];
...@@ -201,7 +202,7 @@ static void usage(const char *message, const char *arg) ...@@ -201,7 +202,7 @@ static void usage(const char *message, const char *arg)
} }
/** Parse the command-line options taken from git */ /** Parse the command-line options taken from git */
static void parse_opts(struct opts *o, int argc, char *argv[]) static void parse_opts(struct catfile_options *o, int argc, char *argv[])
{ {
struct args_info args = ARGS_INFO_INIT; struct args_info args = ARGS_INFO_INIT;
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
*/ */
#include "common.h" #include "common.h"
#include <assert.h>
/* Define the printf format specifer to use for size_t output */ /* Define the printf format specifer to use for size_t output */
#if defined(_MSC_VER) || defined(__MINGW32__) #if defined(_MSC_VER) || defined(__MINGW32__)
...@@ -66,7 +65,7 @@ static void parse_options(const char **repo_path, checkout_options *opts, struct ...@@ -66,7 +65,7 @@ static void parse_options(const char **repo_path, checkout_options *opts, struct
const char *curr = args->argv[args->pos]; const char *curr = args->argv[args->pos];
int bool_arg; int bool_arg;
if (strcmp(curr, "--") == 0) { if (match_arg_separator(args)) {
break; break;
} else if (!strcmp(curr, "--force")) { } else if (!strcmp(curr, "--force")) {
opts->force = 1; opts->force = 1;
...@@ -191,11 +190,7 @@ int lg2_checkout(git_repository *repo, int argc, char **argv) ...@@ -191,11 +190,7 @@ int lg2_checkout(git_repository *repo, int argc, char **argv)
goto cleanup; goto cleanup;
} }
if (args.pos >= args.argc) { if (match_arg_separator(&args)) {
fprintf(stderr, "unhandled\n");
err = -1;
goto cleanup;
} else if (!strcmp("--", args.argv[args.pos])) {
/** /**
* Try to checkout the given path * Try to checkout the given path
*/ */
......
...@@ -12,21 +12,14 @@ ...@@ -12,21 +12,14 @@
* <http://creativecommons.org/publicdomain/zero/1.0/>. * <http://creativecommons.org/publicdomain/zero/1.0/>.
*/ */
#include <assert.h>
#include <stdio.h> #include "common.h"
#include <sys/types.h>
#include <sys/stat.h> #ifndef _WIN32
#ifdef _WIN32
# include <io.h>
#else
# include <fcntl.h>
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <string.h>
#include <errno.h> #include <errno.h>
#include "common.h"
void check_lg2(int error, const char *message, const char *extra) void check_lg2(int error, const char *message, const char *extra)
{ {
const git_error *lg2err; const git_error *lg2err;
...@@ -60,174 +53,6 @@ void fatal(const char *message, const char *extra) ...@@ -60,174 +53,6 @@ void fatal(const char *message, const char *extra)
exit(1); exit(1);
} }
size_t is_prefixed(const char *str, const char *pfx)
{
size_t len = strlen(pfx);
return strncmp(str, pfx, len) ? 0 : len;
}
int optional_str_arg(
const char **out, struct args_info *args, const char *opt, const char *def)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return 0;
if (!found[len]) {
if (args->pos + 1 == args->argc) {
*out = def;
return 1;
}
args->pos += 1;
*out = args->argv[args->pos];
return 1;
}
if (found[len] == '=') {
*out = found + len + 1;
return 1;
}
return 0;
}
int match_str_arg(
const char **out, struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return 0;
if (!found[len]) {
if (args->pos + 1 == args->argc)
fatal("expected value following argument", opt);
args->pos += 1;
*out = args->argv[args->pos];
return 1;
}
if (found[len] == '=') {
*out = found + len + 1;
return 1;
}
return 0;
}
static const char *match_numeric_arg(struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return NULL;
if (!found[len]) {
if (args->pos + 1 == args->argc)
fatal("expected numeric value following argument", opt);
args->pos += 1;
found = args->argv[args->pos];
} else {
found = found + len;
if (*found == '=')
found++;
}
return found;
}
int match_uint16_arg(
uint16_t *out, struct args_info *args, const char *opt)
{
const char *found = match_numeric_arg(args, opt);
uint16_t val;
char *endptr = NULL;
if (!found)
return 0;
val = (uint16_t)strtoul(found, &endptr, 0);
if (!endptr || *endptr != '\0')
fatal("expected number after argument", opt);
if (out)
*out = val;
return 1;
}
int match_uint32_arg(
uint32_t *out, struct args_info *args, const char *opt)
{
const char *found = match_numeric_arg(args, opt);
uint16_t val;
char *endptr = NULL;
if (!found)
return 0;
val = (uint32_t)strtoul(found, &endptr, 0);
if (!endptr || *endptr != '\0')
fatal("expected number after argument", opt);
if (out)
*out = val;
return 1;
}
static int match_int_internal(
int *out, const char *str, int allow_negative, const char *opt)
{
char *endptr = NULL;
int val = (int)strtol(str, &endptr, 10);
if (!endptr || *endptr != '\0')
fatal("expected number", opt);
else if (val < 0 && !allow_negative)
fatal("negative values are not allowed", opt);
if (out)
*out = val;
return 1;
}
int match_bool_arg(int *out, struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
if (!strcmp(found, opt)) {
*out = 1;
return 1;
}
if (!strncmp(found, "--no-", strlen("--no-")) &&
!strcmp(found + strlen("--no-"), opt + 2)) {
*out = 0;
return 1;
}
*out = -1;
return 0;
}
int is_integer(int *out, const char *str, int allow_negative)
{
return match_int_internal(out, str, allow_negative, NULL);
}
int match_int_arg(
int *out, struct args_info *args, const char *opt, int allow_negative)
{
const char *found = match_numeric_arg(args, opt);
if (!found)
return 0;
return match_int_internal(out, found, allow_negative, opt);
}
int diff_output( int diff_output(
const git_diff_delta *d, const git_diff_delta *d,
const git_diff_hunk *h, const git_diff_hunk *h,
......
...@@ -11,7 +11,10 @@ ...@@ -11,7 +11,10 @@
* with this software. If not, see * with this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>. * <http://creativecommons.org/publicdomain/zero/1.0/>.
*/ */
#ifndef INCLUDE_examples_common_h__
#define INCLUDE_examples_common_h__
#include <assert.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <stdio.h> #include <stdio.h>
...@@ -49,6 +52,8 @@ ...@@ -49,6 +52,8 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
#include "args.h"
extern int lg2_add(git_repository *repo, int argc, char **argv); extern int lg2_add(git_repository *repo, int argc, char **argv);
extern int lg2_blame(git_repository *repo, int argc, char **argv); extern int lg2_blame(git_repository *repo, int argc, char **argv);
extern int lg2_cat_file(git_repository *repo, int argc, char **argv); extern int lg2_cat_file(git_repository *repo, int argc, char **argv);
...@@ -94,77 +99,6 @@ extern char *read_file(const char *path); ...@@ -94,77 +99,6 @@ extern char *read_file(const char *path);
extern void fatal(const char *message, const char *extra); extern void fatal(const char *message, const char *extra);
/** /**
* Check if a string has the given prefix. Returns 0 if not prefixed
* or the length of the prefix if it is.
*/
extern size_t is_prefixed(const char *str, const char *pfx);
/**
* Match an integer string, returning 1 if matched, 0 if not.
*/
extern int is_integer(int *out, const char *str, int allow_negative);
struct args_info {
int argc;
char **argv;
int pos;
};
#define ARGS_INFO_INIT { argc, argv, 0 }
/**
* Check current `args` entry against `opt` string. If it matches
* exactly, take the next arg as a string; if it matches as a prefix with
* an equal sign, take the remainder as a string; if value not supplied,
* default value `def` will be given. otherwise return 0.
*/
extern int optional_str_arg(
const char **out, struct args_info *args, const char *opt, const char *def);
/**
* Check current `args` entry against `opt` string. If it matches
* exactly, take the next arg as a string; if it matches as a prefix with
* an equal sign, take the remainder as a string; otherwise return 0.
*/
extern int match_str_arg(
const char **out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as uint16. If
* `opt` matches exactly, take the next arg as a uint16_t value; if `opt`
* is a prefix (equal sign optional), take the remainder of the arg as a
* uint16_t value; otherwise return 0.
*/
extern int match_uint16_arg(
uint16_t *out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as uint32. If
* `opt` matches exactly, take the next arg as a uint16_t value; if `opt`
* is a prefix (equal sign optional), take the remainder of the arg as a
* uint32_t value; otherwise return 0.
*/
extern int match_uint32_arg(
uint32_t *out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as int. If
* `opt` matches exactly, take the next arg as an int value; if it matches
* as a prefix (equal sign optional), take the remainder of the arg as a
* int value; otherwise return 0.
*/
extern int match_int_arg(
int *out, struct args_info *args, const char *opt, int allow_negative);
/**
* Check current `args` entry against a "bool" `opt` (ie. --[no-]progress).
* If `opt` matches positively, out will be set to 1, or if `opt` matches
* negatively, out will be set to 0, and in both cases 1 will be returned.
* If neither the positive or the negative form of opt matched, out will be -1,
* and 0 will be returned.
*/
extern int match_bool_arg(int *out, struct args_info *args, const char *opt);
/**
* Basic output function for plain text diff output * Basic output function for plain text diff output
* Pass `FILE*` such as `stdout` or `stderr` as payload (or NULL == `stdout`) * Pass `FILE*` such as `stdout` or `stderr` as payload (or NULL == `stdout`)
*/ */
...@@ -196,3 +130,5 @@ extern int cred_acquire_cb(git_cred **out, ...@@ -196,3 +130,5 @@ extern int cred_acquire_cb(git_cred **out,
const char *username_from_url, const char *username_from_url,
unsigned int allowed_types, unsigned int allowed_types,
void *payload); void *payload);
#endif
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
*/ */
#include "common.h" #include "common.h"
#include <assert.h>
/** /**
* The following example partially reimplements the `git describe` command * The following example partially reimplements the `git describe` command
...@@ -38,16 +37,14 @@ ...@@ -38,16 +37,14 @@
*/ */
/** describe_options represents the parsed command line options */ /** describe_options represents the parsed command line options */
typedef struct { struct describe_options {
const char **commits; const char **commits;
size_t commit_count; size_t commit_count;
git_describe_options describe_options; git_describe_options describe_options;
git_describe_format_options format_options; git_describe_format_options format_options;
} describe_options; };
typedef struct args_info args_info; static void opts_add_commit(struct describe_options *opts, const char *commit)
static void opts_add_commit(describe_options *opts, const char *commit)
{ {
size_t sz; size_t sz;
...@@ -58,7 +55,7 @@ static void opts_add_commit(describe_options *opts, const char *commit) ...@@ -58,7 +55,7 @@ static void opts_add_commit(describe_options *opts, const char *commit)
opts->commits[opts->commit_count - 1] = commit; opts->commits[opts->commit_count - 1] = commit;
} }
static void do_describe_single(git_repository *repo, describe_options *opts, const char *rev) static void do_describe_single(git_repository *repo, struct describe_options *opts, const char *rev)
{ {
git_object *commit; git_object *commit;
git_describe_result *describe_result; git_describe_result *describe_result;
...@@ -81,7 +78,7 @@ static void do_describe_single(git_repository *repo, describe_options *opts, con ...@@ -81,7 +78,7 @@ static void do_describe_single(git_repository *repo, describe_options *opts, con
printf("%s\n", buf.ptr); printf("%s\n", buf.ptr);
} }
static void do_describe(git_repository *repo, describe_options *opts) static void do_describe(git_repository *repo, struct describe_options *opts)
{ {
if (opts->commit_count == 0) if (opts->commit_count == 0)
do_describe_single(repo, opts, NULL); do_describe_single(repo, opts, NULL);
...@@ -100,9 +97,9 @@ static void print_usage(void) ...@@ -100,9 +97,9 @@ static void print_usage(void)
} }
/** Parse command line arguments */ /** Parse command line arguments */
static void parse_options(describe_options *opts, int argc, char **argv) static void parse_options(struct describe_options *opts, int argc, char **argv)
{ {
args_info args = ARGS_INFO_INIT; struct args_info args = ARGS_INFO_INIT;
for (args.pos = 1; args.pos < argc; ++args.pos) { for (args.pos = 1; args.pos < argc; ++args.pos) {
const char *curr = argv[args.pos]; const char *curr = argv[args.pos];
...@@ -142,7 +139,7 @@ static void parse_options(describe_options *opts, int argc, char **argv) ...@@ -142,7 +139,7 @@ static void parse_options(describe_options *opts, int argc, char **argv)
} }
/** Initialize describe_options struct */ /** Initialize describe_options struct */
static void describe_options_init(describe_options *opts) static void describe_options_init(struct describe_options *opts)
{ {
memset(opts, 0, sizeof(*opts)); memset(opts, 0, sizeof(*opts));
...@@ -154,7 +151,7 @@ static void describe_options_init(describe_options *opts) ...@@ -154,7 +151,7 @@ static void describe_options_init(describe_options *opts)
int lg2_describe(git_repository *repo, int argc, char **argv) int lg2_describe(git_repository *repo, int argc, char **argv)
{ {
describe_options opts; struct describe_options opts;
describe_options_init(&opts); describe_options_init(&opts);
parse_options(&opts, argc, argv); parse_options(&opts, argc, argv);
......
...@@ -47,8 +47,8 @@ enum { ...@@ -47,8 +47,8 @@ enum {
CACHE_NONE = 2 CACHE_NONE = 2
}; };
/** The 'opts' struct captures all the various parsed command line options. */ /** The 'diff_options' struct captures all the various parsed command line options. */
struct opts { struct diff_options {
git_diff_options diffopts; git_diff_options diffopts;
git_diff_find_options findopts; git_diff_find_options findopts;
int color; int color;
...@@ -63,18 +63,17 @@ struct opts { ...@@ -63,18 +63,17 @@ struct opts {
/** These functions are implemented at the end */ /** These functions are implemented at the end */
static void usage(const char *message, const char *arg); static void usage(const char *message, const char *arg);
static void parse_opts(struct opts *o, int argc, char *argv[]); static void parse_opts(struct diff_options *o, int argc, char *argv[]);
static int color_printer( static int color_printer(
const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*); const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*);
static void diff_print_stats(git_diff *diff, struct opts *o); static void diff_print_stats(git_diff *diff, struct diff_options *o);
static void compute_diff_no_index(git_diff **diff, struct opts *o); static void compute_diff_no_index(git_diff **diff, struct diff_options *o);
int lg2_diff(git_repository *repo, int argc, char *argv[]) int lg2_diff(git_repository *repo, int argc, char *argv[])
{ {
git_tree *t1 = NULL, *t2 = NULL; git_tree *t1 = NULL, *t2 = NULL;
git_diff *diff; git_diff *diff;
struct diff_options o = {
struct opts o = {
GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT, GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT,
-1, -1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "." -1, -1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "."
}; };
...@@ -166,7 +165,7 @@ int lg2_diff(git_repository *repo, int argc, char *argv[]) ...@@ -166,7 +165,7 @@ int lg2_diff(git_repository *repo, int argc, char *argv[])
return 0; return 0;
} }
static void compute_diff_no_index(git_diff **diff, struct opts *o) { static void compute_diff_no_index(git_diff **diff, struct diff_options *o) {
git_patch *patch = NULL; git_patch *patch = NULL;
char *file1_str = NULL; char *file1_str = NULL;
char *file2_str = NULL; char *file2_str = NULL;
...@@ -242,11 +241,10 @@ static int color_printer( ...@@ -242,11 +241,10 @@ static int color_printer(
} }
/** Parse arguments as copied from git-diff. */ /** Parse arguments as copied from git-diff. */
static void parse_opts(struct opts *o, int argc, char *argv[]) static void parse_opts(struct diff_options *o, int argc, char *argv[])
{ {
struct args_info args = ARGS_INFO_INIT; struct args_info args = ARGS_INFO_INIT;
for (args.pos = 1; args.pos < argc; ++args.pos) { for (args.pos = 1; args.pos < argc; ++args.pos) {
const char *a = argv[args.pos]; const char *a = argv[args.pos];
...@@ -343,7 +341,7 @@ static void parse_opts(struct opts *o, int argc, char *argv[]) ...@@ -343,7 +341,7 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
} }
/** Display diff output with "--stat", "--numstat", or "--shortstat" */ /** Display diff output with "--stat", "--numstat", or "--shortstat" */
static void diff_print_stats(git_diff *diff, struct opts *o) static void diff_print_stats(git_diff *diff, struct diff_options *o)
{ {
git_diff_stats *stats; git_diff_stats *stats;
git_buf b = GIT_BUF_INIT_CONST(NULL, 0); git_buf b = GIT_BUF_INIT_CONST(NULL, 0);
......
...@@ -3,42 +3,42 @@ ...@@ -3,42 +3,42 @@
static int show_ref(git_reference *ref, void *data) static int show_ref(git_reference *ref, void *data)
{ {
git_repository *repo = data; git_repository *repo = data;
git_reference *resolved = NULL; git_reference *resolved = NULL;
char hex[GIT_OID_HEXSZ+1]; char hex[GIT_OID_HEXSZ+1];
const git_oid *oid; const git_oid *oid;
git_object *obj; git_object *obj;
if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC) if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC)
check_lg2(git_reference_resolve(&resolved, ref), check_lg2(git_reference_resolve(&resolved, ref),
"Unable to resolve symbolic reference", "Unable to resolve symbolic reference",
git_reference_name(ref)); git_reference_name(ref));
oid = git_reference_target(resolved ? resolved : ref); oid = git_reference_target(resolved ? resolved : ref);
git_oid_fmt(hex, oid); git_oid_fmt(hex, oid);
hex[GIT_OID_HEXSZ] = 0; hex[GIT_OID_HEXSZ] = 0;
check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJECT_ANY), check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJECT_ANY),
"Unable to lookup object", hex); "Unable to lookup object", hex);
printf("%s %-6s\t%s\n", printf("%s %-6s\t%s\n",
hex, hex,
git_object_type2string(git_object_type(obj)), git_object_type2string(git_object_type(obj)),
git_reference_name(ref)); git_reference_name(ref));
if (resolved) if (resolved)
git_reference_free(resolved); git_reference_free(resolved);
return 0; return 0;
} }
int lg2_for_each_ref(git_repository *repo, int argc, char **argv) int lg2_for_each_ref(git_repository *repo, int argc, char **argv)
{ {
UNUSED(argv); UNUSED(argv);
if (argc != 1) if (argc != 1)
fatal("Sorry, no for-each-ref options supported yet", NULL); fatal("Sorry, no for-each-ref options supported yet", NULL);
check_lg2(git_reference_foreach(repo, show_ref, repo), check_lg2(git_reference_foreach(repo, show_ref, repo),
"Could not iterate over references", NULL); "Could not iterate over references", NULL);
return 0; return 0;
} }
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
*/ */
/** Forward declarations of helpers */ /** Forward declarations of helpers */
struct opts { struct init_opts {
int no_options; int no_options;
int quiet; int quiet;
int bare; int bare;
...@@ -38,11 +38,11 @@ struct opts { ...@@ -38,11 +38,11 @@ struct opts {
const char *dir; const char *dir;
}; };
static void create_initial_commit(git_repository *repo); static void create_initial_commit(git_repository *repo);
static void parse_opts(struct opts *o, int argc, char *argv[]); static void parse_opts(struct init_opts *o, int argc, char *argv[]);
int lg2_init(git_repository *repo, int argc, char *argv[]) int lg2_init(git_repository *repo, int argc, char *argv[])
{ {
struct opts o = { 1, 0, 0, 0, GIT_REPOSITORY_INIT_SHARED_UMASK, 0, 0, 0 }; struct init_opts o = { 1, 0, 0, 0, GIT_REPOSITORY_INIT_SHARED_UMASK, 0, 0, 0 };
parse_opts(&o, argc, argv); parse_opts(&o, argc, argv);
...@@ -210,7 +210,7 @@ static uint32_t parse_shared(const char *shared) ...@@ -210,7 +210,7 @@ static uint32_t parse_shared(const char *shared)
return 0; return 0;
} }
static void parse_opts(struct opts *o, int argc, char *argv[]) static void parse_opts(struct init_opts *o, int argc, char *argv[])
{ {
struct args_info args = ARGS_INFO_INIT; struct args_info args = ARGS_INFO_INIT;
const char *sharedarg; const char *sharedarg;
......
...@@ -84,8 +84,7 @@ int main(int argc, char **argv) ...@@ -84,8 +84,7 @@ int main(int argc, char **argv)
break; break;
} else if (optional_str_arg(&git_dir, &args, "--git-dir", ".git")) { } else if (optional_str_arg(&git_dir, &args, "--git-dir", ".git")) {
continue; continue;
} else if (!strcmp(a, "--")) { } else if (match_arg_separator(&args)) {
/* arg separator */
break; break;
} }
} }
......
...@@ -424,8 +424,7 @@ static int parse_options( ...@@ -424,8 +424,7 @@ static int parse_options(
else else
/** Try failed revision parse as filename. */ /** Try failed revision parse as filename. */
break; break;
} else if (!strcmp(a, "--")) { } else if (!match_arg_separator(&args)) {
++args.pos;
break; break;
} }
else if (!strcmp(a, "--date-order")) else if (!strcmp(a, "--date-order"))
......
...@@ -25,11 +25,11 @@ ...@@ -25,11 +25,11 @@
* This currently supports the default behavior and the `--error-unmatch` option. * This currently supports the default behavior and the `--error-unmatch` option.
*/ */
typedef struct { struct ls_options {
int error_unmatch; int error_unmatch;
char *files[1024]; char *files[1024];
size_t file_count; size_t file_count;
} ls_options; };
static void usage(const char *message, const char *arg) static void usage(const char *message, const char *arg)
{ {
...@@ -41,12 +41,12 @@ static void usage(const char *message, const char *arg) ...@@ -41,12 +41,12 @@ static void usage(const char *message, const char *arg)
exit(1); exit(1);
} }
static int parse_options(ls_options *opts, int argc, char *argv[]) static int parse_options(struct ls_options *opts, int argc, char *argv[])
{ {
int parsing_files = 0; int parsing_files = 0;
int i; int i;
memset(opts, 0, sizeof(ls_options)); memset(opts, 0, sizeof(struct ls_options));
if (argc < 2) if (argc < 2)
return 0; return 0;
...@@ -78,7 +78,7 @@ static int parse_options(ls_options *opts, int argc, char *argv[]) ...@@ -78,7 +78,7 @@ static int parse_options(ls_options *opts, int argc, char *argv[])
return 0; return 0;
} }
static int print_paths(ls_options *opts, git_index *index) static int print_paths(struct ls_options *opts, git_index *index)
{ {
size_t i; size_t i;
const git_index_entry *entry; const git_index_entry *entry;
...@@ -113,7 +113,7 @@ static int print_paths(ls_options *opts, git_index *index) ...@@ -113,7 +113,7 @@ static int print_paths(ls_options *opts, git_index *index)
int lg2_ls_files(git_repository *repo, int argc, char *argv[]) int lg2_ls_files(git_repository *repo, int argc, char *argv[])
{ {
git_index *index = NULL; git_index *index = NULL;
ls_options opts; struct ls_options opts;
int error; int error;
if ((error = parse_options(&opts, argc, argv)) < 0) if ((error = parse_options(&opts, argc, argv)) < 0)
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
*/ */
#include "common.h" #include "common.h"
#include <assert.h>
/** The following example demonstrates how to do merges with libgit2. /** The following example demonstrates how to do merges with libgit2.
* *
...@@ -24,7 +23,7 @@ ...@@ -24,7 +23,7 @@
* *
*/ */
typedef struct { struct merge_options {
const char **heads; const char **heads;
size_t heads_count; size_t heads_count;
...@@ -32,7 +31,7 @@ typedef struct { ...@@ -32,7 +31,7 @@ typedef struct {
size_t annotated_count; size_t annotated_count;
int no_commit : 1; int no_commit : 1;
} merge_options; };
static void print_usage(void) static void print_usage(void)
{ {
...@@ -40,7 +39,7 @@ static void print_usage(void) ...@@ -40,7 +39,7 @@ static void print_usage(void)
exit(1); exit(1);
} }
static void merge_options_init(merge_options *opts) static void merge_options_init(struct merge_options *opts)
{ {
memset(opts, 0, sizeof(*opts)); memset(opts, 0, sizeof(*opts));
...@@ -50,7 +49,7 @@ static void merge_options_init(merge_options *opts) ...@@ -50,7 +49,7 @@ static void merge_options_init(merge_options *opts)
opts->annotated_count = 0; opts->annotated_count = 0;
} }
static void opts_add_refish(merge_options *opts, const char *refish) static void opts_add_refish(struct merge_options *opts, const char *refish)
{ {
size_t sz; size_t sz;
...@@ -61,7 +60,7 @@ static void opts_add_refish(merge_options *opts, const char *refish) ...@@ -61,7 +60,7 @@ static void opts_add_refish(merge_options *opts, const char *refish)
opts->heads[opts->heads_count - 1] = refish; opts->heads[opts->heads_count - 1] = refish;
} }
static void parse_options(const char **repo_path, merge_options *opts, int argc, char **argv) static void parse_options(const char **repo_path, struct merge_options *opts, int argc, char **argv)
{ {
struct args_info args = ARGS_INFO_INIT; struct args_info args = ARGS_INFO_INIT;
...@@ -83,7 +82,7 @@ static void parse_options(const char **repo_path, merge_options *opts, int argc, ...@@ -83,7 +82,7 @@ static void parse_options(const char **repo_path, merge_options *opts, int argc,
} }
} }
static int resolve_heads(git_repository *repo, merge_options *opts) static int resolve_heads(git_repository *repo, struct merge_options *opts)
{ {
git_annotated_commit **annotated = calloc(opts->heads_count, sizeof(git_annotated_commit *)); git_annotated_commit **annotated = calloc(opts->heads_count, sizeof(git_annotated_commit *));
size_t annotated_count = 0, i; size_t annotated_count = 0, i;
...@@ -201,7 +200,7 @@ static void output_conflicts(git_index *index) ...@@ -201,7 +200,7 @@ static void output_conflicts(git_index *index)
git_index_conflict_iterator_free(conflicts); git_index_conflict_iterator_free(conflicts);
} }
static int create_merge_commit(git_repository *repo, git_index *index, merge_options *opts) static int create_merge_commit(git_repository *repo, git_index *index, struct merge_options *opts)
{ {
git_oid tree_oid, commit_oid; git_oid tree_oid, commit_oid;
git_tree *tree; git_tree *tree;
...@@ -277,7 +276,7 @@ cleanup: ...@@ -277,7 +276,7 @@ cleanup:
int lg2_merge(git_repository *repo, int argc, char **argv) int lg2_merge(git_repository *repo, int argc, char **argv)
{ {
merge_options opts; struct merge_options opts;
git_index *index; git_index *index;
git_repository_state_t state; git_repository_state_t state;
git_merge_analysis_t analysis; git_merge_analysis_t analysis;
......
...@@ -30,7 +30,7 @@ enum subcmd { ...@@ -30,7 +30,7 @@ enum subcmd {
subcmd_show, subcmd_show,
}; };
struct opts { struct remote_opts {
enum subcmd cmd; enum subcmd cmd;
/* for command-specific args */ /* for command-specific args */
...@@ -38,20 +38,20 @@ struct opts { ...@@ -38,20 +38,20 @@ struct opts {
char **argv; char **argv;
}; };
static int cmd_add(git_repository *repo, struct opts *o); static int cmd_add(git_repository *repo, struct remote_opts *o);
static int cmd_remove(git_repository *repo, struct opts *o); static int cmd_remove(git_repository *repo, struct remote_opts *o);
static int cmd_rename(git_repository *repo, struct opts *o); static int cmd_rename(git_repository *repo, struct remote_opts *o);
static int cmd_seturl(git_repository *repo, struct opts *o); static int cmd_seturl(git_repository *repo, struct remote_opts *o);
static int cmd_show(git_repository *repo, struct opts *o); static int cmd_show(git_repository *repo, struct remote_opts *o);
static void parse_subcmd( static void parse_subcmd(
struct opts *opt, int argc, char **argv); struct remote_opts *opt, int argc, char **argv);
static void usage(const char *msg, const char *arg); static void usage(const char *msg, const char *arg);
int lg2_remote(git_repository *repo, int argc, char *argv[]) int lg2_remote(git_repository *repo, int argc, char *argv[])
{ {
int retval = 0; int retval = 0;
struct opts opt = {0}; struct remote_opts opt = {0};
parse_subcmd(&opt, argc, argv); parse_subcmd(&opt, argc, argv);
...@@ -77,7 +77,7 @@ int lg2_remote(git_repository *repo, int argc, char *argv[]) ...@@ -77,7 +77,7 @@ int lg2_remote(git_repository *repo, int argc, char *argv[])
return retval; return retval;
} }
static int cmd_add(git_repository *repo, struct opts *o) static int cmd_add(git_repository *repo, struct remote_opts *o)
{ {
char *name, *url; char *name, *url;
git_remote *remote = {0}; git_remote *remote = {0};
...@@ -94,7 +94,7 @@ static int cmd_add(git_repository *repo, struct opts *o) ...@@ -94,7 +94,7 @@ static int cmd_add(git_repository *repo, struct opts *o)
return 0; return 0;
} }
static int cmd_remove(git_repository *repo, struct opts *o) static int cmd_remove(git_repository *repo, struct remote_opts *o)
{ {
char *name; char *name;
...@@ -109,7 +109,7 @@ static int cmd_remove(git_repository *repo, struct opts *o) ...@@ -109,7 +109,7 @@ static int cmd_remove(git_repository *repo, struct opts *o)
return 0; return 0;
} }
static int cmd_rename(git_repository *repo, struct opts *o) static int cmd_rename(git_repository *repo, struct remote_opts *o)
{ {
int i, retval; int i, retval;
char *old, *new; char *old, *new;
...@@ -134,7 +134,7 @@ static int cmd_rename(git_repository *repo, struct opts *o) ...@@ -134,7 +134,7 @@ static int cmd_rename(git_repository *repo, struct opts *o)
return retval; return retval;
} }
static int cmd_seturl(git_repository *repo, struct opts *o) static int cmd_seturl(git_repository *repo, struct remote_opts *o)
{ {
int i, retval, push = 0; int i, retval, push = 0;
char *name = NULL, *url = NULL; char *name = NULL, *url = NULL;
...@@ -166,7 +166,7 @@ static int cmd_seturl(git_repository *repo, struct opts *o) ...@@ -166,7 +166,7 @@ static int cmd_seturl(git_repository *repo, struct opts *o)
return 0; return 0;
} }
static int cmd_show(git_repository *repo, struct opts *o) static int cmd_show(git_repository *repo, struct remote_opts *o)
{ {
int i; int i;
const char *arg, *name, *fetch, *push; const char *arg, *name, *fetch, *push;
...@@ -213,7 +213,7 @@ static int cmd_show(git_repository *repo, struct opts *o) ...@@ -213,7 +213,7 @@ static int cmd_show(git_repository *repo, struct opts *o)
} }
static void parse_subcmd( static void parse_subcmd(
struct opts *opt, int argc, char **argv) struct remote_opts *opt, int argc, char **argv)
{ {
char *arg = argv[1]; char *arg = argv[1];
enum subcmd cmd = 0; enum subcmd cmd = 0;
......
...@@ -15,16 +15,24 @@ ...@@ -15,16 +15,24 @@
#include "common.h" #include "common.h"
static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts); #include <assert.h>
static int revwalk_parse_options(git_sort_t *sort, struct args_info *args);
static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args);
int lg2_rev_list(git_repository *repo, int argc, char **argv) int lg2_rev_list(git_repository *repo, int argc, char **argv)
{ {
struct args_info args = ARGS_INFO_INIT;
git_revwalk *walk; git_revwalk *walk;
git_oid oid; git_oid oid;
git_sort_t sort;
char buf[GIT_OID_HEXSZ+1]; char buf[GIT_OID_HEXSZ+1];
check_lg2(revwalk_parse_options(&sort, &args), "parsing options", NULL);
check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL); check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
check_lg2(revwalk_parseopts(repo, walk, argc-1, argv+1), "parsing options", NULL); git_revwalk_sorting(walk, sort);
check_lg2(revwalk_parse_revs(repo, walk, &args), "parsing revs", NULL);
while (!git_revwalk_next(&oid, walk)) { while (!git_revwalk_next(&oid, walk)) {
git_oid_fmt(buf, &oid); git_oid_fmt(buf, &oid);
...@@ -32,6 +40,7 @@ int lg2_rev_list(git_repository *repo, int argc, char **argv) ...@@ -32,6 +40,7 @@ int lg2_rev_list(git_repository *repo, int argc, char **argv)
printf("%s\n", buf); printf("%s\n", buf);
} }
git_revwalk_free(walk);
return 0; return 0;
} }
...@@ -80,33 +89,60 @@ out: ...@@ -80,33 +89,60 @@ out:
return error; return error;
} }
static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts) static void print_usage(void)
{
fprintf(stderr, "rev-list [--git-dir=dir] [--topo-order|--date-order] [--reverse] <revspec>\n");
exit(-1);
}
static int revwalk_parse_options(git_sort_t *sort, struct args_info *args)
{ {
int hide, i, error; assert(sort && args);
unsigned int sorting = GIT_SORT_NONE; *sort = GIT_SORT_NONE;
if (args->argc < 1)
print_usage();
for (args->pos = 1; args->pos < args->argc; ++args->pos) {
const char *curr = args->argv[args->pos];
if (!strcmp(curr, "--topo-order")) {
*sort |= GIT_SORT_TOPOLOGICAL;
} else if (!strcmp(curr, "--date-order")) {
*sort |= GIT_SORT_TIME;
} else if (!strcmp(curr, "--reverse")) {
*sort |= (*sort & ~GIT_SORT_REVERSE) ^ GIT_SORT_REVERSE;
} else {
break;
}
}
return 0;
}
static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args)
{
int hide, error;
git_oid oid;
hide = 0; hide = 0;
for (i = 0; i < nopts; i++) { for (; args->pos < args->argc; ++args->pos) {
if (!strcmp(opts[i], "--topo-order")) { const char *curr = args->argv[args->pos];
sorting = GIT_SORT_TOPOLOGICAL | (sorting & GIT_SORT_REVERSE);
git_revwalk_sorting(walk, sorting); if (!strcmp(curr, "--not")) {
} else if (!strcmp(opts[i], "--date-order")) {
sorting = GIT_SORT_TIME | (sorting & GIT_SORT_REVERSE);
git_revwalk_sorting(walk, sorting);
} else if (!strcmp(opts[i], "--reverse")) {
sorting = (sorting & ~GIT_SORT_REVERSE)
| ((sorting & GIT_SORT_REVERSE) ? 0 : GIT_SORT_REVERSE);
git_revwalk_sorting(walk, sorting);
} else if (!strcmp(opts[i], "--not")) {
hide = !hide; hide = !hide;
} else if (opts[i][0] == '^') { } else if (curr[0] == '^') {
if ((error = push_spec(repo, walk, opts[i] + 1, !hide))) if ((error = push_spec(repo, walk, curr + 1, !hide)))
return error; return error;
} else if (strstr(opts[i], "..")) { } else if (strstr(curr, "..")) {
if ((error = push_range(repo, walk, opts[i], hide))) if ((error = push_range(repo, walk, curr, hide)))
return error; return error;
} else { } else {
if ((error = push_spec(repo, walk, opts[i], hide))) if (push_spec(repo, walk, curr, hide) == 0)
continue;
if ((error = git_oid_fromstr(&oid, curr)))
return error;
if ((error = push_commit(walk, &oid, hide)))
return error; return error;
} }
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "common.h" #include "common.h"
int lg2_show_index(git_repository *repo, int argc, char** argv) int lg2_show_index(git_repository *repo, int argc, char **argv)
{ {
git_index *index; git_index *index;
size_t i, ecount; size_t i, ecount;
......
...@@ -43,7 +43,7 @@ enum { ...@@ -43,7 +43,7 @@ enum {
#define MAX_PATHSPEC 8 #define MAX_PATHSPEC 8
struct opts { struct status_opts {
git_status_options statusopt; git_status_options statusopt;
char *repodir; char *repodir;
char *pathspec[MAX_PATHSPEC]; char *pathspec[MAX_PATHSPEC];
...@@ -55,7 +55,7 @@ struct opts { ...@@ -55,7 +55,7 @@ struct opts {
int repeat; int repeat;
}; };
static void parse_opts(struct opts *o, int argc, char *argv[]); static void parse_opts(struct status_opts *o, int argc, char *argv[]);
static void show_branch(git_repository *repo, int format); static void show_branch(git_repository *repo, int format);
static void print_long(git_status_list *status); static void print_long(git_status_list *status);
static void print_short(git_repository *repo, git_status_list *status); static void print_short(git_repository *repo, git_status_list *status);
...@@ -64,7 +64,7 @@ static int print_submod(git_submodule *sm, const char *name, void *payload); ...@@ -64,7 +64,7 @@ static int print_submod(git_submodule *sm, const char *name, void *payload);
int lg2_status(git_repository *repo, int argc, char *argv[]) int lg2_status(git_repository *repo, int argc, char *argv[])
{ {
git_status_list *status; git_status_list *status;
struct opts o = { GIT_STATUS_OPTIONS_INIT, "." }; struct status_opts o = { GIT_STATUS_OPTIONS_INIT, "." };
o.statusopt.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; o.statusopt.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
o.statusopt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | o.statusopt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
...@@ -435,7 +435,7 @@ static int print_submod(git_submodule *sm, const char *name, void *payload) ...@@ -435,7 +435,7 @@ static int print_submod(git_submodule *sm, const char *name, void *payload)
/** /**
* Parse options that git's status command supports. * Parse options that git's status command supports.
*/ */
static void parse_opts(struct opts *o, int argc, char *argv[]) static void parse_opts(struct status_opts *o, int argc, char *argv[])
{ {
struct args_info args = ARGS_INFO_INIT; struct args_info args = ARGS_INFO_INIT;
......
...@@ -31,19 +31,19 @@ ...@@ -31,19 +31,19 @@
*/ */
/** tag_options represents the parsed command line options */ /** tag_options represents the parsed command line options */
typedef struct { struct tag_options {
const char *message; const char *message;
const char *pattern; const char *pattern;
const char *tag_name; const char *tag_name;
const char *target; const char *target;
int num_lines; int num_lines;
int force; int force;
} tag_options; };
/** tag_state represents the current program state for dragging around */ /** tag_state represents the current program state for dragging around */
typedef struct { typedef struct {
git_repository *repo; git_repository *repo;
tag_options *opts; struct tag_options *opts;
} tag_state; } tag_state;
/** An action to execute based on the command line arguments */ /** An action to execute based on the command line arguments */
...@@ -167,7 +167,7 @@ static void action_list_tags(tag_state *state) ...@@ -167,7 +167,7 @@ static void action_list_tags(tag_state *state)
static void action_delete_tag(tag_state *state) static void action_delete_tag(tag_state *state)
{ {
tag_options *opts = state->opts; struct tag_options *opts = state->opts;
git_object *obj; git_object *obj;
git_buf abbrev_oid = {0}; git_buf abbrev_oid = {0};
...@@ -191,7 +191,7 @@ static void action_delete_tag(tag_state *state) ...@@ -191,7 +191,7 @@ static void action_delete_tag(tag_state *state)
static void action_create_lighweight_tag(tag_state *state) static void action_create_lighweight_tag(tag_state *state)
{ {
git_repository *repo = state->repo; git_repository *repo = state->repo;
tag_options *opts = state->opts; struct tag_options *opts = state->opts;
git_oid oid; git_oid oid;
git_object *target; git_object *target;
...@@ -213,7 +213,7 @@ static void action_create_lighweight_tag(tag_state *state) ...@@ -213,7 +213,7 @@ static void action_create_lighweight_tag(tag_state *state)
static void action_create_tag(tag_state *state) static void action_create_tag(tag_state *state)
{ {
git_repository *repo = state->repo; git_repository *repo = state->repo;
tag_options *opts = state->opts; struct tag_options *opts = state->opts;
git_signature *tagger; git_signature *tagger;
git_oid oid; git_oid oid;
git_object *target; git_object *target;
...@@ -243,7 +243,7 @@ static void print_usage(void) ...@@ -243,7 +243,7 @@ static void print_usage(void)
} }
/** Parse command line arguments and choose action to run when done */ /** Parse command line arguments and choose action to run when done */
static void parse_options(tag_action *action, tag_options *opts, int argc, char **argv) static void parse_options(tag_action *action, struct tag_options *opts, int argc, char **argv)
{ {
args_info args = ARGS_INFO_INIT; args_info args = ARGS_INFO_INIT;
*action = &action_list_tags; *action = &action_list_tags;
...@@ -281,7 +281,7 @@ static void parse_options(tag_action *action, tag_options *opts, int argc, char ...@@ -281,7 +281,7 @@ static void parse_options(tag_action *action, tag_options *opts, int argc, char
} }
/** Initialize tag_options struct */ /** Initialize tag_options struct */
static void tag_options_init(tag_options *opts) static void tag_options_init(struct tag_options *opts)
{ {
memset(opts, 0, sizeof(*opts)); memset(opts, 0, sizeof(*opts));
...@@ -295,7 +295,7 @@ static void tag_options_init(tag_options *opts) ...@@ -295,7 +295,7 @@ static void tag_options_init(tag_options *opts)
int lg2_tag(git_repository *repo, int argc, char **argv) int lg2_tag(git_repository *repo, int argc, char **argv)
{ {
tag_options opts; struct tag_options opts;
tag_action action; tag_action action;
tag_state state; tag_state state;
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include "apply.h" #include "apply.h"
#include <assert.h>
#include "git2/apply.h" #include "git2/apply.h"
#include "git2/patch.h" #include "git2/patch.h"
#include "git2/filter.h" #include "git2/filter.h"
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include "checkout.h" #include "checkout.h"
#include <assert.h>
#include "git2/repository.h" #include "git2/repository.h"
#include "git2/refs.h" #include "git2/refs.h"
#include "git2/tree.h" #include "git2/tree.h"
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include "clone.h" #include "clone.h"
#include <assert.h>
#include "git2/clone.h" #include "git2/clone.h"
#include "git2/remote.h" #include "git2/remote.h"
#include "git2/revparse.h" #include "git2/revparse.h"
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include "common.h" #include "common.h"
#include <assert.h>
#include "buffer.h" #include "buffer.h"
#include "tree.h" #include "tree.h"
#include "refdb.h" #include "refdb.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment