34 } |
39 } |
35 |
40 |
36 static int _addpath(PyObject *dirs, PyObject *path) |
41 static int _addpath(PyObject *dirs, PyObject *path) |
37 { |
42 { |
38 Py_ssize_t pos = PyString_GET_SIZE(path); |
43 Py_ssize_t pos = PyString_GET_SIZE(path); |
39 PyObject *newval = NULL, *key = NULL; |
44 PyObject *key = NULL; |
40 int ret = -1; |
45 int ret = -1; |
41 |
46 |
42 while ((pos = _finddir(path, pos - 1)) != -1) { |
47 while ((pos = _finddir(path, pos - 1)) != -1) { |
43 PyObject *val; |
48 PyObject *val; |
44 long v = 0; |
|
45 |
49 |
46 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos); |
50 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos); |
47 |
51 |
48 if (key == NULL) |
52 if (key == NULL) |
49 goto bail; |
53 goto bail; |
50 |
54 |
51 val = PyDict_GetItem(dirs, key); |
55 val = PyDict_GetItem(dirs, key); |
52 if (val != NULL) |
56 if (val != NULL) { |
53 v = PyInt_AS_LONG(val); |
57 PyInt_AS_LONG(val) += 1; |
54 |
58 Py_CLEAR(key); |
55 newval = PyInt_FromLong(v + 1); |
59 continue; |
56 |
60 } |
57 if (newval == NULL) |
61 |
58 goto bail; |
62 /* Force Python to not reuse a small shared int. */ |
59 |
63 val = PyInt_FromLong(0x1eadbeef); |
60 ret = PyDict_SetItem(dirs, key, newval); |
64 |
|
65 if (val == NULL) |
|
66 goto bail; |
|
67 |
|
68 PyInt_AS_LONG(val) = 1; |
|
69 ret = PyDict_SetItem(dirs, key, val); |
|
70 Py_DECREF(val); |
61 if (ret == -1) |
71 if (ret == -1) |
62 goto bail; |
72 goto bail; |
63 Py_CLEAR(key); |
73 Py_CLEAR(key); |
64 Py_CLEAR(newval); |
|
65 } |
74 } |
66 ret = 0; |
75 ret = 0; |
67 |
76 |
68 bail: |
77 bail: |
69 Py_XDECREF(key); |
78 Py_XDECREF(key); |
70 Py_XDECREF(newval); |
|
71 |
79 |
72 return ret; |
80 return ret; |
73 } |
81 } |
74 |
82 |
75 static int _delpath(PyObject *dirs, PyObject *path) |
83 static int _delpath(PyObject *dirs, PyObject *path) |
76 { |
84 { |
77 Py_ssize_t pos = PyString_GET_SIZE(path); |
85 Py_ssize_t pos = PyString_GET_SIZE(path); |
78 PyObject *newval = NULL, *key = NULL; |
86 PyObject *key = NULL; |
79 int ret = -1; |
87 int ret = -1; |
80 |
88 |
81 while ((pos = _finddir(path, pos - 1)) != -1) { |
89 while ((pos = _finddir(path, pos - 1)) != -1) { |
82 PyObject *val; |
90 PyObject *val; |
83 long v; |
|
84 |
91 |
85 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos); |
92 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos); |
86 |
93 |
87 if (key == NULL) |
94 if (key == NULL) |
88 goto bail; |
95 goto bail; |
91 if (val == NULL) { |
98 if (val == NULL) { |
92 PyErr_SetString(PyExc_ValueError, |
99 PyErr_SetString(PyExc_ValueError, |
93 "expected a value, found none"); |
100 "expected a value, found none"); |
94 goto bail; |
101 goto bail; |
95 } |
102 } |
96 v = PyInt_AS_LONG(val); |
103 |
97 |
104 if (--PyInt_AS_LONG(val) <= 0 && |
98 if (v <= 1) { |
105 PyDict_DelItem(dirs, key) == -1) |
99 if (PyDict_DelItem(dirs, key) == -1) |
|
100 goto bail; |
|
101 continue; |
|
102 } |
|
103 newval = PyInt_FromLong(v - 1); |
|
104 |
|
105 if (newval == NULL) |
|
106 goto bail; |
|
107 |
|
108 ret = PyDict_SetItem(dirs, key, newval); |
|
109 if (ret == -1) |
|
110 goto bail; |
106 goto bail; |
111 Py_CLEAR(key); |
107 Py_CLEAR(key); |
112 Py_CLEAR(newval); |
|
113 } |
108 } |
114 ret = 0; |
109 ret = 0; |
115 |
110 |
116 bail: |
111 bail: |
117 Py_XDECREF(key); |
112 Py_XDECREF(key); |
118 Py_XDECREF(newval); |
|
119 |
113 |
120 return ret; |
114 return ret; |
121 } |
115 } |
122 |
116 |
123 static int dirs_fromdict(PyObject *dirs, PyObject *source, char skipchar) |
117 static int dirs_fromdict(PyObject *dirs, PyObject *source, char skipchar) |