#include #include #include #include #include #include #include #include #include "slirc.h" void DrawLRU(int); char LRU_dirty = 1; /* {{{{ LRU */ #define MAXLRU 50 #define MAXUSTR 256 typedef struct _LRUe { struct _LRUe *prev; struct _LRUe *next; char act __attribute__((packed)); char str[MAXUSTR] __attribute__((packed)); } LRUe; typedef struct { LRUe *first; LRUe *free; LRUe x[MAXLRU]; } SLirc_LRU; static SLirc_LRU *LRU; static SLirc_LRU *Create_LRU(void) { LRUe *el; SLirc_LRU *LRU; LRU = (SLirc_LRU *)SLmalloc(sizeof(SLirc_LRU)); if (LRU) { LRU->first = NULL; el = LRU->x; LRU->free = el; for (; el < LRU->x + MAXLRU - 1; el++) el->next = el + 1; el->next = NULL; } return LRU; } static inline LRUe *GetFree(void) { LRUe *el; if ((el = LRU->free)) LRU->free = el->next; return el; } static inline void PutFree(LRUe * el) { el->next = LRU->free; LRU->free = el; } static inline void CutOut(LRUe * el) { el->prev->next = el->next; el->next->prev = el->prev; } static void PutBefore(LRUe * el, LRUe * el0) { el->prev = el0->prev; el->next = el0; el0->prev->next = el; el0->prev = el; } static void MoveBefore(LRUe * el, LRUe * el0) { if (el != el0) { CutOut(el); PutBefore(el, el0); } } static int SLirc_user_save(char *st, int *act) { LRUe *el, *el0, *el5 = NULL; int len, ord = MAXLRU / 2; char *p; if (*act == 'm' || *act == 'o') ord = 0; if ((p = index(st, '!'))) len = p - st; else len = strlen(st); if (!len) return 0; el = el0 = LRU->first; if (!el) { if (*act == 'd') return 0; el = GetFree(); el->prev = el; el->next = el; LRU->first = el; } else { do { if (!ord--) el5 = el; if (el->str[len] == '!' && !IrcCmp(el->str, st, len)) { /* found it */ if (el5) { MoveBefore(el, el5); if (el5 == el0) LRU->first = el; } el->act = *act; return 1; } } while ((el = el->next) != el0); /* drop-thru is not-found */ if (*act == 'd') return 0; if ((el = GetFree())) { if (el5) { PutBefore(el, el5); if (el5 == el0) LRU->first = el; } else PutBefore(el, el0); /* and leaves it last */ } else { el = el0->prev; if (el5) { MoveBefore(el, el5); if (el5 == el0) LRU->first = el; } } } strmcpy(el->str, st, MAXUSTR); el->act = *act; return 0; } static char *SLirc_user_find(char *st, int *act) { LRUe *el, *el0, *el5 = NULL; int len, ord = 0; len = strlen(st); if (len > MAXUSTR - 1) len = MAXUSTR - 1; ord = (*act == 'p' || *act == 'f' || *act == 'd') ? -1 : *act - '0'; el = el0 = LRU->first; if (el) { do { if (!ord--) el5 = el; if (!IrcCmp(el->str, st, len)) { /* found it */ if (*act != 'p') { if (el->str[len] != '!') continue; if (*act != 'f') { if (*act == 'd') { /* delete it */ if (el == el->next) LRU->first = NULL; else { CutOut(el); if (el == el0) LRU->first = el->next; } PutFree(el); } else { /* advance */ if (el5) { MoveBefore(el, el5); if (el5 == el0) LRU->first = el; } el->act = *act; } } } return el->str; } } while ((el = el->next) != el0); } return NullString; } static int SLirc_user_list(void) { LRUe *el, *el0; int m = 0, n = 0; el = el0 = LRU->first; if (el) do { m++; if (n < MAXPMS) Rpms[n++] = el->str; } while ((el = el->next) != el0); Rpms_ct = n; return m; } static int SLirc_user_nickmod(char *from, char *to) { LRUe *el, *el0; char *p, *q; el = el0 = LRU->first; if (el) do { if (!IrcCmp(el->str, from, MAXUSTR - 1)) { /* found it */ el->act = 'n'; p = strmcpy(el->str, to, MAXUSTR); /* p is the terminal null */ q = index(from, '!'); if (q) strmcpy(p, q, el->str + MAXUSTR - p); return 1; } } while ((el = el->next) != el0); return 0; } void DrawLRU(int start) { LRUe *el, *el0; char *p; int Col, len, ix = 0; SLsmg_gotorc(start, 0); SLsmg_set_color((UseColours) ? ColLRUnorm : 0); ix = 0; el = el0 = LRU->first; if (el) { do { if (!(p = index(el->str, '!'))) len = strlen(el->str); else len = p - el->str; if (ix + len > SLtt_Screen_Cols - 2) break; if (ix) { if (UseColours) SLsmg_set_color(ColLRUnorm); SLsmg_write_char(' '); ix++; } ix += len; if (UseColours) { Col = ColLRUnorm; switch (el->act) { case 'd': Col = ColLRUgone; break; case 'j': Col = ColLRUjoin; break; case 'n': Col = ColLRUnmod; break; case 'a': Col = ColLRUactn; break; case 'o': Col = ColLRUmesg; break; case 'm': break; } SLsmg_set_color(Col); } SLsmg_write_nchars(el->str, len); } while ((el = el->next) != el0); } SLsmg_set_color((UseColours) ? ColLRUnorm : 0); SLsmg_erase_eol(); } /* }}}} LRU */ static SLang_Intrin_Fun_Type LRU_Fun_Table[] = { MAKE_INTRINSIC_SI("irc_user_save", SLirc_user_save, SLANG_INT_TYPE), MAKE_INTRINSIC_SI("irc_user_find", SLirc_user_find, SLANG_STRING_TYPE), MAKE_INTRINSIC_0("irc_user_list", SLirc_user_list, SLANG_INT_TYPE), MAKE_INTRINSIC_SS("irc_user_nickmod", SLirc_user_nickmod, SLANG_INT_TYPE), SLANG_END_TABLE }; static SLang_IConstant_Type LRU_Constants [] = { MAKE_ICONSTANT("irc_col_lru_norm", ColLRUnorm), MAKE_ICONSTANT("irc_col_lru_actn", ColLRUactn), MAKE_ICONSTANT("irc_col_lru_mesg", ColLRUmesg), MAKE_ICONSTANT("irc_col_lru_gone", ColLRUgone), MAKE_ICONSTANT("irc_col_lru_join", ColLRUjoin), MAKE_ICONSTANT("irc_col_lru_nmod", ColLRUnmod), SLANG_END_TABLE }; int init_LRU() { LRU = Create_LRU(); if(SLdefine_for_ifdef("LRU")) return 0; return (!SLadd_intrin_fun_table(LRU_Fun_Table, "_LRU") && !SLadd_iconstant_table (LRU_Constants, NULL)); }