Dynarr_declare (specifier_type_entry);
} specifier_type_entry_dynarr;
-specifier_type_entry_dynarr *the_specifier_type_entry_dynarr;
+static specifier_type_entry_dynarr *the_specifier_type_entry_dynarr;
+
+static const struct lrecord_description ste_description_1[] = {
+ { XD_LISP_OBJECT, offsetof (specifier_type_entry, symbol) },
+ { XD_STRUCT_PTR, offsetof (specifier_type_entry, meths), 1, &specifier_methods_description },
+ { XD_END }
+};
+
+static const struct struct_description ste_description = {
+ sizeof (specifier_type_entry),
+ ste_description_1
+};
+
+static const struct lrecord_description sted_description_1[] = {
+ XD_DYNARR_DESC (specifier_type_entry_dynarr, &ste_description),
+ { XD_END }
+};
+
+static const struct struct_description sted_description = {
+ sizeof (specifier_type_entry_dynarr),
+ sted_description_1
+};
static Lisp_Object Vspecifier_type_list;
!NILP (rest);
rest = XSPECIFIER (rest)->next_specifier)
{
- struct Lisp_Specifier *sp = XSPECIFIER (rest);
+ Lisp_Specifier *sp = XSPECIFIER (rest);
/* This effectively changes the specifier specs.
However, there's no need to call
recompute_cached_specifier_everywhere() or the
!NILP (rest);
rest = XSPECIFIER (rest)->next_specifier)
{
- struct Lisp_Specifier *sp = XSPECIFIER (rest);
+ Lisp_Specifier *sp = XSPECIFIER (rest);
/* Make sure we're actually going to be changing something.
Fremove_specifier() always calls
}
static Lisp_Object
-mark_specifier (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_specifier (Lisp_Object obj)
{
- struct Lisp_Specifier *specifier = XSPECIFIER (obj);
+ Lisp_Specifier *specifier = XSPECIFIER (obj);
- markobj (specifier->global_specs);
- markobj (specifier->device_specs);
- markobj (specifier->frame_specs);
- markobj (specifier->window_specs);
- markobj (specifier->buffer_specs);
- markobj (specifier->magic_parent);
- markobj (specifier->fallback);
+ mark_object (specifier->global_specs);
+ mark_object (specifier->device_specs);
+ mark_object (specifier->frame_specs);
+ mark_object (specifier->window_specs);
+ mark_object (specifier->buffer_specs);
+ mark_object (specifier->magic_parent);
+ mark_object (specifier->fallback);
if (!GHOST_SPECIFIER_P (XSPECIFIER (obj)))
- MAYBE_SPECMETH (specifier, mark, (obj, markobj));
+ MAYBE_SPECMETH (specifier, mark, (obj));
return Qnil;
}
*/
void
-prune_specifiers (int (*obj_marked_p) (Lisp_Object))
+prune_specifiers (void)
{
Lisp_Object rest, prev = Qnil;
for (rest = Vall_specifiers;
- !GC_NILP (rest);
+ !NILP (rest);
rest = XSPECIFIER (rest)->next_specifier)
{
- if (! obj_marked_p (rest))
+ if (! marked_p (rest))
{
- struct Lisp_Specifier* sp = XSPECIFIER (rest);
+ Lisp_Specifier* sp = XSPECIFIER (rest);
/* A bit of assertion that we're removing both parts of the
magic one altogether */
- assert (!GC_MAGIC_SPECIFIER_P(sp)
- || (GC_BODILY_SPECIFIER_P(sp) && obj_marked_p (sp->fallback))
- || (GC_GHOST_SPECIFIER_P(sp) && obj_marked_p (sp->magic_parent)));
+ assert (!MAGIC_SPECIFIER_P(sp)
+ || (BODILY_SPECIFIER_P(sp) && marked_p (sp->fallback))
+ || (GHOST_SPECIFIER_P(sp) && marked_p (sp->magic_parent)));
/* This specifier is garbage. Remove it from the list. */
- if (GC_NILP (prev))
+ if (NILP (prev))
Vall_specifiers = sp->next_specifier;
else
XSPECIFIER (prev)->next_specifier = sp->next_specifier;
static void
print_specifier (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
{
- struct Lisp_Specifier *sp = XSPECIFIER (obj);
+ Lisp_Specifier *sp = XSPECIFIER (obj);
char buf[100];
int count = specpdl_depth ();
Lisp_Object the_specs;
static void
finalize_specifier (void *header, int for_disksave)
{
- struct Lisp_Specifier *sp = (struct Lisp_Specifier *) header;
+ Lisp_Specifier *sp = (Lisp_Specifier *) header;
/* don't be snafued by the disksave finalization. */
- if (!for_disksave && !GC_GHOST_SPECIFIER_P(sp) && sp->caching)
+ if (!for_disksave && !GHOST_SPECIFIER_P(sp) && sp->caching)
{
xfree (sp->caching);
sp->caching = 0;
static int
specifier_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
{
- struct Lisp_Specifier *s1 = XSPECIFIER (obj1);
- struct Lisp_Specifier *s2 = XSPECIFIER (obj2);
+ Lisp_Specifier *s1 = XSPECIFIER (obj1);
+ Lisp_Specifier *s2 = XSPECIFIER (obj2);
int retval;
Lisp_Object old_inhibit_quit = Vinhibit_quit;
static unsigned long
specifier_hash (Lisp_Object obj, int depth)
{
- struct Lisp_Specifier *s = XSPECIFIER (obj);
+ Lisp_Specifier *s = XSPECIFIER (obj);
/* specifier hashing is a bit problematic because there are so
many places where data can be stored. We pick what are perhaps
}
static size_t
-sizeof_specifier (CONST void *header)
+sizeof_specifier (const void *header)
{
- if (GHOST_SPECIFIER_P ((struct Lisp_Specifier *) header))
- return sizeof (struct Lisp_Specifier);
+ if (GHOST_SPECIFIER_P ((Lisp_Specifier *) header))
+ return offsetof (Lisp_Specifier, data);
else
{
- CONST struct Lisp_Specifier *p = (CONST struct Lisp_Specifier *) header;
- return sizeof (*p) + p->methods->extra_data_size - 1;
+ const Lisp_Specifier *p = (const Lisp_Specifier *) header;
+ return offsetof (Lisp_Specifier, data) + p->methods->extra_data_size;
}
}
+static const struct lrecord_description specifier_methods_description_1[] = {
+ { XD_LISP_OBJECT, offsetof (struct specifier_methods, predicate_symbol) },
+ { XD_END }
+};
+
+const struct struct_description specifier_methods_description = {
+ sizeof (struct specifier_methods),
+ specifier_methods_description_1
+};
+
+static const struct lrecord_description specifier_caching_description_1[] = {
+ { XD_END }
+};
+
+static const struct struct_description specifier_caching_description = {
+ sizeof (struct specifier_caching),
+ specifier_caching_description_1
+};
+
+static const struct lrecord_description specifier_description[] = {
+ { XD_STRUCT_PTR, offsetof (Lisp_Specifier, methods), 1, &specifier_methods_description },
+ { XD_LO_LINK, offsetof (Lisp_Specifier, next_specifier) },
+ { XD_LISP_OBJECT, offsetof (Lisp_Specifier, global_specs) },
+ { XD_LISP_OBJECT, offsetof (Lisp_Specifier, device_specs) },
+ { XD_LISP_OBJECT, offsetof (Lisp_Specifier, frame_specs) },
+ { XD_LISP_OBJECT, offsetof (Lisp_Specifier, window_specs) },
+ { XD_LISP_OBJECT, offsetof (Lisp_Specifier, buffer_specs) },
+ { XD_STRUCT_PTR, offsetof (Lisp_Specifier, caching), 1, &specifier_caching_description },
+ { XD_LISP_OBJECT, offsetof (Lisp_Specifier, magic_parent) },
+ { XD_LISP_OBJECT, offsetof (Lisp_Specifier, fallback) },
+ { XD_SPECIFIER_END }
+};
+
+const struct lrecord_description specifier_empty_extra_description[] = {
+ { XD_END }
+};
+
DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier,
mark_specifier, print_specifier,
finalize_specifier,
specifier_equal, specifier_hash,
+ specifier_description,
sizeof_specifier,
- struct Lisp_Specifier);
+ Lisp_Specifier);
\f
/************************************************************************/
/* Creating specifiers */
size_t data_size, int call_create_meth)
{
Lisp_Object specifier;
- struct Lisp_Specifier *sp = (struct Lisp_Specifier *)
- alloc_lcrecord (sizeof (struct Lisp_Specifier) +
- data_size - 1, lrecord_specifier);
+ Lisp_Specifier *sp = (Lisp_Specifier *)
+ alloc_lcrecord (offsetof (Lisp_Specifier, data) + data_size,
+ &lrecord_specifier);
sp->methods = spec_meths;
sp->global_specs = Qnil;
TYPE specifies the particular type of specifier, and should be one of
the symbols 'generic, 'integer, 'boolean, 'color, 'font, 'image,
-'face-boolean, or 'toolbar.
-
-For more information on particular types of specifiers, see the functions
-`generic-specifier-p', `integer-specifier-p', `boolean-specifier-p',
-`color-specifier-p', `font-specifier-p', `image-specifier-p',
-`face-boolean-specifier-p', and `toolbar-specifier-p'.
+'face-boolean, 'gutter, 'gutter-size, 'gutter-visible or 'toolbar.
+
+For more information on particular types of specifiers, see the
+functions `generic-specifier-p', `integer-specifier-p',
+`boolean-specifier-p', `color-specifier-p', `font-specifier-p',
+`image-specifier-p', `face-boolean-specifier-p', `gutter-specifier-p,
+`gutter-size-specifier-p, `gutter-visible-specifier-p and
+`toolbar-specifier-p'.
*/
(type))
{
{
/* The return value of this function must be GCPRO'd. */
Lisp_Object rest, list_to_build_up = Qnil;
- struct Lisp_Specifier *sp = XSPECIFIER (specifier);
+ Lisp_Specifier *sp = XSPECIFIER (specifier);
struct gcpro gcpro1;
GCPRO1 (list_to_build_up);
LIST_LOOP (rest, inst_list)
{
Lisp_Object tag_set = XCAR (XCAR (rest));
- Lisp_Object instantiator = Fcopy_tree (XCDR (XCAR (rest)), Qt);
Lisp_Object sub_inst_list = Qnil;
+ Lisp_Object instantiator;
struct gcpro ngcpro1, ngcpro2;
+ if (HAS_SPECMETH_P (sp, copy_instantiator))
+ instantiator = SPECMETH (sp, copy_instantiator,
+ (XCDR (XCAR (rest))));
+ else
+ instantiator = Fcopy_tree (XCDR (XCAR (rest)), Qt);
+
NGCPRO2 (instantiator, sub_inst_list);
/* call the will-add method; it may GC */
sub_inst_list = HAS_SPECMETH_P (sp, going_to_add) ?
specifier_add_spec (Lisp_Object specifier, Lisp_Object locale,
Lisp_Object inst_list, enum spec_add_meth add_meth)
{
- struct Lisp_Specifier *sp = XSPECIFIER (specifier);
+ Lisp_Specifier *sp = XSPECIFIER (specifier);
enum spec_locale_type type = locale_type_from_locale (locale);
Lisp_Object *orig_inst_list, tem;
Lisp_Object list_to_build_up = Qnil;
void
set_specifier_fallback (Lisp_Object specifier, Lisp_Object fallback)
{
- struct Lisp_Specifier *sp = XSPECIFIER (specifier);
+ Lisp_Specifier *sp = XSPECIFIER (specifier);
assert (SPECIFIERP (fallback) ||
!NILP (Fvalid_inst_list_p (fallback, Fspecifier_type (specifier))));
if (SPECIFIERP (fallback))
Lisp_Object depth)
{
/* This function can GC */
- struct Lisp_Specifier *sp;
+ Lisp_Specifier *sp;
Lisp_Object device;
Lisp_Object rest;
int count = specpdl_depth ();
Lisp_Object device = Qnil;
Lisp_Object tag = Qnil;
struct device *d;
- struct Lisp_Specifier *sp;
+ Lisp_Specifier *sp;
sp = XSPECIFIER (specifier);
goto do_fallback;
}
-retry:
+ retry:
/* First see if we can generate one from the window specifiers. */
if (!NILP (window))
CHECK_INSTANCE_ENTRY (window, matchspec, LOCALE_WINDOW);
/* Last and least try the global specifiers. */
CHECK_INSTANCE_ENTRY (Qglobal, matchspec, LOCALE_GLOBAL);
-do_fallback:
+ do_fallback:
/* We're out of specifiers and we still haven't generated an
instance. At least try the fallback ... If this fails,
then we just return Qunbound. */
(specifier, domain, inst_list, default_))
{
Lisp_Object val = Qunbound;
- struct Lisp_Specifier *sp = XSPECIFIER (specifier);
+ Lisp_Specifier *sp = XSPECIFIER (specifier);
struct gcpro gcpro1;
Lisp_Object built_up_list = Qnil;
(specifier, matchspec, domain, inst_list, default_))
{
Lisp_Object val = Qunbound;
- struct Lisp_Specifier *sp = XSPECIFIER (specifier);
+ Lisp_Specifier *sp = XSPECIFIER (specifier);
struct gcpro gcpro1;
Lisp_Object built_up_list = Qnil;
(Lisp_Object specifier, struct frame *f,
Lisp_Object oldval))
{
- struct Lisp_Specifier *sp = XSPECIFIER (specifier);
+ Lisp_Specifier *sp = XSPECIFIER (specifier);
assert (!GHOST_SPECIFIER_P (sp));
if (!sp->caching)
method. */
location = (Lisp_Object *)
((char *) w + XSPECIFIER (specifier)->caching->offset_into_struct_window);
+ /* #### What's the point of this check, other than to optimize image
+ instance instantiation? Unless you specify a caching instantiate
+ method the instantiation that specifier_instance will do will
+ always create a new copy. Thus EQ will always fail. Unfortunately
+ calling equal is no good either as this doesn't take into account
+ things attached to the specifier - for instance strings on
+ extents. --andyp */
if (!EQ (newval, *location))
{
Lisp_Object oldval = *location;
void
syms_of_specifier (void)
{
+ INIT_LRECORD_IMPLEMENTATION (specifier);
+
defsymbol (&Qspecifierp, "specifierp");
defsymbol (&Qconsole_type, "console-type");
specifier_type_create (void)
{
the_specifier_type_entry_dynarr = Dynarr_new (specifier_type_entry);
+ dumpstruct (&the_specifier_type_entry_dynarr, &sted_description);
Vspecifier_type_list = Qnil;
staticpro (&Vspecifier_type_list);
}
void
+reinit_specifier_type_create (void)
+{
+ REINITIALIZE_SPECIFIER_TYPE (generic);
+ REINITIALIZE_SPECIFIER_TYPE (integer);
+ REINITIALIZE_SPECIFIER_TYPE (natnum);
+ REINITIALIZE_SPECIFIER_TYPE (boolean);
+ REINITIALIZE_SPECIFIER_TYPE (display_table);
+}
+
+void
vars_of_specifier (void)
{
Vcached_specifiers = Qnil;
/* Do NOT mark through this, or specifiers will never be GC'd.
This is the same deal as for weak hash tables. */
Vall_specifiers = Qnil;
+ pdump_wire_list (&Vall_specifiers);
Vuser_defined_tags = Qnil;
staticpro (&Vuser_defined_tags);