rpm  5.4.14
rpmfts-py.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include "structmember.h"
8 
9 #ifdef __LCLINT__
10 #undef PyObject_HEAD
11 #define PyObject_HEAD int _PyObjectHead;
12 #endif
13 
14 #include <fts.h>
15 
16 #include "rpmfts-py.h"
17 
18 #include <rpmiotypes.h>
19 
20 #include "debug.h"
21 
22 /*@unchecked@*/
23 static int _rpmfts_debug = 1;
24 
25 #define infoBit(_ix) (1 << (((unsigned)(_ix)) & 0x1f))
26 
27 static const char * ftsInfoStrings[] = {
28  "UNKNOWN",
29  "D",
30  "DC",
31  "DEFAULT",
32  "DNR",
33  "DOT",
34  "DP",
35  "ERR",
36  "F",
37  "INIT",
38  "NS",
39  "NSOK",
40  "SL",
41  "SLNONE",
42  "W",
43 };
44 
45 /*@observer@*/
46 static const char * ftsInfoStr(int fts_info)
47  /*@*/
48 {
49  if (!(fts_info >= 1 && fts_info <= 14))
50  fts_info = 0;
51  return ftsInfoStrings[ fts_info ];
52 }
53 
54 #define RPMFTS_CLOSE 0
55 #define RPMFTS_OPEN 1
56 #define RPMFTS_OPEN_LAZY 2
57 
58 static void
59 rpmfts_debug (const char * msg, rpmftsObject * s)
60 {
61  if (_rpmfts_debug == 0)
62  return;
63  if (msg)
64  fprintf(stderr, "*** %s(%p)", msg, s);
65  if (s)
66  fprintf(stderr, " %u %d ftsp %p fts %p\n", (unsigned) s->ob_refcnt, s->active, s->ftsp, s->fts);
67 }
68 
69 static int
70 rpmfts_initialize(rpmftsObject * s, const char * root, int options, int ignore)
71  /*@modifies s @*/
72 {
73  int ac = 1;
74  size_t nb;
75 
76 /*@-branchstate@*/
77  if (root == NULL) root = "/";
78 /*@=branchstate@*/
79  if (options == -1) options = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT);
80  if (ignore == -1) ignore = infoBit(FTS_DP);
81 
82  s->roots = _free(s->roots);
83 
84  nb = (ac + 1) * sizeof(*s->roots);
85  nb += strlen(root) + 1;
86  s->roots = malloc(nb);
87  if (s->roots != NULL) {
88  char *t = (char *) &s->roots[ac + 1];
89  s->roots[0] = t;
90  s->roots[ac] = NULL;
91  (void) stpcpy(t, root);
92  }
93 
95  s->ignore = ignore;
96  s->compare = NULL;
97 
98  s->ftsp = NULL;
99  s->fts = NULL;
101 
102  return 0;
103 
104 }
105 
106 static int
107 rpmfts_state(rpmftsObject * s, int nactive)
108  /*@modifies s @*/
109 {
110  int rc = 0;
111 
112 rpmfts_debug("rpmfts_state", s);
113  switch (nactive) {
114  case RPMFTS_CLOSE:
115  if (s->ftsp != NULL) {
116  Py_BEGIN_ALLOW_THREADS
117  rc = Fts_close(s->ftsp);
118  Py_END_ALLOW_THREADS
119  s->ftsp = NULL;
120  }
121  break;
122  case RPMFTS_OPEN_LAZY:
123  case RPMFTS_OPEN:
124  if (s->ftsp == NULL) {
125  Py_BEGIN_ALLOW_THREADS
126  s->ftsp = Fts_open((char *const *)s->roots, s->options, (int (*)(const FTSENT **, const FTSENT **))s->compare);
127  Py_END_ALLOW_THREADS
128  }
129  break;
130  }
131  s->fts = NULL;
132  s->active = nactive;
133  return rc;
134 }
135 
136 /*@null@*/
137 static PyObject *
138 rpmfts_step(rpmftsObject * s)
139  /*@modifies s @*/
140 {
141  PyObject * result = NULL;
142  int xx;
143 
144 rpmfts_debug("rpmfts_step", s);
145  if (s->ftsp == NULL)
146  return NULL;
147 
148  do {
149  Py_BEGIN_ALLOW_THREADS
150  s->fts = Fts_read(s->ftsp);
151  Py_END_ALLOW_THREADS
152  } while (s->fts && (infoBit(s->fts->fts_info) & s->ignore));
153 
154  if (s->fts != NULL) {
155  Py_INCREF(s);
156  result = (PyObject *)s;
157  } else {
158  if (s->active == RPMFTS_OPEN_LAZY)
159  xx = rpmfts_state(s, RPMFTS_CLOSE);
160  s->active = RPMFTS_CLOSE;
161  }
162 
163  return result;
164 }
165 
166 /* ---------- */
167 
178 /*@null@*/
179 static PyObject *
180 rpmfts_Debug(/*@unused@*/ rpmftsObject * s, PyObject * args,
181  PyObject * kwds)
182  /*@globals _Py_NoneStruct @*/
183  /*@modifies _Py_NoneStruct @*/
184 {
185  char * kwlist[] = {"debugLevel", NULL};
186 
187  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Debug", kwlist,
188  &_rpmfts_debug))
189  return NULL;
190 
192  return Py_None;
193 }
194 
195 /*@null@*/
196 static PyObject *
197 rpmfts_Open(rpmftsObject * s, PyObject * args, PyObject * kwds)
198  /*@modifies s @*/
199 {
200  char * root = NULL;
201  int options = -1;
202  int ignore = -1;
203  int xx;
204  /* XXX: there's bound to be a better name than "ignore" */
205  char * kwlist[] = {"root", "options", "ignore", NULL};
206 
207 rpmfts_debug("rpmfts_Open", s);
208  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sii:Open", kwlist,
209  &root, &options, &ignore))
210  return NULL;
211 
212  xx = rpmfts_initialize(s, root, options, ignore);
213  xx = rpmfts_state(s, RPMFTS_OPEN);
214 
215  return (PyObject *)s;
216 }
217 
218 /*@null@*/
219 static PyObject *
220 rpmfts_Read(rpmftsObject * s)
221  /*@globals _Py_NoneStruct @*/
222  /*@modifies s, _Py_NoneStruct @*/
223 {
224  PyObject * result;
225 
226 rpmfts_debug("rpmfts_Read", s);
227 
228  result = rpmfts_step(s);
229 
230  if (result == NULL) {
232  return Py_None;
233  }
234 
235  return result;
236 }
237 
238 /*@null@*/
239 static PyObject *
240 rpmfts_Children(rpmftsObject * s, PyObject * args, PyObject * kwds)
241  /*@globals _Py_NoneStruct @*/
242  /*@modifies s, _Py_NoneStruct @*/
243 {
244  int instr;
245  char * kwlist[] = {"instructions", NULL};
246 
247 rpmfts_debug("rpmfts_Children", s);
248  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Children", kwlist, &instr))
249  return NULL;
250 
251  if (!(s && s->ftsp))
252  return NULL;
253 
254  Py_BEGIN_ALLOW_THREADS
255  s->fts = Fts_children(s->ftsp, instr);
256  Py_END_ALLOW_THREADS
257 
259  return Py_None;
260 }
261 
262 /*@null@*/
263 static PyObject *
264 rpmfts_Close(rpmftsObject * s)
265  /*@modifies s @*/
266 {
267 
268 rpmfts_debug("rpmfts_Close", s);
269 
270  return Py_BuildValue("i", rpmfts_state(s, RPMFTS_CLOSE));
271 }
272 
273 /*@null@*/
274 static PyObject *
275 rpmfts_Set(rpmftsObject * s, PyObject * args, PyObject * kwds)
276  /*@modifies s @*/
277 {
278  int instr = 0;
279  int rc = 0;
280  char * kwlist[] = {"instructions", NULL};
281 
282 rpmfts_debug("rpmfts_Set", s);
283  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Set", kwlist, &instr))
284  return NULL;
285 
286  if (s->ftsp && s->fts)
287  rc = Fts_set(s->ftsp, s->fts, instr);
288 
289  return Py_BuildValue("i", rc);
290 }
295 /*@-fullinitblock@*/
296 /*@unchecked@*/ /*@observer@*/
297 static struct PyMethodDef rpmfts_methods[] = {
298  {"Debug", (PyCFunction)rpmfts_Debug, METH_VARARGS|METH_KEYWORDS,
299  NULL},
300  {"open", (PyCFunction)rpmfts_Open, METH_VARARGS|METH_KEYWORDS,
301  NULL},
302  {"read", (PyCFunction)rpmfts_Read, METH_NOARGS,
303  NULL},
304  {"children",(PyCFunction)rpmfts_Children, METH_VARARGS|METH_KEYWORDS,
305  NULL},
306  {"close", (PyCFunction)rpmfts_Close, METH_NOARGS,
307  NULL},
308  {"set", (PyCFunction)rpmfts_Set, METH_VARARGS|METH_KEYWORDS,
309  NULL},
310  {NULL, NULL} /* sentinel */
311 };
312 /*@=fullinitblock@*/
313 
314 /* ---------- */
315 
316 static PyMemberDef rpmfts_members[] = {
317  {"__dict__",T_OBJECT,offsetof(rpmftsObject, md_dict), READONLY,
318  NULL},
319  {"callbacks",T_OBJECT,offsetof(rpmftsObject, callbacks), 0,
320 "Callback dictionary per fts_info state: FTS_{D|DC|DEFAULT|DNR|DOT|DP|ERR|F|INIT|NS|NSOK|SL|SLNONE|W}"},
321  {"options", T_INT, offsetof(rpmftsObject, options), 0,
322 "Option bit(s): FTS_{COMFOLLOW|LOGICAL|NOCHDIR|NOSTAT|PHYSICAL|SEEDOT|XDEV}"},
323  {"ignore", T_INT, offsetof(rpmftsObject, ignore), 0,
324 "Ignore bit(s): (1 << info) with info one of FTS_{D|DC|DEFAULT|DNR|DOT|DP|ERR|F|INIT|NS|NSOK|SL|SLNONE|W}"},
325  {NULL, 0, 0, 0, NULL}
326 };
327 
328 static PyObject * rpmfts_getattro(PyObject * o, PyObject * n)
329  /*@*/
330 {
331 rpmfts_debug("rpmfts_getattro", (rpmftsObject *)o);
332  return PyObject_GenericGetAttr(o, n);
333 }
334 
335 static int rpmfts_setattro(PyObject * o, PyObject * n, PyObject * v)
336  /*@*/
337 {
338 rpmfts_debug("rpmfts_setattro", (rpmftsObject *)o);
339  return PyObject_GenericSetAttr(o, n, v);
340 }
341 
342 /* ---------- */
343 
344 static PyObject *
345 rpmfts_iter(rpmftsObject * s)
346  /*@*/
347 {
348  Py_INCREF(s);
349  return (PyObject *)s;
350 }
351 
352 /*@null@*/
353 static PyObject *
354 rpmfts_iternext(rpmftsObject * s)
355  /*@modifies s @*/
356 {
357  int xx;
358 
359  /* Reset loop indices on 1st entry. */
360  if (s->active == RPMFTS_CLOSE)
361  xx = rpmfts_state(s, RPMFTS_OPEN_LAZY);
362  return rpmfts_step(s);
363 }
364 
365 /* ---------- */
366 
367 static void rpmfts_free(/*@only@*/ PyObject * s)
368  /*@*/
369 {
370  _PyObject_GC_Del(s);
371 }
372 
373 static PyObject * rpmfts_alloc(PyTypeObject * type, Py_ssize_t nitems)
374  /*@*/
375 {
376  return PyType_GenericAlloc(type, nitems);
377 }
378 
379 static void rpmfts_dealloc(/*@only@*/ rpmftsObject * s)
380  /*@modifies s @*/
381 {
382  int xx;
383 
384 rpmfts_debug("rpmfts_dealloc", s);
385  xx = rpmfts_state(s, RPMFTS_CLOSE);
386 
387  s->roots = _free(s->roots);
388 
389  PyObject_GC_UnTrack((PyObject *)s);
390  if (s->md_dict != NULL) {
391  _PyModule_Clear((PyObject *)s);
392  Py_XDECREF(s->md_dict);
393  }
394  if (s->callbacks != NULL) {
395  _PyModule_Clear((PyObject *)s);
396  Py_XDECREF(s->callbacks);
397  }
398  _PyObject_GC_Del((PyObject *)s);
399 }
400 
401 static int rpmfts_init(rpmftsObject * s, PyObject *args, PyObject *kwds)
402  /*@modifies s @*/
403 {
404  char * root = NULL;
405  int options = -1;
406  int ignore = -1;
407  char * kwlist[] = {"root", "options", "ignore", NULL};
408 
409 rpmfts_debug("rpmfts_init", s);
410  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sii:rpmfts_init", kwlist,
411  &root, &options, &ignore))
412  return -1;
413 
414  return rpmfts_initialize(s, root, options, ignore);
415 }
416 
417 /*@null@*/
418 static PyObject * rpmfts_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
419  /*@*/
420 {
421  rpmftsObject *s;
422  PyObject *o;
423  PyObject *n = NULL;
424  char * kwlist[] = {0};
425 
426  /* All the other _new() functions claim to be _init in their errors...*/
427  if (!PyArg_ParseTupleAndKeywords(args, kwds, ":rpmfts_new", kwlist))
428  return NULL;
429 
430  if ((s = PyObject_GC_New(rpmftsObject, type)) == NULL)
431  return NULL;
432 rpmfts_debug("rpmfts_new", s);
433 
434  s->md_dict = PyDict_New();
435  if (s->md_dict == NULL)
436  goto fail;
437  s->callbacks = PyDict_New();
438  if (s->md_dict == NULL)
439  goto fail;
440  if (type->tp_name) {
441  const char * name;
442  if ((name = strrchr(type->tp_name, '.')) != NULL)
443  name++;
444  else
445  name = type->tp_name;
446  n = PyString_FromString(name);
447  }
448  if (n != NULL && PyDict_SetItemString(s->md_dict, "__name__", n) != 0)
449  goto fail;
450  if (PyDict_SetItemString(s->md_dict, "__doc__", Py_None) != 0)
451  goto fail;
452 
453 #define CONSTANT(_v) \
454  PyDict_SetItemString(s->md_dict, #_v, o=PyInt_FromLong(_v)); Py_XDECREF(o)
455 
458 
468 
471 
472  CONSTANT(FTS_D);
473  CONSTANT(FTS_DC);
475  CONSTANT(FTS_DNR);
476  CONSTANT(FTS_DOT);
477  CONSTANT(FTS_DP);
478  CONSTANT(FTS_ERR);
479  CONSTANT(FTS_F);
480  CONSTANT(FTS_NS);
482  CONSTANT(FTS_SL);
484  CONSTANT(FTS_W);
485 
488 
493 
494  s->roots = NULL;
495  s->compare = NULL;
496  s->ftsp = NULL;
497  s->fts = NULL;
498 
499  Py_XDECREF(n);
500  PyObject_GC_Track((PyObject *)s);
501  return (PyObject *)s;
502 
503  fail:
504  Py_XDECREF(n);
505  Py_XDECREF(s);
506  return NULL;
507 }
508 
509 static int rpmfts_traverse(rpmftsObject * s, visitproc visit, void * arg)
510  /*@*/
511 {
512  if (s->md_dict != NULL)
513  return visit(s->md_dict, arg);
514  if (s->callbacks != NULL)
515  return visit(s->callbacks, arg);
516  return 0;
517 }
518 
519 static int rpmfts_print(rpmftsObject * s, FILE * fp,
520  /*@unused@*/ int flags)
521  /*@globals fileSystem @*/
522  /*@modifies fp, fileSystem @*/
523 {
524  static int indent = 2;
525 
526  if (!(s != NULL && s->ftsp != NULL && s->fts != NULL))
527  return -1;
528  fprintf(fp, "FTS_%-7s %*s%s", ftsInfoStr(s->fts->fts_info),
529  indent * (s->fts->fts_level < 0 ? 0 : s->fts->fts_level), "",
530  s->fts->fts_name);
531  return 0;
532 }
533 
536 /*@unchecked@*/ /*@observer@*/
537 static char rpmfts_doc[] =
538 "";
539 
542 /*@-fullinitblock@*/
543 PyTypeObject rpmfts_Type = {
544  PyObject_HEAD_INIT(&PyType_Type)
545  0, /* ob_size */
546  "rpm.fts", /* tp_name */
547  sizeof(rpmftsObject), /* tp_size */
548  0, /* tp_itemsize */
549  /* methods */
550  (destructor) rpmfts_dealloc, /* tp_dealloc */
551  (printfunc) rpmfts_print, /* tp_print */
552  (getattrfunc)0, /* tp_getattr */
553  (setattrfunc)0, /* tp_setattr */
554  (cmpfunc)0, /* tp_compare */
555  (reprfunc)0, /* tp_repr */
556  0, /* tp_as_number */
557  0, /* tp_as_sequence */
558  0, /* tp_as_mapping */
559  (hashfunc)0, /* tp_hash */
560  (ternaryfunc)0, /* tp_call */
561  (reprfunc)0, /* tp_str */
562  (getattrofunc) rpmfts_getattro, /* tp_getattro */
563  (setattrofunc) rpmfts_setattro, /* tp_setattro */
564  0, /* tp_as_buffer */
565  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
566  rpmfts_doc, /* tp_doc */
567  (traverseproc) rpmfts_traverse, /* tp_traverse */
568  0, /* tp_clear */
569  0, /* tp_richcompare */
570  0, /* tp_weaklistoffset */
571  (getiterfunc) rpmfts_iter, /* tp_iter */
572  (iternextfunc) rpmfts_iternext, /* tp_iternext */
573  rpmfts_methods, /* tp_methods */
574  rpmfts_members, /* tp_members */
575  0, /* tp_getset */
576  0, /* tp_base */
577  0, /* tp_dict */
578  0, /* tp_descr_get */
579  0, /* tp_descr_set */
580  offsetof(rpmftsObject, md_dict),/* tp_dictoffset */
581  (initproc) rpmfts_init, /* tp_init */
582  rpmfts_alloc, /* tp_alloc */
583  rpmfts_new, /* tp_new */
584  (freefunc) rpmfts_free, /* tp_free */
585  0, /* tp_is_gc */
586 };
587 /*@=fullinitblock@*/
static int rpmfts_setattro(PyObject *o, PyObject *n, PyObject *v)
Definition: rpmfts-py.c:335
#define FTS_FOLLOW
Definition: fts.h:150
#define FTS_SLNONE
Definition: fts.h:141
static const char * ftsInfoStrings[]
Definition: rpmfts-py.c:27
int xx
Definition: spec.c:744
#define FTS_XDEV
Definition: fts.h:93
static char rpmfts_doc[]
Definition: rpmfts-py.c:537
char * kwlist[]
Definition: rpmal-py.c:27
FTS * Fts_open(char *const *argv, int options, int(*compar)(const FTSENT **, const FTSENT **))
Create a handle for file hierarchy traversal.
Definition: fts.c:207
PyObject * callbacks
Definition: rpmfts-py.h:18
PyTypeObject rpmfts_Type
Definition: rpmfts-py.c:543
FTSENT * fts
Definition: rpmfts-py.h:31
#define FTS_SYMFOLLOW
Definition: fts.h:146
static PyObject *int type
Definition: rpmmi-py.c:151
FTSENT * Fts_children(FTS *sp, int instr)
Return list of children of the current node.
Definition: fts.c:705
static int rpmfts_print(rpmftsObject *s, FILE *fp, int flags)
Definition: rpmfts-py.c:519
return Py_None
Definition: rpmal-py.c:55
static char *size_t nb
fgets(3) analogue that reads \ continuations.
Definition: macro.c:409
static PyObject * rpmfts_alloc(PyTypeObject *type, Py_ssize_t nitems)
Definition: rpmfts-py.c:373
#define FTS_ROOTLEVEL
Definition: fts.h:126
PyObject * args
Definition: rpmts-py.c:200
#define FTS_W
Definition: fts.h:142
int rc
Definition: poptALL.c:670
static PyObject * rpmfts_Debug(rpmftsObject *s, PyObject *args, PyObject *kwds)
Definition: rpmfts-py.c:180
#define FTS_SL
Definition: fts.h:140
#define FTS_NS
Definition: fts.h:138
short fts_level
Definition: fts.h:127
#define RPMFTS_CLOSE
Definition: rpmfts-py.c:54
s ignore
Definition: rpmfts-py.c:95
int ac
Definition: rpmgrep.c:1431
#define CONSTANT(_v)
pid_t result
Definition: rpmsq.c:737
#define RPMFTS_OPEN_LAZY
Definition: rpmfts-py.c:56
static PyObject * rpmfts_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Definition: rpmfts-py.c:418
u_short fts_info
Definition: fts.h:143
#define FTS_D
Definition: fts.h:129
#define FTS_NOINSTR
Definition: fts.h:151
#define FTS_NSOK
Definition: fts.h:139
fprintf(stderr,"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, rsactx, sig, sigp)
#define FTS_COMFOLLOW
Definition: fts.h:87
static const char * ftsInfoStr(int fts_info)
Definition: rpmfts-py.c:46
#define FTS_DEFAULT
Definition: fts.h:131
#define FTS_DC
Definition: fts.h:130
#define FTS_DONTCHDIR
Definition: fts.h:145
#define FTS_DOT
Definition: fts.h:133
char * o
Definition: macro.c:745
#define FTS_SEEDOT
Definition: fts.h:92
#define infoBit(_ix)
Definition: rpmfts-py.c:25
FTSENT * Fts_read(FTS *sp)
Return next node in the file hierarchy traversal.
Definition: fts.c:467
static int rpmfts_traverse(rpmftsObject *s, visitproc visit, void *arg)
Definition: rpmfts-py.c:509
char * n
Definition: macro.c:744
#define FTS_DNR
Definition: fts.h:132
int Fts_set(FTS *sp, FTSENT *p, int instr)
Modify the traversal for a file set member.
Definition: fts.c:688
char fts_name[1]
Definition: fts.h:157
return Py_BuildValue("i", pkgKey)
const char * s
Definition: poptALL.c:734
char * t
Definition: rpmds.c:2716
#define FTS_NOCHDIR
Definition: fts.h:89
Definition: fts.h:102
static int rpmfts_init(rpmftsObject *s, PyObject *args, PyObject *kwds)
Definition: rpmfts-py.c:401
Py_XDECREF(cbInfo->dso)
#define FTS_WHITEOUT
Definition: fts.h:94
s options
Definition: rpmfts-py.c:94
char * stpcpy(char *dest, const char *src)
#define FTS_NAMEONLY
Definition: fts.h:97
int flags
Definition: fnmatch.c:282
const char * msg
Definition: rpmts-py.c:976
#define RPMFTS_OPEN
Definition: rpmfts-py.c:55
#define FTS_PHYSICAL
Definition: fts.h:91
#define FTS_LOGICAL
Definition: fts.h:88
int Fts_close(FTS *sp)
Destroy a file hierarchy traversal handle.
Definition: fts.c:380
static PyObject * rpmfts_getattro(PyObject *o, PyObject *n)
Definition: rpmfts-py.c:328
return NULL
Definition: poptALL.c:613
static int _rpmfts_debug
Definition: rpmfts-py.c:23
static void rpmfts_dealloc(rpmftsObject *s)
Definition: rpmfts-py.c:379
PyObject_HEAD PyObject * md_dict
Definition: rpmfts-py.h:17
static int indent
Definition: rpmgi.c:47
static const char * name
int(* compare)(const void *, const void *)
Definition: rpmfts-py.h:26
#define FTS_AGAIN
Definition: fts.h:149
#define FTS_F
Definition: fts.h:136
int
Save source and expand field into target.
Definition: rpmds.c:2709
static void rpmfts_free(PyObject *s)
Definition: rpmfts-py.c:367
#define FTS_DP
Definition: fts.h:134
static struct PyMethodDef rpmfts_methods[]
Definition: rpmfts-py.c:297
static void rpmfts_debug(const char *msg, rpmftsObject *s)
Definition: rpmfts-py.c:59
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
const char ** roots
Definition: rpmfts-py.h:21
#define FTS_NOSTAT
Definition: fts.h:90
#define FTS_ERR
Definition: fts.h:135
#define FTS_ROOTPARENTLEVEL
Definition: fts.h:125
Py_INCREF(Py_None)
struct rpmftsObject_s rpmftsObject
static PyMemberDef rpmfts_members[]
Definition: rpmfts-py.c:316
#define FTS_OPTIONMASK
Definition: fts.h:95
static int nitems
Definition: rpmcache.c:81
#define FTS_STOP
Definition: fts.h:98
#define FTS_SKIP
Definition: fts.h:152