libgeda: Make sure all object fields are initialized
[geda-gaf.git] / libgeda / include / libgedaguile_priv.h
blob72c1f15a2c578941ad9fcd8e91cda77bf34e3c47
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
26 * Scheme API.
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:
38 * \code
39 * static SCM worker (void *user_data)
40 * {
41 * // ...run Scheme code and/or call Scheme API C functions...
42 * }
44 * void myfunc(TOPLEVEL *toplevel)
45 * {
46 * void *mydata;
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);
56 * worker (mydata);
57 * // ...run Scheme code and/or call Scheme API C functions...
58 * scm_dynwind_end ();
59 * }
60 * \endcode
62 * For more information on dynamic wind, see the Guile Reference
63 * Manual.
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.
80 /*!
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
105 * API. */
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,
113 GEDA_SMOB_PAGE = 1,
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
127 * match \a type.
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
135 * is valid.
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.
144 #ifdef NDEBUG
145 # define EDASCM_ASSERT_SMOB_VALID(x)
146 #else
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)); \
150 } } while (0)
151 #endif
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
176 * garbage-collected.
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
186 * garbage-collected.
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);