static char rcsid[] = "$Id: history.c,v 1.1 1992/09/14 13:02:14 mike Exp $"; /* $Log: history.c,v $ * Revision 1.1 1992/09/14 13:02:14 mike * Initial revision * */ /* 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 #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