splint fiddles, no warnings.
[platform/upstream/rpm.git] / python / rpmfi-py.c
1 /** \ingroup py_c
2  * \file python/rpmfi-py.c
3  */
4
5 #include "system.h"
6
7 #include "Python.h"
8 #ifdef __LCLINT__
9 #undef  PyObject_HEAD
10 #define PyObject_HEAD   int _PyObjectHead;
11 #endif
12
13 #include <rpmlib.h>
14
15 #include "header-py.h"
16 #include "rpmfi-py.h"
17
18 #include "debug.h"
19
20 /*@access rpmfi @*/
21
22 /*@null@*/
23 static PyObject *
24 rpmfi_Debug(/*@unused@*/ rpmfiObject * s, PyObject * args)
25         /*@globals _Py_NoneStruct @*/
26         /*@modifies _Py_NoneStruct @*/
27 {
28     if (!PyArg_ParseTuple(args, "i", &_rpmfi_debug)) return NULL;
29     Py_INCREF(Py_None);
30     return Py_None;
31 }
32
33 /*@null@*/
34 static PyObject *
35 rpmfi_FC(rpmfiObject * s, PyObject * args)
36         /*@*/
37 {
38     if (!PyArg_ParseTuple(args, ":FC")) return NULL;
39     return Py_BuildValue("i", rpmfiFC(s->fi));
40 }
41
42 /*@null@*/
43 static PyObject *
44 rpmfi_FX(rpmfiObject * s, PyObject * args)
45         /*@*/
46 {
47     if (!PyArg_ParseTuple(args, ":FX")) return NULL;
48     return Py_BuildValue("i", rpmfiFX(s->fi));
49 }
50
51 /*@null@*/
52 static PyObject *
53 rpmfi_DC(rpmfiObject * s, PyObject * args)
54         /*@*/
55 {
56     if (!PyArg_ParseTuple(args, ":DC")) return NULL;
57     return Py_BuildValue("i", rpmfiDC(s->fi));
58 }
59
60 /*@null@*/
61 static PyObject *
62 rpmfi_DX(rpmfiObject * s, PyObject * args)
63         /*@*/
64 {
65     if (!PyArg_ParseTuple(args, ":DX")) return NULL;
66     return Py_BuildValue("i", rpmfiDX(s->fi));
67 }
68
69 /*@null@*/
70 static PyObject *
71 rpmfi_BN(rpmfiObject * s, PyObject * args)
72         /*@*/
73 {
74     if (!PyArg_ParseTuple(args, ":BN")) return NULL;
75     return Py_BuildValue("s", xstrdup(rpmfiBN(s->fi)));
76 }
77
78 /*@null@*/
79 static PyObject *
80 rpmfi_DN(rpmfiObject * s, PyObject * args)
81         /*@*/
82 {
83     if (!PyArg_ParseTuple(args, ":DN")) return NULL;
84     return Py_BuildValue("s", xstrdup(rpmfiDN(s->fi)));
85 }
86
87 /*@null@*/
88 static PyObject *
89 rpmfi_FN(rpmfiObject * s, PyObject * args)
90         /*@modifies s @*/
91 {
92     if (!PyArg_ParseTuple(args, ":FN")) return NULL;
93     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
94 }
95
96 /*@null@*/
97 static PyObject *
98 rpmfi_FFlags(rpmfiObject * s, PyObject * args)
99         /*@*/
100 {
101     if (!PyArg_ParseTuple(args, ":FFlags")) return NULL;
102     return Py_BuildValue("i", rpmfiFFlags(s->fi));
103 }
104
105 /*@null@*/
106 static PyObject *
107 rpmfi_VFlags(rpmfiObject * s, PyObject * args)
108         /*@*/
109 {
110     if (!PyArg_ParseTuple(args, ":VFlags")) return NULL;
111     return Py_BuildValue("i", rpmfiVFlags(s->fi));
112 }
113
114 /*@null@*/
115 static PyObject *
116 rpmfi_FMode(rpmfiObject * s, PyObject * args)
117         /*@*/
118 {
119     if (!PyArg_ParseTuple(args, ":FMode")) return NULL;
120     return Py_BuildValue("i", rpmfiFMode(s->fi));
121 }
122
123 /*@null@*/
124 static PyObject *
125 rpmfi_FState(rpmfiObject * s, PyObject * args)
126         /*@*/
127 {
128     if (!PyArg_ParseTuple(args, ":FState")) return NULL;
129     return Py_BuildValue("i", rpmfiFState(s->fi));
130 }
131
132 /* XXX rpmfiMD5 */
133 /*@null@*/
134 static PyObject *
135 rpmfi_MD5(rpmfiObject * s, PyObject * args)
136         /*@*/
137 {
138     const unsigned char * MD5;
139     char fmd5[33];
140     char * t;
141     int i;
142
143     if (!PyArg_ParseTuple(args, ":MD5")) return NULL;
144     MD5 = rpmfiMD5(s->fi);
145     if (MD5 != NULL)
146     for (i = 0, t = fmd5; i < 16; i++, t += 2)
147         sprintf(t, "%02x", MD5[i]);
148     *t = '\0';
149     return Py_BuildValue("s", xstrdup(fmd5));
150 }
151
152 /*@null@*/
153 static PyObject *
154 rpmfi_FLink(rpmfiObject * s, PyObject * args)
155         /*@*/
156 {
157     if (!PyArg_ParseTuple(args, ":FLink")) return NULL;
158     return Py_BuildValue("s", xstrdup(rpmfiFLink(s->fi)));
159 }
160
161 /*@null@*/
162 static PyObject *
163 rpmfi_FSize(rpmfiObject * s, PyObject * args)
164         /*@*/
165 {
166     if (!PyArg_ParseTuple(args, ":FSize")) return NULL;
167     return Py_BuildValue("i", rpmfiFSize(s->fi));
168 }
169
170 /*@null@*/
171 static PyObject *
172 rpmfi_FRdev(rpmfiObject * s, PyObject * args)
173         /*@*/
174 {
175     if (!PyArg_ParseTuple(args, ":FRdev")) return NULL;
176     return Py_BuildValue("i", rpmfiFRdev(s->fi));
177 }
178
179 /*@null@*/
180 static PyObject *
181 rpmfi_FMtime(rpmfiObject * s, PyObject * args)
182         /*@*/
183 {
184     if (!PyArg_ParseTuple(args, ":FMtime")) return NULL;
185     return Py_BuildValue("i", rpmfiFMtime(s->fi));
186 }
187
188 /*@null@*/
189 static PyObject *
190 rpmfi_FUser(rpmfiObject * s, PyObject * args)
191         /*@*/
192 {
193     if (!PyArg_ParseTuple(args, ":FUser")) return NULL;
194     return Py_BuildValue("s", xstrdup(rpmfiFUser(s->fi)));
195 }
196
197 /*@null@*/
198 static PyObject *
199 rpmfi_FGroup(rpmfiObject * s, PyObject * args)
200         /*@*/
201 {
202     if (!PyArg_ParseTuple(args, ":FGroup")) return NULL;
203     return Py_BuildValue("s", xstrdup(rpmfiFGroup(s->fi)));
204 }
205
206 /*@null@*/
207 static PyObject *
208 rpmfi_FColor(rpmfiObject * s, PyObject * args)
209         /*@*/
210 {
211     if (!PyArg_ParseTuple(args, ":FColor")) return NULL;
212     return Py_BuildValue("i", rpmfiFColor(s->fi));
213 }
214
215 /*@null@*/
216 static PyObject *
217 rpmfi_FClass(rpmfiObject * s, PyObject * args)
218         /*@*/
219 {
220     const char * FClass;
221
222     if (!PyArg_ParseTuple(args, ":FClass")) return NULL;
223     if ((FClass = rpmfiFClass(s->fi)) == NULL)
224         FClass = "";
225     return Py_BuildValue("s", xstrdup(FClass));
226 }
227
228 #if Py_TPFLAGS_HAVE_ITER
229 static PyObject *
230 rpmfi_iter(rpmfiObject * s, /*@unused@*/ PyObject * args)
231         /*@*/
232 {
233     Py_INCREF(s);
234     return (PyObject *)s;
235 }
236 #endif
237
238 /*@null@*/
239 static PyObject *
240 rpmfi_iternext(rpmfiObject * s)
241         /*@globals _Py_NoneStruct @*/
242         /*@modifies s, _Py_NoneStruct @*/
243 {
244     PyObject * result = NULL;
245
246     /* Reset loop indices on 1st entry. */
247     if (!s->active) {
248         s->fi = rpmfiInit(s->fi, 0);
249         s->active = 1;
250     }
251
252     /* If more to do, return the file tuple. */
253     if (rpmfiNext(s->fi) >= 0) {
254         const char * FN = rpmfiFN(s->fi);
255         int FSize = rpmfiFSize(s->fi);
256         int FMode = rpmfiFMode(s->fi);
257         int FMtime = rpmfiFMtime(s->fi);
258         int FFlags = rpmfiFFlags(s->fi);
259         int FRdev = rpmfiFRdev(s->fi);
260         int FInode = rpmfiFInode(s->fi);
261         int FNlink = rpmfiFNlink(s->fi);
262         int FState = rpmfiFState(s->fi);
263         int VFlags = rpmfiVFlags(s->fi);
264         const char * FUser = rpmfiFUser(s->fi);
265         const char * FGroup = rpmfiFGroup(s->fi);
266 /*@-shadow@*/
267         const unsigned char * MD5 = rpmfiMD5(s->fi), *s = MD5;
268 /*@=shadow@*/
269         char FMD5[2*16+1], *t = FMD5;
270         static const char hex[] = "0123456789abcdef";
271         int gotMD5, i;
272
273         gotMD5 = 0;
274         if (s)
275         for (i = 0; i < 16; i++) {
276             gotMD5 |= *s;
277             *t++ = hex[ (*s >> 4) & 0xf ];
278             *t++ = hex[ (*s++   ) & 0xf ];
279         }
280         *t = '\0';
281
282         result = PyTuple_New(13);
283         if (FN == NULL) {
284             Py_INCREF(Py_None);
285             PyTuple_SET_ITEM(result, 0, Py_None);
286         } else
287             PyTuple_SET_ITEM(result,  0, Py_BuildValue("s", FN));
288         PyTuple_SET_ITEM(result,  1, PyInt_FromLong(FSize));
289         PyTuple_SET_ITEM(result,  2, PyInt_FromLong(FMode));
290         PyTuple_SET_ITEM(result,  3, PyInt_FromLong(FMtime));
291         PyTuple_SET_ITEM(result,  4, PyInt_FromLong(FFlags));
292         PyTuple_SET_ITEM(result,  5, PyInt_FromLong(FRdev));
293         PyTuple_SET_ITEM(result,  6, PyInt_FromLong(FInode));
294         PyTuple_SET_ITEM(result,  7, PyInt_FromLong(FNlink));
295         PyTuple_SET_ITEM(result,  8, PyInt_FromLong(FState));
296         PyTuple_SET_ITEM(result,  9, PyInt_FromLong(VFlags));
297         if (FUser == NULL) {
298             Py_INCREF(Py_None);
299             PyTuple_SET_ITEM(result, 10, Py_None);
300         } else
301             PyTuple_SET_ITEM(result, 10, Py_BuildValue("s", FUser));
302         if (FGroup == NULL) {
303             Py_INCREF(Py_None);
304             PyTuple_SET_ITEM(result, 11, Py_None);
305         } else
306             PyTuple_SET_ITEM(result, 11, Py_BuildValue("s", FGroup));
307         if (!gotMD5) {
308             Py_INCREF(Py_None);
309             PyTuple_SET_ITEM(result, 12, Py_None);
310         } else
311             PyTuple_SET_ITEM(result, 12, Py_BuildValue("s", FMD5));
312
313     } else
314         s->active = 0;
315
316     return result;
317 }
318
319 static PyObject *
320 rpmfi_Next(rpmfiObject * s, /*@unused@*/ PyObject * args)
321         /*@globals _Py_NoneStruct @*/
322         /*@modifies s, _Py_NoneStruct @*/
323 {
324     PyObject * result = NULL;
325
326     result = rpmfi_iternext(s);
327
328     if (result == NULL) {
329         Py_INCREF(Py_None);
330         return Py_None;
331     }
332
333     return result;
334 }
335
336 #ifdef  NOTYET
337 /*@null@*/
338 static PyObject *
339 rpmfi_NextD(rpmfiObject * s, PyObject * args)
340         /*@*/
341 {
342         if (!PyArg_ParseTuple(args, ":NextD"))
343                 return NULL;
344         Py_INCREF(Py_None);
345         return Py_None;
346 }
347
348 /*@null@*/
349 static PyObject *
350 rpmfi_InitD(rpmfiObject * s, PyObject * args)
351         /*@*/
352 {
353         if (!PyArg_ParseTuple(args, ":InitD"))
354                 return NULL;
355         Py_INCREF(Py_None);
356         return Py_None;
357 }
358 #endif
359
360 /*@-fullinitblock@*/
361 /*@unchecked@*/ /*@observer@*/
362 static struct PyMethodDef rpmfi_methods[] = {
363  {"Debug",      (PyCFunction)rpmfi_Debug,       METH_VARARGS,
364         NULL},
365  {"FC",         (PyCFunction)rpmfi_FC,          METH_VARARGS,
366         NULL},
367  {"FX",         (PyCFunction)rpmfi_FX,          METH_VARARGS,
368         NULL},
369  {"DC",         (PyCFunction)rpmfi_DC,          METH_VARARGS,
370         NULL},
371  {"DX",         (PyCFunction)rpmfi_DX,          METH_VARARGS,
372         NULL},
373  {"BN",         (PyCFunction)rpmfi_BN,          METH_VARARGS,
374         NULL},
375  {"DN",         (PyCFunction)rpmfi_DN,          METH_VARARGS,
376         NULL},
377  {"FN",         (PyCFunction)rpmfi_FN,          METH_VARARGS,
378         NULL},
379  {"FFlags",     (PyCFunction)rpmfi_FFlags,      METH_VARARGS,
380         NULL},
381  {"VFlags",     (PyCFunction)rpmfi_VFlags,      METH_VARARGS,
382         NULL},
383  {"FMode",      (PyCFunction)rpmfi_FMode,       METH_VARARGS,
384         NULL},
385  {"FState",     (PyCFunction)rpmfi_FState,      METH_VARARGS,
386         NULL},
387  {"MD5",        (PyCFunction)rpmfi_MD5,         METH_VARARGS,
388         NULL},
389  {"FLink",      (PyCFunction)rpmfi_FLink,       METH_VARARGS,
390         NULL},
391  {"FSize",      (PyCFunction)rpmfi_FSize,       METH_VARARGS,
392         NULL},
393  {"FRdev",      (PyCFunction)rpmfi_FRdev,       METH_VARARGS,
394         NULL},
395  {"FMtime",     (PyCFunction)rpmfi_FMtime,      METH_VARARGS,
396         NULL},
397  {"FUser",      (PyCFunction)rpmfi_FUser,       METH_VARARGS,
398         NULL},
399  {"FGroup",     (PyCFunction)rpmfi_FGroup,      METH_VARARGS,
400         NULL},
401  {"FColor",     (PyCFunction)rpmfi_FColor,      METH_VARARGS,
402         NULL},
403  {"FClass",     (PyCFunction)rpmfi_FClass,      METH_VARARGS,
404         NULL},
405  {"next",       (PyCFunction)rpmfi_Next,        METH_VARARGS,
406 "fi.next() -> (FN, FSize, FMode, FMtime, FFlags, FRdev, FInode, FNlink, FState, VFlags, FUser, FGroup, FMD5))\n\
407 - Retrieve next file info tuple.\n" },
408 #ifdef  NOTYET
409  {"NextD",      (PyCFunction)rpmfi_NextD,       METH_VARARGS,
410         NULL},
411  {"InitD",      (PyCFunction)rpmfi_InitD,       METH_VARARGS,
412         NULL},
413 #endif
414  {NULL,         NULL}           /* sentinel */
415 };
416 /*@=fullinitblock@*/
417
418 /* ---------- */
419
420 static void
421 rpmfi_dealloc(/*@only@*/ /*@null@*/ rpmfiObject * s)
422         /*@modifies s @*/
423 {
424     if (s) {
425         s->fi = rpmfiFree(s->fi);
426         PyObject_Del(s);
427     }
428 }
429
430 static int
431 rpmfi_print(rpmfiObject * s, FILE * fp, /*@unused@*/ int flags)
432         /*@globals fileSystem @*/
433         /*@modifies s, fp, fileSystem @*/
434 {
435     if (!(s && s->fi))
436         return -1;
437
438     s->fi = rpmfiInit(s->fi, 0);
439     while (rpmfiNext(s->fi) >= 0)
440         fprintf(fp, "%s\n", rpmfiFN(s->fi));
441     return 0;
442 }
443
444 static PyObject * rpmfi_getattro(PyObject * o, PyObject * n)
445         /*@*/
446 {
447     return PyObject_GenericGetAttr(o, n);
448 }
449
450 static int rpmfi_setattro(PyObject * o, PyObject * n, PyObject * v)
451         /*@*/
452 {
453     return PyObject_GenericSetAttr(o, n, v);
454 }
455
456 static int
457 rpmfi_length(rpmfiObject * s)
458         /*@*/
459 {
460     return rpmfiFC(s->fi);
461 }
462
463 /*@null@*/
464 static PyObject *
465 rpmfi_subscript(rpmfiObject * s, PyObject * key)
466         /*@modifies s @*/
467 {
468     int ix;
469
470     if (!PyInt_Check(key)) {
471         PyErr_SetString(PyExc_TypeError, "integer expected");
472         return NULL;
473     }
474
475     ix = (int) PyInt_AsLong(key);
476     rpmfiSetFX(s->fi, ix);
477     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
478 }
479
480 /*@unchecked@*/ /*@observer@*/
481 static PyMappingMethods rpmfi_as_mapping = {
482         (inquiry) rpmfi_length,         /* mp_length */
483         (binaryfunc) rpmfi_subscript,   /* mp_subscript */
484         (objobjargproc)0,               /* mp_ass_subscript */
485 };
486
487 /**
488  */
489 /*@unchecked@*/ /*@observer@*/
490 static char rpmfi_doc[] =
491 "";
492
493 /*@-fullinitblock@*/
494 PyTypeObject rpmfi_Type = {
495         PyObject_HEAD_INIT(&PyType_Type)
496         0,                              /* ob_size */
497         "rpm.fi",                       /* tp_name */
498         sizeof(rpmfiObject),            /* tp_basicsize */
499         0,                              /* tp_itemsize */
500         /* methods */
501         (destructor) rpmfi_dealloc,     /* tp_dealloc */
502         (printfunc) rpmfi_print,        /* tp_print */
503         (getattrfunc)0,                 /* tp_getattr */
504         (setattrfunc)0,                 /* tp_setattr */
505         (cmpfunc)0,                     /* tp_compare */
506         (reprfunc)0,                    /* tp_repr */
507         0,                              /* tp_as_number */
508         0,                              /* tp_as_sequence */
509         &rpmfi_as_mapping,              /* tp_as_mapping */
510         (hashfunc)0,                    /* tp_hash */
511         (ternaryfunc)0,                 /* tp_call */
512         (reprfunc)0,                    /* tp_str */
513         (getattrofunc) rpmfi_getattro,  /* tp_getattro */
514         (setattrofunc) rpmfi_setattro,  /* tp_setattro */
515         0,                              /* tp_as_buffer */
516         Py_TPFLAGS_DEFAULT,             /* tp_flags */
517         rpmfi_doc,                      /* tp_doc */
518 #if Py_TPFLAGS_HAVE_ITER
519         0,                              /* tp_traverse */
520         0,                              /* tp_clear */
521         0,                              /* tp_richcompare */
522         0,                              /* tp_weaklistoffset */
523         (getiterfunc) rpmfi_iter,       /* tp_iter */
524         (iternextfunc) rpmfi_iternext,  /* tp_iternext */
525         rpmfi_methods,                  /* tp_methods */
526         0,                              /* tp_members */
527         0,                              /* tp_getset */
528         0,                              /* tp_base */
529         0,                              /* tp_dict */
530         0,                              /* tp_descr_get */
531         0,                              /* tp_descr_set */
532         0,                              /* tp_dictoffset */
533         0,                              /* tp_init */
534         0,                              /* tp_alloc */
535         0,                              /* tp_new */
536         0,                              /* tp_free */
537         0,                              /* tp_is_gc */
538 #endif
539 };
540 /*@=fullinitblock@*/
541
542 /* ---------- */
543
544 rpmfi fiFromFi(rpmfiObject * s)
545 {
546     return s->fi;
547 }
548
549 rpmfiObject *
550 rpmfi_Wrap(rpmfi fi)
551 {
552     rpmfiObject *s = PyObject_New(rpmfiObject, &rpmfi_Type);
553
554     if (s == NULL)
555         return NULL;
556     s->fi = fi;
557     s->active = 0;
558     return s;
559 }
560
561 rpmfiObject *
562 hdr_fiFromHeader(PyObject * s, PyObject * args)
563 {
564     hdrObject * ho = (hdrObject *)s;
565     PyObject * to = NULL;
566     rpmts ts = NULL;    /* XXX FIXME: fiFromHeader should be a ts method. */
567     rpmTag tagN = RPMTAG_BASENAMES;
568     int scareMem = 0;
569
570     if (!PyArg_ParseTuple(args, "|O:fiFromHeader", &to))
571         return NULL;
572     if (to != NULL) {
573         tagN = tagNumFromPyObject(to);
574         if (tagN == -1) {
575             PyErr_SetString(PyExc_KeyError, "unknown header tag");
576             return NULL;
577         }
578     }
579     return rpmfi_Wrap( rpmfiNew(ts, hdrGetHeader(ho), tagN, scareMem) );
580 }