Signed-off-by: Felipe Contreras <[email protected]>
---
Notes:
This time we use an initializer and alloc function, so we could do:
ri = Git::RevInfo.new()
ri.setup(args)
Or:
ri = Git::RevInfo.setup(args)
The effect is the same.
Also, we use the extremely useful 'method_missing' method, which allows us
to
do the binding at run-time, saving us precious finger typing time and code,
with price of a bit of performance loss, which is not that important in a
script like this.
We could do something fancier like saving the Ruby internal identifiers in
an
array to map them to a C enum, or we could even generate the missing
methods at
run-time, but for now let's stick to the simpler option and just make it
work
with the less possible code.
ruby.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/ruby.c b/ruby.c
index 360515f..d9ee985 100644
--- a/ruby.c
+++ b/ruby.c
@@ -5,6 +5,8 @@
#include "commit.h"
#include "remote.h"
#include "transport.h"
+#include "revision.h"
+#include "diff.h"
#undef NORETURN
#undef PATH_SEP
@@ -17,6 +19,8 @@ static VALUE git_rb_commit_list;
static VALUE git_rb_remote;
static VALUE git_rb_transport;
static VALUE git_rb_ref;
+static VALUE git_rb_rev_info;
+static VALUE git_rb_diff_opt;
static inline VALUE sha1_to_str(const unsigned char *sha1)
{
@@ -277,6 +281,107 @@ static VALUE git_rb_read_sha1_file(VALUE self, VALUE
sha1, VALUE type)
return rb_ary_new3(2, rb_str_new(buffer, size), INT2FIX(g_type));
}
+static VALUE git_rb_rev_info_alloc(VALUE class)
+{
+ struct rev_info *revs;
+ return Data_Make_Struct(class, struct rev_info, NULL, free, revs);
+}
+
+static VALUE git_rb_rev_info_init(VALUE self, VALUE prefix)
+{
+ struct rev_info *revs;
+ Data_Get_Struct(self, struct rev_info, revs);
+ init_revisions(revs, str_to_cstr(prefix));
+ return self;
+}
+
+static VALUE git_rb_rev_info_setup(VALUE self, VALUE args, VALUE opts)
+{
+ struct rev_info *revs;
+ const char *argv[RARRAY_LEN(args) + 2];
+ int i, r;
+
+ argv[0] = "";
+ Data_Get_Struct(self, struct rev_info, revs);
+ for (i = 0; i < RARRAY_LEN(args); i++)
+ argv[i + 1] = RSTRING_PTR(RARRAY_PTR(args)[i]);
+ argv[i + 1] = NULL;
+ r = setup_revisions(RARRAY_LEN(args) + 1, argv, revs, NULL);
+ return INT2FIX(r - 1);
+}
+
+static VALUE git_rb_rev_info_single_setup(VALUE class, VALUE prefix, VALUE
args, VALUE opts)
+{
+ struct rev_info *revs;
+ VALUE self;
+ self = Data_Make_Struct(class, struct rev_info, NULL, free, revs);
+ init_revisions(revs, str_to_cstr(prefix));
+ git_rb_rev_info_setup(self, args, opts);
+ return self;
+}
+
+static VALUE git_rb_rev_info_each_revision(VALUE self, VALUE args, VALUE opts)
+{
+ struct commit *commit;
+ struct rev_info *revs;
+
+ Data_Get_Struct(self, struct rev_info, revs);
+ if (prepare_revision_walk(revs))
+ return Qnil;
+ while ((commit = get_revision(revs))) {
+ VALUE c;
+ c = Data_Wrap_Struct(git_rb_commit, NULL, NULL, commit);
+ rb_yield(c);
+ }
+ return Qnil;
+}
+
+static VALUE git_rb_rev_info_diffopt(VALUE self)
+{
+ struct rev_info *revs;
+
+ Data_Get_Struct(self, struct rev_info, revs);
+ return Data_Wrap_Struct(git_rb_diff_opt, NULL, NULL, &revs->diffopt);
+}
+
+static VALUE git_rb_diff_opt_new(VALUE class)
+{
+ struct diff_options *opt;
+ VALUE self;
+ self = Data_Make_Struct(class, struct diff_options, NULL, free, opt);
+
+ diff_setup(opt);
+
+ return self;
+}
+
+static VALUE git_rb_diff_opt_method_missing(int argc, VALUE *argv, VALUE self)
+{
+ struct diff_options *opt;
+ ID id;
+
+ id = rb_to_id(argv[0]);
+ Data_Get_Struct(self, struct diff_options, opt);
+
+ if (id == rb_intern("stat_width="))
+ opt->stat_width = NUM2INT(argv[1]);
+ else if (id == rb_intern("stat_graph_width="))
+ opt->stat_graph_width = NUM2INT(argv[1]);
+ else if (id == rb_intern("output_format="))
+ opt->output_format = NUM2INT(argv[1]);
+ else if (id == rb_intern("detect_rename="))
+ opt->detect_rename = NUM2INT(argv[1]);
+ else if (id == rb_intern("flags="))
+ opt->flags = NUM2INT(argv[1]);
+ else if (id == rb_intern("output_format"))
+ return INT2FIX(opt->output_format);
+ else if (id == rb_intern("flags"))
+ return INT2FIX(opt->flags);
+ else
+ return rb_call_super(argc, argv);
+ return Qnil;
+}
+
static void git_ruby_init(void)
{
VALUE mod;
@@ -296,6 +401,53 @@ static void git_ruby_init(void)
rb_define_global_const("DEFAULT_ABBREV", INT2FIX(DEFAULT_ABBREV));
+ rb_define_global_const("DIFF_FORMAT_RAW", INT2FIX(DIFF_FORMAT_RAW));
+ rb_define_global_const("DIFF_FORMAT_DIFFSTAT",
INT2FIX(DIFF_FORMAT_DIFFSTAT));
+ rb_define_global_const("DIFF_FORMAT_NUMSTAT",
INT2FIX(DIFF_FORMAT_NUMSTAT));
+ rb_define_global_const("DIFF_FORMAT_SUMMARY",
INT2FIX(DIFF_FORMAT_SUMMARY));
+ rb_define_global_const("DIFF_FORMAT_PATCH", INT2FIX(DIFF_FORMAT_PATCH));
+ rb_define_global_const("DIFF_FORMAT_SHORTSTAT",
INT2FIX(DIFF_FORMAT_SHORTSTAT));
+ rb_define_global_const("DIFF_FORMAT_DIRSTAT",
INT2FIX(DIFF_FORMAT_DIRSTAT));
+ rb_define_global_const("DIFF_FORMAT_NAME", INT2FIX(DIFF_FORMAT_NAME));
+ rb_define_global_const("DIFF_FORMAT_NAME_STATUS",
INT2FIX(DIFF_FORMAT_NAME_STATUS));
+ rb_define_global_const("DIFF_FORMAT_CHECKDIFF",
INT2FIX(DIFF_FORMAT_CHECKDIFF));
+ rb_define_global_const("DIFF_FORMAT_NO_OUTPUT",
INT2FIX(DIFF_FORMAT_NO_OUTPUT));
+ rb_define_global_const("DIFF_FORMAT_CALLBACK",
INT2FIX(DIFF_FORMAT_CALLBACK));
+
+ rb_define_global_const("DIFF_DETECT_RENAME",
INT2FIX(DIFF_DETECT_RENAME));
+ rb_define_global_const("DIFF_DETECT_COPY", INT2FIX(DIFF_DETECT_COPY));
+
+ rb_define_global_const("DIFF_OPT_RECURSIVE",
INT2FIX(DIFF_OPT_RECURSIVE));
+ rb_define_global_const("DIFF_OPT_TREE_IN_RECURSIVE",
INT2FIX(DIFF_OPT_TREE_IN_RECURSIVE));
+ rb_define_global_const("DIFF_OPT_BINARY", INT2FIX(DIFF_OPT_BINARY));
+ rb_define_global_const("DIFF_OPT_TEXT", INT2FIX(DIFF_OPT_TEXT));
+ rb_define_global_const("DIFF_OPT_FULL_INDEX",
INT2FIX(DIFF_OPT_FULL_INDEX));
+ rb_define_global_const("DIFF_OPT_SILENT_ON_REMOVE",
INT2FIX(DIFF_OPT_SILENT_ON_REMOVE));
+ rb_define_global_const("DIFF_OPT_FIND_COPIES_HARDER",
INT2FIX(DIFF_OPT_FIND_COPIES_HARDER));
+ rb_define_global_const("DIFF_OPT_FOLLOW_RENAMES",
INT2FIX(DIFF_OPT_FOLLOW_RENAMES));
+ rb_define_global_const("DIFF_OPT_RENAME_EMPTY",
INT2FIX(DIFF_OPT_RENAME_EMPTY));
+ rb_define_global_const("DIFF_OPT_HAS_CHANGES",
INT2FIX(DIFF_OPT_HAS_CHANGES));
+ rb_define_global_const("DIFF_OPT_QUICK", INT2FIX(DIFF_OPT_QUICK));
+ rb_define_global_const("DIFF_OPT_NO_INDEX", INT2FIX(DIFF_OPT_NO_INDEX));
+ rb_define_global_const("DIFF_OPT_ALLOW_EXTERNAL",
INT2FIX(DIFF_OPT_ALLOW_EXTERNAL));
+ rb_define_global_const("DIFF_OPT_EXIT_WITH_STATUS",
INT2FIX(DIFF_OPT_EXIT_WITH_STATUS));
+ rb_define_global_const("DIFF_OPT_REVERSE_DIFF",
INT2FIX(DIFF_OPT_REVERSE_DIFF));
+ rb_define_global_const("DIFF_OPT_CHECK_FAILED",
INT2FIX(DIFF_OPT_CHECK_FAILED));
+ rb_define_global_const("DIFF_OPT_RELATIVE_NAME",
INT2FIX(DIFF_OPT_RELATIVE_NAME));
+ rb_define_global_const("DIFF_OPT_IGNORE_SUBMODULES",
INT2FIX(DIFF_OPT_IGNORE_SUBMODULES));
+ rb_define_global_const("DIFF_OPT_DIRSTAT_CUMULATIVE",
INT2FIX(DIFF_OPT_DIRSTAT_CUMULATIVE));
+ rb_define_global_const("DIFF_OPT_DIRSTAT_BY_FILE",
INT2FIX(DIFF_OPT_DIRSTAT_BY_FILE));
+ rb_define_global_const("DIFF_OPT_ALLOW_TEXTCONV",
INT2FIX(DIFF_OPT_ALLOW_TEXTCONV));
+ rb_define_global_const("DIFF_OPT_DIFF_FROM_CONTENTS",
INT2FIX(DIFF_OPT_DIFF_FROM_CONTENTS));
+ rb_define_global_const("DIFF_OPT_SUBMODULE_LOG",
INT2FIX(DIFF_OPT_SUBMODULE_LOG));
+ rb_define_global_const("DIFF_OPT_DIRTY_SUBMODULES",
INT2FIX(DIFF_OPT_DIRTY_SUBMODULES));
+ rb_define_global_const("DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES",
INT2FIX(DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES));
+ rb_define_global_const("DIFF_OPT_IGNORE_DIRTY_SUBMODULES",
INT2FIX(DIFF_OPT_IGNORE_DIRTY_SUBMODULES));
+ rb_define_global_const("DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG",
INT2FIX(DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG));
+ rb_define_global_const("DIFF_OPT_DIRSTAT_BY_LINE",
INT2FIX(DIFF_OPT_DIRSTAT_BY_LINE));
+ rb_define_global_const("DIFF_OPT_FUNCCONTEXT",
INT2FIX(DIFF_OPT_FUNCCONTEXT));
+ rb_define_global_const("DIFF_OPT_PICKAXE_IGNORE_CASE",
INT2FIX(DIFF_OPT_PICKAXE_IGNORE_CASE));
+
rb_define_global_function("setup_git_directory",
git_rb_setup_git_directory, 0);
rb_define_global_function("for_each_ref", git_rb_for_each_ref, 0);
rb_define_global_function("dwim_ref", git_rb_dwim_ref, 1);
@@ -334,6 +486,19 @@ static void git_ruby_init(void)
rb_define_method(git_rb_ref, "each", git_rb_ref_each, 0);
rb_define_method(git_rb_ref, "name", git_rb_ref_name, 0);
rb_define_method(git_rb_ref, "old_sha1", git_rb_ref_old_sha1, 0);
+
+ git_rb_rev_info = rb_define_class_under(mod, "RevInfo", rb_cData);
+ rb_include_module(git_rb_rev_info, rb_mEnumerable);
+ rb_define_alloc_func(git_rb_rev_info, git_rb_rev_info_alloc);
+ rb_define_method(git_rb_rev_info, "initialize", git_rb_rev_info_init,
1);
+ rb_define_singleton_method(git_rb_rev_info, "setup",
git_rb_rev_info_single_setup, 3);
+ rb_define_method(git_rb_rev_info, "setup", git_rb_rev_info_setup, 2);
+ rb_define_method(git_rb_rev_info, "each",
git_rb_rev_info_each_revision, 0);
+ rb_define_method(git_rb_rev_info, "diffopt", git_rb_rev_info_diffopt,
0);
+
+ git_rb_diff_opt = rb_define_class_under(mod, "DiffOptions", rb_cData);
+ rb_define_singleton_method(git_rb_diff_opt, "new", git_rb_diff_opt_new,
0);
+ rb_define_method(git_rb_diff_opt, "method_missing",
git_rb_diff_opt_method_missing, -1);
}
static int run_ruby_command(const char *cmd, int argc, const char **argv)
--
1.8.4-fc
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html