XEmacs 21.2.25 "Hephaestus".
[chise/xemacs-chise.git.1] / src / specifier.h
index 14c4cf1..e447d5c 100644 (file)
@@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA.  */
   etc.
 
   A magic specifier consists of two specifier objects. The first one
-  behaves like a normal specifier in all sences. The second one, a
+  behaves like a normal specifier in all senses. The second one, a
   ghost specifier, is a fallback value for the first one, and contains
   values provided by window system, resources etc. which reflect
   default settings for values being specified.
@@ -61,11 +61,11 @@ Boston, MA 02111-1307, USA.  */
   frame defaults, such as
   init-{global,frame,device}-{faces,toolbars,etc}.
 
-  Thus, values supplied by resources or other means of a window system 
+  Thus, values supplied by resources or other means of a window system
   stored in externally unmodifiable ghost objects. Regular lisp code
   may thus freely modify the normal part of a magic specifier, and
   removing a specification for a particular domain causes the
-  specification to consider ghost-provided fallback values, or its own 
+  specification to consider ghost-provided fallback values, or its own
   fallback value.
 
   Rules of conduct for magic specifiers
@@ -76,13 +76,15 @@ Boston, MA 02111-1307, USA.  */
   2. All specifier methods, except for instantiate method, are passed
      the bodily object of the magic specifier. Instantiate method is
      passed the specifier being instantiated.
-  3. Only bodily objects are passed to set_specifier_caching function, 
+  3. Only bodily objects are passed to set_specifier_caching function,
      and only these may be cached.
-  4. All specifiers are added to Vall_specifiers list, both bodily and 
-     ghost. The pair of objects is always removed from the list at the 
+  4. All specifiers are added to Vall_specifiers list, both bodily and
+     ghost. The pair of objects is always removed from the list at the
      same time.
 */
 
+extern const struct struct_description specifier_methods_description;
+
 struct specifier_methods
 {
   CONST char *name;
@@ -95,10 +97,10 @@ struct specifier_methods
 
   /* Mark method: Mark any lisp object within specifier data
      structure. Not required if no specifier data are Lisp_Objects. */
-  void (*mark_method) (Lisp_Object specifier, void (*markobj) (Lisp_Object));
+  void (*mark_method) (Lisp_Object specifier);
 
   /* Equal method: Compare two specifiers. This is called after
-     ensuring that the two specifiers are of the same type, and habe
+     ensuring that the two specifiers are of the same type, and have
      the same specs.  Quit is inhibited during the call so it is safe
      to call internal_equal().
 
@@ -122,6 +124,13 @@ struct specifier_methods
      valid. */
   void (*validate_method) (Lisp_Object instantiator);
 
+
+  /* Copy method: Given an instantiator, copy the bits that we need to
+     for this specifier type.
+
+     If this function is not present, then Fcopy_tree is used. */
+  Lisp_Object (*copy_instantiator_method) (Lisp_Object instantiator);
+
   /* Validate-matchspec method: Given a matchspec, verify that it's
      valid for this specifier type.  If not, signal an error.
 
@@ -185,6 +194,7 @@ struct specifier_methods
   void (*after_change_method) (Lisp_Object specifier,
                               Lisp_Object locale);
 
+  const struct lrecord_description *extra_description;
   int extra_data_size;
 };
 
@@ -220,7 +230,7 @@ struct Lisp_Specifier
      the ghost part of the magic specifier, a pointer to its parent
      object */
   Lisp_Object magic_parent;
-  
+
   /* Fallback value. For magic specifiers, it is a pointer to the ghost. */
   Lisp_Object fallback;
 
@@ -232,7 +242,6 @@ DECLARE_LRECORD (specifier, struct Lisp_Specifier);
 #define XSPECIFIER(x) XRECORD (x, specifier, struct Lisp_Specifier)
 #define XSETSPECIFIER(x, p) XSETRECORD (x, p, specifier)
 #define SPECIFIERP(x) RECORDP (x, specifier)
-#define GC_SPECIFIERP(x) GC_RECORDP (x, specifier)
 #define CHECK_SPECIFIER(x) CHECK_RECORD (x, specifier)
 #define CONCHECK_SPECIFIER(x) CONCHECK_RECORD (x, specifier)
 
@@ -244,13 +253,16 @@ DECLARE_LRECORD (specifier, struct Lisp_Specifier);
 
 /* Call a void-returning specifier method, if it exists.  */
 #define MAYBE_SPECMETH(sp, m, args) do {               \
-  struct Lisp_Specifier *_maybe_specmeth_sp = (sp);    \
-  if (HAS_SPECMETH_P (_maybe_specmeth_sp, m))          \
-    SPECMETH (_maybe_specmeth_sp, m, args);            \
+  struct Lisp_Specifier *maybe_specmeth_sp = (sp);     \
+  if (HAS_SPECMETH_P (maybe_specmeth_sp, m))           \
+    SPECMETH (maybe_specmeth_sp, m, args);             \
 } while (0)
 
 /***** Defining new specifier types *****/
 
+#define specifier_data_offset (offsetof(struct Lisp_Specifier, data))
+extern const struct lrecord_description specifier_empty_extra_description[];
+
 #ifdef ERROR_CHECK_TYPECHECK
 #define DECLARE_SPECIFIER_TYPE(type)                                   \
 extern struct specifier_methods * type##_specifier_methods;            \
@@ -279,10 +291,17 @@ extern struct specifier_methods * type##_specifier_methods
 struct specifier_methods * type##_specifier_methods
 
 #define INITIALIZE_SPECIFIER_TYPE(type, obj_name, pred_sym) do {       \
- type##_specifier_methods = xnew_and_zero (struct specifier_methods);  \
- type##_specifier_methods->name = obj_name;                            \
- defsymbol (&type##_specifier_methods->predicate_symbol, pred_sym);    \
- add_entry_to_specifier_type_list (Q##type, type##_specifier_methods); \
+  type##_specifier_methods = xnew_and_zero (struct specifier_methods); \
+  type##_specifier_methods->name = obj_name;                           \
+  type##_specifier_methods->extra_description =                                \
+    specifier_empty_extra_description;                                 \
+  defsymbol_nodump (&type##_specifier_methods->predicate_symbol, pred_sym);    \
+  add_entry_to_specifier_type_list (Q##type, type##_specifier_methods);        \
+  dumpstruct (&type##_specifier_methods, &specifier_methods_description); \
+} while (0)
+
+#define REINITIALIZE_SPECIFIER_TYPE(type) do { \
+  staticpro_nodump (&type##_specifier_methods->predicate_symbol);      \
 } while (0)
 
 #define INITIALIZE_SPECIFIER_TYPE_WITH_DATA(type, obj_name, pred_sym)  \
@@ -290,6 +309,8 @@ do {                                                                        \
   INITIALIZE_SPECIFIER_TYPE (type, obj_name, pred_sym);                        \
   type##_specifier_methods->extra_data_size =                          \
     sizeof (struct type##_specifier);                                  \
+  type##_specifier_methods->extra_description =                        \
+    type##_specifier_description;                                      \
 } while (0)
 
 /* Declare that specifier-type TYPE has method METH; used in
@@ -303,24 +324,13 @@ do {                                                                      \
   ((sp)->methods == type##_specifier_methods)
 
 /* Any of the two of the magic spec */
-#define MAGIC_SPECIFIER_P(sp) \
-  (!NILP((sp)->magic_parent))
+#define MAGIC_SPECIFIER_P(sp) (!NILP((sp)->magic_parent))
 /* Normal part of the magic specifier */
-#define BODILY_SPECIFIER_P(sp) \
-  (EQ ((sp)->magic_parent, Qt))
+#define BODILY_SPECIFIER_P(sp) EQ ((sp)->magic_parent, Qt)
 /* Ghost part of the magic specifier */
-#define GHOST_SPECIFIER_P(sp) \
-  (SPECIFIERP((sp)->magic_parent))
-/* The same three, when used in GC */
-#define GC_MAGIC_SPECIFIER_P(sp) \
-  (!GC_NILP((sp)->magic_parent))
-#define GC_BODILY_SPECIFIER_P(sp) \
-  (GC_EQ ((sp)->magic_parent, Qt))
-#define GC_GHOST_SPECIFIER_P(sp) \
-  (GC_SPECIFIERP((sp)->magic_parent))
-
-#define GHOST_SPECIFIER(sp) \
-  (XSPECIFIER ((sp)->fallback))
+#define GHOST_SPECIFIER_P(sp) SPECIFIERP((sp)->magic_parent)
+
+#define GHOST_SPECIFIER(sp) XSPECIFIER ((sp)->fallback)
 
 #ifdef ERROR_CHECK_TYPECHECK
 # define SPECIFIER_TYPE_DATA(sp, type) \
@@ -425,7 +435,7 @@ void remove_ghost_specifier (Lisp_Object specifier, Lisp_Object locale,
 int unlock_ghost_specifiers_protected (void);
 
 void cleanup_specifiers (void);
-void prune_specifiers (int (*obj_marked_p) (Lisp_Object));
+void prune_specifiers (void);
 void setup_device_initial_specifier_tags (struct device *d);
 void kill_specifier_buffer_locals (Lisp_Object buffer);