157679Sbostic /*-
2*60663Sbostic * Copyright (c) 1992, 1993
3*60663Sbostic * The Regents of the University of California. All rights reserved.
457679Sbostic *
557679Sbostic * This code is derived from software contributed to Berkeley by
657679Sbostic * Rodney Ruddock of the University of Guelph.
757679Sbostic *
857679Sbostic * %sccs.include.redist.c%
957679Sbostic */
1057679Sbostic
1157679Sbostic #ifndef lint
12*60663Sbostic static char sccsid[] = "@(#)d.c 8.1 (Berkeley) 05/31/93";
1357679Sbostic #endif /* not lint */
1457679Sbostic
1557710Sbostic #include <sys/types.h>
1657710Sbostic
1758315Sbostic #ifdef DBI
1857710Sbostic #include <db.h>
1958315Sbostic #endif
2057710Sbostic #include <regex.h>
2157710Sbostic #include <setjmp.h>
2257710Sbostic #include <stdio.h>
2357710Sbostic #include <stdlib.h>
2457710Sbostic #include <string.h>
2557710Sbostic
2657679Sbostic #include "ed.h"
2757710Sbostic #include "extern.h"
2857679Sbostic
2957710Sbostic static void d_add __P((LINE *, LINE *));
3057710Sbostic
3157679Sbostic /*
3257679Sbostic * This removes lines in the buffer from user access. The specified
3357679Sbostic * lines are not really deleted yet(!) as they might be called back
3458564Sralph * by an undo. So the pointers from Start, End, and neighbours are placed
3557679Sbostic * in a stack for deletion later when no undo can be performed on these lines.
3657679Sbostic * The lines in the buffer are freed then as well.
3757679Sbostic */
3857679Sbostic void
d(inputt,errnum)3957679Sbostic d(inputt, errnum)
4057710Sbostic FILE *inputt;
4157710Sbostic int *errnum;
4257679Sbostic {
4357710Sbostic LINE *l_temp1, *l_temp2;
4457679Sbostic
4558564Sralph if (Start_default && End_default)
4658564Sralph Start = End = current;
4757710Sbostic else
4858564Sralph if (Start_default)
4958564Sralph Start = End;
5058564Sralph if (Start == NULL) {
5158315Sbostic strcpy(help_msg, "buffer empty");
5257710Sbostic *errnum = -1;
5357710Sbostic return;
5457710Sbostic }
5558564Sralph Start_default = End_default = 0;
5657679Sbostic
5758315Sbostic if (join_flag == 0) {
5858315Sbostic if (rol(inputt, errnum))
5958315Sbostic return;
6058315Sbostic }
6158315Sbostic else
6258315Sbostic ss = getc(inputt); /* fed back from join */
6357679Sbostic
6457710Sbostic if ((u_set == 0) && (g_flag == 0))
6557710Sbostic u_clr_stk(); /* for undo */
6657679Sbostic
6758564Sralph if ((Start == NULL) && (End == NULL)) { /* nothing to do... */
6857710Sbostic *errnum = 1;
6957710Sbostic return;
7057710Sbostic }
7157679Sbostic
7258564Sralph d_add(Start, End); /* for buffer clearing later(!) */
7357679Sbostic
7457710Sbostic /*
7558315Sbostic * Now change & preserve the pointers in case of undo and then adjust
7657710Sbostic * them.
7757710Sbostic */
7858315Sbostic sigspecial++;
7958564Sralph if (Start == top) {
8057710Sbostic top = End->below;
8157710Sbostic if (top != NULL) {
8257710Sbostic u_add_stk(&(top->above));
8357710Sbostic (top->above) = NULL;
8457710Sbostic }
8557710Sbostic } else {
8658564Sralph l_temp1 = Start->above;
8757710Sbostic u_add_stk(&(l_temp1->below));
8857710Sbostic (l_temp1->below) = End->below;
8957710Sbostic }
9057679Sbostic
9157710Sbostic if (End == bottom) {
9258564Sralph bottom = Start->above;
9357710Sbostic current = bottom;
9457710Sbostic } else {
9557710Sbostic l_temp2 = End->below;
9657710Sbostic u_add_stk(&(l_temp2->above));
9758564Sralph (l_temp2->above) = Start->above;
9857710Sbostic current = l_temp2;
9957710Sbostic }
10057679Sbostic
10157710Sbostic /* To keep track of the marks. */
10258564Sralph ku_chk(Start, End, NULL);
10357710Sbostic change_flag = 1L;
10457679Sbostic
10558315Sbostic *errnum = 1;
10658315Sbostic sigspecial--;
10758315Sbostic if (sigint_flag && (!sigspecial)) /* next stable spot */
10857710Sbostic SIGINT_ACTION;
10957710Sbostic }
11057679Sbostic
11157679Sbostic
11257679Sbostic /*
11357679Sbostic * This keeps a stack of the start and end lines deleted for clean-up
11457679Sbostic * later (in d_do()). A stack is used because of the global commands.
11557679Sbostic */
11657710Sbostic static void
d_add(top_d,bottom_d)11757679Sbostic d_add(top_d, bottom_d)
11857710Sbostic LINE *top_d, *bottom_d;
11957679Sbostic {
12057710Sbostic struct d_layer *l_temp;
12157679Sbostic
12257710Sbostic l_temp = malloc(sizeof(struct d_layer));
12357710Sbostic (l_temp->begin) = top_d;
12457710Sbostic (l_temp->end) = bottom_d;
12557710Sbostic (l_temp->next) = d_stk;
12657710Sbostic d_stk = l_temp;
12757679Sbostic
12857710Sbostic }
12957679Sbostic
13057679Sbostic /*
13157679Sbostic * This cleans up the LINE structures deleted and no longer accessible
13257679Sbostic * to undo. It performs garbage clean-up on the now non-referenced
13357710Sbostic * text in the buffer.
13457679Sbostic */
13557679Sbostic void
d_do()13657679Sbostic d_do()
13757679Sbostic {
13857710Sbostic struct d_layer *l_temp;
13958315Sbostic #ifdef DBI
14057710Sbostic DBT l_db_key;
14158315Sbostic #endif
14257710Sbostic LINE *l_temp2, *l_temp3;
14357710Sbostic int l_flag;
14457679Sbostic
14557710Sbostic l_temp = d_stk;
14658315Sbostic sigspecial++;
14757710Sbostic do {
14857710Sbostic l_flag = 0;
14957710Sbostic l_temp2 = l_temp->begin;
15057710Sbostic do {
15157710Sbostic l_temp3 = l_temp2;
15258315Sbostic #ifdef STDIO
15358315Sbostic /* no garbage collection done currently */
15458315Sbostic #endif
15558315Sbostic #ifdef DBI
15660655Sbostic /* garbage collection should be done iff the
15760655Sbostic * open was done as btree, not recno.
15860655Sbostic */
15957710Sbostic l_db_key.size = sizeof(recno_t);
16057710Sbostic l_db_key.data = &(l_temp2->handle);
16157710Sbostic (dbhtmp->del) (dbhtmp, &l_db_key, (u_int) 0);
16258315Sbostic #endif
16358315Sbostic #ifdef MEMORY
16458315Sbostic free(l_temp2->handle);
16558315Sbostic #endif
16657710Sbostic if ((l_temp->end) == l_temp2)
16757710Sbostic l_flag = 1;
16857710Sbostic l_temp2 = l_temp3->below;
16957710Sbostic free(l_temp3);
17057710Sbostic } while (l_flag == 0);
17157679Sbostic
17257710Sbostic d_stk = d_stk->next;
17357710Sbostic free(l_temp);
17457710Sbostic l_temp = d_stk;
17557710Sbostic } while (d_stk);
17657679Sbostic
17757710Sbostic d_stk = NULL; /* just to be sure */
17858315Sbostic sigspecial--;
17958315Sbostic if (sigint_flag && (!sigspecial))
18058315Sbostic SIGINT_ACTION;
18157710Sbostic }
182