Mercurial > public > mercurial-scm > hg
annotate mercurial/parsers.c @ 7305:c21d236ca897
hgweb: descend empty directories in web view
When a manifest has a series of directories with nothing in them but a single
directory, displaying the entire chain of empty directories allows for
navigation down to the first non-empty directory with a single click.
Because Java links package hierarchy to directory hierarchy, and because Java
conventions include at least three empty directories at the top of this
hierarchy, descending down empty directories is very common in Java web tools.
author | Ry4an Brase <ry4an-hg@ry4an.org> |
---|---|
date | Mon, 03 Nov 2008 10:20:28 +0100 |
parents | aecea6934fdd |
children | d37c0f4e8f48 |
rev | line source |
---|---|
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 PyObject *flags; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
96 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
97 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
|
98 nlen - 40); |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
99 if (!flags) |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
100 goto bail; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
101 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
102 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
|
103 goto bail; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
104 } |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
105 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
106 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
|
107 goto bail; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
108 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
109 start = cur + 1; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
110 zero = NULL; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
111 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
112 Py_XDECREF(flags); |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
113 Py_XDECREF(node); |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
114 Py_XDECREF(file); |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
115 continue; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
116 bail: |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
117 Py_XDECREF(flags); |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
118 Py_XDECREF(node); |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
119 Py_XDECREF(file); |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
120 goto quit; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
121 } |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
122 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
123 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
|
124 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
|
125 "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
|
126 goto quit; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
127 } |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
128 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
129 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
|
130 return Py_None; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
131 quit: |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
132 return NULL; |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
133 } |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
134 |
7093
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
135 #ifdef _WIN32 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
136 # ifdef _MSC_VER |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
137 /* msvc 6.0 has problems */ |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
138 # define inline __inline |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
139 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
|
140 typedef unsigned __int64 uint64_t; |
7093
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
141 # else |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
142 # include <stdint.h> |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
143 # endif |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
144 static uint32_t ntohl(uint32_t x) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
145 { |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
146 return ((x & 0x000000ffUL) << 24) | |
7190
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
147 ((x & 0x0000ff00UL) << 8) | |
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
148 ((x & 0x00ff0000UL) >> 8) | |
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
149 ((x & 0xff000000UL) >> 24); |
7093
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
150 } |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
151 #else |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
152 /* not windows */ |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
153 # include <sys/types.h> |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
154 # if defined __BEOS__ && !defined __HAIKU__ |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
155 # include <ByteOrder.h> |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
156 # else |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
157 # include <arpa/inet.h> |
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 # include <inttypes.h> |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
160 #endif |
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 static PyObject *parse_dirstate(PyObject *self, PyObject *args) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
163 { |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
164 PyObject *dmap, *cmap, *parents = NULL, *ret = NULL; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
165 PyObject *fname = NULL, *cname = NULL, *entry = NULL; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
166 char *str, *cur, *end, *cpos; |
7174
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
167 int state, mode, size, mtime; |
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
168 unsigned int flen; |
7093
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
169 int len; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
170 char decode[16]; /* for alignment */ |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
171 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
172 if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate", |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
173 &PyDict_Type, &dmap, |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
174 &PyDict_Type, &cmap, |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
175 &str, &len)) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
176 goto quit; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
177 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
178 /* read parents */ |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
179 if (len < 40) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
180 goto quit; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
181 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
182 parents = Py_BuildValue("s#s#", str, 20, str + 20, 20); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
183 if (!parents) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
184 goto quit; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
185 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
186 /* read filenames */ |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
187 cur = str + 40; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
188 end = str + len; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
189 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
190 while (cur < end - 17) { |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
191 /* unpack header */ |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
192 state = *cur; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
193 memcpy(decode, cur + 1, 16); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
194 mode = ntohl(*(uint32_t *)(decode)); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
195 size = ntohl(*(uint32_t *)(decode + 4)); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
196 mtime = ntohl(*(uint32_t *)(decode + 8)); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
197 flen = ntohl(*(uint32_t *)(decode + 12)); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
198 cur += 17; |
7174
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
199 if (flen > end - cur) { |
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
200 PyErr_SetString(PyExc_ValueError, "overflow in dirstate"); |
7093
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
201 goto quit; |
7174
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
202 } |
7093
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
203 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
204 entry = Py_BuildValue("ciii", state, mode, size, mtime); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
205 if (!entry) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
206 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
|
207 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
|
208 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
209 cpos = memchr(cur, 0, flen); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
210 if (cpos) { |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
211 fname = PyString_FromStringAndSize(cur, cpos - cur); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
212 cname = PyString_FromStringAndSize(cpos + 1, |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
213 flen - (cpos - cur) - 1); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
214 if (!fname || !cname || |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
215 PyDict_SetItem(cmap, fname, cname) == -1 || |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
216 PyDict_SetItem(dmap, fname, entry) == -1) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
217 goto quit; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
218 Py_DECREF(cname); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
219 } else { |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
220 fname = PyString_FromStringAndSize(cur, flen); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
221 if (!fname || |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
222 PyDict_SetItem(dmap, fname, entry) == -1) |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
223 goto quit; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
224 } |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
225 cur += flen; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
226 Py_DECREF(fname); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
227 Py_DECREF(entry); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
228 fname = cname = entry = NULL; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
229 } |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
230 |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
231 ret = parents; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
232 Py_INCREF(ret); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
233 quit: |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
234 Py_XDECREF(fname); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
235 Py_XDECREF(cname); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
236 Py_XDECREF(entry); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
237 Py_XDECREF(parents); |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
238 return ret; |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
239 } |
16bafcebd3d1
dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents:
7092
diff
changeset
|
240 |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
241 const char nullid[20]; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
242 const int nullrev = -1; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
243 |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
244 /* 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
|
245 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
|
246 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
|
247 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
|
248 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
|
249 { |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
250 int err; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
251 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
|
252 |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
253 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
|
254 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
|
255 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
|
256 err = -1; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
257 else |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
258 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
|
259 |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
260 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
|
261 if (err) |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
262 goto error_dealloc; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
263 |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
264 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
|
265 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
|
266 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
|
267 if (!entry) |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
268 goto error_dealloc; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
269 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
|
270 |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
271 return entry; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
272 |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
273 error_dealloc: |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
274 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
|
275 return NULL; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
276 } |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
277 |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
278 /* 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
|
279 * 6 bytes: offset |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
280 * 2 bytes: flags |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
281 * 4 bytes: compressed length |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
282 * 4 bytes: uncompressed length |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
283 * 4 bytes: base revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
284 * 4 bytes: link revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
285 * 4 bytes: parent 1 revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
286 * 4 bytes: parent 2 revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
287 * 32 bytes: nodeid (only 20 bytes used) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
288 */ |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
289 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
|
290 PyObject *index, PyObject *nodemap) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
291 { |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
292 PyObject *entry; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
293 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
|
294 uint64_t offset_flags; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
295 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
|
296 const char *c_node_id; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
297 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
|
298 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
|
299 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
300 while (data < end) { |
7174
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
301 unsigned int step; |
7190
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
302 |
7169
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
303 memcpy(decode, data, 64); |
7186
f77c8d8331ca
clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7176
diff
changeset
|
304 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
|
305 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
|
306 offset_flags &= 0xFFFF; |
f77c8d8331ca
clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7176
diff
changeset
|
307 else { |
7169
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
308 uint32_t offset_high = ntohl(*((uint32_t *) decode)); |
7186
f77c8d8331ca
clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7176
diff
changeset
|
309 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
|
310 } |
42db22108d85
revlog parser: use ntohl() instead of ntohll() (fix endianness issues)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7108
diff
changeset
|
311 |
7169
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
312 comp_len = ntohl(*((uint32_t *) (decode + 8))); |
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
313 uncomp_len = ntohl(*((uint32_t *) (decode + 12))); |
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
314 base_rev = ntohl(*((uint32_t *) (decode + 16))); |
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
315 link_rev = ntohl(*((uint32_t *) (decode + 20))); |
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
316 parent_1 = ntohl(*((uint32_t *) (decode + 24))); |
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
317 parent_2 = ntohl(*((uint32_t *) (decode + 28))); |
6d28a399293e
Copy index before parsing to enforce alignment with inline data present.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7154
diff
changeset
|
318 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
|
319 |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
320 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
|
321 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
|
322 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
|
323 c_node_id); |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
324 if (!entry) |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
325 return 0; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
326 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
327 if (inlined) { |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
328 err = PyList_Append(index, entry); |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
329 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
|
330 if (err) |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
331 return 0; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
332 } else |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
333 PyList_SET_ITEM(index, n, entry); /* steals reference */ |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
334 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
335 n++; |
7174
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
336 step = 64 + (inlined ? comp_len : 0); |
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
337 if (end - data < step) |
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
338 break; |
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
339 data += step; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
340 } |
7174
4da87407b845
parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7168
diff
changeset
|
341 if (data != end) { |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
342 if (!PyErr_Occurred()) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
343 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
|
344 return 0; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
345 } |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
346 |
7190
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
347 /* 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
|
348 * 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
|
349 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
|
350 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
|
351 if (!entry) |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
352 return 0; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
353 if (inlined) { |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
354 err = PyList_Append(index, entry); |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
355 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
|
356 if (err) |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
357 return 0; |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
358 } else |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
359 PyList_SET_ITEM(index, n, entry); /* steals reference */ |
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 return 1; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
362 } |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
363 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
364 /* 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
|
365 * following format: (index, nodemap, cache) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
366 * |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
367 * 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
|
368 * 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
|
369 * 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
|
370 */ |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
371 static PyObject *parse_index(PyObject *self, PyObject *args) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
372 { |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
373 const char *data; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
374 int size, inlined; |
7190
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
375 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
|
376 PyObject *data_obj = NULL, *inlined_obj; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
377 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
378 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
|
379 return NULL; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
380 inlined = inlined_obj && PyObject_IsTrue(inlined_obj); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
381 |
7190
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
382 /* 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
|
383 * 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
|
384 * plus one for the nullid */ |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
385 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
|
386 if (!index) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
387 goto quit; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
388 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
389 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
|
390 if (!nodemap) |
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
391 goto quit; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
392 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
393 /* set up the cache return value */ |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
394 if (inlined) { |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
395 /* 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
|
396 data_obj = PyTuple_GET_ITEM(args, 0); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
397 cache = Py_BuildValue("iO", 0, data_obj); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
398 if (!cache) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
399 goto quit; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
400 } else { |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
401 cache = Py_None; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
402 Py_INCREF(Py_None); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
403 } |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
404 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
405 /* 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
|
406 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
|
407 goto quit; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
408 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
409 rval = Py_BuildValue("NNN", index, nodemap, cache); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
410 if (!rval) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
411 goto quit; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
412 return rval; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
413 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
414 quit: |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
415 Py_XDECREF(index); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
416 Py_XDECREF(nodemap); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
417 Py_XDECREF(cache); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
418 Py_XDECREF(rval); |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
419 return NULL; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
420 } |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
421 |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
422 |
6389
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
423 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
|
424 |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
425 static PyMethodDef methods[] = { |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
426 {"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
|
427 {"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
|
428 {"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
|
429 {NULL, NULL} |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
430 }; |
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 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
|
433 { |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
434 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
|
435 } |