/*
 * sh.hist.c: funkcje z "histrii shella"
 */

[....]

void
savehist(sp, mflg)
    struct wordent *sp;      /*jak wyglada ta struktura ? 
                                prosze zajrzec do slowniczka na stronie 
                                poswieconej budowie na koncu */ 
    bool mflg;
{
    register struct Hist *hp, *np;
    register int histlen = 0;
    Char   *cp;

    if (sp && sp->next->word[0] == '\n') /*"znany numer" gdy w tcsh /z promptem
                                           z numerem komendy/ wykonamy 
                                           pusta linie to nie liczy sie ona 
                                           do historii */
                                           
        return;
    cp = varval(STRhistory);            /*pobieramy "string" jaki 
                                          jest wartoscia zmiennej history */
    if (*cp) {
        register Char *p = cp;

        while (*p) {
            if (!Isdigit(*p)) {
                histlen = 0;
                break;
            }
            histlen = histlen * 10 + *p++ - '0'; /* proste obliczenie z zapisu
                                                    history jej wartosci liczbowej */
        }
    }
    for (hp = &Histlist; (np = hp->Hnext) != NULL;)
        if (eventno - np->Href >= histlen || histlen == 0) /*udostepniamy strukture  
                                                             na najdluzej uzywanym miejscu
                                                             (jesli ich brakuje) na przyszle 
                                                             zapisanie historii 
                                                            */
            hp->Hnext = np->Hnext, hfree(np);
        else
            hp = np;
    if (sp)
        (void) enthist(++eventno, sp, 1, mflg);         /* ta funkcja robi prawdziwe 
                                                           wstawianie do historii */
}


static bool
heq(a0, b0)
struct wordent *a0, *b0;
{
/../* porownanie dwoch struktur */
}





/* ta funkcja rzeczywiscie alokuje pamiec dla lini komend w postaci lancucha
   typu wordent , ktory w rzeczywistosci jest przerobiona juz linia komend*/
struct Hist *
enthist(event, lp, docopy, mflg)
    int     event;
    register struct wordent *lp;
    bool    docopy;
    bool    mflg;
{
    extern time_t Htime;
    struct Hist *p = NULL, *pp = &Histlist;
    int n, r;
    register struct Hist *np;
    Char *dp;
    
    if ((dp = varval(STRhistdup)) != STRNULL) {
        if (eq(dp, STRerase)) {
            struct Hist *px;
            for (p = pp; (px = p, p = p->Hnext) != NULL;)
                if (heq(lp, &(p->Hlex))){
                    px->Hnext = p->Hnext;
                    n = p->Hnum + 1;
                    hfree(p);
                    for (p = px->Hnext; p != NULL; p = p->Hnext)
                        p->Href = n--;
                    break;
                }
        }
        else if (eq(dp, STRall)) {
            for (p = pp; (p = p->Hnext) != NULL;)
                if (heq(lp, &(p->Hlex))) {
                    eventno--;
                    break;
                }
        }
        else if (eq(dp, STRprev)) {
            if (pp->Hnext && heq(lp, &(pp->Hnext->Hlex))) {
                p = pp->Hnext;
                eventno--;
            }
        }
    }

    np = p ? p : (struct Hist *) xmalloc((size_t) sizeof(*np));

    if (Htime != (time_t) 0) {
        np->Htime = Htime;
        Htime = 0;
    }
    else
        (void) time(&(np->Htime));

    if (p == np)
        return np;

    np->Hnum = np->Href = event;
    if (docopy) {
        copylex(&np->Hlex, lp); /* kopiuje wordenty tak by tak samo wskazywaly
                                 chodzi tutaj /z referencjami/ o to ze mozemy 
                                 sie odwolac do ktorejs linii i kilka slow wziac stamtad
                                 wtedy lancuch "wordentow" ktory w rzeczywistosci 
                                 jest lancuchem slow bedzie krotszy */  
        if (histvalid)
            np->histline = Strsave(histline);
        else
            np->histline = NULL;
    }
    else {
        np->Hlex.next = lp->next;
        lp->next->prev = &np->Hlex;
        np->Hlex.prev = lp->prev;
        lp->prev->next = &np->Hlex;
        np->histline = NULL;
    }
    if (mflg)
      {
        while ((p = pp->Hnext) && (p->Htime > np->Htime))
          pp = p;
        while (p && p->Htime == np->Htime)
          {
            if (heq(&p->Hlex, &np->Hlex))
              {
                eventno--;
                hfree(np);
                return (p);
              }
            pp = p;
            p = p->Hnext;
          }
        for (p = Histlist.Hnext; p != pp->Hnext; p = p->Hnext)
          {
            n = p->Hnum; r = p->Href;
            p->Hnum = np->Hnum; p->Href = np->Href;
            np->Hnum = n; np->Href = r;
          }
      }
    np->Hnext = pp->Hnext;
    pp->Hnext = np;
    return (np);
}