Хрестоматия по программированию на Си в Unix




Примеры. Хрестоматия по программированию на Си в Unix


Пример 21

/* РЕДАКТОР СТРОКИ И ИСТОРИЯ РЕДАКТИРУЕМЫХ СТРОК */ /* _______________________ файл hist.h __________________________ */ /* ИСТОРИЯ. ЗАПОМИНАНИЕ СТРОК И ВЫДАЧА ИХ НАЗАД ПО ТРЕБОВАНИЮ. */ /* ______________________________________________________________ */ typedef struct { /* Паспорт истории */ Info *list; /* запомненные строки */ int sz; /* размер истории (макс.) */ int len; /* текущее число строк */ Menu mnu; /* меню для выборки из истории */ } Hist; void HistInit(Hist *h, int n); void HistAdd (Hist *h, char *s, int fl); Info *HistSelect(Hist *h, int x, int y);

/* _______________________ файл hist.c __________________________ */ #include "w.h" #include "glob.h" #include "menu.h" #include "hist.h" /* Проинициализировать новую "историю" емкостью n строк */ void HistInit(Hist *h, int n){ register i; if( h->list ){ blkfree( h->list ); h->list = NULL; } h->len = 0; h->mnu.title = "History"; h->mnu.bg_attrib = A_NORMAL; h->mnu.sel_attrib = A_REVERSE; h->list = (Info *) malloc( (n+1) * sizeof(Info)); if( ! h->list ){ h->sz = 0; return; }else h->sz = n; for( i=0; i < n+1 ; i++ ) h->list[i] = NullInfo; } /* Добавить строку s с меткой fl в историю */ void HistAdd (Hist *h, char *s, int fl){ register i, j; Info tmp;

if( h->sz == 0 ) return; /* А нет ли уже такой строки ? */ for( i=0; i < h->len; i++ ) if( !strcmp(s, h->list[i].s )){ /* есть ! */ if( i == 0 ) return; /* первая */ /* сделать ее первой строкой */ tmp = h->list[i]; for( j=i-1; j >= 0; --j ) h->list[j+1] = h->list[j]; h->list[0] = tmp; return; } if( h->len < h->sz ){ for( i=h->len-1; i>= 0; i-- ) h->list[i+1] = h->list[i]; h->len ++ ; }else{ /* выкинуть самую старую строку из истории */ free( h->list[ h->sz - 1 ].s ); for( i=h->sz - 2; i >= 0; i-- ) h->list[i+1] = h->list[i]; } (h->list)[0].s = strdup(s); (h->list)[0].fl = fl; } /* Выборка строки из истории */ Info *HistSelect(Hist *h, int x, int y){ if( h->len == 0 ) return (Info *) NULL; h->mnu.top = y; h->mnu.left = x; h->mnu.items = h->list; MnuInit( & h->mnu ); if( h->mnu.hotkeys ){ register i; for(i=0 ; i < h->mnu.nitems; i++ ) h->mnu.hotkeys[i] = h->list[i].s[0] & 0377; } MnuUsualSelect( & h->mnu, 0 ); MnuDeinit ( & h->mnu ); if( M_REFUSED ( & h->mnu )) return (Info *) NULL; return & h->list[ h->mnu.current ]; }




Содержание  Назад  Вперед