+/* Return a Lisp_Save_Value object with the data saved according to
+ FMT. Format specifiers are `i' for an integer, `p' for a pointer
+ and `o' for Lisp_Object. Up to 4 objects can be specified. */
+
+Lisp_Object
+format_save_value (const char *fmt, ...)
+{
+ va_list ap;
+ int len = strlen (fmt);
+ Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
+ struct Lisp_Save_Value *p = XSAVE_VALUE (val);
+
+ eassert (0 < len && len < 5);
+ va_start (ap, fmt);
+
+#define INITX(index) \
+ do { \
+ if (len <= index) \
+ p->type ## index = SAVE_UNUSED; \
+ else \
+ { \
+ if (fmt[index] == 'i') \
+ { \
+ p->type ## index = SAVE_INTEGER; \
+ p->data[index].integer = va_arg (ap, ptrdiff_t); \
+ } \
+ else if (fmt[index] == 'p') \
+ { \
+ p->type ## index = SAVE_POINTER; \
+ p->data[index].pointer = va_arg (ap, void *); \
+ } \
+ else if (fmt[index] == 'o') \
+ { \
+ p->type ## index = SAVE_OBJECT; \
+ p->data[index].object = va_arg (ap, Lisp_Object); \
+ } \
+ else \
+ emacs_abort (); \
+ } \
+ } while (0)
+
+ INITX (0);
+ INITX (1);
+ INITX (2);
+ INITX (3);
+
+#undef INITX
+
+ va_end (ap);
+ p->area = 0;
+ return val;
+}
+