rpm  4.5
rpmps-py.c
Go to the documentation of this file.
1 
4 /*@-modunconnomods -evalorderuncon @*/
5 
6 #include "system.h"
7 
8 #define _RPMPS_INTERNAL /* XXX rpmps needs iterator */
9 #include <rpmlib.h>
10 
11 #include "rpmdebug-py.c"
12 
13 #include "rpmps-py.h"
14 
15 #include "debug.h"
16 
17 /*@access FILE @*/
18 /*@access rpmps @*/
19 /*@access rpmProblem @*/
20 
21 static PyObject *
23  /*@modifies s @*/
24 {
25 if (_rpmps_debug < 0)
26 fprintf(stderr, "*** rpmps_iter(%p)\n", s);
27  s->ix = -1;
28  Py_INCREF(s);
29  return (PyObject *)s;
30 }
31 
32 /*@null@*/
33 static PyObject *
35  /*@modifies s @*/
36 {
37  PyObject * result = NULL;
38  rpmps ps = s->ps;
39 
40 if (_rpmps_debug < 0)
41 fprintf(stderr, "*** rpmps_iternext(%p) ps %p ix %d active %d\n", s, s->ps, s->ix, s->active);
42 
43  /* Reset loop indices on 1st entry. */
44  if (!s->active) {
45  s->ix = -1;
46  s->active = 1;
47  }
48 
49  /* If more to do, return a problem set string. */
50  s->ix++;
51  if (s->ix < ps->numProblems) {
52  result = Py_BuildValue("s", rpmProblemString(ps->probs+s->ix));
53  } else {
54  s->active = 0;
55  }
56 
57  return result;
58 }
59 
66 
67 /*@null@*/
68 static PyObject *
69 rpmps_Debug(/*@unused@*/ rpmpsObject * s, PyObject * args, PyObject * kwds)
70  /*@globals _Py_NoneStruct @*/
71  /*@modifies _Py_NoneStruct @*/
72 {
73  char * kwlist[] = {"debugLevel", NULL};
74 
75  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmps_debug))
76  return NULL;
77 
78  Py_INCREF(Py_None);
79  return Py_None;
80 }
83 /*@-fullinitblock@*/
84 /*@unchecked@*/ /*@observer@*/
85 static struct PyMethodDef rpmps_methods[] = {
86  {"Debug", (PyCFunction)rpmps_Debug, METH_VARARGS|METH_KEYWORDS,
87  NULL},
88  {NULL, NULL} /* sentinel */
89 };
90 /*@=fullinitblock@*/
91 
92 /* ---------- */
93 
94 static void
96  /*@modifies s @*/
97 {
98 if (_rpmps_debug < 0)
99 fprintf(stderr, "*** rpmps_dealloc(%p)\n", s);
100  if (s) {
101  s->ps = rpmpsFree(s->ps);
102  PyObject_Del(s);
103  }
104 }
105 
106 static int
107 rpmps_print(rpmpsObject * s, FILE * fp, /*@unused@*/ int flags)
108  /*@globals fileSystem @*/
109  /*@modifies s, fp, fileSystem @*/
110 {
111 if (_rpmps_debug < 0)
112 fprintf(stderr, "*** rpmps_print(%p,%p,%x)\n", s, (void *)fp, flags);
113  if (s && s->ps)
114  rpmpsPrint(fp, s->ps);
115  return 0;
116 }
117 
118 static PyObject * rpmps_getattro(PyObject * o, PyObject * n)
119  /*@*/
120 {
121 if (_rpmps_debug < 0)
122 fprintf(stderr, "*** rpmps_getattro(%p,%p)\n", o, n);
123  return PyObject_GenericGetAttr(o, n);
124 }
125 
126 static int rpmps_setattro(PyObject * o, PyObject * n, PyObject * v)
127  /*@*/
128 {
129 if (_rpmps_debug < 0)
130 fprintf(stderr, "*** rpmps_setattro(%p,%p,%p)\n", o, n, v);
131  return PyObject_GenericSetAttr(o, n, v);
132 }
133 
134 static int
136  /*@*/
137 {
138  int rc;
139  rc = rpmpsNumProblems(s->ps);
140 if (_rpmps_debug < 0)
141 fprintf(stderr, "*** rpmps_length(%p) rc %d\n", s, rc);
142  return rc;
143 }
144 
145 /*@null@*/
146 static PyObject *
147 rpmps_subscript(rpmpsObject * s, PyObject * key)
148  /*@*/
149 {
150  PyObject * result = NULL;
151  rpmps ps;
152  int ix;
153 
154  if (!PyInt_Check(key)) {
155 if (_rpmps_debug < 0)
156 fprintf(stderr, "*** rpmps_subscript(%p[%s],%p[%s])\n", s, lbl(s), key, lbl(key));
157  PyErr_SetString(PyExc_TypeError, "integer expected");
158  return NULL;
159  }
160 
161  ix = (int) PyInt_AsLong(key);
162  /* XXX range check */
163  ps = s->ps;
164  if (ix < ps->numProblems) {
165  result = Py_BuildValue("s", rpmProblemString(ps->probs + ix));
166 if (_rpmps_debug < 0)
167 fprintf(stderr, "*** rpmps_subscript(%p,%p) %s\n", s, key, PyString_AsString(result));
168  }
169 
170  return result;
171 }
172 
173 static int
174 rpmps_ass_sub(rpmpsObject * s, PyObject * key, PyObject * value)
175  /*@modifies s @*/
176 {
177  rpmps ps;
178  int ix;
179 
180  if (!PyArg_Parse(key, "i:ass_sub", &ix)) {
181  PyErr_SetString(PyExc_TypeError, "rpmps key type must be integer");
182  return -1;
183  }
184 
185  /* XXX get rid of negative indices */
186  if (ix < 0) ix = -ix;
187 
188  ps = s->ps;
189 
190 if (_rpmps_debug < 0)
191 fprintf(stderr, "*** rpmps_ass_sub(%p[%s],%p[%s],%p[%s]) ps %p[%d:%d:%d]\n", s, lbl(s), key, lbl(key), value, lbl(value), ps, ix, ps->numProblems, ps->numProblemsAlloced);
192 
193  if (value == NULL) {
194  if (ix < ps->numProblems) {
195  rpmProblem op = ps->probs + ix;
196 
197  op->pkgNEVR = _free(op->pkgNEVR);
198  op->altNEVR = _free(op->altNEVR);
199  op->str1 = _free(op->str1);
200 
201  if ((ix+1) == ps->numProblems)
202  memset(op, 0, sizeof(*op));
203  else
204  memmove(op, op+1, (ps->numProblems - ix) * sizeof(*op));
205  if (ps->numProblems > 0)
206  ps->numProblems--;
207  }
208  } else {
209  rpmProblem p = memset(alloca(sizeof(*p)), 0, sizeof(*p));
210  unsigned long ulong1 = p->ulong1;
211 
212  if (!PyArg_ParseTuple(value, "ssOiisN:rpmps value tuple",
213  &p->pkgNEVR, &p->altNEVR, &p->key,
214  &p->type, &p->ignoreProblem, &p->str1,
215  &ulong1))
216  {
217  return -1;
218  }
219 
220 /*@-branchstate@*/
221  if (ix >= ps->numProblems) {
222  /* XXX force append for indices out of range. */
223  rpmpsAppend(s->ps, p->type, p->pkgNEVR, p->key,
224  p->str1, NULL, p->altNEVR, ulong1);
225  } else {
226  rpmProblem op = ps->probs + ix;
227 
228  op->pkgNEVR = _free(op->pkgNEVR);
229  op->altNEVR = _free(op->altNEVR);
230  op->str1 = _free(op->str1);
231 
232  p->pkgNEVR = (p->pkgNEVR && *p->pkgNEVR ? xstrdup(p->pkgNEVR) : NULL);
233  p->altNEVR = (p->altNEVR && *p->altNEVR ? xstrdup(p->altNEVR) : NULL);
234  p->str1 = (p->str1 && *p->str1 ? xstrdup(p->str1) : NULL);
235 
236  *op = *p; /* structure assignment */
237  }
238 /*@=branchstate@*/
239  }
240 
241  return 0;
242 }
243 
244 static PyMappingMethods rpmps_as_mapping = {
245  (inquiry) rpmps_length, /* mp_length */
246  (binaryfunc) rpmps_subscript, /* mp_subscript */
247  (objobjargproc) rpmps_ass_sub, /* mp_ass_subscript */
248 };
249 
252 static int rpmps_init(rpmpsObject * s, PyObject *args, PyObject *kwds)
253  /*@modifies s @*/
254 {
255  char * kwlist[] = {NULL};
256 
257 if (_rpmps_debug < 0)
258 fprintf(stderr, "*** rpmps_init(%p,%p,%p)\n", s, args, kwds);
259 
260  if (!PyArg_ParseTupleAndKeywords(args, kwds, ":rpmps_init", kwlist))
261  return -1;
262 
263  s->ps = rpmpsCreate();
264  s->active = 0;
265  s->ix = -1;
266 
267  return 0;
268 }
269 
272 static void rpmps_free(/*@only@*/ rpmpsObject * s)
273  /*@modifies s @*/
274 {
275 if (_rpmps_debug)
276 fprintf(stderr, "%p -- ps %p\n", s, s->ps);
277  s->ps = rpmpsFree(s->ps);
278 
279  PyObject_Del((PyObject *)s);
280 }
281 
284 static PyObject * rpmps_alloc(PyTypeObject * subtype, int nitems)
285  /*@*/
286 {
287  PyObject * s = PyType_GenericAlloc(subtype, nitems);
288 
289 if (_rpmps_debug < 0)
290 fprintf(stderr, "*** rpmps_alloc(%p,%d) ret %p\n", subtype, nitems, s);
291  return s;
292 }
293 
296 /*@null@*/
297 static PyObject * rpmps_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
298  /*@*/
299 {
300  rpmpsObject * s = (void *) PyObject_New(rpmpsObject, subtype);
301 
302  /* Perform additional initialization. */
303  if (rpmps_init(s, args, kwds) < 0) {
304  rpmps_free(s);
305  return NULL;
306  }
307 
308 if (_rpmps_debug)
309 fprintf(stderr, "%p ++ ps %p\n", s, s->ps);
310 
311  return (PyObject *)s;
312 }
313 
316 /*@unchecked@*/ /*@observer@*/
317 static char rpmps_doc[] =
318 "";
319 
320 /*@-fullinitblock@*/
321 PyTypeObject rpmps_Type = {
322  PyObject_HEAD_INIT(&PyType_Type)
323  0, /* ob_size */
324  "rpm.ps", /* tp_name */
325  sizeof(rpmpsObject), /* tp_basicsize */
326  0, /* tp_itemsize */
327  /* methods */
328  (destructor) rpmps_dealloc, /* tp_dealloc */
329  (printfunc) rpmps_print, /* tp_print */
330  (getattrfunc)0, /* tp_getattr */
331  (setattrfunc)0, /* tp_setattr */
332  (cmpfunc)0, /* tp_compare */
333  (reprfunc)0, /* tp_repr */
334  0, /* tp_as_number */
335  0, /* tp_as_sequence */
336  &rpmps_as_mapping, /* tp_as_mapping */
337  (hashfunc)0, /* tp_hash */
338  (ternaryfunc)0, /* tp_call */
339  (reprfunc)0, /* tp_str */
340  (getattrofunc) rpmps_getattro, /* tp_getattro */
341  (setattrofunc) rpmps_setattro, /* tp_setattro */
342  0, /* tp_as_buffer */
343  Py_TPFLAGS_DEFAULT, /* tp_flags */
344  rpmps_doc, /* tp_doc */
345 #if Py_TPFLAGS_HAVE_ITER
346  0, /* tp_traverse */
347  0, /* tp_clear */
348  (richcmpfunc)0, /* tp_richcompare */
349  0, /* tp_weaklistoffset */
350  (getiterfunc) rpmps_iter, /* tp_iter */
351  (iternextfunc) rpmps_iternext, /* tp_iternext */
352  rpmps_methods, /* tp_methods */
353  0, /* tp_members */
354  0, /* tp_getset */
355  0, /* tp_base */
356  0, /* tp_dict */
357  0, /* tp_descr_get */
358  0, /* tp_descr_set */
359  0, /* tp_dictoffset */
360  (initproc) rpmps_init, /* tp_init */
361  (allocfunc) rpmps_alloc, /* tp_alloc */
362  (newfunc) rpmps_new, /* tp_new */
363  rpmps_free, /* tp_free */
364  0, /* tp_is_gc */
365 #endif
366 };
367 /*@=fullinitblock@*/
368 
369 /* ---------- */
370 
372 {
373  return s->ps;
374 }
375 
376 rpmpsObject *
378 {
379  rpmpsObject * s = PyObject_New(rpmpsObject, &rpmps_Type);
380 
381  if (s == NULL)
382  return NULL;
383  s->ps = ps;
384  s->active = 0;
385  s->ix = -1;
386  return s;
387 }
388 /*@=modunconnomods =evalorderuncon @*/