/*! \brief Free a gEDA smob. * \par Function Description * Finalizes a gEDA smob for deletion, removing the weak reference. * * Used internally to Guile. */ static size_t smob_free (SCM smob) { void *data; /* If the weak reference has already been cleared, do nothing */ if (!EDASCM_SMOB_VALIDP(smob)) return 0; data = (void *) SCM_SMOB_DATA (smob); /* Otherwise, clear the weak reference */ switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: s_toplevel_weak_unref ((TOPLEVEL *) data, smob_weakref_notify, smob); break; case GEDA_SMOB_PAGE: s_page_weak_unref ((PAGE *) data, smob_weakref_notify, smob); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_object_weak_unref ((OBJECT *) data, smob_weakref_notify, smob); s_toplevel_weak_unref ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), smob_weakref2_notify, smob); break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } /* If the smob is marked as garbage-collectable, destroy its * contents. * * Because PAGEs and TOPLEVELs should never be garbage collected, * emit critical warnings if the GC tries to free them. */ if (EDASCM_SMOB_GCP (smob)) { switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: g_critical ("%s: Blocked garbage-collection of TOPLEVEL %p", __FUNCTION__, data); break; case GEDA_SMOB_PAGE: g_critical ("%s: Blocked garbage-collection of PAGE %p", __FUNCTION__, data); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_delete_object ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), (OBJECT *) data); break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } } return 0; }
/*! \brief Print a representation of a gEDA smob. * \par Function Description * Outputs a string representing the gEDA \a smob to a Scheme output * \a port. The format used is "#<geda-TYPE b7ef65d0>", where TYPE is * a string describing the C structure represented by the gEDA smob. * * Used internally to Guile. */ static int smob_print (SCM smob, SCM port, scm_print_state *pstate) { gchar *hexstring; scm_puts ("#<geda-", port); switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: scm_puts ("toplevel", port); break; case GEDA_SMOB_PAGE: scm_puts ("page", port); break; case GEDA_SMOB_OBJECT: scm_puts ("object", port); break; case GEDA_SMOB_CONFIG: scm_puts ("config", port); break; case GEDA_SMOB_CLOSURE: scm_puts ("closure", port); break; default: g_critical ("%s: received bad smob flags.", __FUNCTION__); scm_puts ("unknown", port); } if (SCM_SMOB_DATA (smob) != 0) { scm_dynwind_begin (0); hexstring = g_strdup_printf (" %p", (void *) SCM_SMOB_DATA (smob)); scm_dynwind_unwind_handler (g_free, hexstring, SCM_F_WIND_EXPLICITLY); scm_puts (hexstring, port); scm_dynwind_end (); } else { scm_puts (" (null)", port); } scm_puts (">", port); /* Non-zero means success */ return 1; }
/*! \brief Free a gEDA smob. * \par Function Description * Finalizes a gEDA smob for deletion, removing the weak reference. * * Used internally to Guile. */ static size_t smob_free (SCM smob) { void *data; /* If the weak reference has already been cleared, do nothing */ if (!EDASCM_SMOB_VALIDP(smob)) return 0; data = (void *) SCM_SMOB_DATA (smob); /* If the smob is being finalized, it must not be in the cache! */ g_warn_if_fail (!smob_cache_contains (data)); /* Otherwise, clear the weak reference */ switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: s_toplevel_weak_unref ((TOPLEVEL *) data, smob_weakref_notify, unpack_as_pointer (smob)); break; case GEDA_SMOB_PAGE: s_page_weak_unref ((PAGE *) data, smob_weakref_notify, unpack_as_pointer (smob)); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_object_weak_unref ((OBJECT *) data, smob_weakref2_notify, unpack_as_pointer (smob)); break; case GEDA_SMOB_CONFIG: g_object_unref (G_OBJECT (data)); break; case GEDA_SMOB_CLOSURE: break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } /* If the smob is marked as garbage-collectable, destroy its * contents. * * Because PAGEs and TOPLEVELs should never be garbage collected, * emit critical warnings if the GC tries to free them. */ if (EDASCM_SMOB_GCP (smob)) { switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: g_critical ("%s: Blocked garbage-collection of TOPLEVEL %p", __FUNCTION__, data); break; case GEDA_SMOB_PAGE: g_critical ("%s: Blocked garbage-collection of PAGE %p", __FUNCTION__, data); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_delete_object ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), (OBJECT *) data); break; case GEDA_SMOB_CONFIG: /* These are reference counted, so the structure will have * already been destroyed above if appropriate. */ break; case GEDA_SMOB_CLOSURE: break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } } return 0; }