Merge remote-tracking branch 'delanne/memleak'

This commit is contained in:
J. David Ibáñez 2012-11-14 17:54:00 +01:00
commit 2ac913244d
6 changed files with 98 additions and 41 deletions

@ -57,9 +57,16 @@ OBJECT_STRUCT(Blob, git_blob, blob)
OBJECT_STRUCT(Tag, git_tag, tag) OBJECT_STRUCT(Tag, git_tag, tag)
OBJECT_STRUCT(Index, git_index, index) OBJECT_STRUCT(Index, git_index, index)
OBJECT_STRUCT(Walker, git_revwalk, walk) OBJECT_STRUCT(Walker, git_revwalk, walk)
OBJECT_STRUCT(Diff, git_diff_list, diff)
OBJECT_STRUCT(Config, git_config, config) OBJECT_STRUCT(Config, git_config, config)
typedef struct {
PyObject_HEAD
Repository *repo;
git_diff_list *diff;
PyObject *diff_changes;
} Diff;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
PyObject *owner; /* Tree or TreeBuilder */ PyObject *owner; /* Tree or TreeBuilder */

@ -139,7 +139,7 @@ Config_contains(Config *self, PyObject *py_key) {
return -1; return -1;
err = git_config_get_string(&c_value, self->config, c_key); err = git_config_get_string(&c_value, self->config, c_key);
free(c_key);
if (err == GIT_ENOTFOUND) if (err == GIT_ENOTFOUND)
return 0; return 0;
if (err < 0) { if (err < 0) {
@ -164,15 +164,18 @@ Config_getitem(Config *self, PyObject *py_key)
err = git_config_get_int64(&c_intvalue, self->config, c_key); err = git_config_get_int64(&c_intvalue, self->config, c_key);
if (err == GIT_OK) { if (err == GIT_OK) {
free(c_key);
return PyInt_FromLong((long)c_intvalue); return PyInt_FromLong((long)c_intvalue);
} }
err = git_config_get_bool(&c_boolvalue, self->config, c_key); err = git_config_get_bool(&c_boolvalue, self->config, c_key);
if (err == GIT_OK) { if (err == GIT_OK) {
free(c_key);
return PyBool_FromLong((long)c_boolvalue); return PyBool_FromLong((long)c_boolvalue);
} }
err = git_config_get_string(&c_charvalue, self->config, c_key); err = git_config_get_string(&c_charvalue, self->config, c_key);
free(c_key);
if (err < 0) { if (err < 0) {
if (err == GIT_ENOTFOUND) { if (err == GIT_ENOTFOUND) {
PyErr_SetObject(PyExc_KeyError, py_key); PyErr_SetObject(PyExc_KeyError, py_key);
@ -189,6 +192,7 @@ Config_setitem(Config *self, PyObject *py_key, PyObject *py_value)
{ {
int err; int err;
const char *c_key; const char *c_key;
const char *py_str;
if (!(c_key = py_str_to_c_str(py_key,NULL))) if (!(c_key = py_str_to_c_str(py_key,NULL)))
return -1; return -1;
@ -203,9 +207,13 @@ Config_setitem(Config *self, PyObject *py_key, PyObject *py_value)
(int64_t)PyInt_AsLong(py_value)); (int64_t)PyInt_AsLong(py_value));
} else { } else {
py_value = PyObject_Str(py_value); py_value = PyObject_Str(py_value);
py_str = py_str_to_c_str(py_value,NULL);
err = git_config_set_string(self->config, c_key, err = git_config_set_string(self->config, c_key,
py_str_to_c_str(py_value,NULL)); py_str);
free(py_str);
} }
free(c_key);
if (err < 0) { if (err < 0) {
Error_set(err); Error_set(err);
return -1; return -1;

@ -48,7 +48,7 @@ static int diff_data_cb(
const char *content, const char *content,
size_t content_len) size_t content_len)
{ {
PyObject *hunks, *data, *tmp; PyObject *hunks, *data;
Hunk *hunk; Hunk *hunk;
Py_ssize_t size; Py_ssize_t size;
@ -61,14 +61,12 @@ static int diff_data_cb(
if (hunk == NULL) if (hunk == NULL)
return -1; return -1;
tmp = PyBytes_FromStringAndSize(content, content_len); data = Py_BuildValue("(s#,i)",
content, content_len,
data = Py_BuildValue("(O,i)",
tmp,
line_origin line_origin
); );
PyList_Append(hunk->data, data); PyList_Append(hunk->data, data);
Py_DECREF(data);
return 0; return 0;
} }
@ -91,6 +89,7 @@ static int diff_hunk_cb(
if (hunks == NULL) { if (hunks == NULL) {
hunks = PyList_New(0); hunks = PyList_New(0);
PyDict_SetItemString(cb_data, "hunks", hunks); PyDict_SetItemString(cb_data, "hunks", hunks);
Py_DECREF(hunks);
} }
hunk = (Hunk*)PyType_GenericNew(&HunkType, NULL, NULL); hunk = (Hunk*)PyType_GenericNew(&HunkType, NULL, NULL);
@ -125,6 +124,7 @@ static int diff_hunk_cb(
old_path = malloc(sizeof(char) * len); old_path = malloc(sizeof(char) * len);
if (old_path == NULL) { if (old_path == NULL) {
free(hunk->header); free(hunk->header);
hunk->header = NULL;
return -1; return -1;
} }
@ -153,7 +153,12 @@ static int diff_hunk_cb(
hunk->data = PyList_New(0); hunk->data = PyList_New(0);
} }
PyList_Append(hunks, (PyObject *)hunk); if(PyList_Append(hunks, (PyObject *)hunk) == 0) {
Py_DECREF(hunk);
}
else {
return -1;
}
return 0; return 0;
}; };
@ -169,6 +174,7 @@ static int diff_file_cb(void *cb_data, const git_diff_delta *delta,
if(files == NULL) { if(files == NULL) {
files = PyList_New(0); files = PyList_New(0);
PyDict_SetItemString(cb_data, "files", files); PyDict_SetItemString(cb_data, "files", files);
Py_DECREF(files);
} }
file = Py_BuildValue("(s,s,i)", file = Py_BuildValue("(s,s,i)",
@ -177,7 +183,10 @@ static int diff_file_cb(void *cb_data, const git_diff_delta *delta,
delta->status delta->status
); );
PyList_Append(files, file); if (PyList_Append(files, file) == 0) {
// If success
Py_DECREF(file);
}
} }
return 0; return 0;
@ -186,18 +195,20 @@ static int diff_file_cb(void *cb_data, const git_diff_delta *delta,
PyObject * PyObject *
Diff_changes(Diff *self) Diff_changes(Diff *self)
{ {
PyObject *payload;
payload = PyDict_New();
git_diff_foreach( if (self->diff_changes == NULL){
self->diff, self->diff_changes = PyDict_New();
payload,
&diff_file_cb, git_diff_foreach(
&diff_hunk_cb, self->diff,
&diff_data_cb self->diff_changes,
); &diff_file_cb,
&diff_hunk_cb,
&diff_data_cb
);
}
return payload; return PyDict_Copy(self->diff_changes);
} }
static int diff_print_cb( static int diff_print_cb(
@ -227,24 +238,42 @@ Diff_patch(Diff *self)
static int static int
Hunk_init(Hunk *self, PyObject *args, PyObject *kwds) Hunk_init(Hunk *self, PyObject *args, PyObject *kwds)
{ {
self->old_start = 0; self->header = NULL;
self->old_lines = 0;
self->old_file = NULL;
self->old_start = 0;
self->old_lines = 0;
self->new_start = 0; self->new_file = NULL;
self->new_lines = 0; self->new_start = 0;
self->new_lines = 0;
self->data = PyList_New(0); self->old_oid = NULL;
if (self->data == NULL) { self->new_oid = NULL;
Py_XDECREF(self);
return -1; self->data = PyList_New(0);
} if (self->data == NULL) {
Py_XDECREF(self);
return -1;
}
return 0; return 0;
} }
static void static void
Hunk_dealloc(Hunk *self) Hunk_dealloc(Hunk *self)
{ {
if (self->header != NULL) {
free(self->header);
}
if (self->new_file != NULL) {
free(self->new_file);
}
if (self->old_file != NULL) {
free(self->old_file);
}
Py_XDECREF(self->old_oid);
Py_XDECREF(self->new_oid);
Py_XDECREF(self->data); Py_XDECREF(self->data);
PyObject_Del(self); PyObject_Del(self);
} }
@ -321,6 +350,8 @@ Diff_merge(Diff *self, PyObject *args)
if (err < 0) if (err < 0)
return Error_set(err); return Error_set(err);
Py_XDECREF(self->diff_changes);
self->diff_changes = NULL;
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -329,6 +360,7 @@ Diff_dealloc(Diff *self)
{ {
git_diff_list_free(self->diff); git_diff_list_free(self->diff);
Py_XDECREF(self->repo); Py_XDECREF(self->repo);
Py_XDECREF(self->diff_changes);
PyObject_Del(self); PyObject_Del(self);
} }

@ -214,6 +214,7 @@ Index_get_position(Index *self, PyObject *value)
free(path); free(path);
return -1; return -1;
} }
free(path);
return idx; return idx;
} }
@ -227,14 +228,16 @@ Index_contains(Index *self, PyObject *value)
if (!path) if (!path)
return -1; return -1;
idx = git_index_find(self->index, path); idx = git_index_find(self->index, path);
if (idx == GIT_ENOTFOUND) if (idx == GIT_ENOTFOUND) {
free(path);
return 0; return 0;
}
if (idx < 0) { if (idx < 0) {
Error_set_str(idx, path); Error_set_str(idx, path);
free(path); free(path);
return -1; return -1;
} }
free(path);
return 1; return 1;
} }
@ -339,6 +342,7 @@ Index_read_tree(Index *self, PyObject *value)
return Error_set(err); return Error_set(err);
err = git_index_read_tree(self->index, tree); err = git_index_read_tree(self->index, tree);
git_tree_free(tree);
if (err < 0) if (err < 0)
return Error_set(err); return Error_set(err);

@ -166,6 +166,7 @@ Repository_head(Repository *self)
{ {
git_reference *head; git_reference *head;
const git_oid *oid; const git_oid *oid;
PyObject *pyobj;
int err; int err;
err = git_repository_head(&head, self->repo); err = git_repository_head(&head, self->repo);
@ -179,8 +180,9 @@ Repository_head(Repository *self)
} }
oid = git_reference_oid(head); oid = git_reference_oid(head);
pyobj = lookup_object(self, oid, GIT_OBJ_COMMIT);
return lookup_object(self, oid, GIT_OBJ_COMMIT); git_reference_free(head);
return pyobj;
} }
@ -202,7 +204,7 @@ Repository_revparse_single(Repository *self, PyObject *py_spec)
{ {
git_object *c_obj; git_object *c_obj;
char *c_spec; char *c_spec;
char *encoding = "ascii"; char *encoding = "ascii";
int err; int err;
/* 1- Get the C revision spec */ /* 1- Get the C revision spec */
@ -212,12 +214,14 @@ Repository_revparse_single(Repository *self, PyObject *py_spec)
/* 2- Lookup */ /* 2- Lookup */
err = git_revparse_single(&c_obj, self->repo, c_spec); err = git_revparse_single(&c_obj, self->repo, c_spec);
if (err < 0) { if (err < 0) {
PyObject *err_obj = Error_set_str(err, c_spec); PyObject *err_obj = Error_set_str(err, c_spec);
free(c_spec); free(c_spec);
return err_obj; return err_obj;
} }
free(c_spec);
return wrap_object(c_obj, self); return wrap_object(c_obj, self);
} }
@ -635,7 +639,7 @@ Repository_lookup_reference(Repository *self, PyObject *py_name)
free(c_name); free(c_name);
return err_obj; return err_obj;
} }
free(c_name);
/* 3- Make an instance of Reference and return it */ /* 3- Make an instance of Reference and return it */
return wrap_reference(c_reference); return wrap_reference(c_reference);
} }

@ -43,6 +43,7 @@ void
TreeEntry_dealloc(TreeEntry *self) TreeEntry_dealloc(TreeEntry *self)
{ {
Py_XDECREF(self->owner); Py_XDECREF(self->owner);
git_tree_entry_free(self->entry);
PyObject_Del(self); PyObject_Del(self);
} }
@ -231,7 +232,7 @@ Tree_getitem_by_index(Tree *self, PyObject *py_index)
PyErr_SetObject(PyExc_IndexError, py_index); PyErr_SetObject(PyExc_IndexError, py_index);
return NULL; return NULL;
} }
return wrap_tree_entry(entry, self); return wrap_tree_entry(git_tree_entry_dup(entry), self);
} }
TreeEntry * TreeEntry *
@ -261,6 +262,7 @@ Tree_getitem(Tree *self, PyObject *value)
if (err < 0) if (err < 0)
return (TreeEntry*)Error_set(err); return (TreeEntry*)Error_set(err);
// git_tree_entry_dup is already done in git_tree_entry_bypath
return wrap_tree_entry(entry, self); return wrap_tree_entry(entry, self);
} }
@ -305,10 +307,10 @@ Tree_diff_tree(Tree *self, PyObject *args)
py_diff = PyObject_New(Diff, &DiffType); py_diff = PyObject_New(Diff, &DiffType);
if (py_diff) { if (py_diff) {
Py_INCREF(py_diff);
Py_INCREF(self->repo); Py_INCREF(self->repo);
py_diff->repo = self->repo; py_diff->repo = self->repo;
py_diff->diff = diff; py_diff->diff = diff;
py_diff->diff_changes = NULL;
} }
return (PyObject*)py_diff; return (PyObject*)py_diff;
@ -527,7 +529,7 @@ TreeIter_iternext(TreeIter *self)
return NULL; return NULL;
self->i += 1; self->i += 1;
return (TreeEntry*)wrap_tree_entry(tree_entry, self->owner); return (TreeEntry*)wrap_tree_entry(git_tree_entry_dup(tree_entry), self->owner);
} }
PyTypeObject TreeIterType = { PyTypeObject TreeIterType = {