##// END OF EJS Templates
util.h: more Python 2.4 fixes
Matt Mackall -
r16393:ee163a9c default
parent child Browse files
Show More
@@ -1,713 +1,713
1 1 /*
2 2 parsers.c - efficient content parsing
3 3
4 4 Copyright 2008 Matt Mackall <mpm@selenic.com> and others
5 5
6 6 This software may be used and distributed according to the terms of
7 7 the GNU General Public License, incorporated herein by reference.
8 8 */
9 9
10 10 #include <Python.h>
11 11 #include <ctype.h>
12 12 #include <string.h>
13 13
14 14 #include "util.h"
15 15
16 16 static int hexdigit(char c)
17 17 {
18 18 if (c >= '0' && c <= '9')
19 19 return c - '0';
20 20 if (c >= 'a' && c <= 'f')
21 21 return c - 'a' + 10;
22 22 if (c >= 'A' && c <= 'F')
23 23 return c - 'A' + 10;
24 24
25 25 PyErr_SetString(PyExc_ValueError, "input contains non-hex character");
26 26 return 0;
27 27 }
28 28
29 29 /*
30 30 * Turn a hex-encoded string into binary.
31 31 */
32 32 static PyObject *unhexlify(const char *str, int len)
33 33 {
34 34 PyObject *ret;
35 35 const char *c;
36 36 char *d;
37 37
38 38 ret = PyBytes_FromStringAndSize(NULL, len / 2);
39 39
40 40 if (!ret)
41 41 return NULL;
42 42
43 43 d = PyBytes_AsString(ret);
44 44
45 45 for (c = str; c < str + len;) {
46 46 int hi = hexdigit(*c++);
47 47 int lo = hexdigit(*c++);
48 48 *d++ = (hi << 4) | lo;
49 49 }
50 50
51 51 return ret;
52 52 }
53 53
54 54 /*
55 55 * This code assumes that a manifest is stitched together with newline
56 56 * ('\n') characters.
57 57 */
58 58 static PyObject *parse_manifest(PyObject *self, PyObject *args)
59 59 {
60 60 PyObject *mfdict, *fdict;
61 61 char *str, *cur, *start, *zero;
62 62 int len;
63 63
64 64 if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
65 65 &PyDict_Type, &mfdict,
66 66 &PyDict_Type, &fdict,
67 67 &str, &len))
68 68 goto quit;
69 69
70 70 for (start = cur = str, zero = NULL; cur < str + len; cur++) {
71 71 PyObject *file = NULL, *node = NULL;
72 72 PyObject *flags = NULL;
73 73 int nlen;
74 74
75 75 if (!*cur) {
76 76 zero = cur;
77 77 continue;
78 78 }
79 79 else if (*cur != '\n')
80 80 continue;
81 81
82 82 if (!zero) {
83 83 PyErr_SetString(PyExc_ValueError,
84 84 "manifest entry has no separator");
85 85 goto quit;
86 86 }
87 87
88 88 file = PyBytes_FromStringAndSize(start, zero - start);
89 89
90 90 if (!file)
91 91 goto bail;
92 92
93 93 nlen = cur - zero - 1;
94 94
95 95 node = unhexlify(zero + 1, nlen > 40 ? 40 : nlen);
96 96 if (!node)
97 97 goto bail;
98 98
99 99 if (nlen > 40) {
100 100 flags = PyBytes_FromStringAndSize(zero + 41,
101 101 nlen - 40);
102 102 if (!flags)
103 103 goto bail;
104 104
105 105 if (PyDict_SetItem(fdict, file, flags) == -1)
106 106 goto bail;
107 107 }
108 108
109 109 if (PyDict_SetItem(mfdict, file, node) == -1)
110 110 goto bail;
111 111
112 112 start = cur + 1;
113 113 zero = NULL;
114 114
115 115 Py_XDECREF(flags);
116 116 Py_XDECREF(node);
117 117 Py_XDECREF(file);
118 118 continue;
119 119 bail:
120 120 Py_XDECREF(flags);
121 121 Py_XDECREF(node);
122 122 Py_XDECREF(file);
123 123 goto quit;
124 124 }
125 125
126 126 if (len > 0 && *(cur - 1) != '\n') {
127 127 PyErr_SetString(PyExc_ValueError,
128 128 "manifest contains trailing garbage");
129 129 goto quit;
130 130 }
131 131
132 132 Py_INCREF(Py_None);
133 133 return Py_None;
134 134 quit:
135 135 return NULL;
136 136 }
137 137
138 138 static PyObject *parse_dirstate(PyObject *self, PyObject *args)
139 139 {
140 140 PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
141 141 PyObject *fname = NULL, *cname = NULL, *entry = NULL;
142 142 char *str, *cur, *end, *cpos;
143 143 int state, mode, size, mtime;
144 144 unsigned int flen;
145 145 int len;
146 146 uint32_t decode[4]; /* for alignment */
147 147
148 148 if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
149 149 &PyDict_Type, &dmap,
150 150 &PyDict_Type, &cmap,
151 151 &str, &len))
152 152 goto quit;
153 153
154 154 /* read parents */
155 155 if (len < 40)
156 156 goto quit;
157 157
158 158 parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
159 159 if (!parents)
160 160 goto quit;
161 161
162 162 /* read filenames */
163 163 cur = str + 40;
164 164 end = str + len;
165 165
166 166 while (cur < end - 17) {
167 167 /* unpack header */
168 168 state = *cur;
169 169 memcpy(decode, cur + 1, 16);
170 170 mode = ntohl(decode[0]);
171 171 size = ntohl(decode[1]);
172 172 mtime = ntohl(decode[2]);
173 173 flen = ntohl(decode[3]);
174 174 cur += 17;
175 175 if (cur + flen > end || cur + flen < cur) {
176 176 PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
177 177 goto quit;
178 178 }
179 179
180 180 entry = Py_BuildValue("ciii", state, mode, size, mtime);
181 181 if (!entry)
182 182 goto quit;
183 183 PyObject_GC_UnTrack(entry); /* don't waste time with this */
184 184
185 185 cpos = memchr(cur, 0, flen);
186 186 if (cpos) {
187 187 fname = PyBytes_FromStringAndSize(cur, cpos - cur);
188 188 cname = PyBytes_FromStringAndSize(cpos + 1,
189 189 flen - (cpos - cur) - 1);
190 190 if (!fname || !cname ||
191 191 PyDict_SetItem(cmap, fname, cname) == -1 ||
192 192 PyDict_SetItem(dmap, fname, entry) == -1)
193 193 goto quit;
194 194 Py_DECREF(cname);
195 195 } else {
196 196 fname = PyBytes_FromStringAndSize(cur, flen);
197 197 if (!fname ||
198 198 PyDict_SetItem(dmap, fname, entry) == -1)
199 199 goto quit;
200 200 }
201 201 cur += flen;
202 202 Py_DECREF(fname);
203 203 Py_DECREF(entry);
204 204 fname = cname = entry = NULL;
205 205 }
206 206
207 207 ret = parents;
208 208 Py_INCREF(ret);
209 209 quit:
210 210 Py_XDECREF(fname);
211 211 Py_XDECREF(cname);
212 212 Py_XDECREF(entry);
213 213 Py_XDECREF(parents);
214 214 return ret;
215 215 }
216 216
217 217 /*
218 218 * A list-like object that decodes the contents of a RevlogNG index
219 219 * file on demand. It has limited support for insert and delete at the
220 220 * last element before the end. The last entry is always a sentinel
221 221 * nullid.
222 222 */
223 223 typedef struct {
224 224 PyObject_HEAD
225 225 /* Type-specific fields go here. */
226 226 PyObject *data; /* raw bytes of index */
227 227 PyObject **cache; /* cached tuples */
228 228 const char **offsets; /* populated on demand */
229 229 Py_ssize_t raw_length; /* original number of elements */
230 230 Py_ssize_t length; /* current number of elements */
231 231 PyObject *added; /* populated on demand */
232 232 int inlined;
233 233 } indexObject;
234 234
235 235 static Py_ssize_t index_length(indexObject *self)
236 236 {
237 237 if (self->added == NULL)
238 238 return self->length;
239 239 return self->length + PyList_GET_SIZE(self->added);
240 240 }
241 241
242 242 static PyObject *nullentry;
243 243
244 244 static long inline_scan(indexObject *self, const char **offsets);
245 245
246 246 #if LONG_MAX == 0x7fffffffL
247 static const char *tuple_format = "Kiiiiiis#";
247 static char *tuple_format = "Kiiiiiis#";
248 248 #else
249 static const char *tuple_format = "kiiiiiis#";
249 static char *tuple_format = "kiiiiiis#";
250 250 #endif
251 251
252 252 /* RevlogNG format (all in big endian, data may be inlined):
253 253 * 6 bytes: offset
254 254 * 2 bytes: flags
255 255 * 4 bytes: compressed length
256 256 * 4 bytes: uncompressed length
257 257 * 4 bytes: base revision
258 258 * 4 bytes: link revision
259 259 * 4 bytes: parent 1 revision
260 260 * 4 bytes: parent 2 revision
261 261 * 32 bytes: nodeid (only 20 bytes used)
262 262 */
263 263 static PyObject *index_get(indexObject *self, Py_ssize_t pos)
264 264 {
265 265 uint32_t decode[8]; /* to enforce alignment with inline data */
266 266 uint64_t offset_flags;
267 267 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
268 268 const char *c_node_id;
269 269 const char *data;
270 270 Py_ssize_t length = index_length(self);
271 271 PyObject *entry;
272 272
273 273 if (pos >= length) {
274 274 PyErr_SetString(PyExc_IndexError, "revlog index out of range");
275 275 return NULL;
276 276 }
277 277
278 278 if (pos == length - 1) {
279 279 Py_INCREF(nullentry);
280 280 return nullentry;
281 281 }
282 282
283 283 if (pos >= self->length - 1) {
284 284 PyObject *obj;
285 285 obj = PyList_GET_ITEM(self->added, pos - self->length + 1);
286 286 Py_INCREF(obj);
287 287 return obj;
288 288 }
289 289
290 290 if (self->cache) {
291 291 if (self->cache[pos]) {
292 292 Py_INCREF(self->cache[pos]);
293 293 return self->cache[pos];
294 294 }
295 295 } else {
296 296 self->cache = calloc(self->raw_length, sizeof(PyObject *));
297 297 if (self->cache == NULL)
298 298 return PyErr_NoMemory();
299 299 }
300 300
301 301 if (self->inlined && pos > 0) {
302 302 if (self->offsets == NULL) {
303 303 self->offsets = malloc(self->raw_length *
304 304 sizeof(*self->offsets));
305 305 if (self->offsets == NULL)
306 306 return PyErr_NoMemory();
307 307 inline_scan(self, self->offsets);
308 308 }
309 309 data = self->offsets[pos];
310 310 } else
311 311 data = PyString_AS_STRING(self->data) + pos * 64;
312 312
313 313 memcpy(decode, data, 8 * sizeof(uint32_t));
314 314
315 315 offset_flags = ntohl(decode[1]);
316 316 if (pos == 0) /* mask out version number for the first entry */
317 317 offset_flags &= 0xFFFF;
318 318 else {
319 319 uint32_t offset_high = ntohl(decode[0]);
320 320 offset_flags |= ((uint64_t)offset_high) << 32;
321 321 }
322 322
323 323 comp_len = ntohl(decode[2]);
324 324 uncomp_len = ntohl(decode[3]);
325 325 base_rev = ntohl(decode[4]);
326 326 link_rev = ntohl(decode[5]);
327 327 parent_1 = ntohl(decode[6]);
328 328 parent_2 = ntohl(decode[7]);
329 329 c_node_id = data + 32;
330 330
331 331 entry = Py_BuildValue(tuple_format, offset_flags, comp_len,
332 332 uncomp_len, base_rev, link_rev,
333 333 parent_1, parent_2, c_node_id, 20);
334 334
335 335 if (entry)
336 336 PyObject_GC_UnTrack(entry);
337 337
338 338 self->cache[pos] = entry;
339 339 Py_INCREF(entry);
340 340
341 341 return entry;
342 342 }
343 343
344 344 static PyObject *index_insert(indexObject *self, PyObject *args)
345 345 {
346 346 PyObject *obj, *node;
347 347 long offset;
348 348 Py_ssize_t len;
349 349
350 350 if (!PyArg_ParseTuple(args, "lO", &offset, &obj))
351 351 return NULL;
352 352
353 353 if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 8) {
354 354 PyErr_SetString(PyExc_ValueError, "8-tuple required");
355 355 return NULL;
356 356 }
357 357
358 358 node = PyTuple_GET_ITEM(obj, 7);
359 359 if (!PyString_Check(node) || PyString_GET_SIZE(node) != 20) {
360 360 PyErr_SetString(PyExc_ValueError,
361 361 "20-byte hash required as last element");
362 362 return NULL;
363 363 }
364 364
365 365 len = index_length(self);
366 366
367 367 if (offset < 0)
368 368 offset += len;
369 369
370 370 if (offset != len - 1) {
371 371 PyErr_SetString(PyExc_IndexError,
372 372 "insert only supported at index -1");
373 373 return NULL;
374 374 }
375 375
376 376 if (self->added == NULL) {
377 377 self->added = PyList_New(0);
378 378 if (self->added == NULL)
379 379 return NULL;
380 380 }
381 381
382 382 if (PyList_Append(self->added, obj) == -1)
383 383 return NULL;
384 384
385 385 Py_RETURN_NONE;
386 386 }
387 387
388 388 static void _index_clearcaches(indexObject *self)
389 389 {
390 390 if (self->cache) {
391 391 Py_ssize_t i;
392 392
393 393 for (i = 0; i < self->raw_length; i++) {
394 394 Py_XDECREF(self->cache[i]);
395 395 self->cache[i] = NULL;
396 396 }
397 397 free(self->cache);
398 398 self->cache = NULL;
399 399 }
400 400 if (self->offsets) {
401 401 free(self->offsets);
402 402 self->offsets = NULL;
403 403 }
404 404 }
405 405
406 406 static PyObject *index_clearcaches(indexObject *self)
407 407 {
408 408 _index_clearcaches(self);
409 409 Py_RETURN_NONE;
410 410 }
411 411
412 412 static int index_assign_subscript(indexObject *self, PyObject *item,
413 413 PyObject *value)
414 414 {
415 415 Py_ssize_t start, stop, step, slicelength;
416 416 Py_ssize_t length = index_length(self);
417 417
418 418 if (!PySlice_Check(item) || value != NULL) {
419 419 PyErr_SetString(PyExc_TypeError,
420 420 "revlog index only supports slice deletion");
421 421 return -1;
422 422 }
423 423
424 424 if (PySlice_GetIndicesEx((PySliceObject*)item, length,
425 425 &start, &stop, &step, &slicelength) < 0)
426 426 return -1;
427 427
428 428 if (slicelength <= 0)
429 429 return 0;
430 430
431 431 if ((step < 0 && start < stop) || (step > 0 && start > stop))
432 432 stop = start;
433 433
434 434 if (step < 0) {
435 435 stop = start + 1;
436 436 start = stop + step*(slicelength - 1) - 1;
437 437 step = -step;
438 438 }
439 439
440 440 if (step != 1) {
441 441 PyErr_SetString(PyExc_ValueError,
442 442 "revlog index delete requires step size of 1");
443 443 return -1;
444 444 }
445 445
446 446 if (stop != length - 1) {
447 447 PyErr_SetString(PyExc_IndexError,
448 448 "revlog index deletion indices are invalid");
449 449 return -1;
450 450 }
451 451
452 452 if (start < self->length) {
453 453 self->length = start + 1;
454 454 if (self->added) {
455 455 Py_DECREF(self->added);
456 456 self->added = NULL;
457 457 }
458 458 return 0;
459 459 }
460 460
461 461 return PyList_SetSlice(self->added, start - self->length + 1,
462 462 PyList_GET_SIZE(self->added),
463 463 NULL);
464 464 }
465 465
466 466 static long inline_scan(indexObject *self, const char **offsets)
467 467 {
468 468 const char *data = PyString_AS_STRING(self->data);
469 469 const char *end = data + PyString_GET_SIZE(self->data);
470 470 const long hdrsize = 64;
471 471 long incr = hdrsize;
472 472 Py_ssize_t len = 0;
473 473
474 474 while (data + hdrsize <= end) {
475 475 uint32_t comp_len;
476 476 const char *old_data;
477 477 /* 3rd element of header is length of compressed inline data */
478 478 memcpy(&comp_len, data + 8, sizeof(uint32_t));
479 479 incr = hdrsize + ntohl(comp_len);
480 480 if (incr < hdrsize)
481 481 break;
482 482 if (offsets)
483 483 offsets[len] = data;
484 484 len++;
485 485 old_data = data;
486 486 data += incr;
487 487 if (data <= old_data)
488 488 break;
489 489 }
490 490
491 491 if (data != end && data + hdrsize != end) {
492 492 if (!PyErr_Occurred())
493 493 PyErr_SetString(PyExc_ValueError, "corrupt index file");
494 494 return -1;
495 495 }
496 496
497 497 return len;
498 498 }
499 499
500 500 static int index_real_init(indexObject *self, const char *data, int size,
501 501 PyObject *inlined_obj, PyObject *data_obj)
502 502 {
503 503 self->inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
504 504 self->data = data_obj;
505 505 self->cache = NULL;
506 506
507 507 self->added = NULL;
508 508 self->offsets = NULL;
509 509 Py_INCREF(self->data);
510 510
511 511 if (self->inlined) {
512 512 long len = inline_scan(self, NULL);
513 513 if (len == -1)
514 514 goto bail;
515 515 self->raw_length = len;
516 516 self->length = len + 1;
517 517 } else {
518 518 if (size % 64) {
519 519 PyErr_SetString(PyExc_ValueError, "corrupt index file");
520 520 goto bail;
521 521 }
522 522 self->raw_length = size / 64;
523 523 self->length = self->raw_length + 1;
524 524 }
525 525
526 526 return 0;
527 527 bail:
528 528 return -1;
529 529 }
530 530
531 531 static int index_init(indexObject *self, PyObject *args, PyObject *kwds)
532 532 {
533 533 const char *data;
534 534 int size;
535 535 PyObject *inlined_obj;
536 536
537 537 if (!PyArg_ParseTuple(args, "s#O", &data, &size, &inlined_obj))
538 538 return -1;
539 539
540 540 return index_real_init(self, data, size, inlined_obj,
541 541 PyTuple_GET_ITEM(args, 0));
542 542 }
543 543
544 544 static void index_dealloc(indexObject *self)
545 545 {
546 546 _index_clearcaches(self);
547 547 Py_DECREF(self->data);
548 548 Py_XDECREF(self->added);
549 549 PyObject_Del(self);
550 550 }
551 551
552 552 static PySequenceMethods index_sequence_methods = {
553 553 (lenfunc)index_length, /* sq_length */
554 554 0, /* sq_concat */
555 555 0, /* sq_repeat */
556 556 (ssizeargfunc)index_get, /* sq_item */
557 557 };
558 558
559 559 static PyMappingMethods index_mapping_methods = {
560 560 (lenfunc)index_length, /* mp_length */
561 561 NULL, /* mp_subscript */
562 562 (objobjargproc)index_assign_subscript, /* mp_ass_subscript */
563 563 };
564 564
565 565 static PyMethodDef index_methods[] = {
566 566 {"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
567 567 "clear the index caches"},
568 568 {"insert", (PyCFunction)index_insert, METH_VARARGS,
569 569 "insert an index entry"},
570 570 {NULL} /* Sentinel */
571 571 };
572 572
573 573 static PyTypeObject indexType = {
574 574 PyObject_HEAD_INIT(NULL)
575 575 0, /* ob_size */
576 576 "parsers.index", /* tp_name */
577 577 sizeof(indexObject), /* tp_basicsize */
578 578 0, /* tp_itemsize */
579 579 (destructor)index_dealloc, /* tp_dealloc */
580 580 0, /* tp_print */
581 581 0, /* tp_getattr */
582 582 0, /* tp_setattr */
583 583 0, /* tp_compare */
584 584 0, /* tp_repr */
585 585 0, /* tp_as_number */
586 586 &index_sequence_methods, /* tp_as_sequence */
587 587 &index_mapping_methods, /* tp_as_mapping */
588 588 0, /* tp_hash */
589 589 0, /* tp_call */
590 590 0, /* tp_str */
591 591 0, /* tp_getattro */
592 592 0, /* tp_setattro */
593 593 0, /* tp_as_buffer */
594 594 Py_TPFLAGS_DEFAULT, /* tp_flags */
595 595 "revlog index", /* tp_doc */
596 596 0, /* tp_traverse */
597 597 0, /* tp_clear */
598 598 0, /* tp_richcompare */
599 599 0, /* tp_weaklistoffset */
600 600 0, /* tp_iter */
601 601 0, /* tp_iternext */
602 602 index_methods, /* tp_methods */
603 603 0, /* tp_members */
604 604 0, /* tp_getset */
605 605 0, /* tp_base */
606 606 0, /* tp_dict */
607 607 0, /* tp_descr_get */
608 608 0, /* tp_descr_set */
609 609 0, /* tp_dictoffset */
610 610 (initproc)index_init, /* tp_init */
611 611 0, /* tp_alloc */
612 612 PyType_GenericNew, /* tp_new */
613 613 };
614 614
615 615 /*
616 616 * returns a tuple of the form (index, None, cache) with elements as
617 617 * follows:
618 618 *
619 619 * index: an index object that lazily parses the RevlogNG records
620 620 * cache: if data is inlined, a tuple (index_file_content, 0), else None
621 621 *
622 622 * added complications are for backwards compatibility
623 623 */
624 624 static PyObject *parse_index2(PyObject *self, PyObject *args)
625 625 {
626 626 const char *data;
627 627 int size, ret;
628 628 PyObject *inlined_obj, *tuple = NULL, *cache = NULL;
629 629 indexObject *idx;
630 630
631 631 if (!PyArg_ParseTuple(args, "s#O", &data, &size, &inlined_obj))
632 632 return NULL;
633 633
634 634 idx = PyObject_New(indexObject, &indexType);
635 635
636 636 if (idx == NULL)
637 637 goto bail;
638 638
639 639 ret = index_real_init(idx, data, size, inlined_obj,
640 640 PyTuple_GET_ITEM(args, 0));
641 641 if (ret)
642 642 goto bail;
643 643
644 644 if (idx->inlined) {
645 645 Py_INCREF(idx->data);
646 646 cache = Py_BuildValue("iO", 0, idx->data);
647 647 if (cache == NULL)
648 648 goto bail;
649 649 } else {
650 650 cache = Py_None;
651 651 Py_INCREF(cache);
652 652 }
653 653
654 654 tuple = Py_BuildValue("NN", idx, cache);
655 655 if (!tuple)
656 656 goto bail;
657 657 return tuple;
658 658
659 659 bail:
660 660 Py_XDECREF(idx);
661 661 Py_XDECREF(cache);
662 662 Py_XDECREF(tuple);
663 663 return NULL;
664 664 }
665 665
666 666 static char parsers_doc[] = "Efficient content parsing.";
667 667
668 668 static PyMethodDef methods[] = {
669 669 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
670 670 {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"},
671 671 {"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"},
672 672 {NULL, NULL}
673 673 };
674 674
675 675 static void module_init(PyObject *mod)
676 676 {
677 677 static const char nullid[20];
678 678
679 679 if (PyType_Ready(&indexType) < 0)
680 680 return;
681 681 Py_INCREF(&indexType);
682 682
683 683 PyModule_AddObject(mod, "index", (PyObject *)&indexType);
684 684
685 685 nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0,
686 686 -1, -1, -1, -1, nullid, 20);
687 687 if (nullentry)
688 688 PyObject_GC_UnTrack(nullentry);
689 689 }
690 690
691 691 #ifdef IS_PY3K
692 692 static struct PyModuleDef parsers_module = {
693 693 PyModuleDef_HEAD_INIT,
694 694 "parsers",
695 695 parsers_doc,
696 696 -1,
697 697 methods
698 698 };
699 699
700 700 PyMODINIT_FUNC PyInit_parsers(void)
701 701 {
702 702 PyObject *mod = PyModule_Create(&parsers_module);
703 703 module_init(mod);
704 704 return mod;
705 705 }
706 706 #else
707 707 PyMODINIT_FUNC initparsers(void)
708 708 {
709 709 PyObject *mod = Py_InitModule3("parsers", methods, parsers_doc);
710 710 module_init(mod);
711 711 }
712 712 #endif
713 713
@@ -1,151 +1,154
1 1 /*
2 2 util.h - utility functions for interfacing with the various python APIs.
3 3
4 4 This software may be used and distributed according to the terms of
5 5 the GNU General Public License, incorporated herein by reference.
6 6 */
7 7
8 8 #ifndef _HG_UTIL_H_
9 9 #define _HG_UTIL_H_
10 10
11 11 #if PY_MAJOR_VERSION >= 3
12 12
13 13 #define IS_PY3K
14 14 #define PyInt_FromLong PyLong_FromLong
15 15 #define PyInt_AsLong PyLong_AsLong
16 16
17 17 /*
18 18 Mapping of some of the python < 2.x PyString* functions to py3k's PyUnicode.
19 19
20 20 The commented names below represent those that are present in the PyBytes
21 21 definitions for python < 2.6 (below in this file) that don't have a direct
22 22 implementation.
23 23 */
24 24
25 25 #define PyStringObject PyUnicodeObject
26 26 #define PyString_Type PyUnicode_Type
27 27
28 28 #define PyString_Check PyUnicode_Check
29 29 #define PyString_CheckExact PyUnicode_CheckExact
30 30 #define PyString_CHECK_INTERNED PyUnicode_CHECK_INTERNED
31 31 #define PyString_AS_STRING PyUnicode_AsLatin1String
32 32 #define PyString_GET_SIZE PyUnicode_GET_SIZE
33 33
34 34 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
35 35 #define PyString_FromString PyUnicode_FromString
36 36 #define PyString_FromFormatV PyUnicode_FromFormatV
37 37 #define PyString_FromFormat PyUnicode_FromFormat
38 38 /* #define PyString_Size PyUnicode_GET_SIZE */
39 39 /* #define PyString_AsString */
40 40 /* #define PyString_Repr */
41 41 #define PyString_Concat PyUnicode_Concat
42 42 #define PyString_ConcatAndDel PyUnicode_AppendAndDel
43 43 #define _PyString_Resize PyUnicode_Resize
44 44 /* #define _PyString_Eq */
45 45 #define PyString_Format PyUnicode_Format
46 46 /* #define _PyString_FormatLong */
47 47 /* #define PyString_DecodeEscape */
48 48 #define _PyString_Join PyUnicode_Join
49 49 #define PyString_Decode PyUnicode_Decode
50 50 #define PyString_Encode PyUnicode_Encode
51 51 #define PyString_AsEncodedObject PyUnicode_AsEncodedObject
52 52 #define PyString_AsEncodedString PyUnicode_AsEncodedString
53 53 #define PyString_AsDecodedObject PyUnicode_AsDecodedObject
54 54 #define PyString_AsDecodedString PyUnicode_AsDecodedUnicode
55 55 /* #define PyString_AsStringAndSize */
56 56 #define _PyString_InsertThousandsGrouping _PyUnicode_InsertThousandsGrouping
57 57
58 58 #endif /* PY_MAJOR_VERSION */
59 59
60 60 /* Backports from 2.6 */
61 61 #if PY_VERSION_HEX < 0x02060000
62 62
63 63 #define Py_TYPE(ob) (ob)->ob_type
64 64 #define Py_SIZE(ob) (ob)->ob_size
65 65 #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
66 66
67 67 /* Shamelessly stolen from bytesobject.h */
68 68 #define PyBytesObject PyStringObject
69 69 #define PyBytes_Type PyString_Type
70 70
71 71 #define PyBytes_Check PyString_Check
72 72 #define PyBytes_CheckExact PyString_CheckExact
73 73 #define PyBytes_CHECK_INTERNED PyString_CHECK_INTERNED
74 74 #define PyBytes_AS_STRING PyString_AS_STRING
75 75 #define PyBytes_GET_SIZE PyString_GET_SIZE
76 76 #define Py_TPFLAGS_BYTES_SUBCLASS Py_TPFLAGS_STRING_SUBCLASS
77 77
78 78 #define PyBytes_FromStringAndSize PyString_FromStringAndSize
79 79 #define PyBytes_FromString PyString_FromString
80 80 #define PyBytes_FromFormatV PyString_FromFormatV
81 81 #define PyBytes_FromFormat PyString_FromFormat
82 82 #define PyBytes_Size PyString_Size
83 83 #define PyBytes_AsString PyString_AsString
84 84 #define PyBytes_Repr PyString_Repr
85 85 #define PyBytes_Concat PyString_Concat
86 86 #define PyBytes_ConcatAndDel PyString_ConcatAndDel
87 87 #define _PyBytes_Resize _PyString_Resize
88 88 #define _PyBytes_Eq _PyString_Eq
89 89 #define PyBytes_Format PyString_Format
90 90 #define _PyBytes_FormatLong _PyString_FormatLong
91 91 #define PyBytes_DecodeEscape PyString_DecodeEscape
92 92 #define _PyBytes_Join _PyString_Join
93 93 #define PyBytes_Decode PyString_Decode
94 94 #define PyBytes_Encode PyString_Encode
95 95 #define PyBytes_AsEncodedObject PyString_AsEncodedObject
96 96 #define PyBytes_AsEncodedString PyString_AsEncodedString
97 97 #define PyBytes_AsDecodedObject PyString_AsDecodedObject
98 98 #define PyBytes_AsDecodedString PyString_AsDecodedString
99 99 #define PyBytes_AsStringAndSize PyString_AsStringAndSize
100 100 #define _PyBytes_InsertThousandsGrouping _PyString_InsertThousandsGrouping
101 101
102 102 #endif /* PY_VERSION_HEX */
103 103
104 104 #if (PY_VERSION_HEX < 0x02050000)
105 105 /* Definitions to get compatibility with python 2.4 and earlier which
106 106 does not have Py_ssize_t. See also PEP 353.
107 107 Note: msvc (8 or earlier) does not have ssize_t, so we use Py_ssize_t.
108 108 */
109 109 typedef int Py_ssize_t;
110 typedef Py_ssize_t (*lenfunc)(PyObject *);
111 typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
112
110 113 #if !defined(PY_SSIZE_T_MIN)
111 114 #define PY_SSIZE_T_MAX INT_MAX
112 115 #define PY_SSIZE_T_MIN INT_MIN
113 116 #endif
114 117 #endif
115 118
116 119 #ifdef _WIN32
117 120 #ifdef _MSC_VER
118 121 /* msvc 6.0 has problems */
119 122 #define inline __inline
120 123 typedef unsigned long uint32_t;
121 124 typedef unsigned __int64 uint64_t;
122 125 #else
123 126 #include <stdint.h>
124 127 #endif
125 128 static uint32_t ntohl(uint32_t x)
126 129 {
127 130 return ((x & 0x000000ffUL) << 24) |
128 131 ((x & 0x0000ff00UL) << 8) |
129 132 ((x & 0x00ff0000UL) >> 8) |
130 133 ((x & 0xff000000UL) >> 24);
131 134 }
132 135 #else
133 136 /* not windows */
134 137 #include <sys/types.h>
135 138 #if defined __BEOS__ && !defined __HAIKU__
136 139 #include <ByteOrder.h>
137 140 #else
138 141 #include <arpa/inet.h>
139 142 #endif
140 143 #include <inttypes.h>
141 144 #endif
142 145
143 146 #if defined __hpux || defined __SUNPRO_C || defined _AIX
144 147 #define inline
145 148 #endif
146 149
147 150 #ifdef __linux
148 151 #define inline __inline
149 152 #endif
150 153
151 154 #endif /* _HG_UTIL_H_ */
General Comments 0
You need to be logged in to leave comments. Login now