-/*
+/*
* Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License or (at your option) a later version of the License.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#include <stdlib.h>
#include <sys/stat.h>
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+#ifdef __MINGW32_VERSION
+size_t strnlen(char *text, size_t maxlen)
+{
+ const char *last = memchr(text, '\0', maxlen);
+ return last ? (size_t) (last - text) : maxlen;
+}
+#endif
+
#define bytehex(x) (((x)<0xa)?('0'+(x)):('a'-0xa+(x)))
static PyObject *sha_to_pyhex(const unsigned char *sha)
hexsha[i*2] = bytehex((sha[i] & 0xF0) >> 4);
hexsha[i*2+1] = bytehex(sha[i] & 0x0F);
}
-
+
return PyString_FromStringAndSize(hexsha, 40);
}
common = strlen(b->name);
remain_a = a->name + common;
remain_b = (S_ISDIR(b->mode)?"/":"");
- } else if (strlen(b->name) > strlen(a->name)) {
+ } else if (strlen(b->name) > strlen(a->name)) {
common = strlen(a->name);
remain_a = (S_ISDIR(a->mode)?"/":"");
remain_b = b->name + common;
return strcmp(remain_a, remain_b);
}
+static void free_tree_items(struct tree_item *items, int num) {
+ int i;
+ for (i = 0; i < num; i++) {
+ Py_DECREF(items[i].tuple);
+ }
+ free(items);
+}
+
static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries)
{
struct tree_item *qsort_entries;
int num, i;
PyObject *ret;
- Py_ssize_t pos = 0;
+ Py_ssize_t pos = 0;
PyObject *key, *value;
if (!PyDict_Check(entries)) {
i = 0;
while (PyDict_Next(entries, &pos, &key, &value)) {
- PyObject *py_mode, *py_sha;
-
+ PyObject *py_mode, *py_int_mode, *py_sha;
+
+ if (!PyString_Check(key)) {
+ PyErr_SetString(PyExc_TypeError, "Name is not a string");
+ free_tree_items(qsort_entries, i);
+ return NULL;
+ }
+
if (PyTuple_Size(value) != 2) {
PyErr_SetString(PyExc_ValueError, "Tuple has invalid size");
- free(qsort_entries);
+ free_tree_items(qsort_entries, i);
return NULL;
}
py_mode = PyTuple_GET_ITEM(value, 0);
- py_sha = PyTuple_GET_ITEM(value, 1);
- qsort_entries[i].tuple = Py_BuildValue("(OOO)", key, py_mode, py_sha);
- if (!PyString_CheckExact(key)) {
- PyErr_SetString(PyExc_TypeError, "Name is not a string");
- free(qsort_entries);
+ py_int_mode = PyNumber_Int(py_mode);
+ if (!py_int_mode) {
+ PyErr_SetString(PyExc_TypeError, "Mode is not an integral type");
+ free_tree_items(qsort_entries, i);
return NULL;
}
- qsort_entries[i].name = PyString_AS_STRING(key);
- if (!PyInt_CheckExact(py_mode)) {
- PyErr_SetString(PyExc_TypeError, "Mode is not an int");
- free(qsort_entries);
+
+ py_sha = PyTuple_GET_ITEM(value, 1);
+ if (!PyString_Check(py_sha)) {
+ PyErr_SetString(PyExc_TypeError, "SHA is not a string");
+ Py_DECREF(py_int_mode);
+ free_tree_items(qsort_entries, i);
return NULL;
}
+ qsort_entries[i].name = PyString_AS_STRING(key);
qsort_entries[i].mode = PyInt_AS_LONG(py_mode);
+ qsort_entries[i].tuple = PyTuple_Pack(3, key, py_int_mode, py_sha);
+ Py_DECREF(py_int_mode);
i++;
}
ret = PyList_New(num);
if (ret == NULL) {
- free(qsort_entries);
+ free_tree_items(qsort_entries, i);
PyErr_NoMemory();
return NULL;
}