1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rodney Ruddock of the University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)u.c 5.2 (Berkeley) 01/23/93"; 13 #endif /* not lint */ 14 15 #include <sys/types.h> 16 17 #include <db.h> 18 #include <regex.h> 19 #include <setjmp.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include "ed.h" 25 #include "extern.h" 26 27 /* 28 * This restores the buffer to the state it was in just before the 29 * last buffer modifying command - the global commands (with command 30 * list) are looked at as one buffer modifying command. Note: this 31 * just manipulates the undo stack (u_stk); x-ref u_add_stk(), 32 * u_clr_stk(), d_add(), and d_do(). 33 */ 34 void 35 u(inputt, errnum) 36 FILE *inputt; 37 int *errnum; 38 { 39 if (rol(inputt, errnum)) 40 return; 41 42 if (u_stk == NULL) { 43 *errnum = 1; 44 return; 45 } 46 undo(); 47 *errnum = 1; 48 } 49 50 51 /* This function does the "real work" of the undo. */ 52 void 53 undo() 54 { 55 LINE *l_current, *l_bottom, *l_top; 56 struct u_layer *l_old_u_stk, *l_temp; 57 58 /* This is done because undo can be undone. */ 59 l_current = u_current; 60 l_top = u_top; 61 l_bottom = u_bottom; 62 63 u_current = current; 64 u_top = top; 65 u_bottom = bottom; 66 67 l_old_u_stk = u_stk; 68 u_stk = NULL; 69 70 while (l_old_u_stk != NULL) { 71 u_add_stk(l_old_u_stk->cell); 72 (*(l_old_u_stk->cell)) = (l_old_u_stk->val); 73 l_temp = l_old_u_stk; 74 l_old_u_stk = l_old_u_stk->below; 75 free(l_temp); 76 } 77 78 current = l_current; 79 top = l_top; 80 bottom = l_bottom; 81 } 82 83 /* 84 * This function should be called before u_add_stk is in each command 85 * function, _except_ when the global flag is high (>0) -- otherwise, 86 * we couldn't undo all of the global commands, only the last iteration 87 * of the last command -- and the u command. 88 * This is where we begin to dispose of ed's undo knowledge of a line. 89 * The call to d_do() gets rid of the rest. 90 */ 91 void 92 u_clr_stk() 93 { 94 register struct u_layer *l_temp; 95 96 u_current = current; 97 u_top = top; 98 u_bottom = bottom; 99 100 /* Only if there is something to delete in the buffer. */ 101 if ((u_stk) && (d_stk)) 102 d_do(); 103 104 while (u_stk != NULL) { 105 l_temp = u_stk; 106 u_stk = u_stk->below; 107 free(l_temp); 108 } 109 u_stk = NULL; /* Just to sure. */ 110 } 111 112 /* 113 * Place the addresses of and the pointer values of the LINE structures 114 * that are being changed on the undo stack. This is a quick, simple, 115 * and effective way to preserve what could be be brought back on request 116 * without keeping a copy of every bleep'n thing. 117 */ 118 void 119 u_add_stk(in) 120 LINE **in; 121 { 122 register struct u_layer *l_now; 123 124 if (in == NULL) 125 return; 126 l_now = malloc(sizeof(struct u_layer)); 127 if (l_now == NULL) { 128 strcpy(help_msg, "undo: out of memory error"); 129 return; 130 } 131 if (u_stk == NULL) 132 (l_now->below) = NULL; 133 else 134 (l_now->below) = u_stk; 135 u_stk = l_now; 136 (u_stk->cell) = in; 137 (u_stk->val) = (*(u_stk->cell)); 138 } 139