mercurial/manifest.c
author Yuya Nishihara <yuya@tcha.org>
Fri, 20 Mar 2015 00:22:37 +0900
changeset 24389 93d3e1a8bfb0
parent 24352 d6dbe4d1c9bc
child 24441 e2ed40f0eb2e
permissions -rw-r--r--
test-revert-interactive: eliminate bashism in wildcard pattern The test failed with Debian dash.
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>
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    12
#include <string.h>
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    13
#include <stdlib.h>
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    14
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
/* VC9 doesn't include bool and lacks stdbool.h based on my searching */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    16
#ifdef _MSC_VER
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    17
#define true 1
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    18
#define false 0
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    19
typedef unsigned char bool;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    20
#else
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    21
#include <stdbool.h>
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
#endif
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    23
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    24
#define DEFAULT_LINES 100000
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    25
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    26
typedef struct {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    27
	char *start;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    28
	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
    29
	char hash_suffix;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    30
	bool from_malloc;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    31
	bool deleted;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    32
} line;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    33
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    34
typedef struct {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    35
	PyObject_HEAD
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    36
	PyObject *pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    37
	line *lines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    38
	int numlines; /* number of line entries */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    39
	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
    40
	int maxlines; /* allocated number of lines */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    41
	bool dirty;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    42
} lazymanifest;
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
#define MANIFEST_OOM -1
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    45
#define MANIFEST_NOT_SORTED -2
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
#define MANIFEST_MALFORMED -3
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    47
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    48
/* defined in parsers.c */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    49
PyObject *unhexlify(const char *str, int len);
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 length of the path for a line */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
static size_t pathlen(line *l) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    53
	return strlen(l->start);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    54
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    55
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    56
/* get the node value of a single line */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    57
static PyObject *nodeof(line *l) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    58
	char *s = l->start;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    59
	ssize_t llen = pathlen(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    60
	PyObject *hash = unhexlify(s + llen + 1, 40);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    61
	if (!hash) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    62
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    63
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
	if (l->hash_suffix != '\0') {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
		char newhash[21];
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    66
		memcpy(newhash, PyString_AsString(hash), 20);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    67
		Py_DECREF(hash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    68
		newhash[20] = l->hash_suffix;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    69
		hash = PyString_FromStringAndSize(newhash, 21);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    70
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    71
	return hash;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    72
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    73
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    74
/* 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
    75
static PyObject *hashflags(line *l)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    76
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
	char *s = l->start;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    78
	size_t plen = pathlen(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    79
	PyObject *hash = nodeof(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    80
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    81
	/* 40 for hash, 1 for null byte, 1 for newline */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    82
	size_t hplen = plen + 42;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    83
	Py_ssize_t flen = l->len - hplen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    84
	PyObject *flags;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    85
	PyObject *tup;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    86
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    87
	if (!hash)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    88
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    89
	flags = PyString_FromStringAndSize(s + hplen - 1, flen);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    90
	if (!flags) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    91
		Py_DECREF(hash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    92
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    93
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    94
	tup = PyTuple_Pack(2, hash, flags);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    95
	Py_DECREF(flags);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    96
	Py_DECREF(hash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    97
	return tup;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    98
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
    99
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   100
/* if 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
   101
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
   102
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   103
	if (self->numlines == self->maxlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   104
		self->maxlines *= 2;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   105
		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
   106
	}
24312
f208ce59a6e5 manifest.c: ensure realloc_if_full() returns 1 or 0
Matt Harbison <matt_harbison@yahoo.com>
parents: 24298
diff changeset
   107
	return !!self->lines;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   108
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   109
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
 * 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
   112
 * information about each line in 'self'.
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   113
 */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   114
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
   115
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   116
	char *prev = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   117
	while (len > 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   118
		line *l;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   119
		char *next = memchr(data, '\n', len);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   120
		if (!next) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   121
			return MANIFEST_MALFORMED;
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
		next++; /* advance past newline */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   124
		if (!realloc_if_full(self)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   125
			return MANIFEST_OOM; /* no memory */
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 (prev && strcmp(prev, data) > -1) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   128
			/* 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
   129
			return MANIFEST_NOT_SORTED;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   131
		l = self->lines + ((self->numlines)++);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
		l->start = data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   133
		l->len = next - data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   134
		l->hash_suffix = '\0';
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   135
		l->from_malloc = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   136
		l->deleted = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   137
		len = len - l->len;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   138
		prev = data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   139
		data = next;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   140
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   141
	self->livelines = self->numlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   142
	return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   143
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   144
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   145
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
   146
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   147
	char *data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   148
	Py_ssize_t len;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   149
	int err, ret;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
	PyObject *pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   151
	if (!PyArg_ParseTuple(args, "S", &pydata)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   152
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   153
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   154
	err = PyString_AsStringAndSize(pydata, &data, &len);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   155
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   156
	self->dirty = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   157
	if (err == -1)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   158
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   159
	self->pydata = pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   160
	Py_INCREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   161
	Py_BEGIN_ALLOW_THREADS
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   162
	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
   163
	self->maxlines = DEFAULT_LINES;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   164
	self->numlines = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   165
	if (!self->lines)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   166
		ret = MANIFEST_OOM;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   167
	else
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   168
		ret = find_lines(self, data, len);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   169
	Py_END_ALLOW_THREADS
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   170
	switch (ret) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   171
	case 0:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   172
		break;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   173
	case MANIFEST_OOM:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   174
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   175
		break;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   176
	case MANIFEST_NOT_SORTED:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   177
		PyErr_Format(PyExc_ValueError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   178
			     "Manifest lines not in sorted order.");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   179
		break;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   180
	case MANIFEST_MALFORMED:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   181
		PyErr_Format(PyExc_ValueError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   182
			     "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
   183
		break;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   184
	default:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   185
		PyErr_Format(PyExc_ValueError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   186
			     "Unknown problem parsing manifest.");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   187
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   188
	return ret == 0 ? 0 : -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   189
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   190
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   191
static void lazymanifest_dealloc(lazymanifest *self)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   192
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   193
	/* 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
   194
	int i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   195
	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
   196
		if (self->lines[i].from_malloc) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   197
			free(self->lines[i].start);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   198
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   199
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   200
	if (self->lines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   201
		free(self->lines);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   202
		self->lines = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   203
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   204
	if (self->pydata) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   205
		Py_DECREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   206
		self->pydata = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   207
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   208
	PyObject_Del(self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   209
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   210
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   211
/* iteration support */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   212
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   213
typedef struct {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   214
	PyObject_HEAD lazymanifest *m;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   215
	Py_ssize_t pos;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   216
} lmIter;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   217
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   218
static void lmiter_dealloc(PyObject *o)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   219
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   220
	lmIter *self = (lmIter *)o;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   221
	Py_DECREF(self->m);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   222
	PyObject_Del(self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   223
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   224
24294
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   225
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
   226
{
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   227
	do {
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   228
		self->pos++;
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   229
		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
   230
			return NULL;
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   231
		}
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   232
		/* skip over deleted manifest entries */
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   233
	} 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
   234
	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
   235
}
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   236
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   237
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
   238
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   239
	size_t pl;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   240
	line *l;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   241
	Py_ssize_t consumed;
24294
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   242
	PyObject *path = NULL, *hash = NULL, *flags = NULL;
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   243
	l = lmiter_nextline((lmIter *)o);
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   244
	if (!l) {
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   245
		goto bail;
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   246
	}
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   247
	pl = pathlen(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   248
	path = PyString_FromStringAndSize(l->start, pl);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   249
	hash = nodeof(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   250
	consumed = pl + 41;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   251
	flags = PyString_FromStringAndSize(l->start + consumed,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   252
									   l->len - consumed - 1);
24293
30e9ee203846 lazymanifest: fail if path or hash strings cannot be created
Martin von Zweigbergk <martinvonz@google.com>
parents: 24286
diff changeset
   253
	if (!path || !hash || !flags) {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   254
		goto bail;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   255
	}
24294
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   256
	return PyTuple_Pack(3, path, hash, flags);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   257
 bail:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   258
	Py_XDECREF(path);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   259
	Py_XDECREF(hash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   260
	Py_XDECREF(flags);
24294
3d485727e45e lazymanifest: extract function for iterating to next line
Martin von Zweigbergk <martinvonz@google.com>
parents: 24293
diff changeset
   261
	return NULL;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   262
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   263
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   264
static PyTypeObject lazymanifestEntriesIterator = {
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   265
	PyObject_HEAD_INIT(NULL)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   266
	0,                               /*ob_size */
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   267
	"parsers.lazymanifest.entriesiterator", /*tp_name */
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   268
	sizeof(lmIter),                  /*tp_basicsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   269
	0,                               /*tp_itemsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   270
	lmiter_dealloc,                  /*tp_dealloc */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   271
	0,                               /*tp_print */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   272
	0,                               /*tp_getattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   273
	0,                               /*tp_setattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   274
	0,                               /*tp_compare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   275
	0,                               /*tp_repr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   276
	0,                               /*tp_as_number */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   277
	0,                               /*tp_as_sequence */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   278
	0,                               /*tp_as_mapping */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   279
	0,                               /*tp_hash */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   280
	0,                               /*tp_call */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   281
	0,                               /*tp_str */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   282
	0,                               /*tp_getattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   283
	0,                               /*tp_setattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   284
	0,                               /*tp_as_buffer */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   285
	/* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   286
	   use tp_iter and tp_iternext fields. */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   287
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   288
	"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
   289
	0,                               /* tp_traverse */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   290
	0,                               /* tp_clear */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   291
	0,                               /* tp_richcompare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   292
	0,                               /* tp_weaklistoffset */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   293
	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
   294
	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
   295
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   296
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   297
static PyObject *lmiter_iterkeysnext(PyObject *o)
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   298
{
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   299
	size_t pl;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   300
	line *l = lmiter_nextline((lmIter *)o);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   301
	if (!l) {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   302
		return NULL;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   303
	}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   304
	pl = pathlen(l);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   305
	return PyString_FromStringAndSize(l->start, pl);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   306
}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   307
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   308
static PyTypeObject lazymanifestKeysIterator = {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   309
	PyObject_HEAD_INIT(NULL)
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   310
	0,                               /*ob_size */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   311
	"parsers.lazymanifest.keysiterator", /*tp_name */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   312
	sizeof(lmIter),                  /*tp_basicsize */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   313
	0,                               /*tp_itemsize */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   314
	lmiter_dealloc,                  /*tp_dealloc */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   315
	0,                               /*tp_print */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   316
	0,                               /*tp_getattr */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   317
	0,                               /*tp_setattr */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   318
	0,                               /*tp_compare */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   319
	0,                               /*tp_repr */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   320
	0,                               /*tp_as_number */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   321
	0,                               /*tp_as_sequence */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   322
	0,                               /*tp_as_mapping */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   323
	0,                               /*tp_hash */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   324
	0,                               /*tp_call */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   325
	0,                               /*tp_str */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   326
	0,                               /*tp_getattro */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   327
	0,                               /*tp_setattro */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   328
	0,                               /*tp_as_buffer */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   329
	/* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   330
	   use tp_iter and tp_iternext fields. */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   331
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   332
	"Keys iterator for a lazymanifest.",  /* tp_doc */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   333
	0,                               /* tp_traverse */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   334
	0,                               /* tp_clear */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   335
	0,                               /* tp_richcompare */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   336
	0,                               /* tp_weaklistoffset */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   337
	PyObject_SelfIter,               /* tp_iter: __iter__() method */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   338
	lmiter_iterkeysnext,             /* tp_iternext: next() method */
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   339
};
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   340
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   341
static lazymanifest *lazymanifest_copy(lazymanifest *self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   342
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   343
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
   344
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   345
	lmIter *i = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   346
	lazymanifest *t = lazymanifest_copy(self);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   347
	if (!t) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   348
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   349
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   350
	}
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   351
	i = PyObject_New(lmIter, &lazymanifestEntriesIterator);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   352
	if (i) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   353
		i->m = t;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   354
		i->pos = -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   355
	} else {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   356
		Py_DECREF(t);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   357
		PyErr_NoMemory();
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
	return (PyObject *)i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   360
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   361
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   362
static PyObject *lazymanifest_getkeysiter(lazymanifest *self)
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   363
{
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   364
	lmIter *i = NULL;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   365
	lazymanifest *t = lazymanifest_copy(self);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   366
	if (!t) {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   367
		PyErr_NoMemory();
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   368
		return NULL;
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
	i = PyObject_New(lmIter, &lazymanifestKeysIterator);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   371
	if (i) {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   372
		i->m = t;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   373
		i->pos = -1;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   374
	} else {
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   375
		Py_DECREF(t);
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   376
		PyErr_NoMemory();
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   377
	}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   378
	return (PyObject *)i;
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   379
}
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   380
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   381
/* __getitem__ and __setitem__ support */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   382
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   383
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
   384
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   385
	return self->livelines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   386
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   387
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   388
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
   389
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   390
	return strcmp(((const line *)left)->start,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   391
		      ((const line *)right)->start);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   392
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   393
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   394
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
   395
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   396
	line needle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   397
	line *hit;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   398
	if (!PyString_Check(key)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   399
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   400
			     "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
   401
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   402
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   403
	needle.start = PyString_AsString(key);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   404
	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
   405
		      &linecmp);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   406
	if (!hit || hit->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   407
		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
   408
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   409
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   410
	return hashflags(hit);
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   413
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
   414
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   415
	line needle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   416
	line *hit;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   417
	if (!PyString_Check(key)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   418
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   419
			     "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
   420
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   421
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   422
	needle.start = PyString_AsString(key);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   423
	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
   424
		      &linecmp);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   425
	if (!hit || hit->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   426
		PyErr_Format(PyExc_KeyError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   427
			     "Tried to delete nonexistent manifest entry.");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   428
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   429
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   430
	self->dirty = true;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   431
	hit->deleted = true;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   432
	self->livelines--;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   433
	return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   434
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   435
24228
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   436
/* 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
   437
 * new entry if needed. */
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   438
static int internalsetitem(lazymanifest *self, line *new) {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   439
	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
   440
	while (start < end) {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   441
		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
   442
		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
   443
		if (c < 0)
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   444
			end = pos;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   445
		else if (c > 0)
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   446
			start = pos + 1;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   447
		else {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   448
			if (self->lines[pos].deleted)
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   449
				self->livelines++;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   450
			start = pos;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   451
			goto finish;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   452
		}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   453
	}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   454
	/* 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
   455
	if (!realloc_if_full(self)) {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   456
		PyErr_NoMemory();
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   457
		return -1;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   458
	}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   459
	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
   460
		(self->numlines - start) * sizeof(line));
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   461
	self->numlines++;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   462
	self->livelines++;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   463
finish:
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   464
	self->lines[start] = *new;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   465
	self->dirty = true;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   466
	return 0;
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   467
}
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   468
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   469
static int lazymanifest_setitem(
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   470
	lazymanifest *self, PyObject *key, PyObject *value)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   471
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   472
	char *path;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   473
	Py_ssize_t plen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   474
	PyObject *pyhash;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   475
	Py_ssize_t hlen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   476
	char *hash;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   477
	PyObject *pyflags;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   478
	char *flags;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   479
	Py_ssize_t flen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   480
	size_t dlen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   481
	char *dest;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   482
	int i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   483
	line new;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   484
	if (!PyString_Check(key)) {
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
			     "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
   487
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   488
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   489
	if (!value) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   490
		return lazymanifest_delitem(self, key);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   491
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   492
	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
   493
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   494
			     "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
   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
	if (PyString_AsStringAndSize(key, &path, &plen) == -1) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   498
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   499
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   500
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   501
	pyhash = PyTuple_GetItem(value, 0);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   502
	if (!PyString_Check(pyhash)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   503
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   504
			     "node must be a 20-byte string");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   505
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   506
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   507
	hlen = PyString_Size(pyhash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   508
	/* Some parts of the codebase try and set 21 or 22
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   509
	 * byte "hash" values in order to perturb things for
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   510
	 * status. We have to preserve at least the 21st
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   511
	 * byte. Sigh. If there's a 22nd byte, we drop it on
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   512
	 * the floor, which works fine.
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   513
	 */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   514
	if (hlen != 20 && hlen != 21 && hlen != 22) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   515
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   516
			     "node must be a 20-byte string");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   517
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   518
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   519
	hash = PyString_AsString(pyhash);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   520
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   521
	pyflags = PyTuple_GetItem(value, 1);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   522
	if (!PyString_Check(pyflags) || PyString_Size(pyflags) > 1) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   523
		PyErr_Format(PyExc_TypeError,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   524
			     "flags must a 0 or 1 byte string");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   525
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   526
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   527
	if (PyString_AsStringAndSize(pyflags, &flags, &flen) == -1) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   528
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   529
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   530
	/* one null byte and one newline */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   531
	dlen = plen + 41 + flen + 1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   532
	dest = malloc(dlen);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   533
	if (!dest) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   534
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   535
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   536
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   537
	memcpy(dest, path, plen + 1);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   538
	for (i = 0; i < 20; i++) {
24286
40528ad1b1e8 lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents: 24228
diff changeset
   539
		/* 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
   540
		 * 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
   541
		 */
40528ad1b1e8 lazymanifest: don't depend on printf's 'hh' format to work
Martin von Zweigbergk <martinvonz@google.com>
parents: 24228
diff changeset
   542
		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
   543
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   544
	memcpy(dest + plen + 41, flags, flen);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   545
	dest[plen + 41 + flen] = '\n';
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   546
	new.start = dest;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   547
	new.len = dlen;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   548
	new.hash_suffix = '\0';
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   549
	if (hlen > 20) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   550
		new.hash_suffix = hash[20];
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   551
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   552
	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
   553
	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
   554
	if (internalsetitem(self, &new)) {
542c891274b2 lazymanifest: use a binary search to do an insertion
Augie Fackler <augie@google.com>
parents: 24214
diff changeset
   555
		return -1;
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   556
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   557
	return 0;
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   560
static PyMappingMethods lazymanifest_mapping_methods = {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   561
	(lenfunc)lazymanifest_size,             /* mp_length */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   562
	(binaryfunc)lazymanifest_getitem,       /* mp_subscript */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   563
	(objobjargproc)lazymanifest_setitem,    /* mp_ass_subscript */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   564
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   565
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   566
/* sequence methods (important or __contains__ builds an iterator */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   567
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   568
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
   569
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   570
	line needle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   571
	line *hit;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   572
	if (!PyString_Check(key)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   573
		/* 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
   574
		 * 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
   575
		return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   576
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   577
	needle.start = PyString_AsString(key);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   578
	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
   579
		      &linecmp);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   580
	if (!hit || hit->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   581
		return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   582
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   583
	return 1;
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
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   586
static PySequenceMethods lazymanifest_seq_meths = {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   587
	(lenfunc)lazymanifest_size, /* sq_length */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   588
	0, /* sq_concat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   589
	0, /* sq_repeat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   590
	0, /* sq_item */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   591
	0, /* sq_slice */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   592
	0, /* sq_ass_item */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   593
	0, /* sq_ass_slice */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   594
	(objobjproc)lazymanifest_contains, /* sq_contains */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   595
	0, /* sq_inplace_concat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   596
	0, /* sq_inplace_repeat */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   597
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   598
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   599
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   600
/* Other methods (copy, diff, etc) */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   601
static PyTypeObject lazymanifestType;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   602
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   603
/* If the manifest has changes, build the new manifest text and reindex it. */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   604
static int compact(lazymanifest *self) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   605
	int i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   606
	ssize_t need = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   607
	char *data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   608
	line *src, *dst;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   609
	PyObject *pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   610
	if (!self->dirty)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   611
		return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   612
	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
   613
		if (!self->lines[i].deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   614
			need += self->lines[i].len;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   615
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   616
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   617
	pydata = PyString_FromStringAndSize(NULL, need);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   618
	if (!pydata)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   619
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   620
	data = PyString_AsString(pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   621
	if (!data) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   622
		return -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   623
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   624
	src = self->lines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   625
	dst = self->lines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   626
	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
   627
		char *tofree = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   628
		if (src->from_malloc) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   629
			tofree = src->start;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   630
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   631
		if (!src->deleted) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   632
			memcpy(data, src->start, src->len);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   633
			*dst = *src;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   634
			dst->start = data;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   635
			dst->from_malloc = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   636
			data += dst->len;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   637
			dst++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   638
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   639
		free(tofree);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   640
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   641
	Py_DECREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   642
	self->pydata = pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   643
	self->numlines = self->livelines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   644
	self->dirty = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   645
	return 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   646
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   647
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   648
static PyObject *lazymanifest_text(lazymanifest *self)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   649
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   650
	if (compact(self) != 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   651
		PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   652
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   653
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   654
	Py_INCREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   655
	return self->pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   656
}
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
static lazymanifest *lazymanifest_copy(lazymanifest *self)
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
	lazymanifest *copy = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   661
	if (compact(self) != 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   662
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   663
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   664
	copy = PyObject_New(lazymanifest, &lazymanifestType);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   665
	if (!copy) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   666
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   667
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   668
	copy->numlines = self->numlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   669
	copy->livelines = self->livelines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   670
	copy->dirty = false;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   671
	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
   672
	if (!copy->lines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   673
		goto nomem;
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
	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
   676
	copy->maxlines = self->maxlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   677
	copy->pydata = self->pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   678
	Py_INCREF(copy->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   679
	return copy;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   680
 nomem:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   681
	PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   682
	Py_XDECREF(copy);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   683
	return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   684
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   685
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   686
static lazymanifest *lazymanifest_filtercopy(
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   687
	lazymanifest *self, PyObject *matchfn)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   688
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   689
	lazymanifest *copy = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   690
	int i;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   691
	if (!PyCallable_Check(matchfn)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   692
		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
   693
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   694
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   695
	/* 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
   696
	 * 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
   697
	 * 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
   698
	if (compact(self) != 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   699
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   700
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   701
	copy = PyObject_New(lazymanifest, &lazymanifestType);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   702
	copy->dirty = true;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   703
	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
   704
	if (!copy->lines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   705
		goto nomem;
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
	copy->maxlines = self->maxlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   708
	copy->numlines = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   709
	copy->pydata = self->pydata;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   710
	Py_INCREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   711
	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
   712
		PyObject *arg = PyString_FromString(self->lines[i].start);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   713
		PyObject *arglist = PyTuple_Pack(1, arg);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   714
		PyObject *result = PyObject_CallObject(matchfn, arglist);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   715
		Py_DECREF(arglist);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   716
		Py_DECREF(arg);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   717
		/* 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
   718
		 * through and give up */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   719
		if (!result) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   720
			free(copy->lines);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   721
			Py_DECREF(self->pydata);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   722
			return NULL;
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
		if (PyObject_IsTrue(result)) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   725
			assert(!(self->lines[i].from_malloc));
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   726
			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
   727
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   728
		Py_DECREF(result);
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
	copy->livelines = copy->numlines;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   731
	return copy;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   732
 nomem:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   733
	PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   734
	Py_XDECREF(copy);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   735
	return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   736
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   737
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   738
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
   739
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   740
	lazymanifest *other;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   741
	PyObject *pyclean = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   742
	bool listclean;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   743
	PyObject *emptyTup = NULL, *ret = NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   744
	PyObject *es;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   745
	int sneedle = 0, oneedle = 0;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   746
	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
   747
		return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   748
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   749
	listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   750
	es = PyString_FromString("");
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   751
	if (!es) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   752
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   753
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   754
	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
   755
	Py_DECREF(es);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   756
	if (!emptyTup) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   757
		goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   758
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   759
	ret = PyDict_New();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   760
	if (!ret) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   761
		goto nomem;
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
	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
   764
		line *left = self->lines + sneedle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   765
		line *right = other->lines + oneedle;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   766
		int result;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   767
		PyObject *key;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   768
		PyObject *outer;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   769
		/* 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
   770
		 * the end of the manifest, just skip it. */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   771
		if (left->deleted && sneedle < self->numlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   772
			sneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   773
			continue;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   774
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   775
		if (right->deleted && oneedle < other->numlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   776
			oneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   777
			continue;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   778
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   779
		/* 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
   780
		 * 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
   781
		 * the strcmp. */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   782
		if (sneedle == self->numlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   783
			result = 1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   784
		} else if (oneedle == other->numlines) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   785
			result = -1;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   786
		} else {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   787
			result = linecmp(left, right);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   788
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   789
		key = result <= 0 ?
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   790
			PyString_FromString(left->start) :
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   791
			PyString_FromString(right->start);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   792
		if (!key)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   793
			goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   794
		if (result < 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   795
			PyObject *l = hashflags(left);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   796
			if (!l) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   797
				goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   798
			}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   799
			outer = PyTuple_Pack(2, l, emptyTup);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   800
			Py_DECREF(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   801
			if (!outer) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   802
				goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   803
			}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   804
			PyDict_SetItem(ret, key, outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   805
			Py_DECREF(outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   806
			sneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   807
		} else if (result > 0) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   808
			PyObject *r = hashflags(right);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   809
			if (!r) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   810
				goto nomem;
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
			outer = PyTuple_Pack(2, emptyTup, r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   813
			Py_DECREF(r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   814
			if (!outer) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   815
				goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   816
			}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   817
			PyDict_SetItem(ret, key, outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   818
			Py_DECREF(outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   819
			oneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   820
		} else {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   821
			/* file exists in both manifests */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   822
			if (left->len != right->len
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   823
			    || 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
   824
			    || left->hash_suffix != right->hash_suffix) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   825
				PyObject *l = hashflags(left);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   826
				PyObject *r;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   827
				if (!l) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   828
					goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   829
				}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   830
				r = hashflags(right);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   831
				if (!r) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   832
					Py_DECREF(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   833
					goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   834
				}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   835
				outer = PyTuple_Pack(2, l, r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   836
				Py_DECREF(l);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   837
				Py_DECREF(r);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   838
				if (!outer) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   839
					goto nomem;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   840
				}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   841
				PyDict_SetItem(ret, key, outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   842
				Py_DECREF(outer);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   843
			} else if (listclean) {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   844
				PyDict_SetItem(ret, key, Py_None);
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
			sneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   847
			oneedle++;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   848
		}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   849
		Py_DECREF(key);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   850
	}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   851
	Py_DECREF(emptyTup);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   852
	return ret;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   853
 nomem:
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   854
	PyErr_NoMemory();
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   855
	Py_XDECREF(ret);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   856
	Py_XDECREF(emptyTup);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   857
	return NULL;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   858
}
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   859
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   860
static PyMethodDef lazymanifest_methods[] = {
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   861
	{"iterkeys", (PyCFunction)lazymanifest_getkeysiter, METH_NOARGS,
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24294
diff changeset
   862
	 "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
   863
	{"iterentries", (PyCFunction)lazymanifest_getentriesiter, METH_NOARGS,
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   864
	 "Iterate over (path, nodeid, flags) typles in this lazymanifest."},
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   865
	{"copy", (PyCFunction)lazymanifest_copy, METH_NOARGS,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   866
	 "Make a copy of this lazymanifest."},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   867
	{"filtercopy", (PyCFunction)lazymanifest_filtercopy, METH_O,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   868
	 "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
   869
	{"diff", (PyCFunction)lazymanifest_diff, METH_VARARGS,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   870
	 "Compare this lazymanifest to another one."},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   871
	{"text", (PyCFunction)lazymanifest_text, METH_NOARGS,
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   872
	 "Encode this manifest to text."},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   873
	{NULL},
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   874
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   875
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   876
static PyTypeObject lazymanifestType = {
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   877
	PyObject_HEAD_INIT(NULL)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   878
	0,                                                /* ob_size */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   879
	"parsers.lazymanifest",                           /* tp_name */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   880
	sizeof(lazymanifest),                             /* tp_basicsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   881
	0,                                                /* tp_itemsize */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   882
	(destructor)lazymanifest_dealloc,                 /* tp_dealloc */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   883
	0,                                                /* tp_print */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   884
	0,                                                /* tp_getattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   885
	0,                                                /* tp_setattr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   886
	0,                                                /* tp_compare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   887
	0,                                                /* tp_repr */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   888
	0,                                                /* tp_as_number */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   889
	&lazymanifest_seq_meths,                          /* tp_as_sequence */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   890
	&lazymanifest_mapping_methods,                    /* tp_as_mapping */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   891
	0,                                                /* tp_hash */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   892
	0,                                                /* tp_call */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   893
	0,                                                /* tp_str */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   894
	0,                                                /* tp_getattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   895
	0,                                                /* tp_setattro */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   896
	0,                                                /* tp_as_buffer */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   897
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN, /* tp_flags */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   898
	"TODO(augie)",                                    /* tp_doc */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   899
	0,                                                /* tp_traverse */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   900
	0,                                                /* tp_clear */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   901
	0,                                                /* tp_richcompare */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   902
	0,                                             /* tp_weaklistoffset */
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   903
	(getiterfunc)lazymanifest_getkeysiter,                /* tp_iter */
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   904
	0,                                                /* tp_iternext */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   905
	lazymanifest_methods,                             /* tp_methods */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   906
	0,                                                /* tp_members */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   907
	0,                                                /* tp_getset */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   908
	0,                                                /* tp_base */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   909
	0,                                                /* tp_dict */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   910
	0,                                                /* tp_descr_get */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   911
	0,                                                /* tp_descr_set */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   912
	0,                                                /* tp_dictoffset */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   913
	(initproc)lazymanifest_init,                      /* tp_init */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   914
	0,                                                /* tp_alloc */
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   915
};
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   916
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   917
void manifest_module_init(PyObject * mod)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   918
{
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   919
	lazymanifestType.tp_new = PyType_GenericNew;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   920
	if (PyType_Ready(&lazymanifestType) < 0)
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   921
		return;
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   922
	Py_INCREF(&lazymanifestType);
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
	PyModule_AddObject(mod, "lazymanifest",
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   925
			   (PyObject *)&lazymanifestType);
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents:
diff changeset
   926
}