157702Sbostic /*- 257702Sbostic * Copyright (c) 1992 The Regents of the University of California. 357702Sbostic * All rights reserved. 457702Sbostic * 557702Sbostic * This code is derived from software contributed to Berkeley by 657702Sbostic * Rodney Ruddock of the University of Guelph. 757702Sbostic * 857702Sbostic * %sccs.include.redist.c% 957702Sbostic */ 1057702Sbostic 1157702Sbostic #ifndef lint 12*59475Sbostic static char sccsid[] = "@(#)u.c 5.4 (Berkeley) 04/28/93"; 1357702Sbostic #endif /* not lint */ 1457702Sbostic 1557710Sbostic #include <sys/types.h> 1657710Sbostic 1757710Sbostic #include <regex.h> 1857710Sbostic #include <setjmp.h> 1957710Sbostic #include <stdio.h> 2057710Sbostic #include <stdlib.h> 2157710Sbostic #include <string.h> 2257710Sbostic 2358315Sbostic #ifdef DBI 2458315Sbostic #include <db.h> 2558315Sbostic #endif 2658315Sbostic 2757702Sbostic #include "ed.h" 2857710Sbostic #include "extern.h" 2957702Sbostic 3057702Sbostic /* 3157702Sbostic * This restores the buffer to the state it was in just before the 3257702Sbostic * last buffer modifying command - the global commands (with command 3357702Sbostic * list) are looked at as one buffer modifying command. Note: this 3457702Sbostic * just manipulates the undo stack (u_stk); x-ref u_add_stk(), 3557702Sbostic * u_clr_stk(), d_add(), and d_do(). 3657702Sbostic */ 3757702Sbostic void 3857702Sbostic u(inputt, errnum) 3957710Sbostic FILE *inputt; 4057710Sbostic int *errnum; 4157702Sbostic { 4257710Sbostic if (rol(inputt, errnum)) 4357710Sbostic return; 44*59475Sbostic undo(); /* call even when u_stk==nil */ 4557710Sbostic *errnum = 1; 4657710Sbostic } 4757702Sbostic 4857702Sbostic 49*59475Sbostic /* This function does the "real work" of the undo. 50*59475Sbostic * It is separated out from u() so that the SIGHUP handling 51*59475Sbostic * routine can call it without dealing with rol(), in turn so that 52*59475Sbostic * the buffer is in a "good" state when saved to the 'ed.hup' file. 53*59475Sbostic */ 5457702Sbostic void 5557702Sbostic undo() 5657702Sbostic { 5757710Sbostic LINE *l_current, *l_bottom, *l_top; 5857710Sbostic struct u_layer *l_old_u_stk, *l_temp; 5957702Sbostic 6058315Sbostic sigspecial++; 6157710Sbostic /* This is done because undo can be undone. */ 6257710Sbostic l_current = u_current; 6357710Sbostic l_top = u_top; 6457710Sbostic l_bottom = u_bottom; 6557702Sbostic 6657710Sbostic u_current = current; 6757710Sbostic u_top = top; 6857710Sbostic u_bottom = bottom; 6957702Sbostic 7057710Sbostic l_old_u_stk = u_stk; 7157710Sbostic u_stk = NULL; 7257702Sbostic 7357710Sbostic while (l_old_u_stk != NULL) { 7457710Sbostic u_add_stk(l_old_u_stk->cell); 7557710Sbostic (*(l_old_u_stk->cell)) = (l_old_u_stk->val); 7657710Sbostic l_temp = l_old_u_stk; 7757710Sbostic l_old_u_stk = l_old_u_stk->below; 7857710Sbostic free(l_temp); 7957710Sbostic } 8057702Sbostic 8157710Sbostic current = l_current; 8257710Sbostic top = l_top; 8357710Sbostic bottom = l_bottom; 8458315Sbostic sigspecial--; 8558315Sbostic if (sigint_flag && (!sigspecial)) 8658315Sbostic SIGINT_ACTION; 8757710Sbostic } 8857702Sbostic 89*59475Sbostic 9057710Sbostic /* 9157710Sbostic * This function should be called before u_add_stk is in each command 9257702Sbostic * function, _except_ when the global flag is high (>0) -- otherwise, 9357702Sbostic * we couldn't undo all of the global commands, only the last iteration 9457702Sbostic * of the last command -- and the u command. 9557702Sbostic * This is where we begin to dispose of ed's undo knowledge of a line. 9657702Sbostic * The call to d_do() gets rid of the rest. 9757702Sbostic */ 9857702Sbostic void 9957702Sbostic u_clr_stk() 10057702Sbostic { 10157710Sbostic register struct u_layer *l_temp; 10257702Sbostic 10357710Sbostic u_current = current; 10457710Sbostic u_top = top; 10557710Sbostic u_bottom = bottom; 10657702Sbostic 10758315Sbostic sigspecial++; 10857710Sbostic /* Only if there is something to delete in the buffer. */ 10957710Sbostic if ((u_stk) && (d_stk)) 11057710Sbostic d_do(); 11157702Sbostic 11257710Sbostic while (u_stk != NULL) { 11357710Sbostic l_temp = u_stk; 11457710Sbostic u_stk = u_stk->below; 11557710Sbostic free(l_temp); 11657710Sbostic } 11757710Sbostic u_stk = NULL; /* Just to sure. */ 11858315Sbostic sigspecial--; 11958315Sbostic if (sigint_flag && (!sigspecial)) 12058315Sbostic SIGINT_ACTION; 12157710Sbostic } 12257702Sbostic 12357702Sbostic /* 12457702Sbostic * Place the addresses of and the pointer values of the LINE structures 12557710Sbostic * that are being changed on the undo stack. This is a quick, simple, 12657710Sbostic * and effective way to preserve what could be be brought back on request 12757710Sbostic * without keeping a copy of every bleep'n thing. 12857702Sbostic */ 12957702Sbostic void 13057702Sbostic u_add_stk(in) 13157710Sbostic LINE **in; 13257702Sbostic { 13357710Sbostic register struct u_layer *l_now; 13457702Sbostic 13557710Sbostic if (in == NULL) 13657710Sbostic return; 13757710Sbostic l_now = malloc(sizeof(struct u_layer)); 13857710Sbostic if (l_now == NULL) { 13957710Sbostic strcpy(help_msg, "undo: out of memory error"); 14057710Sbostic return; 14157710Sbostic } 14258315Sbostic sigspecial++; 14357710Sbostic if (u_stk == NULL) 14457710Sbostic (l_now->below) = NULL; 14557710Sbostic else 14657710Sbostic (l_now->below) = u_stk; 14757710Sbostic u_stk = l_now; 14857710Sbostic (u_stk->cell) = in; 14957710Sbostic (u_stk->val) = (*(u_stk->cell)); 15058315Sbostic sigspecial--; 15158315Sbostic if (sigint_flag && (!sigspecial)) 15258315Sbostic SIGINT_ACTION; 15357710Sbostic } 154*59475Sbostic 155*59475Sbostic 156*59475Sbostic /* This 'u' function is just for when 's' notices that a series 157*59475Sbostic * of adjacent lines are changing. It reduces the undo stack height 158*59475Sbostic * and lowers the number of (costly) malloc's with reuse. For 159*59475Sbostic * the environmentally aware the third 'R' is with the 'g' code. 160*59475Sbostic */ 161*59475Sbostic 162*59475Sbostic void 163*59475Sbostic u_pop_n_swap(in) 164*59475Sbostic LINE **in; 165*59475Sbostic { 166*59475Sbostic sigspecial++; 167*59475Sbostic /* put the old value back */ 168*59475Sbostic (*(u_stk->cell)) = (u_stk->val); 169*59475Sbostic /* put the new values */ 170*59475Sbostic (u_stk->cell) = in; 171*59475Sbostic (u_stk->val) = (*(u_stk->cell)); 172*59475Sbostic sigspecial--; 173*59475Sbostic if (sigint_flag && (!sigspecial)) 174*59475Sbostic SIGINT_ACTION; 175*59475Sbostic } 176