+/* The first time a command records something for undo.
+ it also allocates the undo-boundary object
+ which will be added to the list at the end of the command.
+ This ensures we can't run out of space while trying to make
+ an undo-boundary. */
+Lisp_Object pending_boundary;
+
+/* Record point as it was at beginning of this command (if necessary)
+ And prepare the undo info for recording a change.
+ PT is the position of point that will naturally occur as a result of the
+ undo record that will be added just after this command terminates. */
+
+static void
+record_point (pt)
+{
+ int at_boundary;
+
+ /* Allocate a cons cell to be the undo boundary after this command. */
+ if (NILP (pending_boundary))
+ pending_boundary = Fcons (Qnil, Qnil);
+
+ if (!BUFFERP (last_undo_buffer)
+ || current_buffer != XBUFFER (last_undo_buffer))
+ Fundo_boundary ();
+ XSETBUFFER (last_undo_buffer, current_buffer);
+
+ if (CONSP (current_buffer->undo_list))
+ {
+ /* Set AT_BOUNDARY to 1 only when we have nothing other than
+ marker adjustment before undo boundary. */
+
+ Lisp_Object tail = current_buffer->undo_list, elt;
+
+ while (1)
+ {
+ if (NILP (tail))
+ elt = Qnil;
+ else
+ elt = XCAR (tail);
+ if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt))))
+ break;
+ tail = XCDR (tail);
+ }
+ at_boundary = NILP (elt);
+ }
+ else
+ at_boundary = 1;
+
+ if (MODIFF <= SAVE_MODIFF)
+ record_first_change ();
+
+ /* If we are just after an undo boundary, and
+ point wasn't at start of deleted range, record where it was. */
+ if (at_boundary
+ && last_point_position != pt
+ /* If we're called from batch mode, this could be nil. */
+ && BUFFERP (last_point_position_buffer)
+ && current_buffer == XBUFFER (last_point_position_buffer))
+ current_buffer->undo_list
+ = Fcons (make_number (last_point_position), current_buffer->undo_list);
+}
+