mercurial/manifest.c
changeset 30097 3bf4b762537e
parent 30079 84debea79903
child 30168 1a327889c13c
equal deleted inserted replaced
30096:98d3d8108db0 30097:3bf4b762537e
    54 	if (!hash) {
    54 	if (!hash) {
    55 		return NULL;
    55 		return NULL;
    56 	}
    56 	}
    57 	if (l->hash_suffix != '\0') {
    57 	if (l->hash_suffix != '\0') {
    58 		char newhash[21];
    58 		char newhash[21];
    59 		memcpy(newhash, PyString_AsString(hash), 20);
    59 		memcpy(newhash, PyBytes_AsString(hash), 20);
    60 		Py_DECREF(hash);
    60 		Py_DECREF(hash);
    61 		newhash[20] = l->hash_suffix;
    61 		newhash[20] = l->hash_suffix;
    62 		hash = PyString_FromStringAndSize(newhash, 21);
    62 		hash = PyBytes_FromStringAndSize(newhash, 21);
    63 	}
    63 	}
    64 	return hash;
    64 	return hash;
    65 }
    65 }
    66 
    66 
    67 /* get the node hash and flags of a line as a tuple */
    67 /* get the node hash and flags of a line as a tuple */
    77 	PyObject *flags;
    77 	PyObject *flags;
    78 	PyObject *tup;
    78 	PyObject *tup;
    79 
    79 
    80 	if (!hash)
    80 	if (!hash)
    81 		return NULL;
    81 		return NULL;
    82 	flags = PyString_FromStringAndSize(s + hplen - 1, flen);
    82 	flags = PyBytes_FromStringAndSize(s + hplen - 1, flen);
    83 	if (!flags) {
    83 	if (!flags) {
    84 		Py_DECREF(hash);
    84 		Py_DECREF(hash);
    85 		return NULL;
    85 		return NULL;
    86 	}
    86 	}
    87 	tup = PyTuple_Pack(2, hash, flags);
    87 	tup = PyTuple_Pack(2, hash, flags);
   142 	int err, ret;
   142 	int err, ret;
   143 	PyObject *pydata;
   143 	PyObject *pydata;
   144 	if (!PyArg_ParseTuple(args, "S", &pydata)) {
   144 	if (!PyArg_ParseTuple(args, "S", &pydata)) {
   145 		return -1;
   145 		return -1;
   146 	}
   146 	}
   147 	err = PyString_AsStringAndSize(pydata, &data, &len);
   147 	err = PyBytes_AsStringAndSize(pydata, &data, &len);
   148 
   148 
   149 	self->dirty = false;
   149 	self->dirty = false;
   150 	if (err == -1)
   150 	if (err == -1)
   151 		return -1;
   151 		return -1;
   152 	self->pydata = pydata;
   152 	self->pydata = pydata;
   236 	l = lmiter_nextline((lmIter *)o);
   236 	l = lmiter_nextline((lmIter *)o);
   237 	if (!l) {
   237 	if (!l) {
   238 		goto done;
   238 		goto done;
   239 	}
   239 	}
   240 	pl = pathlen(l);
   240 	pl = pathlen(l);
   241 	path = PyString_FromStringAndSize(l->start, pl);
   241 	path = PyBytes_FromStringAndSize(l->start, pl);
   242 	hash = nodeof(l);
   242 	hash = nodeof(l);
   243 	consumed = pl + 41;
   243 	consumed = pl + 41;
   244 	flags = PyString_FromStringAndSize(l->start + consumed,
   244 	flags = PyBytes_FromStringAndSize(l->start + consumed,
   245 					   l->len - consumed - 1);
   245 					   l->len - consumed - 1);
   246 	if (!path || !hash || !flags) {
   246 	if (!path || !hash || !flags) {
   247 		goto done;
   247 		goto done;
   248 	}
   248 	}
   249 	ret = PyTuple_Pack(3, path, hash, flags);
   249 	ret = PyTuple_Pack(3, path, hash, flags);
   298 	line *l = lmiter_nextline((lmIter *)o);
   298 	line *l = lmiter_nextline((lmIter *)o);
   299 	if (!l) {
   299 	if (!l) {
   300 		return NULL;
   300 		return NULL;
   301 	}
   301 	}
   302 	pl = pathlen(l);
   302 	pl = pathlen(l);
   303 	return PyString_FromStringAndSize(l->start, pl);
   303 	return PyBytes_FromStringAndSize(l->start, pl);
   304 }
   304 }
   305 
   305 
   306 #ifdef IS_PY3K
   306 #ifdef IS_PY3K
   307 #define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT
   307 #define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT
   308 #else
   308 #else
   396 
   396 
   397 static PyObject *lazymanifest_getitem(lazymanifest *self, PyObject *key)
   397 static PyObject *lazymanifest_getitem(lazymanifest *self, PyObject *key)
   398 {
   398 {
   399 	line needle;
   399 	line needle;
   400 	line *hit;
   400 	line *hit;
   401 	if (!PyString_Check(key)) {
   401 	if (!PyBytes_Check(key)) {
   402 		PyErr_Format(PyExc_TypeError,
   402 		PyErr_Format(PyExc_TypeError,
   403 			     "getitem: manifest keys must be a string.");
   403 			     "getitem: manifest keys must be a string.");
   404 		return NULL;
   404 		return NULL;
   405 	}
   405 	}
   406 	needle.start = PyString_AsString(key);
   406 	needle.start = PyBytes_AsString(key);
   407 	hit = bsearch(&needle, self->lines, self->numlines, sizeof(line),
   407 	hit = bsearch(&needle, self->lines, self->numlines, sizeof(line),
   408 		      &linecmp);
   408 		      &linecmp);
   409 	if (!hit || hit->deleted) {
   409 	if (!hit || hit->deleted) {
   410 		PyErr_Format(PyExc_KeyError, "No such manifest entry.");
   410 		PyErr_Format(PyExc_KeyError, "No such manifest entry.");
   411 		return NULL;
   411 		return NULL;
   415 
   415 
   416 static int lazymanifest_delitem(lazymanifest *self, PyObject *key)
   416 static int lazymanifest_delitem(lazymanifest *self, PyObject *key)
   417 {
   417 {
   418 	line needle;
   418 	line needle;
   419 	line *hit;
   419 	line *hit;
   420 	if (!PyString_Check(key)) {
   420 	if (!PyBytes_Check(key)) {
   421 		PyErr_Format(PyExc_TypeError,
   421 		PyErr_Format(PyExc_TypeError,
   422 			     "delitem: manifest keys must be a string.");
   422 			     "delitem: manifest keys must be a string.");
   423 		return -1;
   423 		return -1;
   424 	}
   424 	}
   425 	needle.start = PyString_AsString(key);
   425 	needle.start = PyBytes_AsString(key);
   426 	hit = bsearch(&needle, self->lines, self->numlines, sizeof(line),
   426 	hit = bsearch(&needle, self->lines, self->numlines, sizeof(line),
   427 		      &linecmp);
   427 		      &linecmp);
   428 	if (!hit || hit->deleted) {
   428 	if (!hit || hit->deleted) {
   429 		PyErr_Format(PyExc_KeyError,
   429 		PyErr_Format(PyExc_KeyError,
   430 			     "Tried to delete nonexistent manifest entry.");
   430 			     "Tried to delete nonexistent manifest entry.");
   484 	Py_ssize_t flen;
   484 	Py_ssize_t flen;
   485 	size_t dlen;
   485 	size_t dlen;
   486 	char *dest;
   486 	char *dest;
   487 	int i;
   487 	int i;
   488 	line new;
   488 	line new;
   489 	if (!PyString_Check(key)) {
   489 	if (!PyBytes_Check(key)) {
   490 		PyErr_Format(PyExc_TypeError,
   490 		PyErr_Format(PyExc_TypeError,
   491 			     "setitem: manifest keys must be a string.");
   491 			     "setitem: manifest keys must be a string.");
   492 		return -1;
   492 		return -1;
   493 	}
   493 	}
   494 	if (!value) {
   494 	if (!value) {
   497 	if (!PyTuple_Check(value) || PyTuple_Size(value) != 2) {
   497 	if (!PyTuple_Check(value) || PyTuple_Size(value) != 2) {
   498 		PyErr_Format(PyExc_TypeError,
   498 		PyErr_Format(PyExc_TypeError,
   499 			     "Manifest values must be a tuple of (node, flags).");
   499 			     "Manifest values must be a tuple of (node, flags).");
   500 		return -1;
   500 		return -1;
   501 	}
   501 	}
   502 	if (PyString_AsStringAndSize(key, &path, &plen) == -1) {
   502 	if (PyBytes_AsStringAndSize(key, &path, &plen) == -1) {
   503 		return -1;
   503 		return -1;
   504 	}
   504 	}
   505 
   505 
   506 	pyhash = PyTuple_GetItem(value, 0);
   506 	pyhash = PyTuple_GetItem(value, 0);
   507 	if (!PyString_Check(pyhash)) {
   507 	if (!PyBytes_Check(pyhash)) {
   508 		PyErr_Format(PyExc_TypeError,
   508 		PyErr_Format(PyExc_TypeError,
   509 			     "node must be a 20-byte string");
   509 			     "node must be a 20-byte string");
   510 		return -1;
   510 		return -1;
   511 	}
   511 	}
   512 	hlen = PyString_Size(pyhash);
   512 	hlen = PyBytes_Size(pyhash);
   513 	/* Some parts of the codebase try and set 21 or 22
   513 	/* Some parts of the codebase try and set 21 or 22
   514 	 * byte "hash" values in order to perturb things for
   514 	 * byte "hash" values in order to perturb things for
   515 	 * status. We have to preserve at least the 21st
   515 	 * status. We have to preserve at least the 21st
   516 	 * byte. Sigh. If there's a 22nd byte, we drop it on
   516 	 * byte. Sigh. If there's a 22nd byte, we drop it on
   517 	 * the floor, which works fine.
   517 	 * the floor, which works fine.
   519 	if (hlen != 20 && hlen != 21 && hlen != 22) {
   519 	if (hlen != 20 && hlen != 21 && hlen != 22) {
   520 		PyErr_Format(PyExc_TypeError,
   520 		PyErr_Format(PyExc_TypeError,
   521 			     "node must be a 20-byte string");
   521 			     "node must be a 20-byte string");
   522 		return -1;
   522 		return -1;
   523 	}
   523 	}
   524 	hash = PyString_AsString(pyhash);
   524 	hash = PyBytes_AsString(pyhash);
   525 
   525 
   526 	pyflags = PyTuple_GetItem(value, 1);
   526 	pyflags = PyTuple_GetItem(value, 1);
   527 	if (!PyString_Check(pyflags) || PyString_Size(pyflags) > 1) {
   527 	if (!PyBytes_Check(pyflags) || PyBytes_Size(pyflags) > 1) {
   528 		PyErr_Format(PyExc_TypeError,
   528 		PyErr_Format(PyExc_TypeError,
   529 			     "flags must a 0 or 1 byte string");
   529 			     "flags must a 0 or 1 byte string");
   530 		return -1;
   530 		return -1;
   531 	}
   531 	}
   532 	if (PyString_AsStringAndSize(pyflags, &flags, &flen) == -1) {
   532 	if (PyBytes_AsStringAndSize(pyflags, &flags, &flen) == -1) {
   533 		return -1;
   533 		return -1;
   534 	}
   534 	}
   535 	/* one null byte and one newline */
   535 	/* one null byte and one newline */
   536 	dlen = plen + 41 + flen + 1;
   536 	dlen = plen + 41 + flen + 1;
   537 	dest = malloc(dlen);
   537 	dest = malloc(dlen);
   572 
   572 
   573 static int lazymanifest_contains(lazymanifest *self, PyObject *key)
   573 static int lazymanifest_contains(lazymanifest *self, PyObject *key)
   574 {
   574 {
   575 	line needle;
   575 	line needle;
   576 	line *hit;
   576 	line *hit;
   577 	if (!PyString_Check(key)) {
   577 	if (!PyBytes_Check(key)) {
   578 		/* Our keys are always strings, so if the contains
   578 		/* Our keys are always strings, so if the contains
   579 		 * check is for a non-string, just return false. */
   579 		 * check is for a non-string, just return false. */
   580 		return 0;
   580 		return 0;
   581 	}
   581 	}
   582 	needle.start = PyString_AsString(key);
   582 	needle.start = PyBytes_AsString(key);
   583 	hit = bsearch(&needle, self->lines, self->numlines, sizeof(line),
   583 	hit = bsearch(&needle, self->lines, self->numlines, sizeof(line),
   584 		      &linecmp);
   584 		      &linecmp);
   585 	if (!hit || hit->deleted) {
   585 	if (!hit || hit->deleted) {
   586 		return 0;
   586 		return 0;
   587 	}
   587 	}
   617 	for (i = 0; i < self->numlines; i++) {
   617 	for (i = 0; i < self->numlines; i++) {
   618 		if (!self->lines[i].deleted) {
   618 		if (!self->lines[i].deleted) {
   619 			need += self->lines[i].len;
   619 			need += self->lines[i].len;
   620 		}
   620 		}
   621 	}
   621 	}
   622 	pydata = PyString_FromStringAndSize(NULL, need);
   622 	pydata = PyBytes_FromStringAndSize(NULL, need);
   623 	if (!pydata)
   623 	if (!pydata)
   624 		return -1;
   624 		return -1;
   625 	data = PyString_AsString(pydata);
   625 	data = PyBytes_AsString(pydata);
   626 	if (!data) {
   626 	if (!data) {
   627 		return -1;
   627 		return -1;
   628 	}
   628 	}
   629 	src = self->lines;
   629 	src = self->lines;
   630 	dst = self->lines;
   630 	dst = self->lines;
   755 	int sneedle = 0, oneedle = 0;
   755 	int sneedle = 0, oneedle = 0;
   756 	if (!PyArg_ParseTuple(args, "O!|O", &lazymanifestType, &other, &pyclean)) {
   756 	if (!PyArg_ParseTuple(args, "O!|O", &lazymanifestType, &other, &pyclean)) {
   757 		return NULL;
   757 		return NULL;
   758 	}
   758 	}
   759 	listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean);
   759 	listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean);
   760 	es = PyString_FromString("");
   760 	es = PyBytes_FromString("");
   761 	if (!es) {
   761 	if (!es) {
   762 		goto nomem;
   762 		goto nomem;
   763 	}
   763 	}
   764 	emptyTup = PyTuple_Pack(2, Py_None, es);
   764 	emptyTup = PyTuple_Pack(2, Py_None, es);
   765 	Py_DECREF(es);
   765 	Py_DECREF(es);
   795 			result = -1;
   795 			result = -1;
   796 		} else {
   796 		} else {
   797 			result = linecmp(left, right);
   797 			result = linecmp(left, right);
   798 		}
   798 		}
   799 		key = result <= 0 ?
   799 		key = result <= 0 ?
   800 			PyString_FromString(left->start) :
   800 			PyBytes_FromString(left->start) :
   801 			PyString_FromString(right->start);
   801 			PyBytes_FromString(right->start);
   802 		if (!key)
   802 		if (!key)
   803 			goto nomem;
   803 			goto nomem;
   804 		if (result < 0) {
   804 		if (result < 0) {
   805 			PyObject *l = hashflags(left);
   805 			PyObject *l = hashflags(left);
   806 			if (!l) {
   806 			if (!l) {