#include <sys/time.h>
#include <ctype.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <slang.h>
#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));
}
syntax highlighted by Code2HTML, v. 0.9.1