Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/osutil.c @ 5421:9b5d626be8ba
osutil: cleanups
- use tabs
- eliminate old-style function pointer calls
- eliminate weird scoping
- eliminate assignment-in-iff
- use !foo rather than foo == NULL
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 08 Oct 2007 18:47:06 -0500 |
parents | ca890c0c3f1f |
children | a3ba7ef98c94 |
comparison
equal
deleted
inserted
replaced
5420:6d1bd20ae14d | 5421:9b5d626be8ba |
---|---|
16 #include <sys/stat.h> | 16 #include <sys/stat.h> |
17 #include <sys/types.h> | 17 #include <sys/types.h> |
18 #include <unistd.h> | 18 #include <unistd.h> |
19 | 19 |
20 struct listdir_stat { | 20 struct listdir_stat { |
21 PyObject_HEAD | 21 PyObject_HEAD |
22 struct stat st; | 22 struct stat st; |
23 }; | 23 }; |
24 | 24 |
25 #define listdir_slot(name) \ | 25 #define listdir_slot(name) \ |
26 static PyObject *listdir_stat_##name(PyObject *self, void *x) \ | 26 static PyObject *listdir_stat_##name(PyObject *self, void *x) \ |
27 { \ | 27 { \ |
28 return PyInt_FromLong(((struct listdir_stat *) self)->st.name); \ | 28 return PyInt_FromLong(((struct listdir_stat *)self)->st.name); \ |
29 } | 29 } |
30 | 30 |
31 listdir_slot(st_dev); | 31 listdir_slot(st_dev); |
32 listdir_slot(st_mode); | 32 listdir_slot(st_mode); |
33 listdir_slot(st_nlink); | 33 listdir_slot(st_nlink); |
34 listdir_slot(st_size); | 34 listdir_slot(st_size); |
35 listdir_slot(st_mtime); | 35 listdir_slot(st_mtime); |
36 listdir_slot(st_ctime); | 36 listdir_slot(st_ctime); |
37 | 37 |
38 static struct PyGetSetDef listdir_stat_getsets[] = { | 38 static struct PyGetSetDef listdir_stat_getsets[] = { |
39 {"st_dev", listdir_stat_st_dev, 0, 0, 0}, | 39 {"st_dev", listdir_stat_st_dev, 0, 0, 0}, |
40 {"st_mode", listdir_stat_st_mode, 0, 0, 0}, | 40 {"st_mode", listdir_stat_st_mode, 0, 0, 0}, |
41 {"st_nlink", listdir_stat_st_nlink, 0, 0, 0}, | 41 {"st_nlink", listdir_stat_st_nlink, 0, 0, 0}, |
42 {"st_size", listdir_stat_st_size, 0, 0, 0}, | 42 {"st_size", listdir_stat_st_size, 0, 0, 0}, |
43 {"st_mtime", listdir_stat_st_mtime, 0, 0, 0}, | 43 {"st_mtime", listdir_stat_st_mtime, 0, 0, 0}, |
44 {"st_ctime", listdir_stat_st_ctime, 0, 0, 0}, | 44 {"st_ctime", listdir_stat_st_ctime, 0, 0, 0}, |
45 {0, 0, 0, 0, 0} | 45 {0, 0, 0, 0, 0} |
46 }; | 46 }; |
47 | 47 |
48 static PyObject *listdir_stat_new(PyTypeObject *t, PyObject *a, PyObject *k) | 48 static PyObject *listdir_stat_new(PyTypeObject *t, PyObject *a, PyObject *k) |
49 { | 49 { |
50 return (*t->tp_alloc)(t, 0); | 50 return t->tp_alloc(t, 0); |
51 } | 51 } |
52 | 52 |
53 static void listdir_stat_dealloc(PyObject *o) | 53 static void listdir_stat_dealloc(PyObject *o) |
54 { | 54 { |
55 (*o->ob_type->tp_free)(o); | 55 o->ob_type->tp_free(o); |
56 } | 56 } |
57 | 57 |
58 static PyTypeObject listdir_stat_type = { | 58 static PyTypeObject listdir_stat_type = { |
59 PyObject_HEAD_INIT(NULL) | 59 PyObject_HEAD_INIT(NULL) |
60 0, /*ob_size*/ | 60 0, /*ob_size*/ |
61 "osutil.stat", /*tp_name*/ | 61 "osutil.stat", /*tp_name*/ |
62 sizeof(struct listdir_stat), /*tp_basicsize*/ | 62 sizeof(struct listdir_stat), /*tp_basicsize*/ |
63 0, /*tp_itemsize*/ | 63 0, /*tp_itemsize*/ |
64 (destructor)listdir_stat_dealloc, /*tp_dealloc*/ | 64 (destructor)listdir_stat_dealloc, /*tp_dealloc*/ |
65 0, /*tp_print*/ | 65 0, /*tp_print*/ |
66 0, /*tp_getattr*/ | 66 0, /*tp_getattr*/ |
67 0, /*tp_setattr*/ | 67 0, /*tp_setattr*/ |
68 0, /*tp_compare*/ | 68 0, /*tp_compare*/ |
69 0, /*tp_repr*/ | 69 0, /*tp_repr*/ |
70 0, /*tp_as_number*/ | 70 0, /*tp_as_number*/ |
71 0, /*tp_as_sequence*/ | 71 0, /*tp_as_sequence*/ |
72 0, /*tp_as_mapping*/ | 72 0, /*tp_as_mapping*/ |
73 0, /*tp_hash */ | 73 0, /*tp_hash */ |
74 0, /*tp_call*/ | 74 0, /*tp_call*/ |
75 0, /*tp_str*/ | 75 0, /*tp_str*/ |
76 0, /*tp_getattro*/ | 76 0, /*tp_getattro*/ |
77 0, /*tp_setattro*/ | 77 0, /*tp_setattro*/ |
78 0, /*tp_as_buffer*/ | 78 0, /*tp_as_buffer*/ |
79 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | 79 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ |
80 "stat objects", /* tp_doc */ | 80 "stat objects", /* tp_doc */ |
81 0, /* tp_traverse */ | 81 0, /* tp_traverse */ |
82 0, /* tp_clear */ | 82 0, /* tp_clear */ |
83 0, /* tp_richcompare */ | 83 0, /* tp_richcompare */ |
84 0, /* tp_weaklistoffset */ | 84 0, /* tp_weaklistoffset */ |
85 0, /* tp_iter */ | 85 0, /* tp_iter */ |
86 0, /* tp_iternext */ | 86 0, /* tp_iternext */ |
87 0, /* tp_methods */ | 87 0, /* tp_methods */ |
88 0, /* tp_members */ | 88 0, /* tp_members */ |
89 listdir_stat_getsets, /* tp_getset */ | 89 listdir_stat_getsets, /* tp_getset */ |
90 0, /* tp_base */ | 90 0, /* tp_base */ |
91 0, /* tp_dict */ | 91 0, /* tp_dict */ |
92 0, /* tp_descr_get */ | 92 0, /* tp_descr_get */ |
93 0, /* tp_descr_set */ | 93 0, /* tp_descr_set */ |
94 0, /* tp_dictoffset */ | 94 0, /* tp_dictoffset */ |
95 0, /* tp_init */ | 95 0, /* tp_init */ |
96 0, /* tp_alloc */ | 96 0, /* tp_alloc */ |
97 listdir_stat_new, /* tp_new */ | 97 listdir_stat_new, /* tp_new */ |
98 }; | 98 }; |
99 | 99 |
100 static inline int mode_to_kind(int mode) | 100 static inline int mode_to_kind(int mode) |
101 { | 101 { |
102 if (S_ISREG(mode)) return S_IFREG; | 102 if (S_ISREG(mode)) return S_IFREG; |
103 if (S_ISDIR(mode)) return S_IFDIR; | 103 if (S_ISDIR(mode)) return S_IFDIR; |
104 if (S_ISLNK(mode)) return S_IFLNK; | 104 if (S_ISLNK(mode)) return S_IFLNK; |
105 if (S_ISBLK(mode)) return S_IFBLK; | 105 if (S_ISBLK(mode)) return S_IFBLK; |
106 if (S_ISCHR(mode)) return S_IFCHR; | 106 if (S_ISCHR(mode)) return S_IFCHR; |
107 if (S_ISFIFO(mode)) return S_IFIFO; | 107 if (S_ISFIFO(mode)) return S_IFIFO; |
108 if (S_ISSOCK(mode)) return S_IFSOCK; | 108 if (S_ISSOCK(mode)) return S_IFSOCK; |
109 return mode; | 109 return mode; |
110 } | 110 } |
111 | 111 |
112 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs) | 112 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs) |
113 { | 113 { |
114 DIR *dir = NULL; | |
115 struct dirent *ent; | |
116 PyObject *list = NULL; | |
117 PyObject *ctor_args = NULL; | |
118 int all_kinds = 1; | |
119 char *full_path; | |
120 int path_len; | |
121 int do_stat; | |
122 char *path; | |
123 int ret; | |
124 | |
125 { | |
126 static char *kwlist[] = { "path", "stat", NULL }; | 114 static char *kwlist[] = { "path", "stat", NULL }; |
127 PyObject *statobj = NULL; | 115 PyObject *statobj = NULL; |
116 DIR *dir = NULL; | |
117 struct dirent *ent; | |
118 PyObject *list = NULL; | |
119 PyObject *ctor_args = NULL; | |
120 int all_kinds = 1; | |
121 char *full_path; | |
122 int path_len; | |
123 int do_stat; | |
124 char *path; | |
125 int ret; | |
126 ssize_t size; | |
127 ssize_t i; | |
128 int dfd; | |
128 | 129 |
129 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist, | 130 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist, |
130 &path, &path_len, &statobj)) | 131 &path, &path_len, &statobj)) |
131 goto bail; | 132 goto bail; |
132 | 133 |
133 do_stat = statobj && PyObject_IsTrue(statobj); | 134 do_stat = statobj && PyObject_IsTrue(statobj); |
134 } | 135 |
135 | 136 dir = opendir(path); |
136 if ((dir = opendir(path)) == NULL) { | 137 if (!dir) { |
137 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); | 138 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); |
138 goto bail; | 139 goto bail; |
139 } | 140 } |
140 | 141 |
141 if ((list = PyList_New(0)) == NULL) | 142 list = PyList_New(0); |
142 goto bail; | 143 if (!list) |
143 | 144 goto bail; |
144 full_path = alloca(path_len + PATH_MAX + 2); | 145 |
145 memcpy(full_path, path, path_len); | 146 full_path = alloca(path_len + PATH_MAX + 2); |
146 full_path[path_len] = '/'; | 147 memcpy(full_path, path, path_len); |
147 | 148 full_path[path_len] = '/'; |
148 while ((ent = readdir(dir))) { | 149 |
149 PyObject *name = NULL; | 150 for (ent = readdir(dir); ent; ent = readdir(dir)) { |
150 PyObject *py_kind = NULL; | 151 PyObject *name = NULL; |
151 PyObject *val = NULL; | 152 PyObject *py_kind = NULL; |
152 unsigned char d_type; | 153 PyObject *val = NULL; |
153 int kind = -1; | 154 unsigned char d_type; |
154 | 155 int kind = -1; |
155 if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) | 156 |
156 continue; | 157 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) |
158 continue; | |
157 | 159 |
158 #ifdef DT_REG | 160 #ifdef DT_REG |
159 if (do_stat) | 161 if (do_stat) |
160 d_type = 0; | 162 d_type = 0; |
161 else | 163 else |
162 d_type = ent->d_type; | 164 d_type = ent->d_type; |
163 #else | 165 #else |
164 d_type = 0; | 166 d_type = 0; |
165 #endif | 167 #endif |
166 | 168 |
167 switch (d_type) { | 169 switch (d_type) { |
168 #ifdef DT_REG | 170 #ifdef DT_REG |
169 case DT_REG: kind = S_IFREG; break; | 171 case DT_REG: kind = S_IFREG; break; |
170 case DT_DIR: kind = S_IFDIR; break; | 172 case DT_DIR: kind = S_IFDIR; break; |
171 case DT_LNK: kind = S_IFLNK; break; | 173 case DT_LNK: kind = S_IFLNK; break; |
172 case DT_BLK: kind = S_IFBLK; break; | 174 case DT_BLK: kind = S_IFBLK; break; |
173 case DT_CHR: kind = S_IFCHR; break; | 175 case DT_CHR: kind = S_IFCHR; break; |
174 case DT_FIFO: kind = S_IFIFO; break; | 176 case DT_FIFO: kind = S_IFIFO; break; |
175 case DT_SOCK: kind = S_IFSOCK; break; | 177 case DT_SOCK: kind = S_IFSOCK; break; |
176 #endif | 178 #endif |
177 default: | 179 default: |
178 if (all_kinds) | 180 if (all_kinds) |
179 all_kinds = 0; | 181 all_kinds = 0; |
180 break; | 182 break; |
183 } | |
184 | |
185 name = PyString_FromString(ent->d_name); | |
186 if (kind != -1) | |
187 py_kind = PyInt_FromLong(kind); | |
188 else { | |
189 py_kind = Py_None; | |
190 Py_INCREF(Py_None); | |
191 } | |
192 | |
193 val = PyTuple_New(do_stat ? 3 : 2); | |
194 | |
195 if (!name || !py_kind || !val) { | |
196 Py_XDECREF(name); | |
197 Py_XDECREF(py_kind); | |
198 Py_XDECREF(val); | |
199 goto bail; | |
200 } | |
201 | |
202 PyTuple_SET_ITEM(val, 0, name); | |
203 PyTuple_SET_ITEM(val, 1, py_kind); | |
204 if (do_stat) { | |
205 PyTuple_SET_ITEM(val, 2, Py_None); | |
206 Py_INCREF(Py_None); | |
207 } | |
208 | |
209 PyList_Append(list, val); | |
210 Py_DECREF(val); | |
181 } | 211 } |
182 | 212 |
183 name = PyString_FromString(ent->d_name); | 213 PyList_Sort(list); |
184 if (kind != -1) | 214 size = PyList_Size(list); |
185 py_kind = PyInt_FromLong(kind); | 215 #ifdef AT_SYMLINK_NOFOLLOW |
186 else { | 216 dfd = dirfd(dir); |
187 py_kind = Py_None; | 217 #endif |
188 Py_INCREF(Py_None); | 218 |
219 if (do_stat || !all_kinds) { | |
220 for (i = 0; i < size; i++) { | |
221 PyObject *elt = PyList_GetItem(list, i); | |
222 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); | |
223 PyObject *py_st = NULL; | |
224 PyObject *py_kind = PyTuple_GET_ITEM(elt, 1); | |
225 int kind; | |
226 | |
227 kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind); | |
228 | |
229 if (kind != -1 && !do_stat) | |
230 continue; | |
231 | |
232 strcpy(full_path + path_len + 1, name); | |
233 | |
234 if (do_stat) { | |
235 struct listdir_stat *st; | |
236 | |
237 if (!ctor_args) { | |
238 ctor_args = PyTuple_New(0); | |
239 if (!ctor_args) | |
240 goto bail; | |
241 } | |
242 | |
243 st = (struct listdir_stat *) | |
244 PyObject_CallObject((PyObject *)&listdir_stat_type, | |
245 ctor_args); | |
246 | |
247 if (!st) | |
248 goto bail; | |
249 #ifdef AT_SYMLINK_NOFOLLOW | |
250 ret = fstatat(dfd, name, &st->st, AT_SYMLINK_NOFOLLOW); | |
251 #else | |
252 ret = lstat(full_path, &st->st); | |
253 #endif | |
254 if (ret == -1) { | |
255 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, | |
256 full_path); | |
257 goto bail; | |
258 } | |
259 if (kind == -1) | |
260 kind = mode_to_kind(st->st.st_mode); | |
261 py_st = (PyObject *)st; | |
262 } else { | |
263 struct stat buf; | |
264 #ifdef AT_SYMLINK_NOFOLLOW | |
265 ret = fstatat(dfd, ent->d_name, &buf, AT_SYMLINK_NOFOLLOW); | |
266 #else | |
267 ret = lstat(full_path, &buf); | |
268 #endif | |
269 if (ret == -1) { | |
270 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, | |
271 full_path); | |
272 goto bail; | |
273 } | |
274 if (kind == -1) | |
275 kind = mode_to_kind(buf.st_mode); | |
276 } | |
277 | |
278 if (py_kind == Py_None && kind != -1) { | |
279 py_kind = PyInt_FromLong(kind); | |
280 if (!py_kind) | |
281 goto bail; | |
282 Py_XDECREF(Py_None); | |
283 PyTuple_SET_ITEM(elt, 1, py_kind); | |
284 } | |
285 | |
286 if (do_stat) { | |
287 if (!py_st) { | |
288 py_st = Py_None; | |
289 Py_INCREF(Py_None); | |
290 } | |
291 PyTuple_SET_ITEM(elt, 2, py_st); | |
292 } | |
293 } | |
189 } | 294 } |
190 | 295 |
191 val = PyTuple_New(do_stat ? 3 : 2); | 296 goto done; |
192 | 297 |
193 if (name == NULL || py_kind == NULL || val == NULL) { | 298 bail: |
194 Py_XDECREF(name); | 299 Py_XDECREF(list); |
195 Py_XDECREF(py_kind); | 300 |
196 Py_XDECREF(val); | 301 done: |
197 | 302 Py_XDECREF(ctor_args); |
198 goto bail; | 303 if (dir) |
199 } | 304 closedir(dir); |
200 | 305 return list; |
201 PyTuple_SET_ITEM(val, 0, name); | 306 } |
202 PyTuple_SET_ITEM(val, 1, py_kind); | 307 |
203 if (do_stat) { | |
204 PyTuple_SET_ITEM(val, 2, Py_None); | |
205 Py_INCREF(Py_None); | |
206 } | |
207 | |
208 PyList_Append(list, val); | |
209 Py_DECREF(val); | |
210 } | |
211 | |
212 PyList_Sort(list); | |
213 | |
214 if (do_stat || !all_kinds) { | |
215 ssize_t size = PyList_Size(list); | |
216 ssize_t i; | |
217 #ifdef AT_SYMLINK_NOFOLLOW | |
218 int dfd = dirfd(dir); | |
219 #endif | |
220 | |
221 for (i = 0; i < size; i++) { | |
222 PyObject *elt = PyList_GetItem(list, i); | |
223 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); | |
224 PyObject *py_st = NULL; | |
225 PyObject *py_kind = PyTuple_GET_ITEM(elt, 1); | |
226 int kind; | |
227 | |
228 kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind); | |
229 | |
230 if (kind != -1 && !do_stat) | |
231 continue; | |
232 | |
233 strcpy(full_path + path_len + 1, name); | |
234 | |
235 if (do_stat) { | |
236 struct listdir_stat *st; | |
237 | |
238 if (ctor_args == NULL) { | |
239 ctor_args = PyTuple_New(0); | |
240 if (ctor_args == NULL) | |
241 goto bail; | |
242 } | |
243 | |
244 st = (struct listdir_stat *) | |
245 PyObject_CallObject((PyObject *) &listdir_stat_type, | |
246 ctor_args); | |
247 if (st == NULL) | |
248 goto bail; | |
249 #ifdef AT_SYMLINK_NOFOLLOW | |
250 ret = fstatat(dfd, name, &st->st, AT_SYMLINK_NOFOLLOW); | |
251 #else | |
252 ret = lstat(full_path, &st->st); | |
253 #endif | |
254 if (ret == -1) { | |
255 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, | |
256 full_path); | |
257 goto bail; | |
258 } | |
259 if (kind == -1) | |
260 kind = mode_to_kind(st->st.st_mode); | |
261 py_st = (PyObject *) st; | |
262 } else { | |
263 struct stat buf; | |
264 #ifdef AT_SYMLINK_NOFOLLOW | |
265 ret = fstatat(dfd, ent->d_name, &buf, AT_SYMLINK_NOFOLLOW); | |
266 #else | |
267 ret = lstat(full_path, &buf); | |
268 #endif | |
269 if (ret == -1) { | |
270 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, | |
271 full_path); | |
272 goto bail; | |
273 } | |
274 if (kind == -1) | |
275 kind = mode_to_kind(buf.st_mode); | |
276 } | |
277 | |
278 if (py_kind == Py_None && kind != -1) { | |
279 py_kind = PyInt_FromLong(kind); | |
280 if (py_kind == NULL) | |
281 goto bail; | |
282 Py_XDECREF(Py_None); | |
283 PyTuple_SET_ITEM(elt, 1, py_kind); | |
284 } | |
285 | |
286 if (do_stat) { | |
287 if (py_st == NULL) { | |
288 py_st = Py_None; | |
289 Py_INCREF(Py_None); | |
290 } | |
291 PyTuple_SET_ITEM(elt, 2, py_st); | |
292 } | |
293 } | |
294 } | |
295 | |
296 goto done; | |
297 | |
298 bail: | |
299 Py_XDECREF(list); | |
300 | |
301 done: | |
302 Py_XDECREF(ctor_args); | |
303 if (dir) | |
304 closedir(dir); | |
305 | |
306 return list; | |
307 } | |
308 | 308 |
309 static char osutil_doc[] = "Native operating system services."; | 309 static char osutil_doc[] = "Native operating system services."; |
310 | 310 |
311 static PyMethodDef methods[] = { | 311 static PyMethodDef methods[] = { |
312 {"listdir", (PyCFunction) listdir, METH_VARARGS | METH_KEYWORDS, | 312 {"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS, |
313 "list a directory\n"}, | 313 "list a directory\n"}, |
314 {NULL, NULL} | 314 {NULL, NULL} |
315 }; | 315 }; |
316 | 316 |
317 PyMODINIT_FUNC initosutil(void) | 317 PyMODINIT_FUNC initosutil(void) |
318 { | 318 { |
319 if (PyType_Ready(&listdir_stat_type) == -1) | 319 if (PyType_Ready(&listdir_stat_type) == -1) |
320 return; | 320 return; |
321 | 321 |
322 Py_InitModule3("osutil", methods, osutil_doc); | 322 Py_InitModule3("osutil", methods, osutil_doc); |
323 } | 323 } |