mercurial/cext/dirs.c
author Martin von Zweigbergk <martinvonz@google.com>
Sun, 21 Jul 2019 07:59:16 -0700
changeset 42669 36c692eb28d3
parent 42343 d8e55c0c642c
child 43149 2a0774e9d2a8
permissions -rw-r--r--
transaction: leave unfinished without crashing when not properly released I think the transaction.__del__ is there just as a last resort in case we (or an extension) forgot to release the transaction. When that happens, the repo can (or will on Python 3?) get deleted before the transaction. This leads to a crash in test-devel-warnings.t on Python 3 because we tried to access repo.dirstate, where repo was retried from a weak reference. There's not much we can do here, but let's at least avoid the crash. The user will have run `hg recover` afterwards regardless. Differential Revision: https://phab.mercurial-scm.org/D6664
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     1
/*
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     2
 dirs.c - dynamic directory diddling for dirstates
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     3
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     4
 Copyright 2013 Facebook
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     5
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     6
 This software may be used and distributed according to the terms of
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     7
 the GNU General Public License, incorporated herein by reference.
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     8
*/
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
     9
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    10
#define PY_SSIZE_T_CLEAN
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    11
#include <Python.h>
34438
b90e8da190da cext: reorder #include
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32372
diff changeset
    12
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    13
#include "util.h"
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    14
30106
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    15
#ifdef IS_PY3K
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    16
#define PYLONG_VALUE(o) ((PyLongObject *)o)->ob_digit[1]
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    17
#else
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    18
#define PYLONG_VALUE(o) PyInt_AS_LONG(o)
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    19
#endif
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    20
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    21
/*
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    22
 * This is a multiset of directory names, built from the files that
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    23
 * appear in a dirstate or manifest.
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    24
 *
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    25
 * A few implementation notes:
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    26
 *
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    27
 * We modify Python integers for refcounting, but those integers are
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    28
 * never visible to Python code.
18902
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    29
 *
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    30
 * We mutate strings in-place, but leave them immutable once they can
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    31
 * be seen by Python code.
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    32
 */
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    33
typedef struct {
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    34
	PyObject_HEAD
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    35
	PyObject *dict;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    36
} dirsObject;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    37
25093
fe3a72a3e7ca dirs.c: pass C string, not Python string, to _finddir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 25092
diff changeset
    38
static inline Py_ssize_t _finddir(const char *path, Py_ssize_t pos)
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    39
{
25015
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    40
	while (pos != -1) {
25093
fe3a72a3e7ca dirs.c: pass C string, not Python string, to _finddir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 25092
diff changeset
    41
		if (path[pos] == '/')
25015
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    42
			break;
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    43
		pos -= 1;
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    44
	}
42343
d8e55c0c642c util: make util.dirs() and util.finddirs() include root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 34438
diff changeset
    45
	if (pos == -1) {
d8e55c0c642c util: make util.dirs() and util.finddirs() include root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 34438
diff changeset
    46
	  return 0;
d8e55c0c642c util: make util.dirs() and util.finddirs() include root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 34438
diff changeset
    47
	}
25015
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    48
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    49
	return pos;
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    50
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    51
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    52
static int _addpath(PyObject *dirs, PyObject *path)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    53
{
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
    54
	const char *cpath = PyBytes_AS_STRING(path);
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
    55
	Py_ssize_t pos = PyBytes_GET_SIZE(path);
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    56
	PyObject *key = NULL;
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    57
	int ret = -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    58
30107
da08f4707282 dirs: document performance reasons for bypassing Python C API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30106
diff changeset
    59
	/* This loop is super critical for performance. That's why we inline
da08f4707282 dirs: document performance reasons for bypassing Python C API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30106
diff changeset
    60
	* access to Python structs instead of going through a supported API.
da08f4707282 dirs: document performance reasons for bypassing Python C API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30106
diff changeset
    61
	* The implementation, therefore, is heavily dependent on CPython
da08f4707282 dirs: document performance reasons for bypassing Python C API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30106
diff changeset
    62
	* implementation details. We also commit violations of the Python
da08f4707282 dirs: document performance reasons for bypassing Python C API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30106
diff changeset
    63
	* "protocol" such as mutating immutable objects. But since we only
da08f4707282 dirs: document performance reasons for bypassing Python C API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30106
diff changeset
    64
	* mutate objects created in this function or in other well-defined
da08f4707282 dirs: document performance reasons for bypassing Python C API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30106
diff changeset
    65
	* locations, the references are known so these violations should go
30139
27e00e6352ce dirs: add comment about _PyBytes_Resize
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30107
diff changeset
    66
	* unnoticed. The code for adjusting the length of a PyBytesObject is
27e00e6352ce dirs: add comment about _PyBytes_Resize
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30107
diff changeset
    67
	* essentially a minimal version of _PyBytes_Resize. */
25093
fe3a72a3e7ca dirs.c: pass C string, not Python string, to _finddir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 25092
diff changeset
    68
	while ((pos = _finddir(cpath, pos - 1)) != -1) {
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    69
		PyObject *val;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    70
18902
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    71
		/* It's likely that every prefix already has an entry
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    72
		   in our dict. Try to avoid allocating and
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    73
		   deallocating a string for each prefix we check. */
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    74
		if (key != NULL)
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
    75
			((PyBytesObject *)key)->ob_shash = -1;
25015
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    76
		else {
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    77
			/* Force Python to not reuse a small shared string. */
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
    78
			key = PyBytes_FromStringAndSize(cpath,
25015
b3a68fb8b859 dirs: back out forward-searching in finddirs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24651
diff changeset
    79
							 pos < 2 ? 2 : pos);
18902
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    80
			if (key == NULL)
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    81
				goto bail;
8c0a7eeda06d dirs: use mutable strings internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18901
diff changeset
    82
		}
30159
fb5504d7b2c9 dirs: document Py_SIZE weirdness
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30139
diff changeset
    83
		/* Py_SIZE(o) refers to the ob_size member of the struct. Yes,
fb5504d7b2c9 dirs: document Py_SIZE weirdness
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30139
diff changeset
    84
		* assigning to what looks like a function seems wrong. */
30104
63e1dca2d6a4 dirs: inline string macros
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25093
diff changeset
    85
		Py_SIZE(key) = pos;
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
    86
		((PyBytesObject *)key)->ob_sval[pos] = '\0';
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    87
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    88
		val = PyDict_GetItem(dirs, key);
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    89
		if (val != NULL) {
30106
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    90
			PYLONG_VALUE(val) += 1;
25016
42e89b87ca79 dirs: speed up by storing number of direct children per dir
Martin von Zweigbergk <martinvonz@google.com>
parents: 25015
diff changeset
    91
			break;
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    92
		}
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    93
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    94
		/* Force Python to not reuse a small shared int. */
30106
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    95
#ifdef IS_PY3K
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    96
		val = PyLong_FromLong(0x1eadbeef);
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    97
#else
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
    98
		val = PyInt_FromLong(0x1eadbeef);
30106
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
    99
#endif
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   100
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
   101
		if (val == NULL)
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   102
			goto bail;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   103
30106
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
   104
		PYLONG_VALUE(val) = 1;
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
   105
		ret = PyDict_SetItem(dirs, key, val);
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
   106
		Py_DECREF(val);
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   107
		if (ret == -1)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   108
			goto bail;
24651
67241ee427cf dirs._addpath: reinstate use of Py_CLEAR
Siddharth Agarwal <sid0@fb.com>
parents: 24624
diff changeset
   109
		Py_CLEAR(key);
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   110
	}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   111
	ret = 0;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   112
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   113
bail:
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   114
	Py_XDECREF(key);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   115
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   116
	return ret;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   117
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   118
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   119
static int _delpath(PyObject *dirs, PyObject *path)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   120
{
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   121
	char *cpath = PyBytes_AS_STRING(path);
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   122
	Py_ssize_t pos = PyBytes_GET_SIZE(path);
18901
66d3aebe2d95 dirs: use mutable integers internally
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
   123
	PyObject *key = NULL;
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   124
	int ret = -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   125
25093
fe3a72a3e7ca dirs.c: pass C string, not Python string, to _finddir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 25092
diff changeset
   126
	while ((pos = _finddir(cpath, pos - 1)) != -1) {
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   127
		PyObject *val;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   128
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   129
		key = PyBytes_FromStringAndSize(cpath, pos);
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   130
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   131
		if (key == NULL)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   132
			goto bail;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   133
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   134
		val = PyDict_GetItem(dirs, key);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   135
		if (val == NULL) {
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   136
			PyErr_SetString(PyExc_ValueError,
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   137
					"expected a value, found none");
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   138
			goto bail;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   139
		}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   140
30106
cb3048746dae dirs: port PyInt code to work on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30105
diff changeset
   141
		if (--PYLONG_VALUE(val) <= 0) {
25016
42e89b87ca79 dirs: speed up by storing number of direct children per dir
Martin von Zweigbergk <martinvonz@google.com>
parents: 25015
diff changeset
   142
			if (PyDict_DelItem(dirs, key) == -1)
42e89b87ca79 dirs: speed up by storing number of direct children per dir
Martin von Zweigbergk <martinvonz@google.com>
parents: 25015
diff changeset
   143
				goto bail;
42e89b87ca79 dirs: speed up by storing number of direct children per dir
Martin von Zweigbergk <martinvonz@google.com>
parents: 25015
diff changeset
   144
		} else
42e89b87ca79 dirs: speed up by storing number of direct children per dir
Martin von Zweigbergk <martinvonz@google.com>
parents: 25015
diff changeset
   145
			break;
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   146
		Py_CLEAR(key);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   147
	}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   148
	ret = 0;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   149
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   150
bail:
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   151
	Py_XDECREF(key);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   152
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   153
	return ret;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   154
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   155
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   156
static int dirs_fromdict(PyObject *dirs, PyObject *source, char skipchar)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   157
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   158
	PyObject *key, *value;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   159
	Py_ssize_t pos = 0;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   160
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   161
	while (PyDict_Next(source, &pos, &key, &value)) {
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   162
		if (!PyBytes_Check(key)) {
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   163
			PyErr_SetString(PyExc_TypeError, "expected string key");
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   164
			return -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   165
		}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   166
		if (skipchar) {
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 18902
diff changeset
   167
			if (!dirstate_tuple_check(value)) {
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   168
				PyErr_SetString(PyExc_TypeError,
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 18902
diff changeset
   169
						"expected a dirstate tuple");
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   170
				return -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   171
			}
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 18902
diff changeset
   172
			if (((dirstateTupleObject *)value)->state == skipchar)
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   173
				continue;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   174
		}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   175
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   176
		if (_addpath(dirs, key) == -1)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   177
			return -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   178
	}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   179
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   180
	return 0;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   181
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   182
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   183
static int dirs_fromiter(PyObject *dirs, PyObject *source)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   184
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   185
	PyObject *iter, *item = NULL;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   186
	int ret;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   187
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   188
	iter = PyObject_GetIter(source);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   189
	if (iter == NULL)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   190
		return -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   191
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   192
	while ((item = PyIter_Next(iter)) != NULL) {
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   193
		if (!PyBytes_Check(item)) {
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   194
			PyErr_SetString(PyExc_TypeError, "expected string");
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   195
			break;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   196
		}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   197
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   198
		if (_addpath(dirs, item) == -1)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   199
			break;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   200
		Py_CLEAR(item);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   201
	}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   202
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   203
	ret = PyErr_Occurred() ? -1 : 0;
23960
bca4b6f126f2 dirs: fix leak of iterator in dirs_fromiter
Augie Fackler <augie@google.com>
parents: 21809
diff changeset
   204
	Py_DECREF(iter);
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   205
	Py_XDECREF(item);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   206
	return ret;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   207
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   208
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   209
/*
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   210
 * Calculate a refcounted set of directory names for the files in a
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   211
 * dirstate.
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   212
 */
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   213
static int dirs_init(dirsObject *self, PyObject *args)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   214
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   215
	PyObject *dirs = NULL, *source = NULL;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   216
	char skipchar = 0;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   217
	int ret = -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   218
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   219
	self->dict = NULL;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   220
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   221
	if (!PyArg_ParseTuple(args, "|Oc:__init__", &source, &skipchar))
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   222
		return -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   223
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   224
	dirs = PyDict_New();
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   225
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   226
	if (dirs == NULL)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   227
		return -1;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   228
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   229
	if (source == NULL)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   230
		ret = 0;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   231
	else if (PyDict_Check(source))
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   232
		ret = dirs_fromdict(dirs, source, skipchar);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   233
	else if (skipchar)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   234
		PyErr_SetString(PyExc_ValueError,
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   235
				"skip character is only supported "
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   236
				"with a dict source");
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   237
	else
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   238
		ret = dirs_fromiter(dirs, source);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   239
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   240
	if (ret == -1)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   241
		Py_XDECREF(dirs);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   242
	else
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   243
		self->dict = dirs;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   244
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   245
	return ret;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   246
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   247
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   248
PyObject *dirs_addpath(dirsObject *self, PyObject *args)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   249
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   250
	PyObject *path;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   251
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   252
	if (!PyArg_ParseTuple(args, "O!:addpath", &PyBytes_Type, &path))
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   253
		return NULL;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   254
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   255
	if (_addpath(self->dict, path) == -1)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   256
		return NULL;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   257
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   258
	Py_RETURN_NONE;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   259
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   260
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   261
static PyObject *dirs_delpath(dirsObject *self, PyObject *args)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   262
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   263
	PyObject *path;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   264
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   265
	if (!PyArg_ParseTuple(args, "O!:delpath", &PyBytes_Type, &path))
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   266
		return NULL;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   267
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   268
	if (_delpath(self->dict, path) == -1)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   269
		return NULL;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   270
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   271
	Py_RETURN_NONE;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   272
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   273
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   274
static int dirs_contains(dirsObject *self, PyObject *value)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   275
{
30105
b2f90d8878ac dirs: convert PyString to PyBytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30104
diff changeset
   276
	return PyBytes_Check(value) ? PyDict_Contains(self->dict, value) : 0;
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   277
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   278
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   279
static void dirs_dealloc(dirsObject *self)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   280
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   281
	Py_XDECREF(self->dict);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   282
	PyObject_Del(self);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   283
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   284
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   285
static PyObject *dirs_iter(dirsObject *self)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   286
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   287
	return PyObject_GetIter(self->dict);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   288
}
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   289
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   290
static PySequenceMethods dirs_sequence_methods;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   291
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   292
static PyMethodDef dirs_methods[] = {
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   293
	{"addpath", (PyCFunction)dirs_addpath, METH_VARARGS, "add a path"},
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   294
	{"delpath", (PyCFunction)dirs_delpath, METH_VARARGS, "remove a path"},
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   295
	{NULL} /* Sentinel */
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   296
};
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   297
30167
1e5ff5ae1d2b dirs: use PyVarObject_HEAD_INIT
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30159
diff changeset
   298
static PyTypeObject dirsType = { PyVarObject_HEAD_INIT(NULL, 0) };
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   299
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   300
void dirs_module_init(PyObject *mod)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   301
{
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   302
	dirs_sequence_methods.sq_contains = (objobjproc)dirs_contains;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   303
	dirsType.tp_name = "parsers.dirs";
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   304
	dirsType.tp_new = PyType_GenericNew;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   305
	dirsType.tp_basicsize = sizeof(dirsObject);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   306
	dirsType.tp_dealloc = (destructor)dirs_dealloc;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   307
	dirsType.tp_as_sequence = &dirs_sequence_methods;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   308
	dirsType.tp_flags = Py_TPFLAGS_DEFAULT;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   309
	dirsType.tp_doc = "dirs";
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   310
	dirsType.tp_iter = (getiterfunc)dirs_iter;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   311
	dirsType.tp_methods = dirs_methods;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   312
	dirsType.tp_init = (initproc)dirs_init;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   313
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   314
	if (PyType_Ready(&dirsType) < 0)
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   315
		return;
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   316
	Py_INCREF(&dirsType);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   317
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   318
	PyModule_AddObject(mod, "dirs", (PyObject *)&dirsType);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   319
}