Commit | Line | Data |
---|---|---|
289588f2 KB |
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 | |
e692f66f | 12 | static char sccsid[] = "@(#)d.c 5.3 (Berkeley) %G%"; |
289588f2 KB |
13 | #endif /* not lint */ |
14 | ||
ecbf4ad0 KB |
15 | #include <sys/types.h> |
16 | ||
e692f66f | 17 | #ifdef DBI |
ecbf4ad0 | 18 | #include <db.h> |
e692f66f | 19 | #endif |
ecbf4ad0 KB |
20 | #include <regex.h> |
21 | #include <setjmp.h> | |
22 | #include <stdio.h> | |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | ||
289588f2 | 26 | #include "ed.h" |
ecbf4ad0 KB |
27 | #include "extern.h" |
28 | ||
29 | static void d_add __P((LINE *, LINE *)); | |
289588f2 KB |
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 | */ | |
289588f2 KB |
38 | void |
39 | d(inputt, errnum) | |
ecbf4ad0 KB |
40 | FILE *inputt; |
41 | int *errnum; | |
289588f2 | 42 | { |
ecbf4ad0 KB |
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) { | |
e692f66f | 51 | strcpy(help_msg, "buffer empty"); |
ecbf4ad0 KB |
52 | *errnum = -1; |
53 | return; | |
54 | } | |
55 | start_default = End_default = 0; | |
56 | ||
e692f66f KB |
57 | if (join_flag == 0) { |
58 | if (rol(inputt, errnum)) | |
59 | return; | |
60 | } | |
61 | else | |
62 | ss = getc(inputt); /* fed back from join */ | |
ecbf4ad0 KB |
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 | } | |
ecbf4ad0 KB |
71 | |
72 | d_add(start, End); /* for buffer clearing later(!) */ | |
73 | ||
74 | /* | |
e692f66f | 75 | * Now change & preserve the pointers in case of undo and then adjust |
ecbf4ad0 KB |
76 | * them. |
77 | */ | |
e692f66f | 78 | sigspecial++; |
ecbf4ad0 KB |
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 | ||
ecbf4ad0 | 105 | *errnum = 1; |
e692f66f KB |
106 | sigspecial--; |
107 | if (sigint_flag && (!sigspecial)) /* next stable spot */ | |
108 | SIGINT_ACTION; | |
ecbf4ad0 | 109 | } |
289588f2 KB |
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 | */ | |
ecbf4ad0 | 116 | static void |
289588f2 | 117 | d_add(top_d, bottom_d) |
ecbf4ad0 | 118 | LINE *top_d, *bottom_d; |
289588f2 | 119 | { |
ecbf4ad0 | 120 | struct d_layer *l_temp; |
289588f2 | 121 | |
ecbf4ad0 KB |
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; | |
289588f2 | 127 | |
ecbf4ad0 | 128 | } |
289588f2 KB |
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 | |
ecbf4ad0 | 133 | * text in the buffer. |
289588f2 | 134 | */ |
289588f2 KB |
135 | void |
136 | d_do() | |
289588f2 | 137 | { |
ecbf4ad0 | 138 | struct d_layer *l_temp; |
e692f66f | 139 | #ifdef DBI |
ecbf4ad0 | 140 | DBT l_db_key; |
e692f66f | 141 | #endif |
ecbf4ad0 KB |
142 | LINE *l_temp2, *l_temp3; |
143 | int l_flag; | |
144 | ||
145 | l_temp = d_stk; | |
e692f66f | 146 | sigspecial++; |
ecbf4ad0 KB |
147 | do { |
148 | l_flag = 0; | |
149 | l_temp2 = l_temp->begin; | |
150 | do { | |
151 | l_temp3 = l_temp2; | |
e692f66f KB |
152 | #ifdef STDIO |
153 | /* no garbage collection done currently */ | |
154 | #endif | |
155 | #ifdef DBI | |
ecbf4ad0 KB |
156 | l_db_key.size = sizeof(recno_t); |
157 | l_db_key.data = &(l_temp2->handle); | |
158 | (dbhtmp->del) (dbhtmp, &l_db_key, (u_int) 0); | |
e692f66f KB |
159 | #endif |
160 | #ifdef MEMORY | |
161 | free(l_temp2->handle); | |
162 | #endif | |
ecbf4ad0 KB |
163 | if ((l_temp->end) == l_temp2) |
164 | l_flag = 1; | |
165 | l_temp2 = l_temp3->below; | |
166 | free(l_temp3); | |
167 | } while (l_flag == 0); | |
168 | ||
169 | d_stk = d_stk->next; | |
170 | free(l_temp); | |
171 | l_temp = d_stk; | |
172 | } while (d_stk); | |
173 | ||
174 | d_stk = NULL; /* just to be sure */ | |
e692f66f KB |
175 | sigspecial--; |
176 | if (sigint_flag && (!sigspecial)) | |
177 | SIGINT_ACTION; | |
ecbf4ad0 | 178 | } |