[git commit] vi: undo code shrink

Denys Vlasenko vda.linux at googlemail.com
Wed Apr 2 23:45:05 UTC 2014


commit: http://git.busybox.net/busybox/commit/?id=2c51202aece44d0f72b7d496ac94823e10d08d54
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
undo_push                                            414     395     -19
do_cmd                                              4803    4761     -42

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/vi.c |   85 +++++++++++++++++++++++++++++----------------------------
 1 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index e38667a..71086c9 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2209,7 +2209,8 @@ static void showmatching(char *p)
 // Undo functions and hooks added by Jody Bruchon (jody at jodybruchon.com)
 static void undo_push(char *src, unsigned int length, unsigned char u_type)	// Add to the undo stack
 {
-	struct undo_object *undo_temp;
+	struct undo_object *undo_entry;
+
 	// "u_type" values
 	// UNDO_INS: insertion, undo will remove from buffer
 	// UNDO_DEL: deleted text, undo will restore to buffer
@@ -2237,7 +2238,7 @@ static void undo_push(char *src, unsigned int length, unsigned char u_type)	// A
 		case UNDO_DEL:
 			undo_queue_spos = src;
 			undo_q++;
-			undo_queue[(CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q)] = *src;
+			undo_queue[CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q] = *src;
 			// If queue is full, dump it into an object
 			if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX)
 				undo_queue_commit();
@@ -2275,80 +2276,80 @@ static void undo_push(char *src, unsigned int length, unsigned char u_type)	// A
 #endif
 
 	// Allocate a new undo object and use it as the stack tail
-	undo_temp = undo_stack_tail;
-	undo_stack_tail = xmalloc(sizeof(struct undo_object));
+	undo_entry = xzalloc(sizeof(*undo_entry));
+	undo_entry->prev = undo_stack_tail;
+	undo_stack_tail = undo_entry;
 #if ENABLE_FEATURE_VI_UNDO_QUEUE
 	if ((u_type & UNDO_USE_SPOS) != 0) {
-		undo_stack_tail->start = undo_queue_spos - text;	// use start position from queue
+		undo_entry->start = undo_queue_spos - text;	// use start position from queue
 	} else {
-		undo_stack_tail->start = src - text;	// use offset from start of text buffer
+		undo_entry->start = src - text;	// use offset from start of text buffer
 	}
 	u_type = (u_type & ~UNDO_USE_SPOS);
 #else
-	undo_stack_tail->start = src - text;
-#endif /* ENABLE_FEATURE_VI_UNDO_QUEUE */
+	undo_entry->start = src - text;
+#endif
 	// For UNDO_DEL objects, copy the deleted text somewhere
-	switch (u_type) {
-		case UNDO_DEL:
-		case UNDO_DEL_CHAIN:
-			if ((src + length) == end)
-				length--;
-			// If this deletion empties text[], strip the newline. When the buffer becomes
-			// zero-length, a newline is added back, which requires this to compensate.
-			undo_stack_tail->undo_text = xmalloc(length);
-			memcpy(undo_stack_tail->undo_text, src, length);
-			break;
+	undo_entry->u_type = u_type;
+	if (u_type == UNDO_DEL || u_type == UNDO_DEL_CHAIN) {
+		if ((src + length) == end)
+			length--;
+		// If this deletion empties text[], strip the newline. When the buffer becomes
+		// zero-length, a newline is added back, which requires this to compensate.
+		undo_entry->undo_text = xmalloc(length);
+		memcpy(undo_entry->undo_text, src, length);
 	}
-	undo_stack_tail->prev = undo_temp;
-	undo_stack_tail->length = length;
-	undo_stack_tail->u_type = u_type;
+	undo_entry->length = length;
 	file_modified++;
 }
 
 static void undo_pop(void)	// Undo the last operation
 {
-	int repeat = 0;
+	int repeat;
 	char *u_start, *u_end;
-	struct undo_object *undo_temp;
+	struct undo_object *undo_entry;
 
 	// Commit pending undo queue before popping (should be unnecessary)
 	undo_queue_commit();
 
+	undo_entry = undo_stack_tail;
 	// Check for an empty undo stack
-	if (undo_stack_tail == NULL) {
+	if (!undo_entry) {
 		status_line("Already at oldest change");
 		return;
 	}
 
-	switch (undo_stack_tail->u_type) {
+	switch (undo_entry->u_type) {
 	case UNDO_DEL:
 	case UNDO_DEL_CHAIN:
 		// make hole and put in text that was deleted; deallocate text
-		u_start = text + undo_stack_tail->start;
-		text_hole_make(u_start, undo_stack_tail->length);
-		memcpy(u_start, undo_stack_tail->undo_text, undo_stack_tail->length);
-		free(undo_stack_tail->undo_text);
+		u_start = text + undo_entry->start;
+		text_hole_make(u_start, undo_entry->length);
+		memcpy(u_start, undo_entry->undo_text, undo_entry->length);
+		free(undo_entry->undo_text);
 		status_line("Undo [%d] %s %d chars at position %d",
 			file_modified, "restored",
-			undo_stack_tail->length, undo_stack_tail->start);
+			undo_entry->length, undo_entry->start
+		);
 		break;
 	case UNDO_INS:
 	case UNDO_INS_CHAIN:
 		// delete what was inserted
-		u_start = undo_stack_tail->start + text;
-		u_end = u_start - 1 + undo_stack_tail->length;
+		u_start = undo_entry->start + text;
+		u_end = u_start - 1 + undo_entry->length;
 		text_hole_delete(u_start, u_end, NO_UNDO);
 		status_line("Undo [%d] %s %d chars at position %d",
 			file_modified, "deleted",
-			undo_stack_tail->length, undo_stack_tail->start);
+			undo_entry->length, undo_entry->start
+		);
 		break;
 	}
-	// For chained operations, continue popping all the way down the chain.
+	repeat = 0;
+	switch (undo_entry->u_type) {
 	// If this is the end of a chain, lower modification count and refresh display
-	switch (undo_stack_tail->u_type) {
 	case UNDO_DEL:
 	case UNDO_INS:
-		dot = (text + undo_stack_tail->start);
+		dot = (text + undo_entry->start);
 		refresh(FALSE);
 		break;
 	case UNDO_DEL_CHAIN:
@@ -2357,11 +2358,11 @@ static void undo_pop(void)	// Undo the last operation
 		break;
 	}
 	// Deallocate the undo object we just processed
-	undo_temp = undo_stack_tail->prev;
-	free(undo_stack_tail);
-	undo_stack_tail = undo_temp;
+	undo_stack_tail = undo_entry->prev;
+	free(undo_entry);
 	file_modified--;
-	if (repeat == 1) {
+	// For chained operations, continue popping all the way down the chain.
+	if (repeat) {
 		undo_pop();	// Follow the undo chain if one exists
 	}
 }
@@ -2372,7 +2373,7 @@ static void undo_queue_commit(void)	// Flush any queued objects to the undo stac
 	// Pushes the queue object onto the undo stack
 	if (undo_q > 0) {
 		// Deleted character undo events grow from the end
-		undo_push((undo_queue + CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q),
+		undo_push(undo_queue + CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q,
 			undo_q,
 			(undo_queue_state | UNDO_USE_SPOS)
 		);


More information about the busybox-cvs mailing list