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.