home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
me34src.zip
/
me3
/
ed
/
history.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-14
|
4KB
|
144 lines
/* history.c : general purpose remember lines of text for recall.
* It looks like a stack with semi-random access. The stack is fixed size
* with all addations being at the top with a pointer to the interior of
* the stack. Old entries are pushed off the bottom as the stack
* overflows.
* --Bottom-->|oldest entry| ... |most recent entry|<--Top--
* Things a history package needs to implement:
* Hsize(n): set the size of the history buffer to n bytes.
* ??? how get
* Hnext(): Move the stack pointer to the next entry (toward Top).
* TRUE if successful, FALSE if can't move.
* Hprev(): Move the stack pointer to the previous entry (toward Bottom).
* TRUE if successful, FALSE if can't move.
* Htop(): Move history pointer to Top (most recent entry of the history
* stack).
* Hbottom(): Move history pointer to Bottom (the oldest entry of the
* history stack).
* Hcurrent(): Return pointer to current history entry.
* Hsearch(direction,matcher) pfi matcher;
* Search for a pattern. Matcher is called for each entry. If a match
* is found, Hsearch returns a pointer to it and leave pointer at the
* entry else return NULL and don't move pointer.
* The current entry is not matched.
* The caller has to mess with the pattern.
* Hadd(text): Add a history entry to the end to the history stack.
* Updates the pointer.
* ?Hentries() : return the number of entries in the stack.
* C Durland
*/
/* Copyright 1990, 1991 Craig Durland
* Distributed under the terms of the GNU General Public License.
* Distributed "as is", without warranties of any kind, but comments,
* suggestions and bug reports are welcome.
*/
#include <const.h>
#include "led.h"
#define HBUFSIZE 1000
static char *get_hist();
static int Hentries();
static int nth_hist = 0, num_hists = 0;
void Htop() { nth_hist = num_hists; }
void Hbottom() { nth_hist = 0; }
char *Hcurrent()
{
char *ptr = get_hist(nth_hist);
return ptr ? ptr : "";
}
Hnext()
{
if (nth_hist < num_hists-1) { ++nth_hist; return TRUE; }
return FALSE;
}
Hprev()
{
if (0 < nth_hist) { --nth_hist; return TRUE; }
return FALSE;
}
char *Hsearch(search_forward,matcher) int (*matcher)();
{
register char *ptr;
register int j;
if (search_forward)
{
for (j = nth_hist+1; j < num_hists; j++)
if ((*matcher)(ptr = get_hist(j)))
{
found_it:
nth_hist = j;
return ptr;
}
}
else /* search backwards */
{
for (j = nth_hist-1; 0 <= j; j-- )
if ((*matcher)(ptr = get_hist(j))) goto found_it;
}
return NULL;
}
static char history[HBUFSIZE+1];
static int hsize = HBUFSIZE, hidx = 0;
/* Add test to the Top of the history stack. If there is enough room in
* the stack, just add text. If not enough room, remove entries from
* the Bottom of the stack until there is.
* Notes:
* Given: len <= hsize
* you can show: len -(hsize -hidx) <= hidx
* Given: len > (hsize -hidx)
* you can show: len -(hsize -hidx) > 0
* All entries are terminated by '\0' so if i < hidx, there is a
* '\0' before i++ reaches hidx.
*/
int Hadd(text) char *text;
{
int i,j, len = strlen(text) +1;
if (len < 3) return TRUE;
if (hsize < len) return FALSE; /* text won't fit in buffer */
Htop(); Hprev(); if (strcmp(Hcurrent(),text)==0) return TRUE;
if (len>(hsize -hidx)) /* not enough room */
{
if ((i = len -(hsize -hidx)) < hidx) while (history[i++]) ;
j = i; i = 0; while (j<hidx) history[i++] = history[j++];
hidx = i;
}
strcpy(&history[hidx],text); hidx += len;
num_hists = Hentries();
Htop();
return TRUE;
}
/* ******************************************************************** */
/* ******************************************************************** */
/* ******************************************************************** */
static int Hentries() /* return the number of history lines */
{
int j, n = 0;
for (j = 0; j<hidx; j++) if (history[j]=='\0') n++;
return n;
}
static char *get_hist(n) /* return the nth line of the history */
{
int j;
for (j = 0; j<hidx && 0<n; j++) if (history[j]=='\0') n--;
return (n==0 && j<hidx) ? &history[j] : NULL;
}