Mercurial > hg
annotate mercurial/cext/manifest.c @ 45053:cc2572923ea3
revlog: avoid hard-coded hash sizes
Differential Revision: https://phab.mercurial-scm.org/D8683
author | Joerg Sonnenberger <joerg@bec.de> |
---|---|
date | Mon, 06 Jul 2020 14:30:13 +0200 |
parents | 0b0e72b5d551 |
children | d0ef8c1dddd4 |
rev | line source |
---|---|
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1 /* |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
2 * manifest.c - manifest type that does on-demand parsing. |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
3 * |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
4 * Copyright 2015, Google Inc. |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
5 * |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
6 * This software may be used and distributed according to the terms of |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
7 * the GNU General Public License, incorporated herein by reference. |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
8 */ |
24352
d6dbe4d1c9bc
manifest: include Python.h before standard headers
Drew Gottlieb <drgott@google.com>
parents:
24312
diff
changeset
|
9 #include <Python.h> |
d6dbe4d1c9bc
manifest: include Python.h before standard headers
Drew Gottlieb <drgott@google.com>
parents:
24312
diff
changeset
|
10 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
11 #include <assert.h> |
34438
b90e8da190da
cext: reorder #include
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33758
diff
changeset
|
12 #include <stdlib.h> |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
13 #include <string.h> |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
14 |
33758
0f4ac3b6dee4
cext: factor out header for charencode.c
Yuya Nishihara <yuya@tcha.org>
parents:
33757
diff
changeset
|
15 #include "charencode.h" |
24441
e2ed40f0eb2e
manifest: use util.h to get Py_ssize_t
Matt Mackall <mpm@selenic.com>
parents:
24352
diff
changeset
|
16 #include "util.h" |
e2ed40f0eb2e
manifest: use util.h to get Py_ssize_t
Matt Mackall <mpm@selenic.com>
parents:
24352
diff
changeset
|
17 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
18 #define DEFAULT_LINES 100000 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
19 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
20 typedef struct { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
21 char *start; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
22 Py_ssize_t len; /* length of line including terminal newline */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
23 char hash_suffix; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
24 bool from_malloc; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
25 bool deleted; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
26 } line; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
27 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
28 typedef struct { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
29 PyObject_HEAD |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
30 PyObject *pydata; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
31 line *lines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
32 int numlines; /* number of line entries */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
33 int livelines; /* number of non-deleted lines */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
34 int maxlines; /* allocated number of lines */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
35 bool dirty; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
36 } lazymanifest; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
37 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
38 #define MANIFEST_OOM -1 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
39 #define MANIFEST_NOT_SORTED -2 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
40 #define MANIFEST_MALFORMED -3 |
40599
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
41 #define MANIFEST_BOGUS_FILENAME -4 |
40600
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
42 #define MANIFEST_TOO_SHORT_LINE -5 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
43 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
44 /* get the length of the path for a line */ |
44100
969527ac7b44
cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents:
40765
diff
changeset
|
45 static Py_ssize_t pathlen(line *l) |
34440
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
46 { |
39939
e85462d48cb3
manifest: rewrite pathlen() to not cross entry boundary
Yuya Nishihara <yuya@tcha.org>
parents:
39424
diff
changeset
|
47 const char *end = memchr(l->start, '\0', l->len); |
44100
969527ac7b44
cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents:
40765
diff
changeset
|
48 return (end) ? (Py_ssize_t)(end - l->start) : l->len; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
49 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
50 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
51 /* get the node value of a single line */ |
34440
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
52 static PyObject *nodeof(line *l) |
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
53 { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
54 char *s = l->start; |
44100
969527ac7b44
cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents:
40765
diff
changeset
|
55 Py_ssize_t llen = pathlen(l); |
44702
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
56 Py_ssize_t hlen = l->len - llen - 2; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
57 Py_ssize_t hlen_raw = 20; |
39940
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
58 PyObject *hash; |
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
59 if (llen + 1 + 40 + 1 > l->len) { /* path '\0' hash '\n' */ |
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
60 PyErr_SetString(PyExc_ValueError, "manifest line too short"); |
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
61 return NULL; |
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
62 } |
44702
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
63 switch (hlen) { |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
64 case 40: /* sha1 */ |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
65 case 41: /* sha1 with cruft for a merge */ |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
66 break; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
67 case 64: /* new hash */ |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
68 case 65: /* new hash with cruft for a merge */ |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
69 hlen_raw = 32; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
70 break; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
71 default: |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
72 PyErr_SetString(PyExc_ValueError, "invalid node length in manifest"); |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
73 return NULL; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
74 } |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
75 hash = unhexlify(s + llen + 1, hlen_raw * 2); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
76 if (!hash) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
77 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
78 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
79 if (l->hash_suffix != '\0') { |
44702
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
80 char newhash[33]; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
81 memcpy(newhash, PyBytes_AsString(hash), hlen_raw); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
82 Py_DECREF(hash); |
44702
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
83 newhash[hlen_raw] = l->hash_suffix; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
84 hash = PyBytes_FromStringAndSize(newhash, hlen_raw+1); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
85 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
86 return hash; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
87 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
88 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
89 /* get the node hash and flags of a line as a tuple */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
90 static PyObject *hashflags(line *l) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
91 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
92 char *s = l->start; |
44100
969527ac7b44
cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents:
40765
diff
changeset
|
93 Py_ssize_t plen = pathlen(l); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
94 PyObject *hash = nodeof(l); |
44702
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
95 ssize_t hlen; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
96 Py_ssize_t hplen, flen; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
97 PyObject *flags; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
98 PyObject *tup; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
99 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
100 if (!hash) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
101 return NULL; |
44702
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
102 /* hash is either 20 or 21 bytes for an old hash, so we use a |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
103 ternary here to get the "real" hexlified sha length. */ |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
104 hlen = PyBytes_GET_SIZE(hash) < 22 ? 40 : 64; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
105 /* 1 for null byte, 1 for newline */ |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
106 hplen = plen + hlen + 2; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
107 flen = l->len - hplen; |
0b0e72b5d551
manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents:
44132
diff
changeset
|
108 |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
109 flags = PyBytes_FromStringAndSize(s + hplen - 1, flen); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
110 if (!flags) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
111 Py_DECREF(hash); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
112 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
113 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
114 tup = PyTuple_Pack(2, hash, flags); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
115 Py_DECREF(flags); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
116 Py_DECREF(hash); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
117 return tup; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
118 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
119 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
120 /* if we're about to run out of space in the line index, add more */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
121 static bool realloc_if_full(lazymanifest *self) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
122 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
123 if (self->numlines == self->maxlines) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
124 self->maxlines *= 2; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
125 self->lines = realloc(self->lines, self->maxlines * sizeof(line)); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
126 } |
24312
f208ce59a6e5
manifest.c: ensure realloc_if_full() returns 1 or 0
Matt Harbison <matt_harbison@yahoo.com>
parents:
24298
diff
changeset
|
127 return !!self->lines; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
128 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
129 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
130 /* |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
131 * Find the line boundaries in the manifest that 'data' points to and store |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
132 * information about each line in 'self'. |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
133 */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
134 static int find_lines(lazymanifest *self, char *data, Py_ssize_t len) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
135 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
136 char *prev = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
137 while (len > 0) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
138 line *l; |
40599
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
139 char *next; |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
140 if (*data == '\0') { |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
141 /* It's implausible there's no filename, don't |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
142 * even bother looking for the newline. */ |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
143 return MANIFEST_BOGUS_FILENAME; |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
144 } |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
145 next = memchr(data, '\n', len); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
146 if (!next) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
147 return MANIFEST_MALFORMED; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
148 } |
40765
7e6834ade51d
manifest: reject lines shorter than 42 bytes, not 22
Augie Fackler <augie@google.com>
parents:
40601
diff
changeset
|
149 if ((next - data) < 42) { |
7e6834ade51d
manifest: reject lines shorter than 42 bytes, not 22
Augie Fackler <augie@google.com>
parents:
40601
diff
changeset
|
150 /* We should have at least 42 bytes in a line: |
40600
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
151 1 byte filename |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
152 1 NUL |
40765
7e6834ade51d
manifest: reject lines shorter than 42 bytes, not 22
Augie Fackler <augie@google.com>
parents:
40601
diff
changeset
|
153 40 bytes of hash |
40600
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
154 so we can give up here. |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
155 */ |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
156 return MANIFEST_TOO_SHORT_LINE; |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
157 } |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
158 next++; /* advance past newline */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
159 if (prev && strcmp(prev, data) > -1) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
160 /* This data isn't sorted, so we have to abort. */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
161 return MANIFEST_NOT_SORTED; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
162 } |
40601
da4478ca0e32
manifest: perform cheap checks before potentially allocating memory
Augie Fackler <augie@google.com>
parents:
40600
diff
changeset
|
163 if (!realloc_if_full(self)) { |
da4478ca0e32
manifest: perform cheap checks before potentially allocating memory
Augie Fackler <augie@google.com>
parents:
40600
diff
changeset
|
164 return MANIFEST_OOM; /* no memory */ |
da4478ca0e32
manifest: perform cheap checks before potentially allocating memory
Augie Fackler <augie@google.com>
parents:
40600
diff
changeset
|
165 } |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
166 l = self->lines + ((self->numlines)++); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
167 l->start = data; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
168 l->len = next - data; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
169 l->hash_suffix = '\0'; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
170 l->from_malloc = false; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
171 l->deleted = false; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
172 len = len - l->len; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
173 prev = data; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
174 data = next; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
175 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
176 self->livelines = self->numlines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
177 return 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
178 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
179 |
38335
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
180 static void lazymanifest_init_early(lazymanifest *self) |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
181 { |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
182 self->pydata = NULL; |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
183 self->lines = NULL; |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
184 self->numlines = 0; |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
185 self->maxlines = 0; |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
186 } |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
187 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
188 static int lazymanifest_init(lazymanifest *self, PyObject *args) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
189 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
190 char *data; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
191 Py_ssize_t len; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
192 int err, ret; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
193 PyObject *pydata; |
38335
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
194 |
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
195 lazymanifest_init_early(self); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
196 if (!PyArg_ParseTuple(args, "S", &pydata)) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
197 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
198 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
199 err = PyBytes_AsStringAndSize(pydata, &data, &len); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
200 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
201 self->dirty = false; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
202 if (err == -1) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
203 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
204 self->pydata = pydata; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
205 Py_INCREF(self->pydata); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
206 Py_BEGIN_ALLOW_THREADS |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
207 self->lines = malloc(DEFAULT_LINES * sizeof(line)); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
208 self->maxlines = DEFAULT_LINES; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
209 self->numlines = 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
210 if (!self->lines) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
211 ret = MANIFEST_OOM; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
212 else |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
213 ret = find_lines(self, data, len); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
214 Py_END_ALLOW_THREADS |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
215 switch (ret) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
216 case 0: |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
217 break; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
218 case MANIFEST_OOM: |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
219 PyErr_NoMemory(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
220 break; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
221 case MANIFEST_NOT_SORTED: |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
222 PyErr_Format(PyExc_ValueError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
223 "Manifest lines not in sorted order."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
224 break; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
225 case MANIFEST_MALFORMED: |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
226 PyErr_Format(PyExc_ValueError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
227 "Manifest did not end in a newline."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
228 break; |
40599
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
229 case MANIFEST_BOGUS_FILENAME: |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
230 PyErr_Format( |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
231 PyExc_ValueError, |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
232 "Manifest had an entry with a zero-length filename."); |
9eeda7199181
manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents:
39940
diff
changeset
|
233 break; |
40600
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
234 case MANIFEST_TOO_SHORT_LINE: |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
235 PyErr_Format( |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
236 PyExc_ValueError, |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
237 "Manifest had implausibly-short line."); |
f27f8e9ef1e7
manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents:
40599
diff
changeset
|
238 break; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
239 default: |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
240 PyErr_Format(PyExc_ValueError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
241 "Unknown problem parsing manifest."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
242 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
243 return ret == 0 ? 0 : -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
244 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
245 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
246 static void lazymanifest_dealloc(lazymanifest *self) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
247 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
248 /* free any extra lines we had to allocate */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
249 int i; |
38302
6caca2a7d37f
lazymanifest: don't crash when out of memory (issue5916)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
38301
diff
changeset
|
250 for (i = 0; self->lines && (i < self->numlines); i++) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
251 if (self->lines[i].from_malloc) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
252 free(self->lines[i].start); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
253 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
254 } |
38301
d9e87566f879
cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
36619
diff
changeset
|
255 free(self->lines); |
d9e87566f879
cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
36619
diff
changeset
|
256 self->lines = NULL; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
257 if (self->pydata) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
258 Py_DECREF(self->pydata); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
259 self->pydata = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
260 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
261 PyObject_Del(self); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
262 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
263 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
264 /* iteration support */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
265 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
266 typedef struct { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
267 PyObject_HEAD lazymanifest *m; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
268 Py_ssize_t pos; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
269 } lmIter; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
270 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
271 static void lmiter_dealloc(PyObject *o) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
272 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
273 lmIter *self = (lmIter *)o; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
274 Py_DECREF(self->m); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
275 PyObject_Del(self); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
276 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
277 |
24294
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
278 static line *lmiter_nextline(lmIter *self) |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
279 { |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
280 do { |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
281 self->pos++; |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
282 if (self->pos >= self->m->numlines) { |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
283 return NULL; |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
284 } |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
285 /* skip over deleted manifest entries */ |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
286 } while (self->m->lines[self->pos].deleted); |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
287 return self->m->lines + self->pos; |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
288 } |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
289 |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
290 static PyObject *lmiter_iterentriesnext(PyObject *o) |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
291 { |
44100
969527ac7b44
cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents:
40765
diff
changeset
|
292 Py_ssize_t pl; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
293 line *l; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
294 Py_ssize_t consumed; |
24699
64cd23a1bc13
lazymanifest: fix memory leak in lmiter_iterentriesnext() after 3d485727e45e
Mike Hommey <mh@glandium.org>
parents:
24442
diff
changeset
|
295 PyObject *ret = NULL, *path = NULL, *hash = NULL, *flags = NULL; |
24294
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
296 l = lmiter_nextline((lmIter *)o); |
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
297 if (!l) { |
24974
46408b80c3a1
lazymanifest: avoid 'bail' label when used on success path
Martin von Zweigbergk <martinvonz@google.com>
parents:
24710
diff
changeset
|
298 goto done; |
24294
3d485727e45e
lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents:
24293
diff
changeset
|
299 } |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
300 pl = pathlen(l); |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
301 path = PyBytes_FromStringAndSize(l->start, pl); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
302 hash = nodeof(l); |
39940
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
303 if (!path || !hash) { |
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
304 goto done; |
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
305 } |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
306 consumed = pl + 41; |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
307 flags = PyBytes_FromStringAndSize(l->start + consumed, |
27340
7b8b6e3b3571
manifest: fix formatting
Bryan O'Sullivan <bos@serpentine.com>
parents:
24975
diff
changeset
|
308 l->len - consumed - 1); |
39940
5405cb1a7901
manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents:
39939
diff
changeset
|
309 if (!flags) { |
24974
46408b80c3a1
lazymanifest: avoid 'bail' label when used on success path
Martin von Zweigbergk <martinvonz@google.com>
parents:
24710
diff
changeset
|
310 goto done; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
311 } |
24699
64cd23a1bc13
lazymanifest: fix memory leak in lmiter_iterentriesnext() after 3d485727e45e
Mike Hommey <mh@glandium.org>
parents:
24442
diff
changeset
|
312 ret = PyTuple_Pack(3, path, hash, flags); |
24975
89c2bf63a83b
lazymanifest: drop SP before some labels
Martin von Zweigbergk <martinvonz@google.com>
parents:
24974
diff
changeset
|
313 done: |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
314 Py_XDECREF(path); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
315 Py_XDECREF(hash); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
316 Py_XDECREF(flags); |
24699
64cd23a1bc13
lazymanifest: fix memory leak in lmiter_iterentriesnext() after 3d485727e45e
Mike Hommey <mh@glandium.org>
parents:
24442
diff
changeset
|
317 return ret; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
318 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
319 |
30079
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
320 #ifdef IS_PY3K |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
321 #define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
322 #else |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
323 #define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
324 | Py_TPFLAGS_HAVE_ITER |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
325 #endif |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
326 |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
327 static PyTypeObject lazymanifestEntriesIterator = { |
34861
6ece4a85c350
cext: add /* header */ comment to all PyVarObject_HEAD_INIT() calls
Augie Fackler <augie@google.com>
parents:
34440
diff
changeset
|
328 PyVarObject_HEAD_INIT(NULL, 0) /* header */ |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
329 "parsers.lazymanifest.entriesiterator", /*tp_name */ |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
330 sizeof(lmIter), /*tp_basicsize */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
331 0, /*tp_itemsize */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
332 lmiter_dealloc, /*tp_dealloc */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
333 0, /*tp_print */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
334 0, /*tp_getattr */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
335 0, /*tp_setattr */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
336 0, /*tp_compare */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
337 0, /*tp_repr */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
338 0, /*tp_as_number */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
339 0, /*tp_as_sequence */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
340 0, /*tp_as_mapping */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
341 0, /*tp_hash */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
342 0, /*tp_call */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
343 0, /*tp_str */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
344 0, /*tp_getattro */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
345 0, /*tp_setattro */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
346 0, /*tp_as_buffer */ |
30079
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
347 LAZYMANIFESTENTRIESITERATOR_TPFLAGS, /* tp_flags */ |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
348 "Iterator for 3-tuples in a lazymanifest.", /* tp_doc */ |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
349 0, /* tp_traverse */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
350 0, /* tp_clear */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
351 0, /* tp_richcompare */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
352 0, /* tp_weaklistoffset */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
353 PyObject_SelfIter, /* tp_iter: __iter__() method */ |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
354 lmiter_iterentriesnext, /* tp_iternext: next() method */ |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
355 }; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
356 |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
357 static PyObject *lmiter_iterkeysnext(PyObject *o) |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
358 { |
44100
969527ac7b44
cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents:
40765
diff
changeset
|
359 Py_ssize_t pl; |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
360 line *l = lmiter_nextline((lmIter *)o); |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
361 if (!l) { |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
362 return NULL; |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
363 } |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
364 pl = pathlen(l); |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
365 return PyBytes_FromStringAndSize(l->start, pl); |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
366 } |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
367 |
30079
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
368 #ifdef IS_PY3K |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
369 #define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
370 #else |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
371 #define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
372 | Py_TPFLAGS_HAVE_ITER |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
373 #endif |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
374 |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
375 static PyTypeObject lazymanifestKeysIterator = { |
34861
6ece4a85c350
cext: add /* header */ comment to all PyVarObject_HEAD_INIT() calls
Augie Fackler <augie@google.com>
parents:
34440
diff
changeset
|
376 PyVarObject_HEAD_INIT(NULL, 0) /* header */ |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
377 "parsers.lazymanifest.keysiterator", /*tp_name */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
378 sizeof(lmIter), /*tp_basicsize */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
379 0, /*tp_itemsize */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
380 lmiter_dealloc, /*tp_dealloc */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
381 0, /*tp_print */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
382 0, /*tp_getattr */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
383 0, /*tp_setattr */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
384 0, /*tp_compare */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
385 0, /*tp_repr */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
386 0, /*tp_as_number */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
387 0, /*tp_as_sequence */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
388 0, /*tp_as_mapping */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
389 0, /*tp_hash */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
390 0, /*tp_call */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
391 0, /*tp_str */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
392 0, /*tp_getattro */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
393 0, /*tp_setattro */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
394 0, /*tp_as_buffer */ |
30079
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
395 LAZYMANIFESTKEYSITERATOR_TPFLAGS, /* tp_flags */ |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
396 "Keys iterator for a lazymanifest.", /* tp_doc */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
397 0, /* tp_traverse */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
398 0, /* tp_clear */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
399 0, /* tp_richcompare */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
400 0, /* tp_weaklistoffset */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
401 PyObject_SelfIter, /* tp_iter: __iter__() method */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
402 lmiter_iterkeysnext, /* tp_iternext: next() method */ |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
403 }; |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
404 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
405 static lazymanifest *lazymanifest_copy(lazymanifest *self); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
406 |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
407 static PyObject *lazymanifest_getentriesiter(lazymanifest *self) |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
408 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
409 lmIter *i = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
410 lazymanifest *t = lazymanifest_copy(self); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
411 if (!t) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
412 PyErr_NoMemory(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
413 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
414 } |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
415 i = PyObject_New(lmIter, &lazymanifestEntriesIterator); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
416 if (i) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
417 i->m = t; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
418 i->pos = -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
419 } else { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
420 Py_DECREF(t); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
421 PyErr_NoMemory(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
422 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
423 return (PyObject *)i; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
424 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
425 |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
426 static PyObject *lazymanifest_getkeysiter(lazymanifest *self) |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
427 { |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
428 lmIter *i = NULL; |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
429 lazymanifest *t = lazymanifest_copy(self); |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
430 if (!t) { |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
431 PyErr_NoMemory(); |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
432 return NULL; |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
433 } |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
434 i = PyObject_New(lmIter, &lazymanifestKeysIterator); |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
435 if (i) { |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
436 i->m = t; |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
437 i->pos = -1; |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
438 } else { |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
439 Py_DECREF(t); |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
440 PyErr_NoMemory(); |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
441 } |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
442 return (PyObject *)i; |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
443 } |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
444 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
445 /* __getitem__ and __setitem__ support */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
446 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
447 static Py_ssize_t lazymanifest_size(lazymanifest *self) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
448 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
449 return self->livelines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
450 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
451 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
452 static int linecmp(const void *left, const void *right) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
453 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
454 return strcmp(((const line *)left)->start, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
455 ((const line *)right)->start); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
456 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
457 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
458 static PyObject *lazymanifest_getitem(lazymanifest *self, PyObject *key) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
459 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
460 line needle; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
461 line *hit; |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
462 if (!PyBytes_Check(key)) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
463 PyErr_Format(PyExc_TypeError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
464 "getitem: manifest keys must be a string."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
465 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
466 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
467 needle.start = PyBytes_AsString(key); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
468 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
469 &linecmp); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
470 if (!hit || hit->deleted) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
471 PyErr_Format(PyExc_KeyError, "No such manifest entry."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
472 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
473 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
474 return hashflags(hit); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
475 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
476 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
477 static int lazymanifest_delitem(lazymanifest *self, PyObject *key) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
478 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
479 line needle; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
480 line *hit; |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
481 if (!PyBytes_Check(key)) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
482 PyErr_Format(PyExc_TypeError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
483 "delitem: manifest keys must be a string."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
484 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
485 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
486 needle.start = PyBytes_AsString(key); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
487 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
488 &linecmp); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
489 if (!hit || hit->deleted) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
490 PyErr_Format(PyExc_KeyError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
491 "Tried to delete nonexistent manifest entry."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
492 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
493 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
494 self->dirty = true; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
495 hit->deleted = true; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
496 self->livelines--; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
497 return 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
498 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
499 |
24228
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
500 /* Do a binary search for the insertion point for new, creating the |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
501 * new entry if needed. */ |
34440
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
502 static int internalsetitem(lazymanifest *self, line *new) |
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
503 { |
24228
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
504 int start = 0, end = self->numlines; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
505 while (start < end) { |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
506 int pos = start + (end - start) / 2; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
507 int c = linecmp(new, self->lines + pos); |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
508 if (c < 0) |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
509 end = pos; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
510 else if (c > 0) |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
511 start = pos + 1; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
512 else { |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
513 if (self->lines[pos].deleted) |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
514 self->livelines++; |
24710
909ee6b2a024
lazymanifest: prevent leak when updating an entry more than once
Augie Fackler <augie@google.com>
parents:
24699
diff
changeset
|
515 if (self->lines[pos].from_malloc) |
909ee6b2a024
lazymanifest: prevent leak when updating an entry more than once
Augie Fackler <augie@google.com>
parents:
24699
diff
changeset
|
516 free(self->lines[pos].start); |
24228
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
517 start = pos; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
518 goto finish; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
519 } |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
520 } |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
521 /* being here means we need to do an insert */ |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
522 if (!realloc_if_full(self)) { |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
523 PyErr_NoMemory(); |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
524 return -1; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
525 } |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
526 memmove(self->lines + start + 1, self->lines + start, |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
527 (self->numlines - start) * sizeof(line)); |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
528 self->numlines++; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
529 self->livelines++; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
530 finish: |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
531 self->lines[start] = *new; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
532 self->dirty = true; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
533 return 0; |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
534 } |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
535 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
536 static int lazymanifest_setitem( |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
537 lazymanifest *self, PyObject *key, PyObject *value) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
538 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
539 char *path; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
540 Py_ssize_t plen; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
541 PyObject *pyhash; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
542 Py_ssize_t hlen; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
543 char *hash; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
544 PyObject *pyflags; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
545 char *flags; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
546 Py_ssize_t flen; |
44132
f0a4084f82d6
cext: change two more vars to Py_ssize_t in manifest.c
Kyle Lippincott <spectral@google.com>
parents:
44100
diff
changeset
|
547 Py_ssize_t dlen; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
548 char *dest; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
549 int i; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
550 line new; |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
551 if (!PyBytes_Check(key)) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
552 PyErr_Format(PyExc_TypeError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
553 "setitem: manifest keys must be a string."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
554 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
555 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
556 if (!value) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
557 return lazymanifest_delitem(self, key); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
558 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
559 if (!PyTuple_Check(value) || PyTuple_Size(value) != 2) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
560 PyErr_Format(PyExc_TypeError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
561 "Manifest values must be a tuple of (node, flags)."); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
562 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
563 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
564 if (PyBytes_AsStringAndSize(key, &path, &plen) == -1) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
565 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
566 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
567 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
568 pyhash = PyTuple_GetItem(value, 0); |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
569 if (!PyBytes_Check(pyhash)) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
570 PyErr_Format(PyExc_TypeError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
571 "node must be a 20-byte string"); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
572 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
573 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
574 hlen = PyBytes_Size(pyhash); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
575 /* Some parts of the codebase try and set 21 or 22 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
576 * byte "hash" values in order to perturb things for |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
577 * status. We have to preserve at least the 21st |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
578 * byte. Sigh. If there's a 22nd byte, we drop it on |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
579 * the floor, which works fine. |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
580 */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
581 if (hlen != 20 && hlen != 21 && hlen != 22) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
582 PyErr_Format(PyExc_TypeError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
583 "node must be a 20-byte string"); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
584 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
585 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
586 hash = PyBytes_AsString(pyhash); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
587 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
588 pyflags = PyTuple_GetItem(value, 1); |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
589 if (!PyBytes_Check(pyflags) || PyBytes_Size(pyflags) > 1) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
590 PyErr_Format(PyExc_TypeError, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
591 "flags must a 0 or 1 byte string"); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
592 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
593 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
594 if (PyBytes_AsStringAndSize(pyflags, &flags, &flen) == -1) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
595 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
596 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
597 /* one null byte and one newline */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
598 dlen = plen + 41 + flen + 1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
599 dest = malloc(dlen); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
600 if (!dest) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
601 PyErr_NoMemory(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
602 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
603 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
604 memcpy(dest, path, plen + 1); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
605 for (i = 0; i < 20; i++) { |
24286
40528ad1b1e8
lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents:
24228
diff
changeset
|
606 /* Cast to unsigned, so it will not get sign-extended when promoted |
40528ad1b1e8
lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents:
24228
diff
changeset
|
607 * to int (as is done when passing to a variadic function) |
40528ad1b1e8
lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents:
24228
diff
changeset
|
608 */ |
40528ad1b1e8
lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents:
24228
diff
changeset
|
609 sprintf(dest + plen + 1 + (i * 2), "%02x", (unsigned char)hash[i]); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
610 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
611 memcpy(dest + plen + 41, flags, flen); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
612 dest[plen + 41 + flen] = '\n'; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
613 new.start = dest; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
614 new.len = dlen; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
615 new.hash_suffix = '\0'; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
616 if (hlen > 20) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
617 new.hash_suffix = hash[20]; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
618 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
619 new.from_malloc = true; /* is `start` a pointer we allocated? */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
620 new.deleted = false; /* is this entry deleted? */ |
24228
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
621 if (internalsetitem(self, &new)) { |
542c891274b2
lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents:
24214
diff
changeset
|
622 return -1; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
623 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
624 return 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
625 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
626 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
627 static PyMappingMethods lazymanifest_mapping_methods = { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
628 (lenfunc)lazymanifest_size, /* mp_length */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
629 (binaryfunc)lazymanifest_getitem, /* mp_subscript */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
630 (objobjargproc)lazymanifest_setitem, /* mp_ass_subscript */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
631 }; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
632 |
27608
d6aa1a8c8d7c
lazymanifest: add missing closing parenthesis in comment
Augie Fackler <raf@durin42.com>
parents:
27340
diff
changeset
|
633 /* sequence methods (important or __contains__ builds an iterator) */ |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
634 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
635 static int lazymanifest_contains(lazymanifest *self, PyObject *key) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
636 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
637 line needle; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
638 line *hit; |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
639 if (!PyBytes_Check(key)) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
640 /* Our keys are always strings, so if the contains |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
641 * check is for a non-string, just return false. */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
642 return 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
643 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
644 needle.start = PyBytes_AsString(key); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
645 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
646 &linecmp); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
647 if (!hit || hit->deleted) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
648 return 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
649 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
650 return 1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
651 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
652 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
653 static PySequenceMethods lazymanifest_seq_meths = { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
654 (lenfunc)lazymanifest_size, /* sq_length */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
655 0, /* sq_concat */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
656 0, /* sq_repeat */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
657 0, /* sq_item */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
658 0, /* sq_slice */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
659 0, /* sq_ass_item */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
660 0, /* sq_ass_slice */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
661 (objobjproc)lazymanifest_contains, /* sq_contains */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
662 0, /* sq_inplace_concat */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
663 0, /* sq_inplace_repeat */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
664 }; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
665 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
666 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
667 /* Other methods (copy, diff, etc) */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
668 static PyTypeObject lazymanifestType; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
669 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
670 /* If the manifest has changes, build the new manifest text and reindex it. */ |
34440
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
671 static int compact(lazymanifest *self) |
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
672 { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
673 int i; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
674 ssize_t need = 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
675 char *data; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
676 line *src, *dst; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
677 PyObject *pydata; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
678 if (!self->dirty) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
679 return 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
680 for (i = 0; i < self->numlines; i++) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
681 if (!self->lines[i].deleted) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
682 need += self->lines[i].len; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
683 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
684 } |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
685 pydata = PyBytes_FromStringAndSize(NULL, need); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
686 if (!pydata) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
687 return -1; |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
688 data = PyBytes_AsString(pydata); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
689 if (!data) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
690 return -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
691 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
692 src = self->lines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
693 dst = self->lines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
694 for (i = 0; i < self->numlines; i++, src++) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
695 char *tofree = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
696 if (src->from_malloc) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
697 tofree = src->start; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
698 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
699 if (!src->deleted) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
700 memcpy(data, src->start, src->len); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
701 *dst = *src; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
702 dst->start = data; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
703 dst->from_malloc = false; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
704 data += dst->len; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
705 dst++; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
706 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
707 free(tofree); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
708 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
709 Py_DECREF(self->pydata); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
710 self->pydata = pydata; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
711 self->numlines = self->livelines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
712 self->dirty = false; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
713 return 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
714 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
715 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
716 static PyObject *lazymanifest_text(lazymanifest *self) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
717 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
718 if (compact(self) != 0) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
719 PyErr_NoMemory(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
720 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
721 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
722 Py_INCREF(self->pydata); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
723 return self->pydata; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
724 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
725 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
726 static lazymanifest *lazymanifest_copy(lazymanifest *self) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
727 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
728 lazymanifest *copy = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
729 if (compact(self) != 0) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
730 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
731 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
732 copy = PyObject_New(lazymanifest, &lazymanifestType); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
733 if (!copy) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
734 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
735 } |
38335
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
736 lazymanifest_init_early(copy); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
737 copy->numlines = self->numlines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
738 copy->livelines = self->livelines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
739 copy->dirty = false; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
740 copy->lines = malloc(self->maxlines *sizeof(line)); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
741 if (!copy->lines) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
742 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
743 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
744 memcpy(copy->lines, self->lines, self->numlines * sizeof(line)); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
745 copy->maxlines = self->maxlines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
746 copy->pydata = self->pydata; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
747 Py_INCREF(copy->pydata); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
748 return copy; |
24975
89c2bf63a83b
lazymanifest: drop SP before some labels
Martin von Zweigbergk <martinvonz@google.com>
parents:
24974
diff
changeset
|
749 nomem: |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
750 PyErr_NoMemory(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
751 Py_XDECREF(copy); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
752 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
753 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
754 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
755 static lazymanifest *lazymanifest_filtercopy( |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
756 lazymanifest *self, PyObject *matchfn) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
757 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
758 lazymanifest *copy = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
759 int i; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
760 if (!PyCallable_Check(matchfn)) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
761 PyErr_SetString(PyExc_TypeError, "matchfn must be callable"); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
762 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
763 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
764 /* compact ourselves first to avoid double-frees later when we |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
765 * compact tmp so that it doesn't have random pointers to our |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
766 * underlying from_malloc-data (self->pydata is safe) */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
767 if (compact(self) != 0) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
768 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
769 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
770 copy = PyObject_New(lazymanifest, &lazymanifestType); |
27609
ca2d4080a02e
lazymanifest: check error return in filter
Augie Fackler <raf@durin42.com>
parents:
27608
diff
changeset
|
771 if (!copy) { |
ca2d4080a02e
lazymanifest: check error return in filter
Augie Fackler <raf@durin42.com>
parents:
27608
diff
changeset
|
772 goto nomem; |
ca2d4080a02e
lazymanifest: check error return in filter
Augie Fackler <raf@durin42.com>
parents:
27608
diff
changeset
|
773 } |
38335
ae7f27867c2a
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents:
38302
diff
changeset
|
774 lazymanifest_init_early(copy); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
775 copy->dirty = true; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
776 copy->lines = malloc(self->maxlines * sizeof(line)); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
777 if (!copy->lines) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
778 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
779 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
780 copy->maxlines = self->maxlines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
781 copy->numlines = 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
782 copy->pydata = self->pydata; |
39423
ca77788c81bc
manifest: incref/decref copy->pydata to clarify 'copy' holds a reference
Yuya Nishihara <yuya@tcha.org>
parents:
38335
diff
changeset
|
783 Py_INCREF(copy->pydata); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
784 for (i = 0; i < self->numlines; i++) { |
27661
abc79f44f548
lazymanifest: check more return values in filtercopy
Augie Fackler <raf@durin42.com>
parents:
27609
diff
changeset
|
785 PyObject *arglist = NULL, *result = NULL; |
36619
1f8c3fadbb8e
py3: bulk-replace bytes format specifier passed to Py_BuildValue()
Yuya Nishihara <yuya@tcha.org>
parents:
35810
diff
changeset
|
786 arglist = Py_BuildValue(PY23("(s)", "(y)"), |
1f8c3fadbb8e
py3: bulk-replace bytes format specifier passed to Py_BuildValue()
Yuya Nishihara <yuya@tcha.org>
parents:
35810
diff
changeset
|
787 self->lines[i].start); |
27661
abc79f44f548
lazymanifest: check more return values in filtercopy
Augie Fackler <raf@durin42.com>
parents:
27609
diff
changeset
|
788 if (!arglist) { |
39424
094d1f42c484
manifest: fix leak on error return from lazymanifest_filtercopy()
Yuya Nishihara <yuya@tcha.org>
parents:
39423
diff
changeset
|
789 goto bail; |
27661
abc79f44f548
lazymanifest: check more return values in filtercopy
Augie Fackler <raf@durin42.com>
parents:
27609
diff
changeset
|
790 } |
abc79f44f548
lazymanifest: check more return values in filtercopy
Augie Fackler <raf@durin42.com>
parents:
27609
diff
changeset
|
791 result = PyObject_CallObject(matchfn, arglist); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
792 Py_DECREF(arglist); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
793 /* if the callback raised an exception, just let it |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
794 * through and give up */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
795 if (!result) { |
39424
094d1f42c484
manifest: fix leak on error return from lazymanifest_filtercopy()
Yuya Nishihara <yuya@tcha.org>
parents:
39423
diff
changeset
|
796 goto bail; |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
797 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
798 if (PyObject_IsTrue(result)) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
799 assert(!(self->lines[i].from_malloc)); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
800 copy->lines[copy->numlines++] = self->lines[i]; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
801 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
802 Py_DECREF(result); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
803 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
804 copy->livelines = copy->numlines; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
805 return copy; |
24975
89c2bf63a83b
lazymanifest: drop SP before some labels
Martin von Zweigbergk <martinvonz@google.com>
parents:
24974
diff
changeset
|
806 nomem: |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
807 PyErr_NoMemory(); |
39424
094d1f42c484
manifest: fix leak on error return from lazymanifest_filtercopy()
Yuya Nishihara <yuya@tcha.org>
parents:
39423
diff
changeset
|
808 bail: |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
809 Py_XDECREF(copy); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
810 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
811 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
812 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
813 static PyObject *lazymanifest_diff(lazymanifest *self, PyObject *args) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
814 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
815 lazymanifest *other; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
816 PyObject *pyclean = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
817 bool listclean; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
818 PyObject *emptyTup = NULL, *ret = NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
819 PyObject *es; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
820 int sneedle = 0, oneedle = 0; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
821 if (!PyArg_ParseTuple(args, "O!|O", &lazymanifestType, &other, &pyclean)) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
822 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
823 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
824 listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean); |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
825 es = PyBytes_FromString(""); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
826 if (!es) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
827 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
828 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
829 emptyTup = PyTuple_Pack(2, Py_None, es); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
830 Py_DECREF(es); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
831 if (!emptyTup) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
832 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
833 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
834 ret = PyDict_New(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
835 if (!ret) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
836 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
837 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
838 while (sneedle != self->numlines || oneedle != other->numlines) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
839 line *left = self->lines + sneedle; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
840 line *right = other->lines + oneedle; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
841 int result; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
842 PyObject *key; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
843 PyObject *outer; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
844 /* If we're looking at a deleted entry and it's not |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
845 * the end of the manifest, just skip it. */ |
35810
113a30b87716
lazymanifest: avoid reading uninitialized memory
Jun Wu <quark@fb.com>
parents:
34861
diff
changeset
|
846 if (sneedle < self->numlines && left->deleted) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
847 sneedle++; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
848 continue; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
849 } |
35810
113a30b87716
lazymanifest: avoid reading uninitialized memory
Jun Wu <quark@fb.com>
parents:
34861
diff
changeset
|
850 if (oneedle < other->numlines && right->deleted) { |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
851 oneedle++; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
852 continue; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
853 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
854 /* if we're at the end of either manifest, then we |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
855 * know the remaining items are adds so we can skip |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
856 * the strcmp. */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
857 if (sneedle == self->numlines) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
858 result = 1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
859 } else if (oneedle == other->numlines) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
860 result = -1; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
861 } else { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
862 result = linecmp(left, right); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
863 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
864 key = result <= 0 ? |
30097
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
865 PyBytes_FromString(left->start) : |
3bf4b762537e
manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30079
diff
changeset
|
866 PyBytes_FromString(right->start); |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
867 if (!key) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
868 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
869 if (result < 0) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
870 PyObject *l = hashflags(left); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
871 if (!l) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
872 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
873 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
874 outer = PyTuple_Pack(2, l, emptyTup); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
875 Py_DECREF(l); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
876 if (!outer) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
877 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
878 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
879 PyDict_SetItem(ret, key, outer); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
880 Py_DECREF(outer); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
881 sneedle++; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
882 } else if (result > 0) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
883 PyObject *r = hashflags(right); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
884 if (!r) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
885 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
886 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
887 outer = PyTuple_Pack(2, emptyTup, r); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
888 Py_DECREF(r); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
889 if (!outer) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
890 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
891 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
892 PyDict_SetItem(ret, key, outer); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
893 Py_DECREF(outer); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
894 oneedle++; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
895 } else { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
896 /* file exists in both manifests */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
897 if (left->len != right->len |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
898 || memcmp(left->start, right->start, left->len) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
899 || left->hash_suffix != right->hash_suffix) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
900 PyObject *l = hashflags(left); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
901 PyObject *r; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
902 if (!l) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
903 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
904 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
905 r = hashflags(right); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
906 if (!r) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
907 Py_DECREF(l); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
908 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
909 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
910 outer = PyTuple_Pack(2, l, r); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
911 Py_DECREF(l); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
912 Py_DECREF(r); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
913 if (!outer) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
914 goto nomem; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
915 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
916 PyDict_SetItem(ret, key, outer); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
917 Py_DECREF(outer); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
918 } else if (listclean) { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
919 PyDict_SetItem(ret, key, Py_None); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
920 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
921 sneedle++; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
922 oneedle++; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
923 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
924 Py_DECREF(key); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
925 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
926 Py_DECREF(emptyTup); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
927 return ret; |
24975
89c2bf63a83b
lazymanifest: drop SP before some labels
Martin von Zweigbergk <martinvonz@google.com>
parents:
24974
diff
changeset
|
928 nomem: |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
929 PyErr_NoMemory(); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
930 Py_XDECREF(ret); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
931 Py_XDECREF(emptyTup); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
932 return NULL; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
933 } |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
934 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
935 static PyMethodDef lazymanifest_methods[] = { |
24295
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
936 {"iterkeys", (PyCFunction)lazymanifest_getkeysiter, METH_NOARGS, |
2b7ab29627fd
lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents:
24294
diff
changeset
|
937 "Iterate over file names in this lazymanifest."}, |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
938 {"iterentries", (PyCFunction)lazymanifest_getentriesiter, METH_NOARGS, |
29254
c5912a0b156c
lazymanifest: fix typo s/typles/tuples/
Javi Merino <merino.jav@gmail.com>
parents:
27661
diff
changeset
|
939 "Iterate over (path, nodeid, flags) tuples in this lazymanifest."}, |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
940 {"copy", (PyCFunction)lazymanifest_copy, METH_NOARGS, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
941 "Make a copy of this lazymanifest."}, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
942 {"filtercopy", (PyCFunction)lazymanifest_filtercopy, METH_O, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
943 "Make a copy of this manifest filtered by matchfn."}, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
944 {"diff", (PyCFunction)lazymanifest_diff, METH_VARARGS, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
945 "Compare this lazymanifest to another one."}, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
946 {"text", (PyCFunction)lazymanifest_text, METH_NOARGS, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
947 "Encode this manifest to text."}, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
948 {NULL}, |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
949 }; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
950 |
30079
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
951 #ifdef IS_PY3K |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
952 #define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
953 #else |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
954 #define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
955 #endif |
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
956 |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
957 static PyTypeObject lazymanifestType = { |
34861
6ece4a85c350
cext: add /* header */ comment to all PyVarObject_HEAD_INIT() calls
Augie Fackler <augie@google.com>
parents:
34440
diff
changeset
|
958 PyVarObject_HEAD_INIT(NULL, 0) /* header */ |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
959 "parsers.lazymanifest", /* tp_name */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
960 sizeof(lazymanifest), /* tp_basicsize */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
961 0, /* tp_itemsize */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
962 (destructor)lazymanifest_dealloc, /* tp_dealloc */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
963 0, /* tp_print */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
964 0, /* tp_getattr */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
965 0, /* tp_setattr */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
966 0, /* tp_compare */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
967 0, /* tp_repr */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
968 0, /* tp_as_number */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
969 &lazymanifest_seq_meths, /* tp_as_sequence */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
970 &lazymanifest_mapping_methods, /* tp_as_mapping */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
971 0, /* tp_hash */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
972 0, /* tp_call */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
973 0, /* tp_str */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
974 0, /* tp_getattro */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
975 0, /* tp_setattro */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
976 0, /* tp_as_buffer */ |
30079
84debea79903
manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29254
diff
changeset
|
977 LAZYMANIFEST_TPFLAGS, /* tp_flags */ |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
978 "TODO(augie)", /* tp_doc */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
979 0, /* tp_traverse */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
980 0, /* tp_clear */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
981 0, /* tp_richcompare */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
982 0, /* tp_weaklistoffset */ |
24298
49cd847fd69a
lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents:
24295
diff
changeset
|
983 (getiterfunc)lazymanifest_getkeysiter, /* tp_iter */ |
24214
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
984 0, /* tp_iternext */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
985 lazymanifest_methods, /* tp_methods */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
986 0, /* tp_members */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
987 0, /* tp_getset */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
988 0, /* tp_base */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
989 0, /* tp_dict */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
990 0, /* tp_descr_get */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
991 0, /* tp_descr_set */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
992 0, /* tp_dictoffset */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
993 (initproc)lazymanifest_init, /* tp_init */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
994 0, /* tp_alloc */ |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
995 }; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
996 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
997 void manifest_module_init(PyObject * mod) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
998 { |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
999 lazymanifestType.tp_new = PyType_GenericNew; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1000 if (PyType_Ready(&lazymanifestType) < 0) |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1001 return; |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1002 Py_INCREF(&lazymanifestType); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1003 |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1004 PyModule_AddObject(mod, "lazymanifest", |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1005 (PyObject *)&lazymanifestType); |
a5f1bccd2996
manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1006 } |