1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library - Scheme API
3 * Copyright (C) 2010-2013 Peter Brett <peter@peter-b.co.uk>
4 * Copyright (C) 2010-2020 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 /*! \defgroup guile_c_iface gEDA Scheme API: C interface
22 * \brief Interface to the gEDA Scheme API for programs written in C.
24 * This module contains a variety of functions for use in applications
25 * that use libgeda and which need to make use of or extend the gEDA
28 * To initialise the API, edascm_init() needs to be called before any
29 * Scheme code is executed or any of the other functions listed in
30 * this module are called. Normally, this will be called
31 * automatically by libgeda_init().
33 * The Scheme API requires a libgeda #TOPLEVEL context to be available
34 * at any given time. The #TOPLEVEL can be set on a per-thread basis
35 * using the edascm_dynwind_toplevel() or edascm_c_with_toplevel()
36 * functions. For example:
39 * static SCM worker (void *user_data)
41 * // ...run Scheme code and/or call Scheme API C functions...
44 * void myfunc(TOPLEVEL *toplevel)
48 * // ...set up mydata... //
50 * // Set current toplevel using edascm_c_with_toplevel()
51 * edascm_c_with_toplevel (toplevel, worker, mydata);
53 * // Set current toplevel using dynamic wind
54 * scm_dynwind_begin (0);
55 * edascm_dynwind_toplevel (toplevel);
57 * // ...run Scheme code and/or call Scheme API C functions...
62 * For more information on dynamic wind, see the Guile Reference
65 * The remaining functions in this module allow you to convert gEDA
66 * #OBJECT and #PAGE structures to and from Scheme values ("smobs").
68 * When an #OBJECT is created by Scheme code, it is permitted to be
69 * garbage-collected if all references to it are lost; this is an
70 * important part of allowing Scheme programmers to write efficient
71 * code. However, because #OBJECT instances are not reference
72 * counted, each Scheme object that contains an #OBJECT has a flag
73 * that indicates whether it is wholly owned by Scheme or whether
74 * there are any remaining references to it from C code. If you use
75 * edascm_from_object() to create a Scheme value for an #OBJECT that
76 * has no remaining references from other C structures, you should use
77 * edascm_c_set_gc() to mark it as garbage-collectable.
81 * \file libgedaguile_priv.h
82 * Scheme API private declarations and definitions.
83 * \warning Don't include from libgeda_priv.h: should only be included
84 * by Scheme API source files.
87 #include <libgeda/libgedaguile.h>
89 void edascm_init_smob ();
90 void edascm_init_toplevel ();
91 void edascm_init_object ();
92 void edascm_init_complex ();
93 void edascm_init_page ();
94 void edascm_init_attrib ();
95 void edascm_init_os ();
96 void edascm_init_config ();
97 void edascm_init_closure (void);
98 void edascm_init_log (void);
99 void edascm_init_deprecated ();
101 /* ---------------------------------------- */
103 /* Macros and constants for working with the geda smob type. These are
104 * for the convenience of the other C functions used by the Scheme
107 /*! The tag used to identify gEDA data structures in Scheme. */
108 extern scm_t_bits geda_smob_tag
;
110 /*! The flags used to determine which C structure a smob contains. */
111 enum geda_smob_flags
{
112 GEDA_SMOB_TOPLEVEL
= 0,
114 GEDA_SMOB_OBJECT
= 2,
115 GEDA_SMOB_CONFIG
= 3,
116 GEDA_SMOB_CLOSURE
= 4,
117 GEDA_SMOB_TYPE_MASK
= 0xf,
118 GEDA_SMOB_GC_FLAG
= 0x100,
121 /*! Retrieve the type flags for a gEDA smob. */
122 #define EDASCM_SMOB_TYPE(x) (SCM_SMOB_FLAGS (x) & GEDA_SMOB_TYPE_MASK)
124 /*! \brief Test the type of a gEDA smob.
125 * \par Macro Description
126 * Returns non-zero if \a x is a gEDA smob and the type flags of \a x
129 #define EDASCM_SMOB_TYPEP(x, type) \
130 (SCM_SMOB_PREDICATE (geda_smob_tag, x) && (EDASCM_SMOB_TYPE (x) == type))
132 /*! \brief Test whether a gEDA smob is valid.
133 * \par Macro Description
134 * Returns non-zero if \a x is a gEDA smob and the pointer it contains
137 #define EDASCM_SMOB_VALIDP(x) \
138 (SCM_SMOB_PREDICATE (geda_smob_tag, x) && ((void *)SCM_SMOB_DATA (x) != NULL))
140 /*! \brief Assert that a gEDA smob is valid.
141 * \par Macro Description
142 * Throw an error if assertions are enabled and \a x is invalid.
145 # define EDASCM_ASSERT_SMOB_VALID(x)
147 # define EDASCM_ASSERT_SMOB_VALID(x) \
148 do { if (!EDASCM_SMOB_VALIDP(x)) { \
149 scm_misc_error (NULL, "Found invalid gEDA smob ~S", scm_list_1 (x)); \
153 /* Create a Guile value from a TOPLEVEL structure. */
154 SCM
edascm_from_toplevel (TOPLEVEL
*toplevel
);
156 /*! Tests whether a Scheme value is a TOPLEVEL smob. */
157 #define EDASCM_TOPLEVELP(x) EDASCM_SMOB_TYPEP(x, GEDA_SMOB_TOPLEVEL)
159 /*! Tests whether a Scheme value is a PAGE smob. */
160 #define EDASCM_PAGEP(x) EDASCM_SMOB_TYPEP(x, GEDA_SMOB_PAGE)
162 /*! Tests whether a Scheme value is an OBJECT smob. */
163 #define EDASCM_OBJECTP(x) EDASCM_SMOB_TYPEP(x, GEDA_SMOB_OBJECT)
165 /*! Tests whether a Scheme value is an EdaConfig smob. */
166 #define EDASCM_CONFIGP(x) EDASCM_SMOB_TYPEP(x, GEDA_SMOB_CONFIG)
168 /*! Tests whether a Scheme value is a C closure smob. */
169 #define EDASCM_CLOSUREP(x) EDASCM_SMOB_TYPEP(x, GEDA_SMOB_CLOSURE)
172 * \brief Test whether a structure may be garbage-collected
173 * \par Macro Description
174 * Tests whether the C structure contained by the smob \a x is only
175 * referenced by Scheme code, and thus can be free()'d when \a x is
178 #define EDASCM_SMOB_GCP(x) \
179 (SCM_SMOB_PREDICATE (geda_smob_tag, x) && ((SCM_SMOB_FLAGS (x) & GEDA_SMOB_GC_FLAG) != 0))
182 * \brief Set whether a structure may be garbage-collected
183 * \par Macro Description
184 * Set whether the structure contained by the smob \a x is only
185 * referenced by Scheme code, and thus should be free()'d when \a x is
188 * \param x Smob to modify.
189 * \param gc Non-zero if \a x should be garbage-collected.
191 #define EDASCM_SMOB_SET_GC(x, gc) \
192 SCM_SET_SMOB_FLAGS (x, gc ? (SCM_SMOB_FLAGS (x) | GEDA_SMOB_GC_FLAG) \
193 : (SCM_SMOB_FLAGS (x) & ~GEDA_SMOB_GC_FLAG))
195 /* ---------------------------------------- */
197 GList
*edascm_to_object_glist (SCM objs
, const char *subr
)
198 G_GNUC_WARN_UNUSED_RESULT
;
199 SCM
edascm_from_object_glist (const GList
*objs
);
200 int edascm_is_object_type (SCM smob
, int type
);
203 /*! \brief Flag an object's page as having been changed. */
204 extern void o_page_changed (TOPLEVEL
*t
, OBJECT
*o
);
206 /* ---------------------------------------- */
208 extern SCM edascm_object_state_sym
;
210 /* ---------------------------------------- */
212 SCM
edascm_from_closure (SCM (*func
)(SCM
, gpointer
), gpointer user_data
);