1 /* Copyright (C) 2013-2020 Roland Lutz
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software Foundation,
15 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21 static PyObject
*to_python_list(xorn_object_t
*objects
, size_t count
)
26 list
= PyList_New(count
);
30 for (i
= 0; i
< count
; i
++) {
31 PyObject
*ob_item
= build_object(objects
[i
]);
32 if (ob_item
== NULL
) {
37 PyList_SET_ITEM(list
, i
, ob_item
);
44 static PyObject
*get_objects_attached_to(
45 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
47 PyObject
*rev_arg
= NULL
, *ob_arg
= NULL
;
48 static char *kwlist
[] = { "rev", "ob", NULL
};
50 if (!PyArg_ParseTupleAndKeywords(
51 args
, kwds
, "O!O:get_objects_attached_to", kwlist
,
52 &RevisionType
, &rev_arg
, &ob_arg
))
55 if (ob_arg
!= Py_None
&&
56 !PyObject_TypeCheck(ob_arg
, &ObjectType
)) {
58 snprintf(buf
, BUFSIZ
, "get_objects_attached_to() argument 2 "
59 "must be %.50s or None, not %.50s",
61 ob_arg
->ob_type
->tp_name
);
62 PyErr_SetString(PyExc_TypeError
, buf
);
66 if (ob_arg
!= Py_None
&&
67 !xorn_object_exists_in_revision(((Revision
*)rev_arg
)->rev
,
68 ((Object
*)ob_arg
)->ob
)) {
69 PyErr_SetString(PyExc_KeyError
, "object does not exist");
73 xorn_object_t
*objects
;
76 if (xorn_get_objects_attached_to(((Revision
*)rev_arg
)->rev
,
77 ob_arg
== Py_None
? NULL
:
78 ((Object
*)ob_arg
)->ob
,
79 &objects
, &count
) == -1)
80 return PyErr_NoMemory();
82 return to_python_list(objects
, count
);
85 static PyObject
*get_selected_objects(
86 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
88 PyObject
*rev_arg
= NULL
, *sel_arg
= NULL
;
89 static char *kwlist
[] = { "rev", "sel", NULL
};
91 if (!PyArg_ParseTupleAndKeywords(
92 args
, kwds
, "O!O!:get_selected_objects", kwlist
,
93 &RevisionType
, &rev_arg
, &SelectionType
, &sel_arg
))
96 xorn_object_t
*objects
;
99 if (xorn_get_selected_objects(((Revision
*)rev_arg
)->rev
,
100 ((Selection
*)sel_arg
)->sel
,
101 &objects
, &count
) == -1)
102 return PyErr_NoMemory();
104 return to_python_list(objects
, count
);
107 static PyObject
*get_added_objects(
108 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
110 PyObject
*from_arg
= NULL
, *to_arg
= NULL
;
111 static char *kwlist
[] = { "from", "to", NULL
};
113 if (!PyArg_ParseTupleAndKeywords(
114 args
, kwds
, "O!O!:get_added_objects", kwlist
,
115 &RevisionType
, &from_arg
, &RevisionType
, &to_arg
))
118 xorn_object_t
*objects
;
121 if (xorn_get_added_objects(((Revision
*)from_arg
)->rev
,
122 ((Revision
*)to_arg
)->rev
,
123 &objects
, &count
) == -1)
124 return PyErr_NoMemory();
126 return to_python_list(objects
, count
);
129 static PyObject
*get_removed_objects(
130 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
132 PyObject
*from_arg
= NULL
, *to_arg
= NULL
;
133 static char *kwlist
[] = { "from", "to", NULL
};
135 if (!PyArg_ParseTupleAndKeywords(
136 args
, kwds
, "O!O!:get_removed_objects", kwlist
,
137 &RevisionType
, &from_arg
, &RevisionType
, &to_arg
))
140 xorn_object_t
*objects
;
143 if (xorn_get_removed_objects(((Revision
*)from_arg
)->rev
,
144 ((Revision
*)to_arg
)->rev
,
145 &objects
, &count
) == -1)
146 return PyErr_NoMemory();
148 return to_python_list(objects
, count
);
151 static PyObject
*get_modified_objects(
152 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
154 PyObject
*from_arg
= NULL
, *to_arg
= NULL
;
155 static char *kwlist
[] = { "from", "to", NULL
};
157 if (!PyArg_ParseTupleAndKeywords(
158 args
, kwds
, "O!O!:get_modified_objects", kwlist
,
159 &RevisionType
, &from_arg
, &RevisionType
, &to_arg
))
162 xorn_object_t
*objects
;
165 if (xorn_get_modified_objects(((Revision
*)from_arg
)->rev
,
166 ((Revision
*)to_arg
)->rev
,
167 &objects
, &count
) == -1)
168 return PyErr_NoMemory();
170 return to_python_list(objects
, count
);
173 /****************************************************************************/
175 static PyObject
*select_none(
176 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
178 xorn_selection_t sel
= xorn_select_none();
179 return sel
? build_selection(sel
) : PyErr_NoMemory();
182 static PyObject
*select_object(
183 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
185 PyObject
*ob_arg
= NULL
;
186 static char *kwlist
[] = { "ob", NULL
};
188 if (!PyArg_ParseTupleAndKeywords(
189 args
, kwds
, "O!:select_object", kwlist
,
190 &ObjectType
, &ob_arg
))
193 xorn_selection_t sel
= xorn_select_object(((Object
*)ob_arg
)->ob
);
194 return sel
? build_selection(sel
) : PyErr_NoMemory();
197 static PyObject
*select_attached_to(
198 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
200 PyObject
*rev_arg
= NULL
, *ob_arg
= NULL
;
201 static char *kwlist
[] = { "rev", "ob", NULL
};
203 if (!PyArg_ParseTupleAndKeywords(
204 args
, kwds
, "O!O:select_attached_to", kwlist
,
205 &RevisionType
, &rev_arg
, &ob_arg
))
208 if (ob_arg
!= Py_None
&&
209 !PyObject_TypeCheck(ob_arg
, &ObjectType
)) {
211 snprintf(buf
, BUFSIZ
, "select_attached_to() argument 2 "
212 "must be %.50s or None, not %.50s",
214 ob_arg
->ob_type
->tp_name
);
215 PyErr_SetString(PyExc_TypeError
, buf
);
219 if (ob_arg
!= Py_None
&&
220 !xorn_object_exists_in_revision(((Revision
*)rev_arg
)->rev
,
221 ((Object
*)ob_arg
)->ob
)) {
222 PyErr_SetString(PyExc_KeyError
, "object does not exist");
226 xorn_selection_t sel
= xorn_select_attached_to(
227 ((Revision
*)rev_arg
)->rev
,
228 ob_arg
== Py_None
? NULL
: ((Object
*)ob_arg
)->ob
);
229 return sel
? build_selection(sel
) : PyErr_NoMemory();
232 static PyObject
*select_all(
233 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
235 PyObject
*rev_arg
= NULL
;
236 static char *kwlist
[] = { "rev", NULL
};
238 if (!PyArg_ParseTupleAndKeywords(
239 args
, kwds
, "O!:select_all", kwlist
,
240 &RevisionType
, &rev_arg
))
243 xorn_selection_t sel
= xorn_select_all(((Revision
*)rev_arg
)->rev
);
244 return sel
? build_selection(sel
) : PyErr_NoMemory();
247 static PyObject
*select_all_except(
248 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
250 PyObject
*rev_arg
= NULL
, *sel_arg
= NULL
;
251 static char *kwlist
[] = { "rev", "sel", NULL
};
253 if (!PyArg_ParseTupleAndKeywords(
254 args
, kwds
, "O!O!:select_all_except", kwlist
,
255 &RevisionType
, &rev_arg
, &SelectionType
, &sel_arg
))
258 xorn_selection_t sel
= xorn_select_all_except(
259 ((Revision
*)rev_arg
)->rev
, ((Selection
*)sel_arg
)->sel
);
260 return sel
? build_selection(sel
) : PyErr_NoMemory();
263 static PyObject
*select_including(
264 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
266 PyObject
*sel_arg
= NULL
, *ob_arg
= NULL
;
267 static char *kwlist
[] = { "sel", "ob", NULL
};
269 if (!PyArg_ParseTupleAndKeywords(
270 args
, kwds
, "O!O!:select_including", kwlist
,
271 &SelectionType
, &sel_arg
, &ObjectType
, &ob_arg
))
274 xorn_selection_t sel
= xorn_select_including(
275 ((Selection
*)sel_arg
)->sel
, ((Object
*)ob_arg
)->ob
);
276 return sel
? build_selection(sel
) : PyErr_NoMemory();
279 static PyObject
*select_excluding(
280 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
282 PyObject
*sel_arg
= NULL
, *ob_arg
= NULL
;
283 static char *kwlist
[] = { "sel", "ob", NULL
};
285 if (!PyArg_ParseTupleAndKeywords(
286 args
, kwds
, "O!O!:select_excluding", kwlist
,
287 &SelectionType
, &sel_arg
, &ObjectType
, &ob_arg
))
290 xorn_selection_t sel
= xorn_select_excluding(
291 ((Selection
*)sel_arg
)->sel
, ((Object
*)ob_arg
)->ob
);
292 return sel
? build_selection(sel
) : PyErr_NoMemory();
295 static PyObject
*select_union(
296 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
298 PyObject
*sel0_arg
= NULL
, *sel1_arg
= NULL
;
299 static char *kwlist
[] = { "sel0", "sel1", NULL
};
301 if (!PyArg_ParseTupleAndKeywords(
302 args
, kwds
, "O!O!:select_union", kwlist
,
303 &SelectionType
, &sel0_arg
, &SelectionType
, &sel1_arg
))
306 xorn_selection_t sel
= xorn_select_union(((Selection
*)sel0_arg
)->sel
,
307 ((Selection
*)sel1_arg
)->sel
);
308 return sel
? build_selection(sel
) : PyErr_NoMemory();
311 static PyObject
*select_intersection(
312 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
314 PyObject
*sel0_arg
= NULL
, *sel1_arg
= NULL
;
315 static char *kwlist
[] = { "sel0", "sel1", NULL
};
317 if (!PyArg_ParseTupleAndKeywords(
318 args
, kwds
, "O!O!:select_intersection", kwlist
,
319 &SelectionType
, &sel0_arg
, &SelectionType
, &sel1_arg
))
322 xorn_selection_t sel
= xorn_select_intersection(
323 ((Selection
*)sel0_arg
)->sel
, ((Selection
*)sel1_arg
)->sel
);
324 return sel
? build_selection(sel
) : PyErr_NoMemory();
327 static PyObject
*select_difference(
328 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
330 PyObject
*sel0_arg
= NULL
, *sel1_arg
= NULL
;
331 static char *kwlist
[] = { "sel0", "sel1", NULL
};
333 if (!PyArg_ParseTupleAndKeywords(
334 args
, kwds
, "O!O!:select_difference", kwlist
,
335 &SelectionType
, &sel0_arg
, &SelectionType
, &sel1_arg
))
338 xorn_selection_t sel
= xorn_select_difference(
339 ((Selection
*)sel0_arg
)->sel
, ((Selection
*)sel1_arg
)->sel
);
340 return sel
? build_selection(sel
) : PyErr_NoMemory();
343 static PyObject
*selection_is_empty(
344 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
346 PyObject
*rev_arg
= NULL
, *sel_arg
= NULL
;
347 static char *kwlist
[] = { "rev", "sel", NULL
};
349 if (!PyArg_ParseTupleAndKeywords(
350 args
, kwds
, "O!O!:selection_is_empty", kwlist
,
351 &RevisionType
, &rev_arg
, &SelectionType
, &sel_arg
))
354 PyObject
*result
= xorn_selection_is_empty(
355 ((Revision
*)rev_arg
)->rev
,
356 ((Selection
*)sel_arg
)->sel
) ? Py_True
: Py_False
;
361 static PyObject
*object_is_selected(
362 PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
364 PyObject
*rev_arg
= NULL
, *sel_arg
= NULL
, *ob_arg
= NULL
;
365 static char *kwlist
[] = { "rev", "sel", "ob", NULL
};
367 if (!PyArg_ParseTupleAndKeywords(
368 args
, kwds
, "O!O!O!:object_is_selected", kwlist
,
369 &RevisionType
, &rev_arg
, &SelectionType
, &sel_arg
,
370 &ObjectType
, &ob_arg
))
373 PyObject
*result
= xorn_object_is_selected(
374 ((Revision
*)rev_arg
)->rev
,
375 ((Selection
*)sel_arg
)->sel
,
376 ((Object
*)ob_arg
)->ob
) ? Py_True
: Py_False
;
381 static PyMethodDef methods
[] = {
382 { "get_objects_attached_to",
383 (PyCFunction
)get_objects_attached_to
, METH_KEYWORDS
,
384 PyDoc_STR("get_objects_attached_to(rev, ob) -> [Object] -- "
385 "a list of objects in a revision which are attached to a "
387 { "get_selected_objects",
388 (PyCFunction
)get_selected_objects
, METH_KEYWORDS
,
389 PyDoc_STR("get_selected_objects(rev, sel) -> [Object] -- "
390 "a list of objects which are in a revision as well as in "
392 { "get_added_objects", (PyCFunction
)get_added_objects
, METH_KEYWORDS
,
393 PyDoc_STR("get_added_objects(from, to) -> [Object] -- "
394 "a list of objects which are in one revision but not in "
396 { "get_removed_objects",
397 (PyCFunction
)get_removed_objects
, METH_KEYWORDS
,
398 PyDoc_STR("get_removed_objects(from, to) -> [Object] -- "
399 "a list of objects which are in one revision but not in "
401 { "get_modified_objects",
402 (PyCFunction
)get_modified_objects
, METH_KEYWORDS
,
403 PyDoc_STR("get_modified_objects(from, to) -> [Object] -- "
404 "a list of objects which exist in two revisions but have "
405 "different type or data") },
407 { "select_none", (PyCFunction
)select_none
, METH_NOARGS
,
408 PyDoc_STR("select_none() -> Selection -- "
409 "an empty selection") },
410 { "select_object", (PyCFunction
)select_object
, METH_KEYWORDS
,
411 PyDoc_STR("select_object(ob) -> Selection -- "
412 "a selection containing a single object") },
413 { "select_attached_to", (PyCFunction
)select_attached_to
, METH_KEYWORDS
,
414 PyDoc_STR("select_attached_to(rev, ob) -> Selection -- "
415 "a selection containing all objects in a revision "
416 "attached to a given object") },
417 { "select_all", (PyCFunction
)select_all
, METH_KEYWORDS
,
418 PyDoc_STR("select_all(rev) -> Selection -- "
419 "a selection containing all objects in a revision") },
420 { "select_all_except", (PyCFunction
)select_all_except
, METH_KEYWORDS
,
421 PyDoc_STR("select_all_except(rev, sel) -> Selection -- "
422 "a selection containing all objects in a revision except "
423 "those in a given selection") },
424 { "select_including", (PyCFunction
)select_including
, METH_KEYWORDS
,
425 PyDoc_STR("select_including(sel, ob) -> Selection -- "
426 "a selection which contains all the objects in an "
427 "existing selection plus a given object") },
428 { "select_excluding", (PyCFunction
)select_excluding
, METH_KEYWORDS
,
429 PyDoc_STR("select_excluding(sel, ob) -> Selection -- "
430 "a selection which contains all the objects in an "
431 "existing selection minus a given object") },
432 { "select_union", (PyCFunction
)select_union
, METH_KEYWORDS
,
433 PyDoc_STR("select_union(sel0, sel1) -> Selection -- "
434 "a selection containing the objects in either given "
436 { "select_intersection",
437 (PyCFunction
)select_intersection
, METH_KEYWORDS
,
438 PyDoc_STR("select_intersection(sel0, sel1) -> Selection -- "
439 "a selection containing the objects in both given "
441 { "select_difference", (PyCFunction
)select_difference
, METH_KEYWORDS
,
442 PyDoc_STR("select_difference(sel0, sel1) -> Selection -- "
443 "a selection containing the objects contained in one "
444 "given selection, but not the other") },
445 { "selection_is_empty", (PyCFunction
)selection_is_empty
, METH_KEYWORDS
,
446 PyDoc_STR("selection_is_empty(rev, sel) -> bool -- "
447 "whether a selection is empty in a given revision") },
448 { "object_is_selected", (PyCFunction
)object_is_selected
, METH_KEYWORDS
,
449 PyDoc_STR("object_is_selected(rev, sel, ob) -> bool -- "
450 "whether an object exists in a revision and is selected "
453 { NULL
, NULL
, 0, NULL
} /* Sentinel */
456 static int add_type(PyObject
*module
, const char *name
, PyTypeObject
*value
)
459 return PyModule_AddObject(module
, name
, (PyObject
*)value
);
462 PyMODINIT_FUNC
initstorage(void)
466 if (PyType_Ready(&RevisionType
) == -1) return;
467 if (PyType_Ready(&ObjectType
) == -1) return;
468 if (PyType_Ready(&SelectionType
) == -1) return;
470 if (PyType_Ready(&ArcType
) == -1) return;
471 if (PyType_Ready(&BoxType
) == -1) return;
472 if (PyType_Ready(&CircleType
) == -1) return;
473 if (PyType_Ready(&ComponentType
) == -1) return;
474 if (PyType_Ready(&LineType
) == -1) return;
475 if (PyType_Ready(&NetType
) == -1) return;
476 if (PyType_Ready(&PathType
) == -1) return;
477 if (PyType_Ready(&PictureType
) == -1) return;
478 if (PyType_Ready(&TextType
) == -1) return;
479 if (PyType_Ready(&LineAttrType
) == -1) return;
480 if (PyType_Ready(&FillAttrType
) == -1) return;
482 m
= Py_InitModule3("storage", methods
,
483 PyDoc_STR("Xorn storage backend"));
485 if (add_type(m
, "Revision", &RevisionType
) == -1) return;
486 if (add_type(m
, "Object", &ObjectType
) == -1) return;
487 if (add_type(m
, "Selection", &SelectionType
) == -1) return;
489 if (add_type(m
, "Arc", &ArcType
) == -1) return;
490 if (add_type(m
, "Box", &BoxType
) == -1) return;
491 if (add_type(m
, "Circle", &CircleType
) == -1) return;
492 if (add_type(m
, "Component", &ComponentType
) == -1) return;
493 if (add_type(m
, "Line", &LineType
) == -1) return;
494 if (add_type(m
, "Net", &NetType
) == -1) return;
495 if (add_type(m
, "Path", &PathType
) == -1) return;
496 if (add_type(m
, "Picture", &PictureType
) == -1) return;
497 if (add_type(m
, "Text", &TextType
) == -1) return;
498 if (add_type(m
, "LineAttr", &LineAttrType
) == -1) return;
499 if (add_type(m
, "FillAttr", &FillAttrType
) == -1) return;