[BACK]Return to fep_hist.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / fep

Annotation of OpenXM_contrib2/fep/fep_hist.c, Revision 1.3

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>