static PyObject *py_parse_tree(PyObject *self, PyObject *args) { char *text, *end; int len, namelen; PyObject *ret, *item, *name; if (!PyArg_ParseTuple(args, "s#", &text, &len)) return NULL; ret = PyDict_New(); if (ret == NULL) { return NULL; } end = text + len; while (text < end) { long mode; mode = strtol(text, &text, 8); if (*text != ' ') { PyErr_SetString(PyExc_RuntimeError, "Expected space"); Py_DECREF(ret); return NULL; } text++; namelen = strlen(text); name = PyString_FromStringAndSize(text, namelen); if (name == NULL) { Py_DECREF(ret); return NULL; } item = Py_BuildValue("(lN)", mode, sha_to_pyhex((unsigned char *)text+namelen+1)); if (item == NULL) { Py_DECREF(ret); Py_DECREF(name); return NULL; } if (PyDict_SetItem(ret, name, item) == -1) { Py_DECREF(ret); Py_DECREF(item); return NULL; } Py_DECREF(name); Py_DECREF(item); text += namelen+21; } return ret; }
static PyObject *py_sha_to_hex(PyObject *self, PyObject *py_sha) { if (!PyString_CheckExact(py_sha)) { PyErr_SetString(PyExc_TypeError, "sha is not a string"); return NULL; } if (PyString_Size(py_sha) != 20) { PyErr_SetString(PyExc_ValueError, "sha is not 20 bytes long"); return NULL; } return sha_to_pyhex((unsigned char *)PyString_AsString(py_sha)); }
static PyObject *py_parse_tree(PyObject *self, PyObject *args) { char *text, *start, *end; int len, namelen; PyObject *ret, *item, *name; if (!PyArg_ParseTuple(args, "s#", &text, &len)) return NULL; /* TODO: currently this returns a list; if memory usage is a concern, * consider rewriting as a custom iterator object */ ret = PyList_New(0); if (ret == NULL) { return NULL; } start = text; end = text + len; while (text < end) { long mode; mode = strtol(text, &text, 8); if (*text != ' ') { PyErr_SetString(PyExc_ValueError, "Expected space"); Py_DECREF(ret); return NULL; } text++; namelen = strnlen(text, len - (text - start)); name = PyString_FromStringAndSize(text, namelen); if (name == NULL) { Py_DECREF(ret); return NULL; } if (text + namelen + 20 >= end) { PyErr_SetString(PyExc_ValueError, "SHA truncated"); Py_DECREF(ret); Py_DECREF(name); return NULL; } item = Py_BuildValue("(NlN)", name, mode, sha_to_pyhex((unsigned char *)text+namelen+1)); if (item == NULL) { Py_DECREF(ret); Py_DECREF(name); return NULL; } if (PyList_Append(ret, item) == -1) { Py_DECREF(ret); Py_DECREF(item); return NULL; } Py_DECREF(item); text += namelen+21; } return ret; }
static PyObject *py_parse_tree(PyObject *self, PyObject *args, PyObject *kw) { char *text, *start, *end; int len, namelen, strict; PyObject *ret, *item, *name, *sha, *py_strict = NULL; static char *kwlist[] = {"text", "strict", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|O", kwlist, &text, &len, &py_strict)) return NULL; strict = py_strict ? PyObject_IsTrue(py_strict) : 0; /* TODO: currently this returns a list; if memory usage is a concern, * consider rewriting as a custom iterator object */ ret = PyList_New(0); if (ret == NULL) { return NULL; } start = text; end = text + len; while (text < end) { long mode; if (strict && text[0] == '0') { PyErr_SetString(object_format_exception_cls, "Illegal leading zero on mode"); Py_DECREF(ret); return NULL; } mode = strtol(text, &text, 8); if (*text != ' ') { PyErr_SetString(PyExc_ValueError, "Expected space"); Py_DECREF(ret); return NULL; } text++; namelen = strnlen(text, len - (text - start)); name = PyString_FromStringAndSize(text, namelen); if (name == NULL) { Py_DECREF(ret); return NULL; } if (text + namelen + 20 >= end) { PyErr_SetString(PyExc_ValueError, "SHA truncated"); Py_DECREF(ret); Py_DECREF(name); return NULL; } sha = sha_to_pyhex((unsigned char *)text+namelen+1); if (sha == NULL) { Py_DECREF(ret); Py_DECREF(name); return NULL; } item = Py_BuildValue("(NlN)", name, mode, sha); if (item == NULL) { Py_DECREF(ret); Py_DECREF(sha); Py_DECREF(name); return NULL; } if (PyList_Append(ret, item) == -1) { Py_DECREF(ret); Py_DECREF(item); return NULL; } Py_DECREF(item); text += namelen+21; } return ret; }