Annotation of OpenXM_contrib2/asir2000/fep/fep_hist.c, Revision 1.1
1.1 ! noro 1: /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */
! 2:
! 3: #ifndef lint
! 4: static char rcsid[]=
! 5: "$Header: fep_hist.c,v 4.3 88/11/25 20:45:25 utashiro Exp $ (SRA)";
! 6: #endif /* lint */
! 7:
! 8: #include <stdio.h>
! 9: #include <stdlib.h>
! 10: #include <unistd.h>
! 11: #include <ctype.h>
! 12: #include "fep_defs.h"
! 13: #include "fep_glob.h"
! 14: #include "fep_funcs.h"
! 15:
! 16: #if defined(__FreeBSD__) || defined(__CYGWIN__)
! 17: #define re_comp regcomp
! 18: #define re_exec regexec
! 19: #endif
! 20:
! 21: char **HistoryTable;
! 22: int TopOfHist;
! 23: int TailOfHist;
! 24: int CurrentHist;
! 25: int HistorySize;
! 26:
! 27: int uniqline = 1;
! 28:
! 29: char *getOldestHistory();
! 30: char *getYoungestHistory();
! 31:
! 32: char *argv[MAXARGS];
! 33: int argc;
! 34:
! 35: init_hist(size)
! 36: int size;
! 37: {
! 38: char *itoa();
! 39:
! 40: TopOfHist = 0;
! 41: TailOfHist = 0;
! 42: CurrentHist = 0;
! 43: HistorySize = size;
! 44:
! 45: /*
! 46: * "set_var" will call "changeHistorySize" function for initilize
! 47: * history table.
! 48: */
! 49: set_var ("history", itoa (HistorySize));
! 50: }
! 51:
! 52: char *
! 53: itoa (i)
! 54: int i;
! 55: {
! 56: static char buf[64];
! 57:
! 58: sprintf (buf, "%d", i);
! 59: return (buf);
! 60: }
! 61:
! 62: addHistory(string)
! 63: char *string;
! 64: {
! 65: char *allocAndCopyThere();
! 66: char *prev;
! 67: int slen;
! 68:
! 69: if (HistorySize <= 0)
! 70: return;
! 71:
! 72: CurrentHist = TailOfHist;
! 73: prev = getYoungestHistory ();
! 74: if (look_var ("ignore-same-line") && prev && !strcmp (string, prev))
! 75: return;
! 76: if ((slen = lookd_var ("ignore-short-line"))>0 && strlen (string) <= slen)
! 77: return;
! 78:
! 79: if (TailOfHist-HistorySize >= TopOfHist) {
! 80: if (HistoryTable[TopOfHist % HistorySize])
! 81: free(HistoryTable[TopOfHist % HistorySize]);
! 82: TopOfHist++;
! 83: }
! 84: HistoryTable[(TailOfHist++)%HistorySize] = allocAndCopyThere(string);
! 85: CurrentHist = TailOfHist;
! 86: }
! 87:
! 88: void
! 89: resetCurrentHistory()
! 90: {
! 91: CurrentHist = TailOfHist;
! 92: }
! 93:
! 94: char *
! 95: getHistory(num)
! 96: int num;
! 97: {
! 98: if (HistorySize <= 0)
! 99: return (0);
! 100:
! 101: if (num < TopOfHist || TailOfHist <= num) {
! 102: return ((char *)0);
! 103: }
! 104: else {
! 105: return (HistoryTable[num % HistorySize]);
! 106: }
! 107: }
! 108:
! 109: char *
! 110: getCurrentHistory()
! 111: {
! 112: return (getHistory (CurrentHist));
! 113: }
! 114:
! 115: char *
! 116: getPreviousHistory()
! 117: {
! 118: if (HistorySize <= 0)
! 119: return (0);
! 120:
! 121: if (TailOfHist == 0) {
! 122: return((char *)0);
! 123: }
! 124: if (CurrentHist == TopOfHist)
! 125: CurrentHist = TailOfHist - 1;
! 126: else
! 127: CurrentHist--;
! 128: return (getCurrentHistory ());
! 129: }
! 130:
! 131: char *
! 132: getNextHistory()
! 133: {
! 134:
! 135: if (HistorySize <= 0)
! 136: return (0);
! 137:
! 138: if (CurrentHist == TailOfHist || CurrentHist == TailOfHist-1)
! 139: CurrentHist = TopOfHist;
! 140: else
! 141: CurrentHist++;
! 142: return (getCurrentHistory ());
! 143: }
! 144:
! 145: getOldestHistNum()
! 146: {
! 147:
! 148: return (TopOfHist);
! 149: }
! 150:
! 151: getYoungestHistNum()
! 152: {
! 153:
! 154: return (TailOfHist-1);
! 155: }
! 156:
! 157: char *
! 158: getOldestHistory()
! 159: {
! 160: register char *cp;
! 161:
! 162: if (TailOfHist == 0)
! 163: return("");
! 164:
! 165: cp = HistoryTable[TopOfHist];
! 166: return (cp ? cp : "");
! 167: }
! 168:
! 169: char *
! 170: getYoungestHistory()
! 171: {
! 172: register char *cp;
! 173:
! 174: if (TailOfHist == 0)
! 175: return("");
! 176:
! 177: cp = getHistory (getYoungestHistNum());
! 178: return (cp ? cp : "");
! 179: }
! 180:
! 181: getCurrentHistNum()
! 182: {
! 183: return (CurrentHist);
! 184: }
! 185:
! 186: char *
! 187: allocAndCopyThere(string)
! 188: char *string;
! 189: {
! 190: register char *cp;
! 191:
! 192: cp = (char *)malloc(strlen(string)+1);
! 193:
! 194: if (cp == (char *)0)
! 195: return ((char *)0);
! 196:
! 197: strcpy(cp, string);
! 198: return(cp);
! 199: }
! 200:
! 201: char *
! 202: historyExtract(string)
! 203: char *string;
! 204: {
! 205: char *search_reverse_history();
! 206:
! 207: if (HistorySize <= 0)
! 208: return (0);
! 209:
! 210: switch (*++string) {
! 211: case '0':
! 212: case '1':
! 213: case '2':
! 214: case '3':
! 215: case '4':
! 216: case '5':
! 217: case '6':
! 218: case '7':
! 219: case '8':
! 220: case '9':
! 221: {
! 222: register int histNum;
! 223:
! 224: histNum = (atoi (string)) - 1;
! 225: if (TopOfHist <= histNum && histNum < TailOfHist) {
! 226: CurrentHist = histNum;
! 227: return (HistoryTable[histNum % HistorySize]);
! 228: }
! 229: else {
! 230: return ((char *) 0);
! 231: }
! 232: }
! 233: break;
! 234:
! 235: case '-':
! 236: {
! 237: register int histNum;
! 238:
! 239: if (! isdigit(*++string))
! 240: return ((char *) 0);
! 241:
! 242: histNum = TailOfHist - (atoi (string));
! 243: if (TopOfHist <= histNum && histNum < TailOfHist) {
! 244: CurrentHist = histNum;
! 245: return (HistoryTable[histNum % HistorySize]);
! 246: }
! 247: else {
! 248: return ((char *) 0);
! 249: }
! 250: }
! 251: break;
! 252:
! 253: case '!':
! 254: if (TailOfHist != 0) {
! 255: CurrentHist = TailOfHist - 1;
! 256: return (HistoryTable[(TailOfHist - 1) % HistorySize]);
! 257: }
! 258: break;
! 259:
! 260: case '?':
! 261: return (search_reverse_history (++string));
! 262:
! 263: default:
! 264: {
! 265: char buf[64];
! 266:
! 267: strcpy (buf, "^");
! 268: strncat (buf, string, 64);
! 269: return (search_reverse_history (buf));
! 270: }
! 271: }
! 272: return ((char *) 0);
! 273: }
! 274:
! 275: char *
! 276: search_reverse_history (string)
! 277: char *string;
! 278: {
! 279: register int i;
! 280: char *re_comp();
! 281:
! 282: if (string != NULL) {
! 283: set_var ("search-string", string);
! 284: if (re_comp(string) != (char *)0)
! 285: return ((char *) 0);
! 286: i = TailOfHist - 1;
! 287: }
! 288: else
! 289: i = CurrentHist - 1;
! 290:
! 291: for (; i >= TopOfHist; i--) {
! 292: if (re_exec(HistoryTable[i % HistorySize]) == 1) {
! 293: CurrentHist = i;
! 294: return(HistoryTable[i % HistorySize]);
! 295: }
! 296: }
! 297: return ((char *) 0);
! 298: }
! 299:
! 300: char *
! 301: search_forward_history (string)
! 302: char *string;
! 303: {
! 304: register int i;
! 305: char *re_comp();
! 306:
! 307: if (string != NULL) {
! 308: if (re_comp(string) != (char *)0)
! 309: return ((char *) 0);
! 310: i = TopOfHist;
! 311: }
! 312: else
! 313: i = CurrentHist + 1;
! 314:
! 315: for (; i <= TailOfHist; i++) {
! 316: if (re_exec(HistoryTable[i % HistorySize]) == 1) {
! 317: CurrentHist = i;
! 318: return(HistoryTable[i % HistorySize]);
! 319: }
! 320: }
! 321: return ((char *) 0);
! 322: }
! 323:
! 324: /*
! 325: * Change history table size.
! 326: */
! 327: changeHistorySize(newsize)
! 328: int newsize;
! 329: {
! 330: char **newHistTable;
! 331: register int newTop, i;
! 332:
! 333: if (newsize > 0)
! 334: newHistTable = (char **)calloc(sizeof(char *), newsize);
! 335:
! 336:
! 337: if (newHistTable == 0)
! 338: return (0);
! 339:
! 340: newTop = (TailOfHist - newsize < TopOfHist)
! 341: ? TopOfHist : TailOfHist - newsize;
! 342:
! 343: /*
! 344: * This function can be called for initializing history table
! 345: */
! 346: if (HistoryTable) {
! 347: for (i = TailOfHist-1; i >= TopOfHist && i >= newTop; i--) {
! 348: newHistTable[i%newsize] = HistoryTable[i%HistorySize];
! 349: }
! 350:
! 351: for (i = TopOfHist; i < newTop; i++) {
! 352: if (HistoryTable[i%HistorySize]) {
! 353: free(HistoryTable[i%HistorySize]);
! 354: }
! 355: }
! 356: free(HistoryTable);
! 357: }
! 358:
! 359: if (newsize <= 0)
! 360: HistoryTable = (char **) 0;
! 361:
! 362: TopOfHist = newTop;
! 363: HistorySize = newsize;
! 364: HistoryTable = newHistTable;
! 365:
! 366: if (look_var ("debug")) {
! 367: printf ("history: top=%d, tail=%d, size=%d\n",
! 368: TopOfHist, TailOfHist, HistorySize);
! 369: }
! 370:
! 371: return (1);
! 372:
! 373: }
! 374:
! 375: /*
! 376: * Built-in function "fep-history"
! 377: */
! 378: fep_history (comline)
! 379: char *comline;
! 380: {
! 381: int num;
! 382:
! 383: argc = mkargv (comline, argv, MAXARGS);
! 384:
! 385: if (argc == 2)
! 386: num = atoi (argv[1]);
! 387: else
! 388: num = 0;
! 389:
! 390: hist_showHistory (num);
! 391: }
! 392:
! 393: hist_showHistory (num)
! 394: int num;
! 395: {
! 396: register int from, to, i;
! 397: char *cp;
! 398:
! 399: if (num <= 0)
! 400: num = HistorySize;
! 401:
! 402: from = getOldestHistNum ();
! 403: to = getYoungestHistNum ();
! 404:
! 405: from = max (from, to - num + 1);
! 406:
! 407: if (CurrentHist < from) {
! 408: from = max (getOldestHistNum(), CurrentHist - num/2);
! 409: to = min (getYoungestHistNum(), from + num - 1);
! 410: }
! 411:
! 412: for (i = from; i <= to; i++) {
! 413: if (cp = getHistory(i)) {
! 414: printf("%c%4d ", (i == CurrentHist) ? '>' : ' ', i+1);
! 415: ctlprint(cp);
! 416: }
! 417: }
! 418: }
! 419:
! 420: char *
! 421: mk_home_relative (cp)
! 422: char *cp;
! 423: {
! 424: static char buf[256];
! 425:
! 426: /*
! 427: * If variable "history-file" is not absolute path name,
! 428: * change it to relative path name from home directory.
! 429: */
! 430: if (*cp != '/' && !(*cp == '.' && *(cp+1) == '/')) {
! 431: strcpy (buf, getenv ("HOME"));
! 432: strcat (buf, "/");
! 433: strcat (buf, cp);
! 434: }
! 435: else
! 436: strcpy (buf, cp);
! 437:
! 438: return (buf);
! 439: }
! 440:
! 441: fep_save_history (comline)
! 442: char *comline;
! 443: {
! 444: char *file;
! 445: char **argp;
! 446: FILE *fp;
! 447: int num = 0;
! 448:
! 449: argc = mkargv (comline, argv, MAXARGS);
! 450:
! 451: argp = argv;
! 452: ++argp;
! 453:
! 454: if (isdigit (**argp))
! 455: num = atoi (*argp++);
! 456:
! 457: if (*argp == NULL) {
! 458: char *cp;
! 459:
! 460: if ((cp = look_var ("history-file")) == NULL) {
! 461: clear_edit_line ();
! 462: printf (
! 463: "%s: Argument or \"history-file\" variables is required\n",
! 464: argv[0]
! 465: );
! 466: recover_edit_line (1);
! 467: return;
! 468: }
! 469: file = mk_home_relative (cp);
! 470: }
! 471: else
! 472: file = *argp;
! 473:
! 474: save_history (file, num);
! 475: }
! 476:
! 477: #define MAXSAVEHIST 512
! 478:
! 479: save_history (file, num)
! 480: char *file;
! 481: int num;
! 482: {
! 483: int old, new;
! 484: FILE *fp, *fopen();
! 485: char *cp;
! 486:
! 487: old = getOldestHistNum ();
! 488: new = getYoungestHistNum ();
! 489:
! 490: if (num <= 0)
! 491: num = MAXSAVEHIST;
! 492:
! 493: if (new - num + 1 > old)
! 494: old = new - num + 1;
! 495:
! 496: if (look_var ("debug")) {
! 497: printf ("save history from %d to %d\n", old, new);
! 498: }
! 499:
! 500: if ((fp = fopen (file, "w")) == NULL) {
! 501: clear_edit_line ();
! 502: perror (file);
! 503: recover_edit_line (1);
! 504: return;
! 505: }
! 506:
! 507: while (old <= new) {
! 508: cp = getHistory (old++);
! 509: fprintf (fp, "%s\n", cp);
! 510: }
! 511:
! 512: fclose (fp);
! 513: return;
! 514: }
! 515:
! 516: fep_read_history (comline)
! 517: char *comline;
! 518: {
! 519: char *file;
! 520: char **argp;
! 521: FILE *fp;
! 522:
! 523: argc = mkargv (comline, argv, MAXARGS);
! 524:
! 525: argp = argv;
! 526: ++argp;
! 527:
! 528: if (*argp == NULL) {
! 529: char *cp;
! 530:
! 531: if ((cp = look_var ("history-file")) == NULL) {
! 532: clear_edit_line ();
! 533: printf (
! 534: "%s: Argument or \"history-file\" variables is required\n",
! 535: argv[0]
! 536: );
! 537: recover_edit_line (1);
! 538: return;
! 539: }
! 540: file = mk_home_relative (cp);
! 541: }
! 542: else
! 543: file = *argp;
! 544:
! 545: read_history (file);
! 546: }
! 547:
! 548: read_history (file)
! 549: char *file;
! 550: {
! 551: FILE *fp;
! 552: char line [MAXCMDLEN];
! 553: register int i;
! 554:
! 555: if ((fp = fopen (file, "r")) == NULL) {
! 556: clear_edit_line ();
! 557: perror (file);
! 558: recover_edit_line (1);
! 559: return;
! 560: }
! 561:
! 562: while (fgets (line, MAXCMDLEN, fp)) {
! 563: i = strlen (line) - 1;
! 564: if (line [i] == '\n')
! 565: line [i] = '\0';
! 566: addHistory (line);
! 567: }
! 568: return;
! 569: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>