This is mark.c in view mode; [Download] [Up]
/* mark.c */
/* Copyright 1995 by Steve Kirkendall */
char id_mark[] = "$Id: mark.c,v 2.10 1996/05/30 17:39:04 steve Exp $";
#include "elvis.h"
MARK namedmark[26];
/* Allocate a mark, pointing to a specific location in a specific buffer. As changes are
* make to the buffer, the mark's offset into that buffer will automatically be updated.
*/
#ifndef DEBUG_ALLOC
MARK markalloc(buffer, offset)
BUFFER buffer; /* the buffer that the new mark will refer to */
long offset; /* position of the mark within buffer */
{
MARK newp;
newp = (MARK)safealloc(1, sizeof(MARKBUF));
#else
MARK _markalloc(file, line, buffer, offset)
char *file; /* source file where allocating */
int line; /* source line where allocating */
BUFFER buffer; /* the buffer that the new mark will refer to */
long offset; /* position of the mark within buffer */
{
MARK newp;
assert(buffer != NULL && offset >= 0 && offset <= o_bufchars(buffer));
newp = (MARK)_safealloc(file, line, False, 1, sizeof(MARKBUF));
#endif
newp->buffer = buffer;
newp->offset = offset;
newp->next = bufmarks(buffer);
bufsetmarks(buffer, newp);
return newp;
}
/* Free a mark which was created by markalloc(). This also adjusts the
* namedmarks[] array, if necessary.
*/
#ifndef DEBUG_ALLOC
void markfree(mark)
MARK mark; /* the mark to destroy */
{
#else
void _markfree(file, line, mark)
char *file;
int line;
MARK mark;
{
#endif
MARK lag;
int i;
/* remove from buffer's list of marks */
if (mark == bufmarks(mark->buffer))
{
bufsetmarks(mark->buffer, mark->next);
}
else
{
for (lag = bufmarks(mark->buffer); lag->next != mark; lag = lag->next)
{
assert(lag->next);
}
lag->next = mark->next;
}
/* if in namedmarks, then unset the namedmarks variable */
for (i = 0; i < QTY(namedmark); i++)
{
if (namedmark[i] == mark)
{
namedmark[i] = NULL;
break;
}
}
/* free the mark's resources */
#ifndef DEBUG_ALLOC
safefree(mark);
#else
_safefree(file, line, mark);
#endif
}
/* Adjust the offset of every who's offset is greater than "from". If at "to"
* or later, add "delta" to it. Between "from" and "to", add some fraction
* of "delta" to it.
*
* This function is meant to be called only from bufreplace().
*/
void markadjust(from, to, delta)
MARK from; /* old start of text */
MARK to; /* old end of text */
long delta; /* difference between old "to" and new "to" offsets */
{
MARK mark; /* used for scanning the buffer's mark list */
long dist; /* original distance between "from" and "to" */
long tooff; /* original offset of "to" */
long fromoff;/* original offset of "from" */
/* trivial case */
if (delta == 0)
{
return;
}
/* Compute some stuff that depends on the "to" mark. Note that we
* must do this before the loop, because during the loop we may adjust
* the value of the "to" mark itself!
*/
tooff = to->offset;
fromoff = from->offset;
dist = tooff - fromoff;
assert(from->buffer == to->buffer && -delta <= dist && dist >= 0);
/* for every mark... */
for (mark = bufmarks(from->buffer); mark; mark = mark->next)
{
/* adjust, if affected by mod */
if (mark->offset > tooff)
{
mark->offset += delta;
}
else if (mark->offset > fromoff)
{
/* NOTE: At this point we know that dist!=0 because
* that could only happen if fromoff==tooff, and we
* can only get here if this mark's offset <= tooff
* but >fromoff. When tooff==fromoff, that is
* impossible!
*/
mark->offset += delta * (mark->offset - from->offset) / dist;
}
}
}
/* Find the line number of a mark. This is defined as being the number of
* newlines preceding the mark, plus 1. Note that this is not necessarily
* how the edit mode defines lines.
*/
long markline(mark)
MARK mark; /* mark to be converted */
{
long lnum;
(void)lowoffset(bufbufinfo(markbuffer(mark)), markoffset(mark), NULL, NULL, NULL, &lnum);
return lnum;
}
/* Adjust a mark so that it points to a specific line, and then return mark.
* If the requested line doesn't exist, return NULL.
*/
MARK marksetline(mark, linenum)
MARK mark; /* the mark to be adjusted */
long linenum;/* the desired line number */
{
/* if bogus line number, return NULL */
if (linenum < 1 || linenum > o_buflines(markbuffer(mark)))
{
return NULL;
}
/* else change the mark's offset & return it */
mark->offset = lowline(bufbufinfo(markbuffer(mark)), linenum);
assert(mark->offset < o_bufchars(markbuffer(mark)));
return mark;
}
/* Change the buffer of a mark. This involves deleting the mark from the mark list of the old
* buffer, and then adding it to the list of the new buffer.
*/
void marksetbuffer(mark, buffer)
MARK mark; /* the mark to be moved */
BUFFER buffer; /* the new buffer that the mark should refer to */
{
MARK lag;
/* remove from old buffer's list of marks */
if (mark == bufmarks(mark->buffer))
{
bufsetmarks(mark->buffer, mark->next);
}
else
{
assert(bufmarks(mark->buffer));
for (lag = bufmarks(mark->buffer); lag->next != mark; lag = lag->next)
{
assert(lag->next->next);
}
lag->next = mark->next;
}
/* insert it into the new buffer's list */
mark->buffer = buffer;
mark->next = bufmarks(buffer);
bufsetmarks(buffer, mark);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.