/* file: bookmark.e Copyright (c) 1991, by Marshall E. Giguere, all rights reserved. BookMarks is my poor effort to permit mulitiple saved positions within a buffer. Bookmarks are kept in a buffer specific ring buffer oddly called bookmarks[]. Bookmarks permit access either by direct address, i.e. the actual bookmark number, or by a non-destructive pop in either the forward, or backwards directions. The size of the ring buffer is controlled at compile time by the definition MAX_BOOKMARKS which is set to 10 by default. You can change the size of the ring by changing MAX_BOOKMARKS to some other appropriate value. Bookmark numbering follows C array subscripting convention, i.e. bookmarks range from 0 to MAX_BOOKMARKS - 1. This means that in the default case bookmarks range from 0..9 inclusive. The following commands represent the accessible user interface to Epsilon: set-book-mark sets either the mark specified by ARG, or the next available one if nothing is specified. goto-book-mark ARG specifies the mark to goto, if none is specified the last set mark is assumed. pop-next-mark walk around the ring in a forward direction, i.e. left to right. pop-prev-mark walk around the ring in a backward direction, i.e. right to left. kill-book-mark removes ARG specifed mark from the ring. No ARG means kill all bookmarks. kill-all-bookmarks deletes all bookmarks. show-bookmarks lists the bookmarks in the ring (for debugging) Class: Bookmark Instance variables: */ #define EMPTY -1 /* sentinel for empty ring slot */ #define MAX_BOOKMARKS 10 /* defines size of ring */ #define TRUE 1 #define FALSE 0 #define QUE_END MAX_BOOKMARKS - 1 /* last ring position */ #include "eel.h" buffer int next_available; /* next mark in ring to be used */ buffer int last_set_bookmark; /* ring position of last set bookmark */ buffer int visiting_bookmark; /* current or last visited bookmark */ buffer int bookmarks[MAX_BOOKMARKS]; /* ring of book marks */ buffer int temp; /* temporary int holder */ /* Bookmark methods: Interface: Public set_book_mark() Public goto_book_mark() Public pop_prev_mark() Public pop_next_mark() Public kill_book_mark() Public kill_all_bookmarks() Public get_visiting() Public is_empty(m) Public is_valid_bookmark(m) Private add_book_mark(m) Private make_bookmark_current(m) Private bump_next_available() Private previous_bookmark(m) Private when_loading() Private set_last_bookmark(m) Private set_visiting(m) Private remove_bookmark(m) Implementation: */ /* method Private */ when_loading() { int i; next_available.default = 0; /* point to first slot in ring */ last_set_bookmark.default = EMPTY; /* nothing last set */ visiting_bookmark.default = EMPTY; /* nothing currently active */ for( i=0; i= 0 && m < QUE_END ) { return( m + 1 ); } } /* end next_bookmark */ /* method Private previous_bookmark - returns the valid predecessor for the supplied bookmark. No checking is done for EMPTY bookmarks I let the caller decide what to do about that situation. History: 13-Aug-91 MGiguere Fixed wrap around computation error. 24-Aug-90 MGiguere Created. */ int previous_bookmark( m ) int m; { if ( m == 0 ) { return( QUE_END ); } if ( m > 0 && m <= QUE_END ) { return( m - 1 ); } } /* end previous_bookmark */ /* method Private add_book_mark - puts book marks into the ring ring and generally manages the ring ring. History: 22-Dec-90 MGiguere Created. */ add_book_mark(m) int m; { if ( is_valid_bookmark( m ) ) { /* check for valid book mark */ bookmarks[m] = point; set_last_bookmark( m ); set_visiting( m ); if ( m == next_available ) bump_next_available(); say( "Book mark %d set.", m ); } else { /* invalid book mark sent */ error( "ERROR: invalid book mark %d.", m ); } }/* end add_book_mark */ /* method Private set_last_bookmark - sets the instance variable last_set_bookmark. History: 22-Dec-90 MGiguere Created. */ set_last_bookmark(m) int m; { last_set_bookmark = m; }/* end set_last_bookmark */ /* method Private bump_next_available - sets next_available to the next book mark in the ring ring. Old values are overwritten as the ring pointer moves around the ring. History: 22-Dec-90 MGiguere Created. */ bump_next_available() { next_available = ( next_available + 1 ) % MAX_BOOKMARKS; }/* end bump_next_avialable */ /* method Private make_bookmark_current - goes to the specified book mark and places that bookmark at point. History: 22-Dec-90 MGiguere Created. */ make_bookmark_current(m) int m; { if ( ( is_valid_bookmark( m ) ) && ( !is_empty( m ) ) ) { /* valid book mark? */ point = bookmarks[m]; /* yes */ set_visiting( m ); } else { /* invalid */ error( "ERROR: illegal book mark %d specifed.", m ); } }/* end make_bookmark_current */ /* method Private set_visiting - sets the value of the most currently visited bookmark. History: 22-Dec-90 MGiguere Created. */ set_visiting(m) int m; { visiting_bookmark = m; }/*end set_visiting */ /* method Private is_valid_bookmark - tests a book mark to determine if it is within the legal range 0 to QUE_END. Returns TRUE if the bookmark is in the valid range otherwise returns FALSE. History: 24-Dec-90 MGiguere Created. */ is_valid_bookmark(m) int m; { if ( ( m < 0 ) || ( m >= QUE_END ) ) { return FALSE; } else { return TRUE; } }/* end is_valid_bookmark */ /* method Public is_empty - checks the specified bookmark slot to see if it is currently occupied, returns TRUE if the slot is unoccupied, FALSE if it is in use. History: 24-Dec-90 MGiguere Created. */ is_empty(m) int m; { if ( !is_valid_bookmark( m ) ) { return FALSE; } else { if ( bookmarks[m] == EMPTY ) { return TRUE; } else return FALSE; } }/* end is_empty */ /* method Public kill_book_mark - removed the specified book mark from the ring and sets the entry to EMPTY. If no argument is supplied then all bookmarks are killed. History: 14-Aug-91 MGiguere No arg. now kills all marks. 24-Dec-90 MGiguere Created. */ command kill_book_mark() { if ( !has_arg ) { kill_all_bookmarks(); } else { temp = iter; iter = 0; if ( !is_valid_bookmark( temp ) ) { error( "ERROR: Illegal book mark %d specified.", temp ); } else bookmarks[temp] = EMPTY; } }/* end kill_book_mark */ /* method Public kill_all_bookmarks - this command may be used either as a function or bound to a keymap. This command has direct access the the private representation of the bookmark data and is therefore dangerous. History: 24-Dec-90 MGiguere Created. */ command kill_all_bookmarks() { int i; for( i=0; i