/* * 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); }