aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-04-03 01:45:05 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-04-03 01:45:05 +0200
commit2c51202aece44d0f72b7d496ac94823e10d08d54 (patch)
tree90f73c49cd485842df40510ea3ba602b17ea6bd2
parenta8d6f9bee43aba077f7a3a9bcb6ac64e5d877278 (diff)
downloadbusybox-w32-2c51202aece44d0f72b7d496ac94823e10d08d54.tar.gz
busybox-w32-2c51202aece44d0f72b7d496ac94823e10d08d54.tar.bz2
busybox-w32-2c51202aece44d0f72b7d496ac94823e10d08d54.zip
vi: undo code shrink
function old new delta undo_push 414 395 -19 do_cmd 4803 4761 -42 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c83
1 files changed, 42 insertions, 41 deletions
diff --git a/editors/vi.c b/editors/vi.c
index e38667ad1..71086c901 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2209,7 +2209,8 @@ static void showmatching(char *p)
2209// Undo functions and hooks added by Jody Bruchon (jody@jodybruchon.com) 2209// Undo functions and hooks added by Jody Bruchon (jody@jodybruchon.com)
2210static void undo_push(char *src, unsigned int length, unsigned char u_type) // Add to the undo stack 2210static void undo_push(char *src, unsigned int length, unsigned char u_type) // Add to the undo stack
2211{ 2211{
2212 struct undo_object *undo_temp; 2212 struct undo_object *undo_entry;
2213
2213 // "u_type" values 2214 // "u_type" values
2214 // UNDO_INS: insertion, undo will remove from buffer 2215 // UNDO_INS: insertion, undo will remove from buffer
2215 // UNDO_DEL: deleted text, undo will restore to buffer 2216 // 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
2237 case UNDO_DEL: 2238 case UNDO_DEL:
2238 undo_queue_spos = src; 2239 undo_queue_spos = src;
2239 undo_q++; 2240 undo_q++;
2240 undo_queue[(CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q)] = *src; 2241 undo_queue[CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q] = *src;
2241 // If queue is full, dump it into an object 2242 // If queue is full, dump it into an object
2242 if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX) 2243 if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX)
2243 undo_queue_commit(); 2244 undo_queue_commit();
@@ -2275,80 +2276,80 @@ static void undo_push(char *src, unsigned int length, unsigned char u_type) // A
2275#endif 2276#endif
2276 2277
2277 // Allocate a new undo object and use it as the stack tail 2278 // Allocate a new undo object and use it as the stack tail
2278 undo_temp = undo_stack_tail; 2279 undo_entry = xzalloc(sizeof(*undo_entry));
2279 undo_stack_tail = xmalloc(sizeof(struct undo_object)); 2280 undo_entry->prev = undo_stack_tail;
2281 undo_stack_tail = undo_entry;
2280#if ENABLE_FEATURE_VI_UNDO_QUEUE 2282#if ENABLE_FEATURE_VI_UNDO_QUEUE
2281 if ((u_type & UNDO_USE_SPOS) != 0) { 2283 if ((u_type & UNDO_USE_SPOS) != 0) {
2282 undo_stack_tail->start = undo_queue_spos - text; // use start position from queue 2284 undo_entry->start = undo_queue_spos - text; // use start position from queue
2283 } else { 2285 } else {
2284 undo_stack_tail->start = src - text; // use offset from start of text buffer 2286 undo_entry->start = src - text; // use offset from start of text buffer
2285 } 2287 }
2286 u_type = (u_type & ~UNDO_USE_SPOS); 2288 u_type = (u_type & ~UNDO_USE_SPOS);
2287#else 2289#else
2288 undo_stack_tail->start = src - text; 2290 undo_entry->start = src - text;
2289#endif /* ENABLE_FEATURE_VI_UNDO_QUEUE */ 2291#endif
2290 // For UNDO_DEL objects, copy the deleted text somewhere 2292 // For UNDO_DEL objects, copy the deleted text somewhere
2291 switch (u_type) { 2293 undo_entry->u_type = u_type;
2292 case UNDO_DEL: 2294 if (u_type == UNDO_DEL || u_type == UNDO_DEL_CHAIN) {
2293 case UNDO_DEL_CHAIN: 2295 if ((src + length) == end)
2294 if ((src + length) == end) 2296 length--;
2295 length--; 2297 // If this deletion empties text[], strip the newline. When the buffer becomes
2296 // If this deletion empties text[], strip the newline. When the buffer becomes 2298 // zero-length, a newline is added back, which requires this to compensate.
2297 // zero-length, a newline is added back, which requires this to compensate. 2299 undo_entry->undo_text = xmalloc(length);
2298 undo_stack_tail->undo_text = xmalloc(length); 2300 memcpy(undo_entry->undo_text, src, length);
2299 memcpy(undo_stack_tail->undo_text, src, length);
2300 break;
2301 } 2301 }
2302 undo_stack_tail->prev = undo_temp; 2302 undo_entry->length = length;
2303 undo_stack_tail->length = length;
2304 undo_stack_tail->u_type = u_type;
2305 file_modified++; 2303 file_modified++;
2306} 2304}
2307 2305
2308static void undo_pop(void) // Undo the last operation 2306static void undo_pop(void) // Undo the last operation
2309{ 2307{
2310 int repeat = 0; 2308 int repeat;
2311 char *u_start, *u_end; 2309 char *u_start, *u_end;
2312 struct undo_object *undo_temp; 2310 struct undo_object *undo_entry;
2313 2311
2314 // Commit pending undo queue before popping (should be unnecessary) 2312 // Commit pending undo queue before popping (should be unnecessary)
2315 undo_queue_commit(); 2313 undo_queue_commit();
2316 2314
2315 undo_entry = undo_stack_tail;
2317 // Check for an empty undo stack 2316 // Check for an empty undo stack
2318 if (undo_stack_tail == NULL) { 2317 if (!undo_entry) {
2319 status_line("Already at oldest change"); 2318 status_line("Already at oldest change");
2320 return; 2319 return;
2321 } 2320 }
2322 2321
2323 switch (undo_stack_tail->u_type) { 2322 switch (undo_entry->u_type) {
2324 case UNDO_DEL: 2323 case UNDO_DEL:
2325 case UNDO_DEL_CHAIN: 2324 case UNDO_DEL_CHAIN:
2326 // make hole and put in text that was deleted; deallocate text 2325 // make hole and put in text that was deleted; deallocate text
2327 u_start = text + undo_stack_tail->start; 2326 u_start = text + undo_entry->start;
2328 text_hole_make(u_start, undo_stack_tail->length); 2327 text_hole_make(u_start, undo_entry->length);
2329 memcpy(u_start, undo_stack_tail->undo_text, undo_stack_tail->length); 2328 memcpy(u_start, undo_entry->undo_text, undo_entry->length);
2330 free(undo_stack_tail->undo_text); 2329 free(undo_entry->undo_text);
2331 status_line("Undo [%d] %s %d chars at position %d", 2330 status_line("Undo [%d] %s %d chars at position %d",
2332 file_modified, "restored", 2331 file_modified, "restored",
2333 undo_stack_tail->length, undo_stack_tail->start); 2332 undo_entry->length, undo_entry->start
2333 );
2334 break; 2334 break;
2335 case UNDO_INS: 2335 case UNDO_INS:
2336 case UNDO_INS_CHAIN: 2336 case UNDO_INS_CHAIN:
2337 // delete what was inserted 2337 // delete what was inserted
2338 u_start = undo_stack_tail->start + text; 2338 u_start = undo_entry->start + text;
2339 u_end = u_start - 1 + undo_stack_tail->length; 2339 u_end = u_start - 1 + undo_entry->length;
2340 text_hole_delete(u_start, u_end, NO_UNDO); 2340 text_hole_delete(u_start, u_end, NO_UNDO);
2341 status_line("Undo [%d] %s %d chars at position %d", 2341 status_line("Undo [%d] %s %d chars at position %d",
2342 file_modified, "deleted", 2342 file_modified, "deleted",
2343 undo_stack_tail->length, undo_stack_tail->start); 2343 undo_entry->length, undo_entry->start
2344 );
2344 break; 2345 break;
2345 } 2346 }
2346 // For chained operations, continue popping all the way down the chain. 2347 repeat = 0;
2348 switch (undo_entry->u_type) {
2347 // If this is the end of a chain, lower modification count and refresh display 2349 // If this is the end of a chain, lower modification count and refresh display
2348 switch (undo_stack_tail->u_type) {
2349 case UNDO_DEL: 2350 case UNDO_DEL:
2350 case UNDO_INS: 2351 case UNDO_INS:
2351 dot = (text + undo_stack_tail->start); 2352 dot = (text + undo_entry->start);
2352 refresh(FALSE); 2353 refresh(FALSE);
2353 break; 2354 break;
2354 case UNDO_DEL_CHAIN: 2355 case UNDO_DEL_CHAIN:
@@ -2357,11 +2358,11 @@ static void undo_pop(void) // Undo the last operation
2357 break; 2358 break;
2358 } 2359 }
2359 // Deallocate the undo object we just processed 2360 // Deallocate the undo object we just processed
2360 undo_temp = undo_stack_tail->prev; 2361 undo_stack_tail = undo_entry->prev;
2361 free(undo_stack_tail); 2362 free(undo_entry);
2362 undo_stack_tail = undo_temp;
2363 file_modified--; 2363 file_modified--;
2364 if (repeat == 1) { 2364 // For chained operations, continue popping all the way down the chain.
2365 if (repeat) {
2365 undo_pop(); // Follow the undo chain if one exists 2366 undo_pop(); // Follow the undo chain if one exists
2366 } 2367 }
2367} 2368}
@@ -2372,7 +2373,7 @@ static void undo_queue_commit(void) // Flush any queued objects to the undo stac
2372 // Pushes the queue object onto the undo stack 2373 // Pushes the queue object onto the undo stack
2373 if (undo_q > 0) { 2374 if (undo_q > 0) {
2374 // Deleted character undo events grow from the end 2375 // Deleted character undo events grow from the end
2375 undo_push((undo_queue + CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q), 2376 undo_push(undo_queue + CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q,
2376 undo_q, 2377 undo_q,
2377 (undo_queue_state | UNDO_USE_SPOS) 2378 (undo_queue_state | UNDO_USE_SPOS)
2378 ); 2379 );