Show More
@@ -138,25 +138,12 b' static int dirs_fromdict(PyObject *dirs,' | |||||
138 | return -1; |
|
138 | return -1; | |
139 | } |
|
139 | } | |
140 | if (skipchar) { |
|
140 | if (skipchar) { | |
141 | PyObject *st; |
|
141 | if (!dirstate_tuple_check(value)) { | |
142 |
|
||||
143 | if (!PyTuple_Check(value) || |
|
|||
144 | PyTuple_GET_SIZE(value) == 0) { |
|
|||
145 | PyErr_SetString(PyExc_TypeError, |
|
142 | PyErr_SetString(PyExc_TypeError, | |
146 |
"expected |
|
143 | "expected a dirstate tuple"); | |
147 | return -1; |
|
144 | return -1; | |
148 | } |
|
145 | } | |
149 |
|
146 | if (((dirstateTupleObject *)value)->state == skipchar) | ||
150 | st = PyTuple_GET_ITEM(value, 0); |
|
|||
151 |
|
||||
152 | if (!PyString_Check(st) || PyString_GET_SIZE(st) == 0) { |
|
|||
153 | PyErr_SetString(PyExc_TypeError, |
|
|||
154 | "expected non-empty string " |
|
|||
155 | "at tuple index 0"); |
|
|||
156 | return -1; |
|
|||
157 | } |
|
|||
158 |
|
||||
159 | if (PyString_AS_STRING(st)[0] == skipchar) |
|
|||
160 | continue; |
|
147 | continue; | |
161 | } |
|
148 | } | |
162 |
|
149 |
@@ -14,9 +14,7 b' propertycache = util.propertycache' | |||||
14 | filecache = scmutil.filecache |
|
14 | filecache = scmutil.filecache | |
15 | _rangemask = 0x7fffffff |
|
15 | _rangemask = 0x7fffffff | |
16 |
|
16 | |||
17 | def dirstatetuple(*x): |
|
17 | dirstatetuple = parsers.dirstatetuple | |
18 | # x is a tuple |
|
|||
19 | return x |
|
|||
20 |
|
18 | |||
21 | class repocache(filecache): |
|
19 | class repocache(filecache): | |
22 | """filecache for files in .hg/""" |
|
20 | """filecache for files in .hg/""" |
@@ -153,6 +153,122 b' quit:' | |||||
153 | return NULL; |
|
153 | return NULL; | |
154 | } |
|
154 | } | |
155 |
|
155 | |||
|
156 | static inline dirstateTupleObject *make_dirstate_tuple(char state, int mode, | |||
|
157 | int size, int mtime) | |||
|
158 | { | |||
|
159 | dirstateTupleObject *t = PyObject_New(dirstateTupleObject, | |||
|
160 | &dirstateTupleType); | |||
|
161 | if (!t) | |||
|
162 | return NULL; | |||
|
163 | t->state = state; | |||
|
164 | t->mode = mode; | |||
|
165 | t->size = size; | |||
|
166 | t->mtime = mtime; | |||
|
167 | return t; | |||
|
168 | } | |||
|
169 | ||||
|
170 | static PyObject *dirstate_tuple_new(PyTypeObject *subtype, PyObject *args, | |||
|
171 | PyObject *kwds) | |||
|
172 | { | |||
|
173 | /* We do all the initialization here and not a tp_init function because | |||
|
174 | * dirstate_tuple is immutable. */ | |||
|
175 | dirstateTupleObject *t; | |||
|
176 | char state; | |||
|
177 | int size, mode, mtime; | |||
|
178 | if (!PyArg_ParseTuple(args, "ciii", &state, &mode, &size, &mtime)) | |||
|
179 | return NULL; | |||
|
180 | ||||
|
181 | t = (dirstateTupleObject *)subtype->tp_alloc(subtype, 1); | |||
|
182 | if (!t) | |||
|
183 | return NULL; | |||
|
184 | t->state = state; | |||
|
185 | t->mode = mode; | |||
|
186 | t->size = size; | |||
|
187 | t->mtime = mtime; | |||
|
188 | ||||
|
189 | return (PyObject *)t; | |||
|
190 | } | |||
|
191 | ||||
|
192 | static void dirstate_tuple_dealloc(PyObject *o) | |||
|
193 | { | |||
|
194 | PyObject_Del(o); | |||
|
195 | } | |||
|
196 | ||||
|
197 | static Py_ssize_t dirstate_tuple_length(PyObject *o) | |||
|
198 | { | |||
|
199 | return 4; | |||
|
200 | } | |||
|
201 | ||||
|
202 | static PyObject *dirstate_tuple_item(PyObject *o, Py_ssize_t i) | |||
|
203 | { | |||
|
204 | dirstateTupleObject *t = (dirstateTupleObject *)o; | |||
|
205 | switch (i) { | |||
|
206 | case 0: | |||
|
207 | return PyBytes_FromStringAndSize(&t->state, 1); | |||
|
208 | case 1: | |||
|
209 | return PyInt_FromLong(t->mode); | |||
|
210 | case 2: | |||
|
211 | return PyInt_FromLong(t->size); | |||
|
212 | case 3: | |||
|
213 | return PyInt_FromLong(t->mtime); | |||
|
214 | default: | |||
|
215 | PyErr_SetString(PyExc_IndexError, "index out of range"); | |||
|
216 | return NULL; | |||
|
217 | } | |||
|
218 | } | |||
|
219 | ||||
|
220 | static PySequenceMethods dirstate_tuple_sq = { | |||
|
221 | dirstate_tuple_length, /* sq_length */ | |||
|
222 | 0, /* sq_concat */ | |||
|
223 | 0, /* sq_repeat */ | |||
|
224 | dirstate_tuple_item, /* sq_item */ | |||
|
225 | 0, /* sq_ass_item */ | |||
|
226 | 0, /* sq_contains */ | |||
|
227 | 0, /* sq_inplace_concat */ | |||
|
228 | 0 /* sq_inplace_repeat */ | |||
|
229 | }; | |||
|
230 | ||||
|
231 | PyTypeObject dirstateTupleType = { | |||
|
232 | PyVarObject_HEAD_INIT(NULL, 0) | |||
|
233 | "dirstate_tuple", /* tp_name */ | |||
|
234 | sizeof(dirstateTupleObject),/* tp_basicsize */ | |||
|
235 | 0, /* tp_itemsize */ | |||
|
236 | (destructor)dirstate_tuple_dealloc, /* tp_dealloc */ | |||
|
237 | 0, /* tp_print */ | |||
|
238 | 0, /* tp_getattr */ | |||
|
239 | 0, /* tp_setattr */ | |||
|
240 | 0, /* tp_compare */ | |||
|
241 | 0, /* tp_repr */ | |||
|
242 | 0, /* tp_as_number */ | |||
|
243 | &dirstate_tuple_sq, /* tp_as_sequence */ | |||
|
244 | 0, /* tp_as_mapping */ | |||
|
245 | 0, /* tp_hash */ | |||
|
246 | 0, /* tp_call */ | |||
|
247 | 0, /* tp_str */ | |||
|
248 | 0, /* tp_getattro */ | |||
|
249 | 0, /* tp_setattro */ | |||
|
250 | 0, /* tp_as_buffer */ | |||
|
251 | Py_TPFLAGS_DEFAULT, /* tp_flags */ | |||
|
252 | "dirstate tuple", /* tp_doc */ | |||
|
253 | 0, /* tp_traverse */ | |||
|
254 | 0, /* tp_clear */ | |||
|
255 | 0, /* tp_richcompare */ | |||
|
256 | 0, /* tp_weaklistoffset */ | |||
|
257 | 0, /* tp_iter */ | |||
|
258 | 0, /* tp_iternext */ | |||
|
259 | 0, /* tp_methods */ | |||
|
260 | 0, /* tp_members */ | |||
|
261 | 0, /* tp_getset */ | |||
|
262 | 0, /* tp_base */ | |||
|
263 | 0, /* tp_dict */ | |||
|
264 | 0, /* tp_descr_get */ | |||
|
265 | 0, /* tp_descr_set */ | |||
|
266 | 0, /* tp_dictoffset */ | |||
|
267 | 0, /* tp_init */ | |||
|
268 | 0, /* tp_alloc */ | |||
|
269 | dirstate_tuple_new, /* tp_new */ | |||
|
270 | }; | |||
|
271 | ||||
156 | static PyObject *parse_dirstate(PyObject *self, PyObject *args) |
|
272 | static PyObject *parse_dirstate(PyObject *self, PyObject *args) | |
157 | { |
|
273 | { | |
158 | PyObject *dmap, *cmap, *parents = NULL, *ret = NULL; |
|
274 | PyObject *dmap, *cmap, *parents = NULL, *ret = NULL; | |
@@ -192,11 +308,8 b' static PyObject *parse_dirstate(PyObject' | |||||
192 | goto quit; |
|
308 | goto quit; | |
193 | } |
|
309 | } | |
194 |
|
310 | |||
195 | entry = Py_BuildValue("ciii", state, mode, size, mtime); |
|
311 | entry = (PyObject *)make_dirstate_tuple(state, mode, size, | |
196 | if (!entry) |
|
312 | mtime); | |
197 | goto quit; |
|
|||
198 | PyObject_GC_UnTrack(entry); /* don't waste time with this */ |
|
|||
199 |
|
||||
200 | cpos = memchr(cur, 0, flen); |
|
313 | cpos = memchr(cur, 0, flen); | |
201 | if (cpos) { |
|
314 | if (cpos) { | |
202 | fname = PyBytes_FromStringAndSize(cur, cpos - cur); |
|
315 | fname = PyBytes_FromStringAndSize(cur, cpos - cur); | |
@@ -316,33 +429,30 b' static PyObject *pack_dirstate(PyObject ' | |||||
316 | p += 20; |
|
429 | p += 20; | |
317 |
|
430 | |||
318 | for (pos = 0; PyDict_Next(map, &pos, &k, &v); ) { |
|
431 | for (pos = 0; PyDict_Next(map, &pos, &k, &v); ) { | |
|
432 | dirstateTupleObject *tuple; | |||
|
433 | char state; | |||
319 | uint32_t mode, size, mtime; |
|
434 | uint32_t mode, size, mtime; | |
320 | Py_ssize_t len, l; |
|
435 | Py_ssize_t len, l; | |
321 | PyObject *o; |
|
436 | PyObject *o; | |
322 |
char * |
|
437 | char *t; | |
323 |
|
438 | |||
324 | if (!PyTuple_Check(v) || PyTuple_GET_SIZE(v) != 4) { |
|
439 | if (!dirstate_tuple_check(v)) { | |
325 |
PyErr_SetString(PyExc_TypeError, |
|
440 | PyErr_SetString(PyExc_TypeError, | |
|
441 | "expected a dirstate tuple"); | |||
326 | goto bail; |
|
442 | goto bail; | |
327 | } |
|
443 | } | |
328 | o = PyTuple_GET_ITEM(v, 0); |
|
444 | tuple = (dirstateTupleObject *)v; | |
329 | if (PyString_AsStringAndSize(o, &s, &l) == -1 || l != 1) { |
|
445 | ||
330 | PyErr_SetString(PyExc_TypeError, "expected one byte"); |
|
446 | state = tuple->state; | |
331 | goto bail; |
|
447 | mode = tuple->mode; | |
332 | } |
|
448 | size = tuple->size; | |
333 | *p++ = *s; |
|
449 | mtime = tuple->mtime; | |
334 | if (getintat(v, 1, &mode) == -1) |
|
450 | if (state == 'n' && mtime == (uint32_t)now) { | |
335 | goto bail; |
|
|||
336 | if (getintat(v, 2, &size) == -1) |
|
|||
337 | goto bail; |
|
|||
338 | if (getintat(v, 3, &mtime) == -1) |
|
|||
339 | goto bail; |
|
|||
340 | if (*s == 'n' && mtime == (uint32_t)now) { |
|
|||
341 | /* See pure/parsers.py:pack_dirstate for why we do |
|
451 | /* See pure/parsers.py:pack_dirstate for why we do | |
342 | * this. */ |
|
452 | * this. */ | |
343 | mtime = -1; |
|
453 | mtime = -1; | |
344 |
mtime_unset = |
|
454 | mtime_unset = (PyObject *)make_dirstate_tuple( | |
345 |
|
|
455 | state, mode, size, mtime); | |
346 | if (!mtime_unset) |
|
456 | if (!mtime_unset) | |
347 | goto bail; |
|
457 | goto bail; | |
348 | if (PyDict_SetItem(map, k, mtime_unset) == -1) |
|
458 | if (PyDict_SetItem(map, k, mtime_unset) == -1) | |
@@ -350,6 +460,7 b' static PyObject *pack_dirstate(PyObject ' | |||||
350 | Py_DECREF(mtime_unset); |
|
460 | Py_DECREF(mtime_unset); | |
351 | mtime_unset = NULL; |
|
461 | mtime_unset = NULL; | |
352 | } |
|
462 | } | |
|
463 | *p++ = state; | |||
353 | putbe32(mode, p); |
|
464 | putbe32(mode, p); | |
354 | putbe32(size, p + 4); |
|
465 | putbe32(size, p + 4); | |
355 | putbe32(mtime, p + 8); |
|
466 | putbe32(mtime, p + 8); | |
@@ -2021,11 +2132,14 b' static void module_init(PyObject *mod)' | |||||
2021 | dirs_module_init(mod); |
|
2132 | dirs_module_init(mod); | |
2022 |
|
2133 | |||
2023 | indexType.tp_new = PyType_GenericNew; |
|
2134 | indexType.tp_new = PyType_GenericNew; | |
2024 |
if (PyType_Ready(&indexType) < 0 |
|
2135 | if (PyType_Ready(&indexType) < 0 || | |
|
2136 | PyType_Ready(&dirstateTupleType) < 0) | |||
2025 | return; |
|
2137 | return; | |
2026 | Py_INCREF(&indexType); |
|
2138 | Py_INCREF(&indexType); | |
2027 |
|
||||
2028 | PyModule_AddObject(mod, "index", (PyObject *)&indexType); |
|
2139 | PyModule_AddObject(mod, "index", (PyObject *)&indexType); | |
|
2140 | Py_INCREF(&dirstateTupleType); | |||
|
2141 | PyModule_AddObject(mod, "dirstatetuple", | |||
|
2142 | (PyObject *)&dirstateTupleType); | |||
2029 |
|
2143 | |||
2030 | nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0, |
|
2144 | nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0, | |
2031 | -1, -1, -1, -1, nullid, 20); |
|
2145 | -1, -1, -1, -1, nullid, 20); |
@@ -15,6 +15,12 b' import struct, zlib, cStringIO' | |||||
15 | _decompress = zlib.decompress |
|
15 | _decompress = zlib.decompress | |
16 | _sha = util.sha1 |
|
16 | _sha = util.sha1 | |
17 |
|
17 | |||
|
18 | # Some code below makes tuples directly because it's more convenient. However, | |||
|
19 | # code outside this module should always use dirstatetuple. | |||
|
20 | def dirstatetuple(*x): | |||
|
21 | # x is a tuple | |||
|
22 | return x | |||
|
23 | ||||
18 | def parse_manifest(mfdict, fdict, lines): |
|
24 | def parse_manifest(mfdict, fdict, lines): | |
19 | for l in lines.splitlines(): |
|
25 | for l in lines.splitlines(): | |
20 | f, n = l.split('\0') |
|
26 | f, n = l.split('\0') | |
@@ -104,7 +110,7 b' def pack_dirstate(dmap, copymap, pl, now' | |||||
104 | # dirstate, forcing future 'status' calls to compare the |
|
110 | # dirstate, forcing future 'status' calls to compare the | |
105 | # contents of the file if the size is the same. This prevents |
|
111 | # contents of the file if the size is the same. This prevents | |
106 | # mistakenly treating such files as clean. |
|
112 | # mistakenly treating such files as clean. | |
107 | e = (e[0], e[1], e[2], -1) |
|
113 | e = dirstatetuple(e[0], e[1], e[2], -1) | |
108 | dmap[f] = e |
|
114 | dmap[f] = e | |
109 |
|
115 | |||
110 | if f in copymap: |
|
116 | if f in copymap: |
@@ -151,6 +151,17 b' typedef unsigned __int64 uint64_t;' | |||||
151 | #define inline __inline |
|
151 | #define inline __inline | |
152 | #endif |
|
152 | #endif | |
153 |
|
153 | |||
|
154 | typedef struct { | |||
|
155 | PyObject_HEAD | |||
|
156 | char state; | |||
|
157 | int mode; | |||
|
158 | int size; | |||
|
159 | int mtime; | |||
|
160 | } dirstateTupleObject; | |||
|
161 | ||||
|
162 | PyTypeObject dirstateTupleType; | |||
|
163 | #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateTupleType) | |||
|
164 | ||||
154 | static inline uint32_t getbe32(const char *c) |
|
165 | static inline uint32_t getbe32(const char *c) | |
155 | { |
|
166 | { | |
156 | const unsigned char *d = (const unsigned char *)c; |
|
167 | const unsigned char *d = (const unsigned char *)c; |
General Comments 0
You need to be logged in to leave comments.
Login now