Show More
@@ -138,25 +138,12 b' static int dirs_fromdict(PyObject *dirs,' | |||
|
138 | 138 | return -1; |
|
139 | 139 | } |
|
140 | 140 | if (skipchar) { |
|
141 | PyObject *st; | |
|
142 | ||
|
143 | if (!PyTuple_Check(value) || | |
|
144 | PyTuple_GET_SIZE(value) == 0) { | |
|
141 | if (!dirstate_tuple_check(value)) { | |
|
145 | 142 | PyErr_SetString(PyExc_TypeError, |
|
146 |
"expected |
|
|
143 | "expected a dirstate tuple"); | |
|
147 | 144 | return -1; |
|
148 | 145 | } |
|
149 | ||
|
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) | |
|
146 | if (((dirstateTupleObject *)value)->state == skipchar) | |
|
160 | 147 | continue; |
|
161 | 148 | } |
|
162 | 149 |
@@ -14,9 +14,7 b' propertycache = util.propertycache' | |||
|
14 | 14 | filecache = scmutil.filecache |
|
15 | 15 | _rangemask = 0x7fffffff |
|
16 | 16 | |
|
17 | def dirstatetuple(*x): | |
|
18 | # x is a tuple | |
|
19 | return x | |
|
17 | dirstatetuple = parsers.dirstatetuple | |
|
20 | 18 | |
|
21 | 19 | class repocache(filecache): |
|
22 | 20 | """filecache for files in .hg/""" |
@@ -153,6 +153,122 b' quit:' | |||
|
153 | 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 | 272 | static PyObject *parse_dirstate(PyObject *self, PyObject *args) |
|
157 | 273 | { |
|
158 | 274 | PyObject *dmap, *cmap, *parents = NULL, *ret = NULL; |
@@ -192,11 +308,8 b' static PyObject *parse_dirstate(PyObject' | |||
|
192 | 308 | goto quit; |
|
193 | 309 | } |
|
194 | 310 | |
|
195 | entry = Py_BuildValue("ciii", state, mode, size, mtime); | |
|
196 | if (!entry) | |
|
197 | goto quit; | |
|
198 | PyObject_GC_UnTrack(entry); /* don't waste time with this */ | |
|
199 | ||
|
311 | entry = (PyObject *)make_dirstate_tuple(state, mode, size, | |
|
312 | mtime); | |
|
200 | 313 | cpos = memchr(cur, 0, flen); |
|
201 | 314 | if (cpos) { |
|
202 | 315 | fname = PyBytes_FromStringAndSize(cur, cpos - cur); |
@@ -316,33 +429,30 b' static PyObject *pack_dirstate(PyObject ' | |||
|
316 | 429 | p += 20; |
|
317 | 430 | |
|
318 | 431 | for (pos = 0; PyDict_Next(map, &pos, &k, &v); ) { |
|
432 | dirstateTupleObject *tuple; | |
|
433 | char state; | |
|
319 | 434 | uint32_t mode, size, mtime; |
|
320 | 435 | Py_ssize_t len, l; |
|
321 | 436 | PyObject *o; |
|
322 |
char * |
|
|
437 | char *t; | |
|
323 | 438 | |
|
324 | if (!PyTuple_Check(v) || PyTuple_GET_SIZE(v) != 4) { | |
|
325 |
PyErr_SetString(PyExc_TypeError, |
|
|
439 | if (!dirstate_tuple_check(v)) { | |
|
440 | PyErr_SetString(PyExc_TypeError, | |
|
441 | "expected a dirstate tuple"); | |
|
326 | 442 | goto bail; |
|
327 | 443 | } |
|
328 | o = PyTuple_GET_ITEM(v, 0); | |
|
329 | if (PyString_AsStringAndSize(o, &s, &l) == -1 || l != 1) { | |
|
330 | PyErr_SetString(PyExc_TypeError, "expected one byte"); | |
|
331 | goto bail; | |
|
332 | } | |
|
333 | *p++ = *s; | |
|
334 | if (getintat(v, 1, &mode) == -1) | |
|
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) { | |
|
444 | tuple = (dirstateTupleObject *)v; | |
|
445 | ||
|
446 | state = tuple->state; | |
|
447 | mode = tuple->mode; | |
|
448 | size = tuple->size; | |
|
449 | mtime = tuple->mtime; | |
|
450 | if (state == 'n' && mtime == (uint32_t)now) { | |
|
341 | 451 | /* See pure/parsers.py:pack_dirstate for why we do |
|
342 | 452 | * this. */ |
|
343 | 453 | mtime = -1; |
|
344 |
mtime_unset = |
|
|
345 |
|
|
|
454 | mtime_unset = (PyObject *)make_dirstate_tuple( | |
|
455 | state, mode, size, mtime); | |
|
346 | 456 | if (!mtime_unset) |
|
347 | 457 | goto bail; |
|
348 | 458 | if (PyDict_SetItem(map, k, mtime_unset) == -1) |
@@ -350,6 +460,7 b' static PyObject *pack_dirstate(PyObject ' | |||
|
350 | 460 | Py_DECREF(mtime_unset); |
|
351 | 461 | mtime_unset = NULL; |
|
352 | 462 | } |
|
463 | *p++ = state; | |
|
353 | 464 | putbe32(mode, p); |
|
354 | 465 | putbe32(size, p + 4); |
|
355 | 466 | putbe32(mtime, p + 8); |
@@ -2021,11 +2132,14 b' static void module_init(PyObject *mod)' | |||
|
2021 | 2132 | dirs_module_init(mod); |
|
2022 | 2133 | |
|
2023 | 2134 | indexType.tp_new = PyType_GenericNew; |
|
2024 |
if (PyType_Ready(&indexType) < 0 |
|
|
2135 | if (PyType_Ready(&indexType) < 0 || | |
|
2136 | PyType_Ready(&dirstateTupleType) < 0) | |
|
2025 | 2137 | return; |
|
2026 | 2138 | Py_INCREF(&indexType); |
|
2027 | ||
|
2028 | 2139 | PyModule_AddObject(mod, "index", (PyObject *)&indexType); |
|
2140 | Py_INCREF(&dirstateTupleType); | |
|
2141 | PyModule_AddObject(mod, "dirstatetuple", | |
|
2142 | (PyObject *)&dirstateTupleType); | |
|
2029 | 2143 | |
|
2030 | 2144 | nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0, |
|
2031 | 2145 | -1, -1, -1, -1, nullid, 20); |
@@ -15,6 +15,12 b' import struct, zlib, cStringIO' | |||
|
15 | 15 | _decompress = zlib.decompress |
|
16 | 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 | 24 | def parse_manifest(mfdict, fdict, lines): |
|
19 | 25 | for l in lines.splitlines(): |
|
20 | 26 | f, n = l.split('\0') |
@@ -104,7 +110,7 b' def pack_dirstate(dmap, copymap, pl, now' | |||
|
104 | 110 | # dirstate, forcing future 'status' calls to compare the |
|
105 | 111 | # contents of the file if the size is the same. This prevents |
|
106 | 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 | 114 | dmap[f] = e |
|
109 | 115 | |
|
110 | 116 | if f in copymap: |
@@ -151,6 +151,17 b' typedef unsigned __int64 uint64_t;' | |||
|
151 | 151 | #define inline __inline |
|
152 | 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 | 165 | static inline uint32_t getbe32(const char *c) |
|
155 | 166 | { |
|
156 | 167 | const unsigned char *d = (const unsigned char *)c; |
General Comments 0
You need to be logged in to leave comments.
Login now