mercurial/cext/manifest.c
author Joerg Sonnenberger <joerg@bec.de>
Mon, 06 Jul 2020 03:43:32 +0200
changeset 45118 d0ef8c1dddd4
parent 44702 0b0e72b5d551
child 45141 9719e118e4af
permissions -rw-r--r--
manifest: tigher manifest parsing and flag use In the manifest line, flags are put directly after the hash, so the parser has been guessing the presence of flags based on the length of the hash. Replace this assumption by an enumeration of the valid flags and removing them from the hash first as they are distinct input values. Consistently handle the expected 256bit length of the SHA1-replacement in the pure Python parser. Check that setting flags will use one of the blessed values. Extend write logic in the C version to handle 256bit hashes as well. Verify that hashes always have exactly the expected length. Since 1070df141718 we should no longer depend on the old extra-byte hack. Differential Revision: https://phab.mercurial-scm.org/D8679
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 */
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    52
static PyObject *nodeof(line *l, char *flag)
34440
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;
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    57
	Py_ssize_t hlen_raw;
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
	}
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    63
	/* Detect flags after the hash first. */
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    64
	switch (s[llen + hlen]) {
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    65
	case 'l':
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    66
	case 't':
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    67
	case 'x':
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    68
		*flag = s[llen + hlen];
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    69
		--hlen;
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    70
		break;
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    71
	default:
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    72
		*flag = '\0';
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    73
		break;
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    74
	}
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    75
44702
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    76
	switch (hlen) {
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    77
	case 40: /* sha1 */
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
    78
		hlen_raw = 20;
44702
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    79
		break;
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    80
	case 64: /* new hash */
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    81
		hlen_raw = 32;
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    82
		break;
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    83
	default:
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    84
		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
    85
		return NULL;
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    86
	}
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    87
	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
    88
	if (!hash) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    89
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    90
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    91
	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
    92
		char newhash[33];
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    93
		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
    94
		Py_DECREF(hash);
44702
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
    95
		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
    96
		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
    97
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    98
	return hash;
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   101
/* 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
   102
static PyObject *hashflags(line *l)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   103
{
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   104
	char flag;
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   105
	PyObject *hash = nodeof(l, &flag);
44702
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
   106
	ssize_t hlen;
0b0e72b5d551 manifest: start removing 40-byte hash restrictions from C code
Augie Fackler <augie@google.com>
parents: 44132
diff changeset
   107
	Py_ssize_t hplen, flen;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   108
	PyObject *flags;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   109
	PyObject *tup;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   110
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   111
	if (!hash)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   112
		return NULL;
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   113
	flags = PyBytes_FromStringAndSize(&flag, flag ? 1 : 0);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   114
	if (!flags) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   115
		Py_DECREF(hash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   116
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   117
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   118
	tup = PyTuple_Pack(2, hash, flags);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   119
	Py_DECREF(flags);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   120
	Py_DECREF(hash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   121
	return tup;
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   124
/* 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
   125
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
   126
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   127
	if (self->numlines == self->maxlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   128
		self->maxlines *= 2;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   129
		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
   130
	}
24312
f208ce59a6e5 manifest.c: ensure realloc_if_full() returns 1 or 0
Matt Harbison <matt_harbison@yahoo.com>
parents: 24298
diff changeset
   131
	return !!self->lines;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
}
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
/*
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   135
 * 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
   136
 * information about each line in 'self'.
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   137
 */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   138
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
   139
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   140
	char *prev = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   141
	while (len > 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   142
		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
   143
		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
   144
		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
   145
			/* 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
   146
			 * 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
   147
			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
   148
		}
9eeda7199181 manifest: make sure there's a filename before bothering to look for newline
Augie Fackler <augie@google.com>
parents: 39940
diff changeset
   149
		next = memchr(data, '\n', len);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
		if (!next) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   151
			return MANIFEST_MALFORMED;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   152
		}
40765
7e6834ade51d manifest: reject lines shorter than 42 bytes, not 22
Augie Fackler <augie@google.com>
parents: 40601
diff changeset
   153
		if ((next - data) < 42) {
7e6834ade51d manifest: reject lines shorter than 42 bytes, not 22
Augie Fackler <augie@google.com>
parents: 40601
diff changeset
   154
			/* 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
   155
			   1 byte filename
f27f8e9ef1e7 manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents: 40599
diff changeset
   156
			   1 NUL
40765
7e6834ade51d manifest: reject lines shorter than 42 bytes, not 22
Augie Fackler <augie@google.com>
parents: 40601
diff changeset
   157
			   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
   158
			   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
   159
			*/
f27f8e9ef1e7 manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents: 40599
diff changeset
   160
			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
   161
		}
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   162
		next++; /* advance past newline */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   163
		if (prev && strcmp(prev, data) > -1) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   164
			/* 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
   165
			return MANIFEST_NOT_SORTED;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   166
		}
40601
da4478ca0e32 manifest: perform cheap checks before potentially allocating memory
Augie Fackler <augie@google.com>
parents: 40600
diff changeset
   167
		if (!realloc_if_full(self)) {
da4478ca0e32 manifest: perform cheap checks before potentially allocating memory
Augie Fackler <augie@google.com>
parents: 40600
diff changeset
   168
			return MANIFEST_OOM; /* no memory */
da4478ca0e32 manifest: perform cheap checks before potentially allocating memory
Augie Fackler <augie@google.com>
parents: 40600
diff changeset
   169
		}
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   170
		l = self->lines + ((self->numlines)++);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   171
		l->start = data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   172
		l->len = next - data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   173
		l->hash_suffix = '\0';
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   174
		l->from_malloc = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   175
		l->deleted = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   176
		len = len - l->len;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   177
		prev = data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   178
		data = next;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   179
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   180
	self->livelines = self->numlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   181
	return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   182
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   183
38335
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   184
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
   185
{
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   186
	self->pydata = NULL;
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   187
	self->lines = NULL;
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   188
	self->numlines = 0;
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   189
	self->maxlines = 0;
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   190
}
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   191
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   192
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
   193
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   194
	char *data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   195
	Py_ssize_t len;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   196
	int err, ret;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   197
	PyObject *pydata;
38335
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   198
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   199
	lazymanifest_init_early(self);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   200
	if (!PyArg_ParseTuple(args, "S", &pydata)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   201
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   202
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   203
	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
   204
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   205
	self->dirty = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   206
	if (err == -1)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   207
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   208
	self->pydata = pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   209
	Py_INCREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   210
	Py_BEGIN_ALLOW_THREADS
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   211
	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
   212
	self->maxlines = DEFAULT_LINES;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   213
	self->numlines = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   214
	if (!self->lines)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   215
		ret = MANIFEST_OOM;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   216
	else
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   217
		ret = find_lines(self, data, len);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   218
	Py_END_ALLOW_THREADS
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   219
	switch (ret) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   220
	case 0:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   221
		break;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   222
	case MANIFEST_OOM:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   223
		PyErr_NoMemory();
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_NOT_SORTED:
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 lines not in sorted order.");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   228
		break;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   229
	case MANIFEST_MALFORMED:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   230
		PyErr_Format(PyExc_ValueError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   231
			     "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
   232
		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
   233
	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
   234
		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
   235
			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
   236
			"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
   237
		break;
40600
f27f8e9ef1e7 manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents: 40599
diff changeset
   238
	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
   239
		PyErr_Format(
f27f8e9ef1e7 manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents: 40599
diff changeset
   240
			PyExc_ValueError,
f27f8e9ef1e7 manifest: also reject obviously-too-short lines when parsing lines
Augie Fackler <augie@google.com>
parents: 40599
diff changeset
   241
			"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
   242
		break;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   243
	default:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   244
		PyErr_Format(PyExc_ValueError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   245
			     "Unknown problem parsing manifest.");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   246
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   247
	return ret == 0 ? 0 : -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   248
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   249
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   250
static void lazymanifest_dealloc(lazymanifest *self)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   251
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   252
	/* 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
   253
	int i;
38302
6caca2a7d37f lazymanifest: don't crash when out of memory (issue5916)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 38301
diff changeset
   254
	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
   255
		if (self->lines[i].from_malloc) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   256
			free(self->lines[i].start);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   257
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   258
	}
38301
d9e87566f879 cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 36619
diff changeset
   259
	free(self->lines);
d9e87566f879 cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 36619
diff changeset
   260
	self->lines = NULL;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   261
	if (self->pydata) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   262
		Py_DECREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   263
		self->pydata = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   264
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   265
	PyObject_Del(self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   266
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   267
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   268
/* iteration support */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   269
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   270
typedef struct {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   271
	PyObject_HEAD lazymanifest *m;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   272
	Py_ssize_t pos;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   273
} lmIter;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   274
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   275
static void lmiter_dealloc(PyObject *o)
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
	lmIter *self = (lmIter *)o;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   278
	Py_DECREF(self->m);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   279
	PyObject_Del(self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   280
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   281
24294
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   282
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
   283
{
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   284
	do {
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   285
		self->pos++;
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   286
		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
   287
			return NULL;
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
		/* skip over deleted manifest entries */
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   290
	} 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
   291
	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
   292
}
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   293
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   294
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
   295
{
44100
969527ac7b44 cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents: 40765
diff changeset
   296
	Py_ssize_t pl;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   297
	line *l;
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   298
	char flag;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   299
	Py_ssize_t consumed;
24699
64cd23a1bc13 lazymanifest: fix memory leak in lmiter_iterentriesnext() after 3d485727e45e
Mike Hommey <mh@glandium.org>
parents: 24442
diff changeset
   300
	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
   301
	l = lmiter_nextline((lmIter *)o);
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   302
	if (!l) {
24974
46408b80c3a1 lazymanifest: avoid 'bail' label when used on success path
Martin von Zweigbergk <martinvonz@google.com>
parents: 24710
diff changeset
   303
		goto done;
24294
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   304
	}
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   305
	pl = pathlen(l);
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   306
	path = PyBytes_FromStringAndSize(l->start, pl);
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   307
	hash = nodeof(l, &flag);
39940
5405cb1a7901 manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents: 39939
diff changeset
   308
	if (!path || !hash) {
5405cb1a7901 manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents: 39939
diff changeset
   309
		goto done;
5405cb1a7901 manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents: 39939
diff changeset
   310
	}
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   311
	flags = PyBytes_FromStringAndSize(&flag, flag ? 1 : 0);
39940
5405cb1a7901 manifest: fix out-of-bounds read of corrupted manifest entry
Yuya Nishihara <yuya@tcha.org>
parents: 39939
diff changeset
   312
	if (!flags) {
24974
46408b80c3a1 lazymanifest: avoid 'bail' label when used on success path
Martin von Zweigbergk <martinvonz@google.com>
parents: 24710
diff changeset
   313
		goto done;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   314
	}
24699
64cd23a1bc13 lazymanifest: fix memory leak in lmiter_iterentriesnext() after 3d485727e45e
Mike Hommey <mh@glandium.org>
parents: 24442
diff changeset
   315
	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
   316
done:
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   317
	Py_XDECREF(path);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   318
	Py_XDECREF(hash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   319
	Py_XDECREF(flags);
24699
64cd23a1bc13 lazymanifest: fix memory leak in lmiter_iterentriesnext() after 3d485727e45e
Mike Hommey <mh@glandium.org>
parents: 24442
diff changeset
   320
	return ret;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   321
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   322
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
   323
#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
   324
#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
   325
#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
   326
#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
   327
	| 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
   328
#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
   329
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   330
static PyTypeObject lazymanifestEntriesIterator = {
34861
6ece4a85c350 cext: add /* header */ comment to all PyVarObject_HEAD_INIT() calls
Augie Fackler <augie@google.com>
parents: 34440
diff changeset
   331
	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
   332
	"parsers.lazymanifest.entriesiterator", /*tp_name */
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   333
	sizeof(lmIter),                  /*tp_basicsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   334
	0,                               /*tp_itemsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   335
	lmiter_dealloc,                  /*tp_dealloc */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   336
	0,                               /*tp_print */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   337
	0,                               /*tp_getattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   338
	0,                               /*tp_setattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   339
	0,                               /*tp_compare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   340
	0,                               /*tp_repr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   341
	0,                               /*tp_as_number */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   342
	0,                               /*tp_as_sequence */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   343
	0,                               /*tp_as_mapping */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   344
	0,                               /*tp_hash */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   345
	0,                               /*tp_call */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   346
	0,                               /*tp_str */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   347
	0,                               /*tp_getattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   348
	0,                               /*tp_setattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   349
	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
   350
	LAZYMANIFESTENTRIESITERATOR_TPFLAGS, /* tp_flags */
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   351
	"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
   352
	0,                               /* tp_traverse */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   353
	0,                               /* tp_clear */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   354
	0,                               /* tp_richcompare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   355
	0,                               /* tp_weaklistoffset */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   356
	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
   357
	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
   358
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   359
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   360
static PyObject *lmiter_iterkeysnext(PyObject *o)
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   361
{
44100
969527ac7b44 cext: fix compiler warning about sign changing
Kyle Lippincott <spectral@google.com>
parents: 40765
diff changeset
   362
	Py_ssize_t pl;
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   363
	line *l = lmiter_nextline((lmIter *)o);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   364
	if (!l) {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   365
		return NULL;
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
	pl = pathlen(l);
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   368
	return PyBytes_FromStringAndSize(l->start, pl);
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   369
}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   370
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
   371
#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
   372
#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
   373
#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
   374
#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
   375
	| 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
   376
#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
   377
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   378
static PyTypeObject lazymanifestKeysIterator = {
34861
6ece4a85c350 cext: add /* header */ comment to all PyVarObject_HEAD_INIT() calls
Augie Fackler <augie@google.com>
parents: 34440
diff changeset
   379
	PyVarObject_HEAD_INIT(NULL, 0) /* header */
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   380
	"parsers.lazymanifest.keysiterator", /*tp_name */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   381
	sizeof(lmIter),                  /*tp_basicsize */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   382
	0,                               /*tp_itemsize */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   383
	lmiter_dealloc,                  /*tp_dealloc */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   384
	0,                               /*tp_print */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   385
	0,                               /*tp_getattr */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   386
	0,                               /*tp_setattr */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   387
	0,                               /*tp_compare */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   388
	0,                               /*tp_repr */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   389
	0,                               /*tp_as_number */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   390
	0,                               /*tp_as_sequence */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   391
	0,                               /*tp_as_mapping */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   392
	0,                               /*tp_hash */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   393
	0,                               /*tp_call */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   394
	0,                               /*tp_str */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   395
	0,                               /*tp_getattro */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   396
	0,                               /*tp_setattro */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   397
	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
   398
	LAZYMANIFESTKEYSITERATOR_TPFLAGS, /* tp_flags */
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   399
	"Keys iterator for a lazymanifest.",  /* tp_doc */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   400
	0,                               /* tp_traverse */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   401
	0,                               /* tp_clear */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   402
	0,                               /* tp_richcompare */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   403
	0,                               /* tp_weaklistoffset */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   404
	PyObject_SelfIter,               /* tp_iter: __iter__() method */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   405
	lmiter_iterkeysnext,             /* tp_iternext: next() method */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   406
};
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   407
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   408
static lazymanifest *lazymanifest_copy(lazymanifest *self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   409
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   410
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
   411
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   412
	lmIter *i = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   413
	lazymanifest *t = lazymanifest_copy(self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   414
	if (!t) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   415
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   416
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   417
	}
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   418
	i = PyObject_New(lmIter, &lazymanifestEntriesIterator);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   419
	if (i) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   420
		i->m = t;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   421
		i->pos = -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   422
	} else {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   423
		Py_DECREF(t);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   424
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   425
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   426
	return (PyObject *)i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   427
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   428
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   429
static PyObject *lazymanifest_getkeysiter(lazymanifest *self)
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   430
{
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   431
	lmIter *i = NULL;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   432
	lazymanifest *t = lazymanifest_copy(self);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   433
	if (!t) {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   434
		PyErr_NoMemory();
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   435
		return NULL;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   436
	}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   437
	i = PyObject_New(lmIter, &lazymanifestKeysIterator);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   438
	if (i) {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   439
		i->m = t;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   440
		i->pos = -1;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   441
	} else {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   442
		Py_DECREF(t);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   443
		PyErr_NoMemory();
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   444
	}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   445
	return (PyObject *)i;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   446
}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   447
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   448
/* __getitem__ and __setitem__ support */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   449
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   450
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
   451
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   452
	return self->livelines;
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   455
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
   456
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   457
	return strcmp(((const line *)left)->start,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   458
		      ((const line *)right)->start);
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   461
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
   462
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   463
	line needle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   464
	line *hit;
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   465
	if (!PyBytes_Check(key)) {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   466
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   467
			     "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
   468
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   469
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   470
	needle.start = PyBytes_AsString(key);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   471
	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
   472
		      &linecmp);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   473
	if (!hit || hit->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   474
		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
   475
		return NULL;
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
	return hashflags(hit);
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   480
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
   481
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   482
	line needle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   483
	line *hit;
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   484
	if (!PyBytes_Check(key)) {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   485
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   486
			     "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
   487
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   488
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   489
	needle.start = PyBytes_AsString(key);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   490
	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
   491
		      &linecmp);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   492
	if (!hit || hit->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   493
		PyErr_Format(PyExc_KeyError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   494
			     "Tried to delete nonexistent manifest entry.");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   495
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   496
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   497
	self->dirty = true;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   498
	hit->deleted = true;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   499
	self->livelines--;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   500
	return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   501
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   502
24228
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   503
/* 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
   504
 * new entry if needed. */
34440
7ed0750c71a1 cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34438
diff changeset
   505
static int internalsetitem(lazymanifest *self, line *new)
7ed0750c71a1 cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34438
diff changeset
   506
{
24228
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   507
	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
   508
	while (start < end) {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   509
		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
   510
		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
   511
		if (c < 0)
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   512
			end = pos;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   513
		else if (c > 0)
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   514
			start = pos + 1;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   515
		else {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   516
			if (self->lines[pos].deleted)
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   517
				self->livelines++;
24710
909ee6b2a024 lazymanifest: prevent leak when updating an entry more than once
Augie Fackler <augie@google.com>
parents: 24699
diff changeset
   518
			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
   519
				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
   520
			start = pos;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   521
			goto finish;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   522
		}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   523
	}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   524
	/* 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
   525
	if (!realloc_if_full(self)) {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   526
		PyErr_NoMemory();
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   527
		return -1;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   528
	}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   529
	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
   530
		(self->numlines - start) * sizeof(line));
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   531
	self->numlines++;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   532
	self->livelines++;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   533
finish:
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   534
	self->lines[start] = *new;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   535
	self->dirty = true;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   536
	return 0;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   537
}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   538
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   539
static int lazymanifest_setitem(
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   540
	lazymanifest *self, PyObject *key, PyObject *value)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   541
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   542
	char *path;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   543
	Py_ssize_t plen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   544
	PyObject *pyhash;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   545
	Py_ssize_t hlen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   546
	char *hash;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   547
	PyObject *pyflags;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   548
	char *flags;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   549
	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
   550
	Py_ssize_t dlen;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   551
	char *dest;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   552
	int i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   553
	line new;
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   554
	if (!PyBytes_Check(key)) {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   555
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   556
			     "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
   557
		return -1;
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 (!value) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   560
		return lazymanifest_delitem(self, key);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   561
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   562
	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
   563
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   564
			     "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
   565
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   566
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   567
	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
   568
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   569
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   570
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   571
	pyhash = PyTuple_GetItem(value, 0);
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   572
	if (!PyBytes_Check(pyhash)) {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   573
		PyErr_Format(PyExc_TypeError,
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   574
			     "node must be a 20 or 32 bytes string");
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   575
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   576
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   577
	hlen = PyBytes_Size(pyhash);
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   578
	if (hlen != 20 && hlen != 32) {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   579
		PyErr_Format(PyExc_TypeError,
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   580
			     "node must be a 20 or 32 bytes string");
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   581
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   582
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   583
	hash = PyBytes_AsString(pyhash);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   584
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   585
	pyflags = PyTuple_GetItem(value, 1);
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   586
	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
   587
		PyErr_Format(PyExc_TypeError,
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   588
			     "flags must a 0 or 1 bytes string");
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   589
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   590
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   591
	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
   592
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   593
	}
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   594
	if (flen == 1) {
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   595
		switch (*flags) {
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   596
		case 'l':
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   597
		case 't':
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   598
		case 'x':
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   599
			break;
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   600
		default:
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   601
			PyErr_Format(PyExc_TypeError, "invalid manifest flag");
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   602
			return -1;
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   603
		}
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   604
	}
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   605
	/* one null byte and one newline */
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   606
	dlen = plen + hlen * 2 + 1 + flen + 1;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   607
	dest = malloc(dlen);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   608
	if (!dest) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   609
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   610
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   611
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   612
	memcpy(dest, path, plen + 1);
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   613
	for (i = 0; i < hlen; i++) {
24286
40528ad1b1e8 lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents: 24228
diff changeset
   614
		/* 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
   615
		 * 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
   616
		 */
40528ad1b1e8 lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents: 24228
diff changeset
   617
		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
   618
	}
45118
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   619
	memcpy(dest + plen + 2 * hlen + 1, flags, flen);
d0ef8c1dddd4 manifest: tigher manifest parsing and flag use
Joerg Sonnenberger <joerg@bec.de>
parents: 44702
diff changeset
   620
	dest[plen + 2 * hlen + 1 + flen] = '\n';
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   621
	new.start = dest;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   622
	new.len = dlen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   623
	new.hash_suffix = '\0';
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   624
	if (hlen > 20) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   625
		new.hash_suffix = hash[20];
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
	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
   628
	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
   629
	if (internalsetitem(self, &new)) {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   630
		return -1;
24214
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
	return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   633
}
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 PyMappingMethods lazymanifest_mapping_methods = {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   636
	(lenfunc)lazymanifest_size,             /* mp_length */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   637
	(binaryfunc)lazymanifest_getitem,       /* mp_subscript */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   638
	(objobjargproc)lazymanifest_setitem,    /* mp_ass_subscript */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   639
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   640
27608
d6aa1a8c8d7c lazymanifest: add missing closing parenthesis in comment
Augie Fackler <raf@durin42.com>
parents: 27340
diff changeset
   641
/* 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
   642
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   643
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
   644
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   645
	line needle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   646
	line *hit;
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   647
	if (!PyBytes_Check(key)) {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   648
		/* 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
   649
		 * 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
   650
		return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   651
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   652
	needle.start = PyBytes_AsString(key);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   653
	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
   654
		      &linecmp);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   655
	if (!hit || hit->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   656
		return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   657
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   658
	return 1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   659
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   660
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   661
static PySequenceMethods lazymanifest_seq_meths = {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   662
	(lenfunc)lazymanifest_size, /* sq_length */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   663
	0, /* sq_concat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   664
	0, /* sq_repeat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   665
	0, /* sq_item */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   666
	0, /* sq_slice */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   667
	0, /* sq_ass_item */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   668
	0, /* sq_ass_slice */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   669
	(objobjproc)lazymanifest_contains, /* sq_contains */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   670
	0, /* sq_inplace_concat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   671
	0, /* sq_inplace_repeat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   672
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   673
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   674
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   675
/* Other methods (copy, diff, etc) */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   676
static PyTypeObject lazymanifestType;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   677
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   678
/* 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
   679
static int compact(lazymanifest *self)
7ed0750c71a1 cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34438
diff changeset
   680
{
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   681
	int i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   682
	ssize_t need = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   683
	char *data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   684
	line *src, *dst;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   685
	PyObject *pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   686
	if (!self->dirty)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   687
		return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   688
	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
   689
		if (!self->lines[i].deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   690
			need += self->lines[i].len;
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
	}
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   693
	pydata = PyBytes_FromStringAndSize(NULL, need);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   694
	if (!pydata)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   695
		return -1;
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   696
	data = PyBytes_AsString(pydata);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   697
	if (!data) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   698
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   699
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   700
	src = self->lines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   701
	dst = self->lines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   702
	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
   703
		char *tofree = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   704
		if (src->from_malloc) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   705
			tofree = src->start;
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
		if (!src->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   708
			memcpy(data, src->start, src->len);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   709
			*dst = *src;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   710
			dst->start = data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   711
			dst->from_malloc = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   712
			data += dst->len;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   713
			dst++;
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
		free(tofree);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   716
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   717
	Py_DECREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   718
	self->pydata = pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   719
	self->numlines = self->livelines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   720
	self->dirty = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   721
	return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   722
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   723
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   724
static PyObject *lazymanifest_text(lazymanifest *self)
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
	if (compact(self) != 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   727
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   728
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   729
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   730
	Py_INCREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   731
	return self->pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   732
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   733
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   734
static lazymanifest *lazymanifest_copy(lazymanifest *self)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   735
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   736
	lazymanifest *copy = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   737
	if (compact(self) != 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   738
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   739
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   740
	copy = PyObject_New(lazymanifest, &lazymanifestType);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   741
	if (!copy) {
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
	}
38335
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   744
	lazymanifest_init_early(copy);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   745
	copy->numlines = self->numlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   746
	copy->livelines = self->livelines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   747
	copy->dirty = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   748
	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
   749
	if (!copy->lines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   750
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   751
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   752
	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
   753
	copy->maxlines = self->maxlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   754
	copy->pydata = self->pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   755
	Py_INCREF(copy->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   756
	return copy;
24975
89c2bf63a83b lazymanifest: drop SP before some labels
Martin von Zweigbergk <martinvonz@google.com>
parents: 24974
diff changeset
   757
nomem:
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   758
	PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   759
	Py_XDECREF(copy);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   760
	return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   761
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   762
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   763
static lazymanifest *lazymanifest_filtercopy(
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   764
	lazymanifest *self, PyObject *matchfn)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   765
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   766
	lazymanifest *copy = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   767
	int i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   768
	if (!PyCallable_Check(matchfn)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   769
		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
   770
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   771
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   772
	/* 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
   773
	 * 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
   774
	 * 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
   775
	if (compact(self) != 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   776
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   777
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   778
	copy = PyObject_New(lazymanifest, &lazymanifestType);
27609
ca2d4080a02e lazymanifest: check error return in filter
Augie Fackler <raf@durin42.com>
parents: 27608
diff changeset
   779
	if (!copy) {
ca2d4080a02e lazymanifest: check error return in filter
Augie Fackler <raf@durin42.com>
parents: 27608
diff changeset
   780
		goto nomem;
ca2d4080a02e lazymanifest: check error return in filter
Augie Fackler <raf@durin42.com>
parents: 27608
diff changeset
   781
	}
38335
ae7f27867c2a manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Yuya Nishihara <yuya@tcha.org>
parents: 38302
diff changeset
   782
	lazymanifest_init_early(copy);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   783
	copy->dirty = true;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   784
	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
   785
	if (!copy->lines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   786
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   787
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   788
	copy->maxlines = self->maxlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   789
	copy->numlines = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   790
	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
   791
	Py_INCREF(copy->pydata);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   792
	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
   793
		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
   794
		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
   795
					self->lines[i].start);
27661
abc79f44f548 lazymanifest: check more return values in filtercopy
Augie Fackler <raf@durin42.com>
parents: 27609
diff changeset
   796
		if (!arglist) {
39424
094d1f42c484 manifest: fix leak on error return from lazymanifest_filtercopy()
Yuya Nishihara <yuya@tcha.org>
parents: 39423
diff changeset
   797
			goto bail;
27661
abc79f44f548 lazymanifest: check more return values in filtercopy
Augie Fackler <raf@durin42.com>
parents: 27609
diff changeset
   798
		}
abc79f44f548 lazymanifest: check more return values in filtercopy
Augie Fackler <raf@durin42.com>
parents: 27609
diff changeset
   799
		result = PyObject_CallObject(matchfn, arglist);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   800
		Py_DECREF(arglist);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   801
		/* 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
   802
		 * through and give up */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   803
		if (!result) {
39424
094d1f42c484 manifest: fix leak on error return from lazymanifest_filtercopy()
Yuya Nishihara <yuya@tcha.org>
parents: 39423
diff changeset
   804
			goto bail;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   805
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   806
		if (PyObject_IsTrue(result)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   807
			assert(!(self->lines[i].from_malloc));
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   808
			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
   809
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   810
		Py_DECREF(result);
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
	copy->livelines = copy->numlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   813
	return copy;
24975
89c2bf63a83b lazymanifest: drop SP before some labels
Martin von Zweigbergk <martinvonz@google.com>
parents: 24974
diff changeset
   814
nomem:
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   815
	PyErr_NoMemory();
39424
094d1f42c484 manifest: fix leak on error return from lazymanifest_filtercopy()
Yuya Nishihara <yuya@tcha.org>
parents: 39423
diff changeset
   816
bail:
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   817
	Py_XDECREF(copy);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   818
	return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   819
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   820
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   821
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
   822
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   823
	lazymanifest *other;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   824
	PyObject *pyclean = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   825
	bool listclean;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   826
	PyObject *emptyTup = NULL, *ret = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   827
	PyObject *es;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   828
	int sneedle = 0, oneedle = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   829
	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
   830
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   831
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   832
	listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean);
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   833
	es = PyBytes_FromString("");
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   834
	if (!es) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   835
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   836
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   837
	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
   838
	Py_DECREF(es);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   839
	if (!emptyTup) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   840
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   841
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   842
	ret = PyDict_New();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   843
	if (!ret) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   844
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   845
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   846
	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
   847
		line *left = self->lines + sneedle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   848
		line *right = other->lines + oneedle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   849
		int result;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   850
		PyObject *key;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   851
		PyObject *outer;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   852
		/* 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
   853
		 * the end of the manifest, just skip it. */
35810
113a30b87716 lazymanifest: avoid reading uninitialized memory
Jun Wu <quark@fb.com>
parents: 34861
diff changeset
   854
		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
   855
			sneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   856
			continue;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   857
		}
35810
113a30b87716 lazymanifest: avoid reading uninitialized memory
Jun Wu <quark@fb.com>
parents: 34861
diff changeset
   858
		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
   859
			oneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   860
			continue;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   861
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   862
		/* 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
   863
		 * 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
   864
		 * the strcmp. */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   865
		if (sneedle == self->numlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   866
			result = 1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   867
		} else if (oneedle == other->numlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   868
			result = -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   869
		} else {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   870
			result = linecmp(left, right);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   871
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   872
		key = result <= 0 ?
30097
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   873
			PyBytes_FromString(left->start) :
3bf4b762537e manifest: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30079
diff changeset
   874
			PyBytes_FromString(right->start);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   875
		if (!key)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   876
			goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   877
		if (result < 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   878
			PyObject *l = hashflags(left);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   879
			if (!l) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   880
				goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   881
			}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   882
			outer = PyTuple_Pack(2, l, emptyTup);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   883
			Py_DECREF(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   884
			if (!outer) {
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
			PyDict_SetItem(ret, key, outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   888
			Py_DECREF(outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   889
			sneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   890
		} else if (result > 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   891
			PyObject *r = hashflags(right);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   892
			if (!r) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   893
				goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   894
			}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   895
			outer = PyTuple_Pack(2, emptyTup, r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   896
			Py_DECREF(r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   897
			if (!outer) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   898
				goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   899
			}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   900
			PyDict_SetItem(ret, key, outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   901
			Py_DECREF(outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   902
			oneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   903
		} else {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   904
			/* file exists in both manifests */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   905
			if (left->len != right->len
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   906
			    || 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
   907
			    || left->hash_suffix != right->hash_suffix) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   908
				PyObject *l = hashflags(left);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   909
				PyObject *r;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   910
				if (!l) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   911
					goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   912
				}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   913
				r = hashflags(right);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   914
				if (!r) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   915
					Py_DECREF(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   916
					goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   917
				}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   918
				outer = PyTuple_Pack(2, l, r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   919
				Py_DECREF(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   920
				Py_DECREF(r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   921
				if (!outer) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   922
					goto nomem;
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
				PyDict_SetItem(ret, key, outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   925
				Py_DECREF(outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   926
			} else if (listclean) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   927
				PyDict_SetItem(ret, key, Py_None);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   928
			}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   929
			sneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   930
			oneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   931
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   932
		Py_DECREF(key);
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
	Py_DECREF(emptyTup);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   935
	return ret;
24975
89c2bf63a83b lazymanifest: drop SP before some labels
Martin von Zweigbergk <martinvonz@google.com>
parents: 24974
diff changeset
   936
nomem:
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   937
	PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   938
	Py_XDECREF(ret);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   939
	Py_XDECREF(emptyTup);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   940
	return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   941
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   942
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   943
static PyMethodDef lazymanifest_methods[] = {
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   944
	{"iterkeys", (PyCFunction)lazymanifest_getkeysiter, METH_NOARGS,
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   945
	 "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
   946
	{"iterentries", (PyCFunction)lazymanifest_getentriesiter, METH_NOARGS,
29254
c5912a0b156c lazymanifest: fix typo s/typles/tuples/
Javi Merino <merino.jav@gmail.com>
parents: 27661
diff changeset
   947
	 "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
   948
	{"copy", (PyCFunction)lazymanifest_copy, METH_NOARGS,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   949
	 "Make a copy of this lazymanifest."},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   950
	{"filtercopy", (PyCFunction)lazymanifest_filtercopy, METH_O,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   951
	 "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
   952
	{"diff", (PyCFunction)lazymanifest_diff, METH_VARARGS,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   953
	 "Compare this lazymanifest to another one."},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   954
	{"text", (PyCFunction)lazymanifest_text, METH_NOARGS,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   955
	 "Encode this manifest to text."},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   956
	{NULL},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   957
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   958
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
   959
#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
   960
#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
   961
#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
   962
#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
   963
#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
   964
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   965
static PyTypeObject lazymanifestType = {
34861
6ece4a85c350 cext: add /* header */ comment to all PyVarObject_HEAD_INIT() calls
Augie Fackler <augie@google.com>
parents: 34440
diff changeset
   966
	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
   967
	"parsers.lazymanifest",                           /* tp_name */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   968
	sizeof(lazymanifest),                             /* tp_basicsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   969
	0,                                                /* tp_itemsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   970
	(destructor)lazymanifest_dealloc,                 /* tp_dealloc */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   971
	0,                                                /* tp_print */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   972
	0,                                                /* tp_getattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   973
	0,                                                /* tp_setattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   974
	0,                                                /* tp_compare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   975
	0,                                                /* tp_repr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   976
	0,                                                /* tp_as_number */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   977
	&lazymanifest_seq_meths,                          /* tp_as_sequence */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   978
	&lazymanifest_mapping_methods,                    /* tp_as_mapping */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   979
	0,                                                /* tp_hash */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   980
	0,                                                /* tp_call */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   981
	0,                                                /* tp_str */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   982
	0,                                                /* tp_getattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   983
	0,                                                /* tp_setattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   984
	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
   985
	LAZYMANIFEST_TPFLAGS,                             /* tp_flags */
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   986
	"TODO(augie)",                                    /* tp_doc */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   987
	0,                                                /* tp_traverse */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   988
	0,                                                /* tp_clear */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   989
	0,                                                /* tp_richcompare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   990
	0,                                             /* tp_weaklistoffset */
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   991
	(getiterfunc)lazymanifest_getkeysiter,                /* tp_iter */
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   992
	0,                                                /* tp_iternext */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   993
	lazymanifest_methods,                             /* tp_methods */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   994
	0,                                                /* tp_members */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   995
	0,                                                /* tp_getset */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   996
	0,                                                /* tp_base */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   997
	0,                                                /* tp_dict */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   998
	0,                                                /* tp_descr_get */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   999
	0,                                                /* tp_descr_set */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1000
	0,                                                /* tp_dictoffset */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1001
	(initproc)lazymanifest_init,                      /* tp_init */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1002
	0,                                                /* tp_alloc */
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1005
void manifest_module_init(PyObject * mod)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1006
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1007
	lazymanifestType.tp_new = PyType_GenericNew;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1008
	if (PyType_Ready(&lazymanifestType) < 0)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1009
		return;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1010
	Py_INCREF(&lazymanifestType);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1011
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1012
	PyModule_AddObject(mod, "lazymanifest",
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1013
			   (PyObject *)&lazymanifestType);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
  1014
}