[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.7

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

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