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[] = "@(#)d.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 static void d_add __P((LINE *, LINE *)); 28 29 /* 30 * This removes lines in the buffer from user access. The specified 31 * lines are not really deleted yet(!) as they might be called back 32 * by an undo. So the pointers from start, End, and neighbours are placed 33 * in a stack for deletion later when no undo can be performed on these lines. 34 * The lines in the buffer are freed then as well. 35 */ 36 void 37 d(inputt, errnum) 38 FILE *inputt; 39 int *errnum; 40 { 41 LINE *l_temp1, *l_temp2; 42 43 if (start_default && End_default) 44 start = End = current; 45 else 46 if (start_default) 47 start = End; 48 if (start == NULL) { 49 strcpy(help_msg, "bad address"); 50 *errnum = -1; 51 return; 52 } 53 start_default = End_default = 0; 54 55 if (rol(inputt, errnum)) 56 return; 57 58 if ((u_set == 0) && (g_flag == 0)) 59 u_clr_stk(); /* for undo */ 60 61 if ((start == NULL) && (End == NULL)) { /* nothing to do... */ 62 *errnum = 1; 63 return; 64 } 65 if (sigint_flag) 66 SIGINT_ACTION; 67 68 d_add(start, End); /* for buffer clearing later(!) */ 69 70 /* 71 * Now change preserve the pointers in case of undo and then adjust 72 * them. 73 */ 74 if (start == top) { 75 top = End->below; 76 if (top != NULL) { 77 u_add_stk(&(top->above)); 78 (top->above) = NULL; 79 } 80 } else { 81 l_temp1 = start->above; 82 u_add_stk(&(l_temp1->below)); 83 (l_temp1->below) = End->below; 84 } 85 86 if (End == bottom) { 87 bottom = start->above; 88 current = bottom; 89 } else { 90 l_temp2 = End->below; 91 u_add_stk(&(l_temp2->above)); 92 (l_temp2->above) = start->above; 93 current = l_temp2; 94 } 95 96 /* To keep track of the marks. */ 97 ku_chk(start, End, NULL); 98 change_flag = 1L; 99 100 if (sigint_flag) /* next stable spot */ 101 SIGINT_ACTION; 102 103 if (start == End) { 104 *errnum = 1; 105 return; 106 } 107 *errnum = 1; 108 } 109 110 111 /* 112 * This keeps a stack of the start and end lines deleted for clean-up 113 * later (in d_do()). A stack is used because of the global commands. 114 */ 115 static void 116 d_add(top_d, bottom_d) 117 LINE *top_d, *bottom_d; 118 { 119 struct d_layer *l_temp; 120 121 l_temp = malloc(sizeof(struct d_layer)); 122 (l_temp->begin) = top_d; 123 (l_temp->end) = bottom_d; 124 (l_temp->next) = d_stk; 125 d_stk = l_temp; 126 127 } 128 129 /* 130 * This cleans up the LINE structures deleted and no longer accessible 131 * to undo. It performs garbage clean-up on the now non-referenced 132 * text in the buffer. 133 */ 134 void 135 d_do() 136 { 137 struct d_layer *l_temp; 138 DBT l_db_key; 139 LINE *l_temp2, *l_temp3; 140 int l_flag; 141 142 l_temp = d_stk; 143 do { 144 l_flag = 0; 145 l_temp2 = l_temp->begin; 146 do { 147 l_temp3 = l_temp2; 148 /* 149 * We do it, but db(3) says it doesn't really do it 150 * yet. 151 */ 152 l_db_key.size = sizeof(recno_t); 153 l_db_key.data = &(l_temp2->handle); 154 (dbhtmp->del) (dbhtmp, &l_db_key, (u_int) 0); 155 if ((l_temp->end) == l_temp2) 156 l_flag = 1; 157 l_temp2 = l_temp3->below; 158 free(l_temp3); 159 } while (l_flag == 0); 160 161 d_stk = d_stk->next; 162 free(l_temp); 163 l_temp = d_stk; 164 } while (d_stk); 165 166 d_stk = NULL; /* just to be sure */ 167 } 168