Merge fixes from branch 'xorn'
[geda-gaf.git] / xorn / src / cpython / guile / scm2py.c
blobf8bc8cb37a5f3e4ddc4d0cbfbbefecd54101ec41
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. */
17 #include "module.h"
20 PyObject *scm2py(SCM value)
22 if (value == NULL)
23 return NULL;
24 if (scm_is_eq(value, SCM_UNSPECIFIED)) {
25 Py_INCREF(Py_None);
26 return Py_None;
28 if (scm_is_exact_integer(value))
29 return PyInt_FromLong(scm_to_long(value));
30 if (scm_is_real(value))
31 return PyFloat_FromDouble(scm_to_double(value));
32 if (scm_is_bool(value)) {
33 PyObject *result = scm_to_bool(value) ? Py_True : Py_False;
34 Py_INCREF(result);
35 return result;
37 if (scm_is_null(value))
38 return PyTuple_New(0);
39 if (scm_is_string(value)) {
40 size_t len = 0;
41 char *s = scm_to_utf8_stringn(value, &len);
42 PyObject *result = PyUnicode_FromStringAndSize(s, len);
43 free(s);
44 return result;
46 if (scm_is_pair(value)) {
47 unsigned int len = scm_to_uint(scm_length(value));
48 PyObject *result = PyTuple_New(len);
49 scm_dynwind_begin(0);
50 scm_dynwind_unwind_handler(
51 (void (*)(void *))Py_DecRef, result, 0);
52 unsigned int i;
53 for (i = 0; i < len; i++) {
54 PyObject *item = scm2py(scm_car(value));
55 if (item == NULL) {
56 scm_dynwind_end();
57 Py_DECREF(result);
58 return NULL;
60 PyTuple_SET_ITEM(result, i, item);
61 value = scm_cdr(value);
63 scm_dynwind_end();
64 return result;
66 if (scm_to_bool(scm_procedure_p(value))) {
67 SCM ptr = scm_assq_ref(gsubr_alist, value);
68 if (!scm_is_false(ptr)) {
69 PyObject *result = scm_to_pointer(ptr);
70 Py_INCREF(result);
71 return result;
73 Procedure *result =
74 (Procedure *)ProcedureType.tp_alloc(&ProcedureType, 0);
75 if (result == NULL)
76 return NULL;
77 result->proc = value;
78 return (PyObject *)result;
81 char *msg = scm_to_utf8_stringn(
82 scm_simple_format(
83 SCM_BOOL_F,
84 scm_from_utf8_string(
85 "Guile expression ~S doesn't have a "
86 "corresponding Python value"),
87 scm_list_1(value)), NULL);
88 PyErr_SetString(PyExc_TypeError, msg);
89 free(msg);
90 return NULL;