some lint, some bug fixes, ^C handling improvements
[unix-history] / usr / src / contrib / ed / d.c
CommitLineData
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 12static 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
29static 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
38void
39d(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 116static void
289588f2 117d_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
135void
136d_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}