File: [local] / OpenXM_contrib2 / fep / fep_hist.c (download)
Revision 1.5, Fri Apr 23 05:34:05 2010 UTC (14 years, 5 months ago) by ohara
Branch: MAIN
CVS Tags: RELEASE_1_3_1_13b Changes since 1.4: +1 -0
lines
Add some header files.
|
/* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */
#ifndef lint
static char rcsid[]=
"$Header: fep_hist.c,v 4.3 88/11/25 20:45:25 utashiro Exp $ (SRA)";
#endif /* lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "fep_defs.h"
#include "fep_glob.h"
#include "fep_funcs.h"
#if defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__APPLE_CC__) || defined(__INTERIX)
#include <regex.h>
regex_t Re_pat;
#define re_comp(p) (regcomp(&Re_pat,(p), REG_EXTENDED|REG_NOSUB))
#define re_exec(p) (!regexec(&Re_pat, (p), 0 , NULL, 0))
#else
char *re_comp();
#endif
char **HistoryTable;
int TopOfHist;
int TailOfHist;
int CurrentHist;
int HistorySize;
int uniqline = 1;
char *getOldestHistory();
char *getYoungestHistory();
char *argv[MAXARGS];
int argc;
init_hist(size)
int size;
{
char *itoa();
TopOfHist = 0;
TailOfHist = 0;
CurrentHist = 0;
HistorySize = size;
/*
* "set_var" will call "changeHistorySize" function for initilize
* history table.
*/
set_var ("history", itoa (HistorySize));
}
char *
itoa (i)
int i;
{
static char buf[64];
sprintf (buf, "%d", i);
return (buf);
}
addHistory(string)
char *string;
{
char *allocAndCopyThere();
char *prev;
int slen;
if (HistorySize <= 0)
return;
CurrentHist = TailOfHist;
prev = getYoungestHistory ();
if (look_var ("ignore-same-line") && prev && !strcmp (string, prev))
return;
if ((slen = lookd_var ("ignore-short-line"))>0 && strlen (string) <= slen)
return;
if (TailOfHist-HistorySize >= TopOfHist) {
if (HistoryTable[TopOfHist % HistorySize])
free(HistoryTable[TopOfHist % HistorySize]);
TopOfHist++;
}
HistoryTable[(TailOfHist++)%HistorySize] = allocAndCopyThere(string);
CurrentHist = TailOfHist;
}
void
resetCurrentHistory()
{
CurrentHist = TailOfHist;
}
char *
getHistory(num)
int num;
{
if (HistorySize <= 0)
return (0);
if (num < TopOfHist || TailOfHist <= num) {
return ((char *)0);
}
else {
return (HistoryTable[num % HistorySize]);
}
}
char *
getCurrentHistory()
{
return (getHistory (CurrentHist));
}
char *
getPreviousHistory()
{
if (HistorySize <= 0)
return (0);
if (TailOfHist == 0) {
return((char *)0);
}
if (CurrentHist == TopOfHist)
CurrentHist = TailOfHist - 1;
else
CurrentHist--;
return (getCurrentHistory ());
}
char *
getNextHistory()
{
if (HistorySize <= 0)
return (0);
if (CurrentHist == TailOfHist || CurrentHist == TailOfHist-1)
CurrentHist = TopOfHist;
else
CurrentHist++;
return (getCurrentHistory ());
}
getOldestHistNum()
{
return (TopOfHist);
}
getYoungestHistNum()
{
return (TailOfHist-1);
}
char *
getOldestHistory()
{
register char *cp;
if (TailOfHist == 0)
return("");
cp = HistoryTable[TopOfHist];
return (cp ? cp : "");
}
char *
getYoungestHistory()
{
register char *cp;
if (TailOfHist == 0)
return("");
cp = getHistory (getYoungestHistNum());
return (cp ? cp : "");
}
getCurrentHistNum()
{
return (CurrentHist);
}
char *
allocAndCopyThere(string)
char *string;
{
register char *cp;
cp = (char *)malloc(strlen(string)+1);
if (cp == (char *)0)
return ((char *)0);
strcpy(cp, string);
return(cp);
}
char *
historyExtract(string)
char *string;
{
char *search_reverse_history();
if (HistorySize <= 0)
return (0);
switch (*++string) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
register int histNum;
histNum = (atoi (string)) - 1;
if (TopOfHist <= histNum && histNum < TailOfHist) {
CurrentHist = histNum;
return (HistoryTable[histNum % HistorySize]);
}
else {
return ((char *) 0);
}
}
break;
case '-':
{
register int histNum;
if (! isdigit(*++string))
return ((char *) 0);
histNum = TailOfHist - (atoi (string));
if (TopOfHist <= histNum && histNum < TailOfHist) {
CurrentHist = histNum;
return (HistoryTable[histNum % HistorySize]);
}
else {
return ((char *) 0);
}
}
break;
case '!':
if (TailOfHist != 0) {
CurrentHist = TailOfHist - 1;
return (HistoryTable[(TailOfHist - 1) % HistorySize]);
}
break;
case '?':
return (search_reverse_history (++string));
default:
{
char buf[64];
strcpy (buf, "^");
strncat (buf, string, 64);
return (search_reverse_history (buf));
}
}
return ((char *) 0);
}
char *
search_reverse_history (string)
char *string;
{
register int i;
if (string != NULL) {
set_var ("search-string", string);
if (re_comp(string) != (char *)0)
return ((char *) 0);
i = TailOfHist - 1;
}
else
i = CurrentHist - 1;
for (; i >= TopOfHist; i--) {
if (re_exec(HistoryTable[i % HistorySize]) == 1) {
CurrentHist = i;
return(HistoryTable[i % HistorySize]);
}
}
return ((char *) 0);
}
char *
search_forward_history (string)
char *string;
{
register int i;
if (string != NULL) {
if (re_comp(string) != (char *)0)
return ((char *) 0);
i = TopOfHist;
}
else
i = CurrentHist + 1;
for (; i <= TailOfHist; i++) {
if (re_exec(HistoryTable[i % HistorySize]) == 1) {
CurrentHist = i;
return(HistoryTable[i % HistorySize]);
}
}
return ((char *) 0);
}
/*
* Change history table size.
*/
changeHistorySize(newsize)
int newsize;
{
char **newHistTable;
register int newTop, i;
if (newsize > 0)
newHistTable = (char **)calloc(sizeof(char *), newsize);
if (newHistTable == 0)
return (0);
newTop = (TailOfHist - newsize < TopOfHist)
? TopOfHist : TailOfHist - newsize;
/*
* This function can be called for initializing history table
*/
if (HistoryTable) {
for (i = TailOfHist-1; i >= TopOfHist && i >= newTop; i--) {
newHistTable[i%newsize] = HistoryTable[i%HistorySize];
}
for (i = TopOfHist; i < newTop; i++) {
if (HistoryTable[i%HistorySize]) {
free(HistoryTable[i%HistorySize]);
}
}
free(HistoryTable);
}
if (newsize <= 0)
HistoryTable = (char **) 0;
TopOfHist = newTop;
HistorySize = newsize;
HistoryTable = newHistTable;
if (look_var ("debug")) {
printf ("history: top=%d, tail=%d, size=%d\n",
TopOfHist, TailOfHist, HistorySize);
}
return (1);
}
/*
* Built-in function "fep-history"
*/
fep_history (comline)
char *comline;
{
int num;
argc = mkargv (comline, argv, MAXARGS);
if (argc == 2)
num = atoi (argv[1]);
else
num = 0;
hist_showHistory (num);
}
hist_showHistory (num)
int num;
{
register int from, to, i;
char *cp;
if (num <= 0)
num = HistorySize;
from = getOldestHistNum ();
to = getYoungestHistNum ();
from = max (from, to - num + 1);
if (CurrentHist < from) {
from = max (getOldestHistNum(), CurrentHist - num/2);
to = min (getYoungestHistNum(), from + num - 1);
}
for (i = from; i <= to; i++) {
if (cp = getHistory(i)) {
printf("%c%4d ", (i == CurrentHist) ? '>' : ' ', i+1);
ctlprint(cp);
}
}
}
char *
mk_home_relative (cp)
char *cp;
{
static char buf[256];
/*
* If variable "history-file" is not absolute path name,
* change it to relative path name from home directory.
*/
if (*cp != '/' && !(*cp == '.' && *(cp+1) == '/')) {
strcpy (buf, getenv ("HOME"));
strcat (buf, "/");
strcat (buf, cp);
}
else
strcpy (buf, cp);
return (buf);
}
fep_save_history (comline)
char *comline;
{
char *file;
char **argp;
FILE *fp;
int num = 0;
argc = mkargv (comline, argv, MAXARGS);
argp = argv;
++argp;
if (isdigit (**argp))
num = atoi (*argp++);
if (*argp == NULL) {
char *cp;
if ((cp = look_var ("history-file")) == NULL) {
clear_edit_line ();
printf (
"%s: Argument or \"history-file\" variables is required\n",
argv[0]
);
recover_edit_line (1);
return;
}
file = mk_home_relative (cp);
}
else
file = *argp;
save_history (file, num);
}
#define MAXSAVEHIST 512
save_history (file, num)
char *file;
int num;
{
int old, new;
FILE *fp, *fopen();
char *cp;
old = getOldestHistNum ();
new = getYoungestHistNum ();
if (num <= 0)
num = MAXSAVEHIST;
if (new - num + 1 > old)
old = new - num + 1;
if (look_var ("debug")) {
printf ("save history from %d to %d\n", old, new);
}
if ((fp = fopen (file, "w")) == NULL) {
clear_edit_line ();
perror (file);
recover_edit_line (1);
return;
}
while (old <= new) {
cp = getHistory (old++);
fprintf (fp, "%s\n", cp);
}
fclose (fp);
return;
}
fep_read_history (comline)
char *comline;
{
char *file;
char **argp;
FILE *fp;
argc = mkargv (comline, argv, MAXARGS);
argp = argv;
++argp;
if (*argp == NULL) {
char *cp;
if ((cp = look_var ("history-file")) == NULL) {
clear_edit_line ();
printf (
"%s: Argument or \"history-file\" variables is required\n",
argv[0]
);
recover_edit_line (1);
return;
}
file = mk_home_relative (cp);
}
else
file = *argp;
read_history (file);
}
read_history (file)
char *file;
{
FILE *fp;
char line [MAXCMDLEN];
register int i;
if ((fp = fopen (file, "r")) == NULL) {
clear_edit_line ();
perror (file);
recover_edit_line (1);
return;
}
while (fgets (line, MAXCMDLEN, fp)) {
i = strlen (line) - 1;
if (line [i] == '\n')
line [i] = '\0';
addHistory (line);
}
return;
}