Example #1
0
static PyObject* Row_repr(PyObject* o)
{
    Row* self = (Row*)o;

    if (self->cValues == 0)
        return PyString_FromString("()");

    Object pieces(PyTuple_New(self->cValues));
    if (!pieces)
        return 0;

    Py_ssize_t length = 2 + (2 * (self->cValues-1)); // parens + ', ' separators

    for (Py_ssize_t i = 0; i < self->cValues; i++)
    {
        PyObject* piece = PyObject_Repr(self->apValues[i]);
        if (!piece)
            return 0;

        length += Text_Size(piece);

        PyTuple_SET_ITEM(pieces.Get(), i, piece);
    }

    if (self->cValues == 1)
    {
        // Need a trailing comma: (value,)
        length += 2;
    }

    PyObject* result = Text_New(length);
    if (!result)
        return 0;
    TEXT_T* buffer = Text_Buffer(result);
    Py_ssize_t offset = 0;
    buffer[offset++] = '(';
    for (Py_ssize_t i = 0; i < self->cValues; i++)
    {
        PyObject* item = PyTuple_GET_ITEM(pieces.Get(), i);
        memcpy(&buffer[offset], Text_Buffer(item), Text_Size(item) * sizeof(TEXT_T));
        offset += Text_Size(item);

        if (i != self->cValues-1 || self->cValues == 1)
        {
            buffer[offset++] = ',';
            buffer[offset++] = ' ';
        }
    }
    buffer[offset++] = ')';

    I(offset == length);

    return result;
}
Example #2
0
static PyObject *py_sorted_tree_items(PyObject *self, PyObject *args)
{
	struct tree_item *qsort_entries = NULL;
	int name_order, num_entries, n = 0, i;
	PyObject *entries, *py_name_order, *ret, *key, *value, *py_mode, *py_sha;
	Py_ssize_t pos = 0;
	int (*cmp)(const void *, const void *);

	if (!PyArg_ParseTuple(args, "OO", &entries, &py_name_order))
		goto error;

	if (!PyDict_Check(entries)) {
		PyErr_SetString(PyExc_TypeError, "Argument not a dictionary");
		goto error;
	}

	name_order = PyObject_IsTrue(py_name_order);
	if (name_order == -1)
		goto error;
	cmp = name_order ? cmp_tree_item_name_order : cmp_tree_item;

	num_entries = PyDict_Size(entries);
	if (PyErr_Occurred())
		goto error;
	qsort_entries = PyMem_New(struct tree_item, num_entries);
	if (!qsort_entries) {
		PyErr_NoMemory();
		goto error;
	}

	while (PyDict_Next(entries, &pos, &key, &value)) {
		if (!Text_Check(key)) {
			PyErr_SetString(PyExc_TypeError, "Name is not a string");
			goto error;
		}

		if (PyTuple_Size(value) != 2) {
			PyErr_SetString(PyExc_ValueError, "Tuple has invalid size");
			goto error;
		}

		py_mode = PyTuple_GET_ITEM(value, 0);
		if (!PyInt_Check(py_mode)) {
			PyErr_SetString(PyExc_TypeError, "Mode is not an integral type");
			goto error;
		}

		py_sha = PyTuple_GET_ITEM(value, 1);
		if (!Text_Check(py_sha)) {
			PyErr_SetString(PyExc_TypeError, "SHA is not a string");
			goto error;
		}
		qsort_entries[n].name = Text_Buffer(key);
		qsort_entries[n].mode = PyInt_AS_LONG(py_mode);

		qsort_entries[n].tuple = PyObject_CallFunctionObjArgs(
		                tree_entry_cls, key, py_mode, py_sha, NULL);
		if (qsort_entries[n].tuple == NULL)
			goto error;
		n++;
	}

	qsort(qsort_entries, num_entries, sizeof(struct tree_item), cmp);

	ret = PyList_New(num_entries);
	if (ret == NULL) {
		PyErr_NoMemory();
		goto error;
	}

	for (i = 0; i < num_entries; i++) {
		PyList_SET_ITEM(ret, i, qsort_entries[i].tuple);
	}
	PyMem_Free(qsort_entries);
	return ret;

error:
	for (i = 0; i < n; i++) {
		Py_XDECREF(qsort_entries[i].tuple);
	}
	PyMem_Free(qsort_entries);
	return NULL;
}