+ ((void) ((lheader)->lisp_readonly = 1))
+
+/* External description stuff
+
+ A lrecord external description is an array of values. The first
+ value of each line is a type, the second the offset in the lrecord
+ structure. Following values are parameters, their presence, type
+ and number is type-dependant.
+
+ The description ends with a "XD_END" or "XD_SPECIFIER_END" record.
+
+ Some example descriptions :
+ static const struct lrecord_description cons_description[] = {
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Cons, car), 2 },
+ { XD_END }
+ };
+
+ Which means "two lisp objects starting at the 'car' element"
+
+ static const struct lrecord_description string_description[] = {
+ { XD_BYTECOUNT, offsetof(Lisp_String, size) },
+ { XD_OPAQUE_DATA_PTR, offsetof(Lisp_String, data), XD_INDIRECT(0, 1) },
+ { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 },
+ { XD_END }
+ };
+ "A pointer to string data at 'data', the size of the pointed array being the value
+ of the size variable plus 1, and one lisp object at 'plist'"
+
+ The existing types :
+ XD_LISP_OBJECT
+ Lisp objects. The third element is the count. This is also the type to use
+ for pointers to other lrecords.
+
+ XD_LO_RESET_NIL
+ Lisp objects which will be reset to Qnil when dumping. Useful for cleaning
+ up caches.
+
+ XD_LO_LINK
+ Link in a linked list of objects of the same type.
+
+ XD_OPAQUE_PTR
+ Pointer to undumpable data. Must be NULL when dumping.
+
+ XD_STRUCT_PTR
+ Pointer to described struct. Parameters are number of structures and
+ struct_description.
+
+ XD_OPAQUE_DATA_PTR
+ Pointer to dumpable opaque data. Parameter is the size of the data.
+ Pointed data must be relocatable without changes.
+
+ XD_C_STRING
+ Pointer to a C string.
+
+ XD_DOC_STRING
+ Pointer to a doc string (C string if positive, opaque value if negative)
+
+ XD_INT_RESET
+ An integer which will be reset to a given value in the dump file.
+
+
+ XD_SIZE_T
+ size_t value. Used for counts.
+
+ XD_INT
+ int value. Used for counts.
+
+ XD_LONG
+ long value. Used for counts.
+
+ XD_BYTECOUNT
+ bytecount value. Used for counts.
+
+ XD_END
+ Special type indicating the end of the array.
+
+ XD_SPECIFIER_END
+ Special type indicating the end of the array for a specifier. Extra
+ description is going to be fetched from the specifier methods.
+
+
+ Special macros:
+ XD_INDIRECT(line, delta)
+ Usable where a "count" or "size" is requested. Gives the value of
+ the element which is at line number 'line' in the description (count
+ starts at zero) and adds delta to it.
+*/
+
+enum lrecord_description_type {
+ XD_LISP_OBJECT,
+ XD_LO_RESET_NIL,
+ XD_LO_LINK,
+ XD_OPAQUE_PTR,
+ XD_STRUCT_PTR,
+ XD_OPAQUE_DATA_PTR,
+ XD_C_STRING,
+ XD_DOC_STRING,
+ XD_INT_RESET,
+ XD_SIZE_T,
+ XD_INT,
+ XD_LONG,
+ XD_BYTECOUNT,
+ XD_END,
+ XD_SPECIFIER_END
+};
+
+struct lrecord_description {
+ enum lrecord_description_type type;
+ int offset;
+ EMACS_INT data1;
+ const struct struct_description *data2;
+};
+
+struct struct_description {
+ size_t size;
+ const struct lrecord_description *description;
+};
+
+#define XD_INDIRECT(val, delta) (-1-((val)|(delta<<8)))
+
+#define XD_IS_INDIRECT(code) (code<0)
+#define XD_INDIRECT_VAL(code) ((-1-code) & 255)
+#define XD_INDIRECT_DELTA(code) (((-1-code)>>8) & 255)
+
+#define XD_DYNARR_DESC(base_type, sub_desc) \
+ { XD_STRUCT_PTR, offsetof(base_type, base), XD_INDIRECT(1, 0), sub_desc }, \
+ { XD_INT, offsetof(base_type, cur) }, \
+ { XD_INT_RESET, offsetof(base_type, max), XD_INDIRECT(1, 0) }