xref: /csrg-svn/contrib/ed/d.c (revision 60663)
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