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