+ ((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" 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_STRING_DATA, offsetof(Lisp_String, data) },
+ { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 },
+ { XD_END }
+ };
+ "A string data pointer at 'data', 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_STRING_DATA
+ Pointer to string data.
+
+ 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_SIZE_T
+ size_t value. Used for counts.
+
+ XD_INT
+ int value. Used for counts.
+
+ XD_LONG
+ long value. Used for counts.
+
+ XD_END
+ Special type indicating the end of the array.
+
+
+ Special macros:
+ XD_INDIRECT(line)
+ 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).
+
+ XD_PARENT_INDIRECT(line)
+ Same as XD_INDIRECT but the element number refers to the parent structure.
+ Usable only in struct descriptions.
+*/
+
+enum lrecord_description_type {
+ XD_LISP_OBJECT,
+ XD_STRING_DATA,
+ XD_OPAQUE_PTR,
+ XD_STRUCT_PTR,
+ XD_OPAQUE_DATA_PTR,
+ XD_SIZE_T,
+ XD_INT,
+ XD_LONG,
+ XD_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(count) (-1-(count))
+#define XD_PARENT_INDIRECT(count) (-1000-(count))
+
+#define XD_DYNARR_DESC(base_type, sub_desc) \
+ { XD_STRUCT_PTR, offsetof(base_type, base), XD_INDIRECT(1), sub_desc }, \
+ { XD_INT, offsetof(base_type, max) }