xref: /original-bsd/contrib/ed/d.c (revision 05bf53f3)
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
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
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
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