mercurial/parsers.c
author Greg Ward <greg-hg@gerg.ca>
Mon, 15 Feb 2010 15:25:29 -0500
branchstable
changeset 10505 b3311e26f94f
parent 10449 7c8266c1d15a
child 11361 3de3d670d2b6
permissions -rw-r--r--
merge: fix --preview to show all nodes that will be merged (issue2043). Formerly, it omitted nodes that were not descendants of the least common ancestor of the two merge parents, even though those nodes contribute to the merge. The new algorithm uses revlog.findmissing() instead of ancestor() + nodesbetween().
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     1
/*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     2
 parsers.c - efficient content parsing
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     3
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     4
 Copyright 2008 Matt Mackall <mpm@selenic.com> and others
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     5
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     6
 This software may be used and distributed according to the terms of
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     7
 the GNU General Public License, incorporated herein by reference.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     8
*/
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     9
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    10
#include <Python.h>
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    11
#include <ctype.h>
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    12
#include <string.h>
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    13
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    14
static int hexdigit(char c)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    15
{
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    16
	if (c >= '0' && c <= '9')
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    17
		return c - '0';
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    18
	if (c >= 'a' && c <= 'f')
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    19
		return c - 'a' + 10;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    20
	if (c >= 'A' && c <= 'F')
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    21
		return c - 'A' + 10;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    22
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    23
	PyErr_SetString(PyExc_ValueError, "input contains non-hex character");
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    24
	return 0;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    25
}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    26
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    27
/*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    28
 * Turn a hex-encoded string into binary.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    29
 */
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    30
static PyObject *unhexlify(const char *str, int len)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    31
{
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    32
	PyObject *ret;
6395
3f0294536b24 fix const annotation warning
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6389
diff changeset
    33
	const char *c;
3f0294536b24 fix const annotation warning
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6389
diff changeset
    34
	char *d;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    35
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    36
	ret = PyString_FromStringAndSize(NULL, len / 2);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    37
	if (!ret)
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    38
		return NULL;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    39
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    40
	d = PyString_AS_STRING(ret);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    41
	for (c = str; c < str + len;) {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    42
		int hi = hexdigit(*c++);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    43
		int lo = hexdigit(*c++);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    44
		*d++ = (hi << 4) | lo;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    45
	}
7091
12b35ae03365 parsers: clean up whitespace
Matt Mackall <mpm@selenic.com>
parents: 6395
diff changeset
    46
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    47
	return ret;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    48
}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    49
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    50
/*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    51
 * This code assumes that a manifest is stitched together with newline
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    52
 * ('\n') characters.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    53
 */
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    54
static PyObject *parse_manifest(PyObject *self, PyObject *args)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    55
{
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    56
	PyObject *mfdict, *fdict;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    57
	char *str, *cur, *start, *zero;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    58
	int len;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    59
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    60
	if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    61
			      &PyDict_Type, &mfdict,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    62
			      &PyDict_Type, &fdict,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    63
			      &str, &len))
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    64
		goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    65
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    66
	for (start = cur = str, zero = NULL; cur < str + len; cur++) {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    67
		PyObject *file = NULL, *node = NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    68
		PyObject *flags = NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    69
		int nlen;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    70
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    71
		if (!*cur) {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    72
			zero = cur;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    73
			continue;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    74
		}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    75
		else if (*cur != '\n')
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    76
			continue;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    77
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    78
		if (!zero) {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    79
			PyErr_SetString(PyExc_ValueError,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    80
					"manifest entry has no separator");
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    81
			goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    82
		}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    83
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    84
		file = PyString_FromStringAndSize(start, zero - start);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    85
		if (!file)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    86
			goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    87
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    88
		nlen = cur - zero - 1;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    89
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    90
		node = unhexlify(zero + 1, nlen > 40 ? 40 : nlen);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    91
		if (!node)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    92
			goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    93
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    94
		if (nlen > 40) {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    95
			flags = PyString_FromStringAndSize(zero + 41,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    96
							   nlen - 40);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    97
			if (!flags)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    98
				goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    99
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   100
			if (PyDict_SetItem(fdict, file, flags) == -1)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   101
				goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   102
		}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   103
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   104
		if (PyDict_SetItem(mfdict, file, node) == -1)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   105
			goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   106
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   107
		start = cur + 1;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   108
		zero = NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   109
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   110
		Py_XDECREF(flags);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   111
		Py_XDECREF(node);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   112
		Py_XDECREF(file);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   113
		continue;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   114
	bail:
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   115
		Py_XDECREF(flags);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   116
		Py_XDECREF(node);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   117
		Py_XDECREF(file);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   118
		goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   119
	}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   120
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   121
	if (len > 0 && *(cur - 1) != '\n') {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   122
		PyErr_SetString(PyExc_ValueError,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   123
				"manifest contains trailing garbage");
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   124
		goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   125
	}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   126
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   127
	Py_INCREF(Py_None);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   128
	return Py_None;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   129
quit:
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   130
	return NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   131
}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   132
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   133
#ifdef _WIN32
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   134
#ifdef _MSC_VER
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   135
/* msvc 6.0 has problems */
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   136
#define inline __inline
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   137
typedef unsigned long uint32_t;
7122
3cf699e89e48 Fix missing uint64_t definition in parsers.c under Windows
Dhruva Krishnamurthy <dhruvakm@gmail.com>
parents: 7108
diff changeset
   138
typedef unsigned __int64 uint64_t;
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   139
#else
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   140
#include <stdint.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   141
#endif
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   142
static uint32_t ntohl(uint32_t x)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   143
{
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   144
	return ((x & 0x000000ffUL) << 24) |
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   145
	       ((x & 0x0000ff00UL) <<  8) |
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   146
	       ((x & 0x00ff0000UL) >>  8) |
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   147
	       ((x & 0xff000000UL) >> 24);
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   148
}
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   149
#else
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   150
/* not windows */
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   151
#include <sys/types.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   152
#if defined __BEOS__ && !defined __HAIKU__
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   153
#include <ByteOrder.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   154
#else
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   155
#include <arpa/inet.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   156
#endif
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   157
#include <inttypes.h>
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   158
#endif
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   159
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   160
static PyObject *parse_dirstate(PyObject *self, PyObject *args)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   161
{
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   162
	PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   163
	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   164
	char *str, *cur, *end, *cpos;
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   165
	int state, mode, size, mtime;
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   166
	unsigned int flen;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   167
	int len;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   168
	char decode[16]; /* for alignment */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   169
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   170
	if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   171
			      &PyDict_Type, &dmap,
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   172
			      &PyDict_Type, &cmap,
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   173
			      &str, &len))
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   174
		goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   175
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   176
	/* read parents */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   177
	if (len < 40)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   178
		goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   179
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   180
	parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   181
	if (!parents)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   182
		goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   183
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   184
	/* read filenames */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   185
	cur = str + 40;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   186
	end = str + len;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   187
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   188
	while (cur < end - 17) {
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   189
		/* unpack header */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   190
		state = *cur;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   191
		memcpy(decode, cur + 1, 16);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   192
		mode = ntohl(*(uint32_t *)(decode));
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   193
		size = ntohl(*(uint32_t *)(decode + 4));
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   194
		mtime = ntohl(*(uint32_t *)(decode + 8));
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   195
		flen = ntohl(*(uint32_t *)(decode + 12));
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   196
		cur += 17;
10449
7c8266c1d15a parsers: fix some signed comparison issues
Matt Mackall <mpm@selenic.com>
parents: 10282
diff changeset
   197
		if (cur + flen > end || cur + flen < cur) {
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   198
			PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   199
			goto quit;
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   200
		}
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   201
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   202
		entry = Py_BuildValue("ciii", state, mode, size, mtime);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   203
		if (!entry)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   204
			goto quit;
7175
5d8626b2c1db parsers.c: do not try to untrack after a failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7174
diff changeset
   205
		PyObject_GC_UnTrack(entry); /* don't waste time with this */
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   206
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   207
		cpos = memchr(cur, 0, flen);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   208
		if (cpos) {
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   209
			fname = PyString_FromStringAndSize(cur, cpos - cur);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   210
			cname = PyString_FromStringAndSize(cpos + 1,
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   211
							   flen - (cpos - cur) - 1);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   212
			if (!fname || !cname ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   213
			    PyDict_SetItem(cmap, fname, cname) == -1 ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   214
			    PyDict_SetItem(dmap, fname, entry) == -1)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   215
				goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   216
			Py_DECREF(cname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   217
		} else {
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   218
			fname = PyString_FromStringAndSize(cur, flen);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   219
			if (!fname ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   220
			    PyDict_SetItem(dmap, fname, entry) == -1)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   221
				goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   222
		}
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   223
		cur += flen;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   224
		Py_DECREF(fname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   225
		Py_DECREF(entry);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   226
		fname = cname = entry = NULL;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   227
	}
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   228
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   229
	ret = parents;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   230
	Py_INCREF(ret);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   231
quit:
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   232
	Py_XDECREF(fname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   233
	Py_XDECREF(cname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   234
	Py_XDECREF(entry);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   235
	Py_XDECREF(parents);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   236
	return ret;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   237
}
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   238
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   239
const char nullid[20];
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   240
const int nullrev = -1;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   241
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   242
/* create an index tuple, insert into the nodemap */
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   243
static PyObject * _build_idx_entry(PyObject *nodemap, int n, uint64_t offset_flags,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   244
                                   int comp_len, int uncomp_len, int base_rev,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   245
                                   int link_rev, int parent_1, int parent_2,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   246
                                   const char *c_node_id)
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   247
{
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   248
	int err;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   249
	PyObject *entry, *node_id, *n_obj;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   250
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   251
	node_id = PyString_FromStringAndSize(c_node_id, 20);
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   252
	n_obj = PyInt_FromLong(n);
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   253
	if (!node_id || !n_obj)
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   254
		err = -1;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   255
	else
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   256
		err = PyDict_SetItem(nodemap, node_id, n_obj);
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   257
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   258
	Py_XDECREF(n_obj);
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   259
	if (err)
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   260
		goto error_dealloc;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   261
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   262
	entry = Py_BuildValue("LiiiiiiN", offset_flags, comp_len,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   263
			      uncomp_len, base_rev, link_rev,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   264
			      parent_1, parent_2, node_id);
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   265
	if (!entry)
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   266
		goto error_dealloc;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   267
	PyObject_GC_UnTrack(entry); /* don't waste time with this */
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   268
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   269
	return entry;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   270
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   271
error_dealloc:
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   272
	Py_XDECREF(node_id);
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   273
	return NULL;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   274
}
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   275
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   276
/* RevlogNG format (all in big endian, data may be inlined):
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   277
 *    6 bytes: offset
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   278
 *    2 bytes: flags
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   279
 *    4 bytes: compressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   280
 *    4 bytes: uncompressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   281
 *    4 bytes: base revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   282
 *    4 bytes: link revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   283
 *    4 bytes: parent 1 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   284
 *    4 bytes: parent 2 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   285
 *   32 bytes: nodeid (only 20 bytes used)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   286
 */
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   287
static int _parse_index_ng (const char *data, int size, int inlined,
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   288
			    PyObject *index, PyObject *nodemap)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   289
{
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   290
	PyObject *entry;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   291
	int n = 0, err;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   292
	uint64_t offset_flags;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   293
	int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   294
	const char *c_node_id;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   295
	const char *end = data + size;
7169
6d28a399293e Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7154
diff changeset
   296
	char decode[64]; /* to enforce alignment with inline data */
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   297
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   298
	while (data < end) {
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   299
		unsigned int step;
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   300
7169
6d28a399293e Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7154
diff changeset
   301
		memcpy(decode, data, 64);
7186
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7176
diff changeset
   302
		offset_flags = ntohl(*((uint32_t *) (decode + 4)));
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7176
diff changeset
   303
		if (n == 0) /* mask out version number for the first entry */
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7176
diff changeset
   304
			offset_flags &= 0xFFFF;
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7176
diff changeset
   305
		else {
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   306
			uint32_t offset_high =  ntohl(*((uint32_t *)decode));
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   307
			offset_flags |= ((uint64_t)offset_high) << 32;
7133
42db22108d85 revlog parser: use ntohl() instead of ntohll() (fix endianness issues)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7108
diff changeset
   308
		}
42db22108d85 revlog parser: use ntohl() instead of ntohll() (fix endianness issues)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7108
diff changeset
   309
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   310
		comp_len = ntohl(*((uint32_t *)(decode + 8)));
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   311
		uncomp_len = ntohl(*((uint32_t *)(decode + 12)));
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   312
		base_rev = ntohl(*((uint32_t *)(decode + 16)));
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   313
		link_rev = ntohl(*((uint32_t *)(decode + 20)));
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   314
		parent_1 = ntohl(*((uint32_t *)(decode + 24)));
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9427
diff changeset
   315
		parent_2 = ntohl(*((uint32_t *)(decode + 28)));
7169
6d28a399293e Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7154
diff changeset
   316
		c_node_id = decode + 32;
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   317
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   318
		entry = _build_idx_entry(nodemap, n, offset_flags,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   319
					comp_len, uncomp_len, base_rev,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   320
					link_rev, parent_1, parent_2,
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   321
					c_node_id);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   322
		if (!entry)
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   323
			return 0;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   324
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   325
		if (inlined) {
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   326
			err = PyList_Append(index, entry);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   327
			Py_DECREF(entry);
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   328
			if (err)
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   329
				return 0;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   330
		} else
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   331
			PyList_SET_ITEM(index, n, entry); /* steals reference */
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   332
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   333
		n++;
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   334
		step = 64 + (inlined ? comp_len : 0);
10449
7c8266c1d15a parsers: fix some signed comparison issues
Matt Mackall <mpm@selenic.com>
parents: 10282
diff changeset
   335
		if (data + step > end || data + step < data)
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   336
			break;
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   337
		data += step;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   338
	}
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   339
	if (data != end) {
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   340
		if (!PyErr_Occurred())
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   341
			PyErr_SetString(PyExc_ValueError, "corrupt index file");
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   342
		return 0;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   343
	}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   344
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   345
	/* create the nullid/nullrev entry in the nodemap and the
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   346
	 * magic nullid entry in the index at [-1] */
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   347
	entry = _build_idx_entry(nodemap,
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   348
			nullrev, 0, 0, 0, -1, -1, -1, -1, nullid);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   349
	if (!entry)
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   350
		return 0;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   351
	if (inlined) {
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   352
		err = PyList_Append(index, entry);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   353
		Py_DECREF(entry);
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   354
		if (err)
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   355
			return 0;
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   356
	} else
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   357
		PyList_SET_ITEM(index, n, entry); /* steals reference */
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   358
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   359
	return 1;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   360
}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   361
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   362
/* This function parses a index file and returns a Python tuple of the
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   363
 * following format: (index, nodemap, cache)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   364
 *
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   365
 * index: a list of tuples containing the RevlogNG records
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   366
 * nodemap: a dict mapping node ids to indices in the index list
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   367
 * cache: if data is inlined, a tuple (index_file_content, 0) else None
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   368
 */
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   369
static PyObject *parse_index(PyObject *self, PyObject *args)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   370
{
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   371
	const char *data;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   372
	int size, inlined;
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   373
	PyObject *rval = NULL, *index = NULL, *nodemap = NULL, *cache = NULL;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   374
	PyObject *data_obj = NULL, *inlined_obj;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   375
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   376
	if (!PyArg_ParseTuple(args, "s#O", &data, &size, &inlined_obj))
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   377
		return NULL;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   378
	inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   379
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   380
	/* If no data is inlined, we know the size of the index list in
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   381
	 * advance: size divided by size of one one revlog record (64 bytes)
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   382
	 * plus one for the nullid */
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   383
	index = inlined ? PyList_New(0) : PyList_New(size / 64 + 1);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   384
	if (!index)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   385
		goto quit;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   386
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   387
	nodemap = PyDict_New();
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   388
	if (!nodemap)
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   389
		goto quit;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   390
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   391
	/* set up the cache return value */
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   392
	if (inlined) {
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   393
		/* Note that the reference to data_obj is only borrowed */
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   394
		data_obj = PyTuple_GET_ITEM(args, 0);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   395
		cache = Py_BuildValue("iO", 0, data_obj);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   396
		if (!cache)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   397
			goto quit;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   398
	} else {
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   399
		cache = Py_None;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   400
		Py_INCREF(Py_None);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   401
	}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   402
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   403
	/* actually populate the index and the nodemap with data */
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   404
	if (!_parse_index_ng (data, size, inlined, index, nodemap))
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   405
		goto quit;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   406
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   407
	rval = Py_BuildValue("NNN", index, nodemap, cache);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   408
	if (!rval)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   409
		goto quit;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   410
	return rval;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   411
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   412
quit:
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   413
	Py_XDECREF(index);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   414
	Py_XDECREF(nodemap);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   415
	Py_XDECREF(cache);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   416
	Py_XDECREF(rval);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   417
	return NULL;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   418
}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   419
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   420
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   421
static char parsers_doc[] = "Efficient content parsing.";
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   422
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   423
static PyMethodDef methods[] = {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   424
	{"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   425
	{"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"},
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   426
	{"parse_index", parse_index, METH_VARARGS, "parse a revlog index\n"},
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   427
	{NULL, NULL}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   428
};
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   429
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   430
PyMODINIT_FUNC initparsers(void)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   431
{
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   432
	Py_InitModule3("parsers", methods, parsers_doc);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   433
}