4.4BSD/usr/src/contrib/ed/d.c

Compare this file to the similar file:
Show the results in this format:

/*-
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rodney Ruddock of the University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef lint
static char sccsid[] = "@(#)d.c	8.1 (Berkeley) 5/31/93";
#endif /* not lint */

#include <sys/types.h>

#ifdef DBI
#include <db.h>
#endif
#include <regex.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ed.h"
#include "extern.h"

static void d_add __P((LINE *, LINE *));

/*
 * This removes lines in the buffer from user access. The specified
 * lines are not really deleted yet(!) as they might be called back
 * by an undo. So the pointers from Start, End, and neighbours are placed
 * in a stack for deletion later when no undo can be performed on these lines.
 * The lines in the buffer are freed then as well.
 */
void
d(inputt, errnum)
	FILE *inputt;
	int *errnum;
{
	LINE *l_temp1, *l_temp2;

	if (Start_default && End_default)
		Start = End = current;
	else
		if (Start_default)
			Start = End;
	if (Start == NULL) {
		strcpy(help_msg, "buffer empty");
		*errnum = -1;
		return;
	}
	Start_default = End_default = 0;

	if (join_flag == 0) {
		if (rol(inputt, errnum))
			return;
	}
	else
		ss = getc(inputt); /* fed back from join */

	if ((u_set == 0) && (g_flag == 0))
		u_clr_stk();	/* for undo */

	if ((Start == NULL) && (End == NULL)) {	/* nothing to do... */
		*errnum = 1;
		return;
	}

	d_add(Start, End);	/* for buffer clearing later(!) */

	/*
	 * Now change & preserve the pointers in case of undo and then adjust
	 * them.
	 */
	sigspecial++;
	if (Start == top) {
		top = End->below;
		if (top != NULL) {
			u_add_stk(&(top->above));
			(top->above) = NULL;
		}
	} else {
		l_temp1 = Start->above;
		u_add_stk(&(l_temp1->below));
		(l_temp1->below) = End->below;
	}

	if (End == bottom) {
		bottom = Start->above;
		current = bottom;
	} else {
		l_temp2 = End->below;
		u_add_stk(&(l_temp2->above));
		(l_temp2->above) = Start->above;
		current = l_temp2;
	}

	/* To keep track of the marks. */
	ku_chk(Start, End, NULL);
	change_flag = 1L;

	*errnum = 1;
	sigspecial--;
	if (sigint_flag && (!sigspecial))	/* next stable spot */
		SIGINT_ACTION;
}


/*
 * This keeps a stack of the start and end lines deleted for clean-up
 * later (in d_do()). A stack is used because of the global commands.
 */
static void
d_add(top_d, bottom_d)
	LINE *top_d, *bottom_d;
{
	struct d_layer *l_temp;

	l_temp = malloc(sizeof(struct d_layer));
	(l_temp->begin) = top_d;
	(l_temp->end) = bottom_d;
	(l_temp->next) = d_stk;
	d_stk = l_temp;

}

/*
 * This cleans up the LINE structures deleted and no longer accessible
 * to undo. It performs garbage clean-up on the now non-referenced
 * text in the buffer.
 */
void
d_do()
{
	struct d_layer *l_temp;
#ifdef DBI
	DBT l_db_key;
#endif
	LINE *l_temp2, *l_temp3;
	int l_flag;

	l_temp = d_stk;
	sigspecial++;
	do {
		l_flag = 0;
		l_temp2 = l_temp->begin;
		do {
			l_temp3 = l_temp2;
#ifdef STDIO
			/* no garbage collection done currently */
#endif
#ifdef DBI
			/* garbage collection should be done iff the
			 * open was done as btree, not recno.
			 */
			l_db_key.size = sizeof(recno_t);
			l_db_key.data = &(l_temp2->handle);
			(dbhtmp->del) (dbhtmp, &l_db_key, (u_int) 0);
#endif
#ifdef MEMORY
			free(l_temp2->handle);
#endif
			if ((l_temp->end) == l_temp2)
				l_flag = 1;
			l_temp2 = l_temp3->below;
			free(l_temp3);
		} while (l_flag == 0);

		d_stk = d_stk->next;
		free(l_temp);
		l_temp = d_stk;
	} while (d_stk);

	d_stk = NULL;		/* just to be sure */
	sigspecial--;
	if (sigint_flag && (!sigspecial))
		SIGINT_ACTION;
}