1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. 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 8.1 (Berkeley) 05/31/93";
13 #endif /* not lint */
14
15 #include <sys/types.h>
16
17 #ifdef DBI
18 #include <db.h>
19 #endif
20 #include <regex.h>
21 #include <setjmp.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "ed.h"
27 #include "extern.h"
28
29 static void d_add __P((LINE *, LINE *));
30
31 /*
32 * This removes lines in the buffer from user access. The specified
33 * lines are not really deleted yet(!) as they might be called back
34 * by an undo. So the pointers from Start, End, and neighbours are placed
35 * in a stack for deletion later when no undo can be performed on these lines.
36 * The lines in the buffer are freed then as well.
37 */
38 void
d(inputt,errnum)39 d(inputt, errnum)
40 FILE *inputt;
41 int *errnum;
42 {
43 LINE *l_temp1, *l_temp2;
44
45 if (Start_default && End_default)
46 Start = End = current;
47 else
48 if (Start_default)
49 Start = End;
50 if (Start == NULL) {
51 strcpy(help_msg, "buffer empty");
52 *errnum = -1;
53 return;
54 }
55 Start_default = End_default = 0;
56
57 if (join_flag == 0) {
58 if (rol(inputt, errnum))
59 return;
60 }
61 else
62 ss = getc(inputt); /* fed back from join */
63
64 if ((u_set == 0) && (g_flag == 0))
65 u_clr_stk(); /* for undo */
66
67 if ((Start == NULL) && (End == NULL)) { /* nothing to do... */
68 *errnum = 1;
69 return;
70 }
71
72 d_add(Start, End); /* for buffer clearing later(!) */
73
74 /*
75 * Now change & preserve the pointers in case of undo and then adjust
76 * them.
77 */
78 sigspecial++;
79 if (Start == top) {
80 top = End->below;
81 if (top != NULL) {
82 u_add_stk(&(top->above));
83 (top->above) = NULL;
84 }
85 } else {
86 l_temp1 = Start->above;
87 u_add_stk(&(l_temp1->below));
88 (l_temp1->below) = End->below;
89 }
90
91 if (End == bottom) {
92 bottom = Start->above;
93 current = bottom;
94 } else {
95 l_temp2 = End->below;
96 u_add_stk(&(l_temp2->above));
97 (l_temp2->above) = Start->above;
98 current = l_temp2;
99 }
100
101 /* To keep track of the marks. */
102 ku_chk(Start, End, NULL);
103 change_flag = 1L;
104
105 *errnum = 1;
106 sigspecial--;
107 if (sigint_flag && (!sigspecial)) /* next stable spot */
108 SIGINT_ACTION;
109 }
110
111
112 /*
113 * This keeps a stack of the start and end lines deleted for clean-up
114 * later (in d_do()). A stack is used because of the global commands.
115 */
116 static void
d_add(top_d,bottom_d)117 d_add(top_d, bottom_d)
118 LINE *top_d, *bottom_d;
119 {
120 struct d_layer *l_temp;
121
122 l_temp = malloc(sizeof(struct d_layer));
123 (l_temp->begin) = top_d;
124 (l_temp->end) = bottom_d;
125 (l_temp->next) = d_stk;
126 d_stk = l_temp;
127
128 }
129
130 /*
131 * This cleans up the LINE structures deleted and no longer accessible
132 * to undo. It performs garbage clean-up on the now non-referenced
133 * text in the buffer.
134 */
135 void
d_do()136 d_do()
137 {
138 struct d_layer *l_temp;
139 #ifdef DBI
140 DBT l_db_key;
141 #endif
142 LINE *l_temp2, *l_temp3;
143 int l_flag;
144
145 l_temp = d_stk;
146 sigspecial++;
147 do {
148 l_flag = 0;
149 l_temp2 = l_temp->begin;
150 do {
151 l_temp3 = l_temp2;
152 #ifdef STDIO
153 /* no garbage collection done currently */
154 #endif
155 #ifdef DBI
156 /* garbage collection should be done iff the
157 * open was done as btree, not recno.
158 */
159 l_db_key.size = sizeof(recno_t);
160 l_db_key.data = &(l_temp2->handle);
161 (dbhtmp->del) (dbhtmp, &l_db_key, (u_int) 0);
162 #endif
163 #ifdef MEMORY
164 free(l_temp2->handle);
165 #endif
166 if ((l_temp->end) == l_temp2)
167 l_flag = 1;
168 l_temp2 = l_temp3->below;
169 free(l_temp3);
170 } while (l_flag == 0);
171
172 d_stk = d_stk->next;
173 free(l_temp);
174 l_temp = d_stk;
175 } while (d_stk);
176
177 d_stk = NULL; /* just to be sure */
178 sigspecial--;
179 if (sigint_flag && (!sigspecial))
180 SIGINT_ACTION;
181 }
182