%%% General Purpose Routines for Manipulating Linked-Lists %%% Copyright (C) 1998 Stanley J. Brooks typedef struct { n,p,l,v } LLP_Type; % next, prev, list , element typedef struct { f,ct } LL_Type; % first element, count of elements define make_list() { variable list = @LL_Type; list.f = NULL; list.ct = 0; return list; } define s_putlast(ls,v) { variable el = @LLP_Type; el.l = ls; el.v = v; ls.ct++; if (ls.f == NULL) { ls.f = el; el.p = el; el.n = el; return el; } variable el0 = ls.f; variable ell = el0.p; el.p = el0.p; el.n = el0; el0.p = el; ell.n = el; return el; } define s_put1st(ls,v) { ls.f = s_putlast(ls,v); return ls.f; } define s_del(el) { if (el == NULL) return; variable ls = el.l; ls.ct--; !if (ls.ct) { ls.f = NULL; return; } variable el1 = el.p; variable el2 = el.n; el1.n = el2; el2.p = el1; if (ls.f == el) ls.f = el2; } define s_put(p,wher,v) { !if(wher) { p.v = v; return p; } variable ls = p.l; variable el = @LLP_Type; el.l = ls; el.v = v; ls.ct++; variable el1,el2; if (wher > 0) { el1 = p; el2 = p.n; }else{ el1 = p.p; el2 = p; } variable el0 = ls.f; el.n = el2; el.p = el1; el2.p = el; el1.n = el; if (wher < 0) if (p == ls.f) ls.f = el; return el; } define s_move(tgt,wher,el) { if (el != tgt) { s_del(el); el = s_put(tgt,wher,el.v); } return el; } define s_ord(el) { variable ls = el.l; variable el0 = ls.f, elx, i = 0; for (elx = el0; elx != el; ) { i++; elx = elx.n; if (elx == el0) return -1; } return i; } define s_nth(ls,n) { variable elx; elx = ls.f; if (n < 0) n += ls.ct; if (mul2(n) > ls.ct) { if (n >= ls.ct) return NULL; loop (ls.ct - n) elx = elx.p; }else{ if (n < 0) return NULL; loop (n) elx = elx.n; } return elx; } define s_dofunc(ls,func) { if (ls.f == NULL) return; variable el0,el,i = 0; el0 = ls.f; el = el0; do { @func(el,i); i++; el = el.n; }while (el != el0); } define s_find_n(p,func) { if (p == NULL) return NULL; variable ls = p.l; variable el0,el; el0 = ls.f; el = p; do { !if (@func(el.v)) return el; el = el.n; }while (el != el0); return NULL; } define s_find_p(p,func) { if (p == NULL) return NULL; variable ls = p.l; variable el0,el; el0 = ls.f; el = p; do { !if (@func(el.v)) return el; el = el.p; }while (el != el0); return NULL; } % this should be jazzed up to take variable number of pm's define s_find_n1(p,func,pm2) { if (p == NULL) return NULL; variable ls = p.l; variable el0,el; el0 = ls.f; el = p; do { if (@func(el.v,pm2)) return el; el = el.n; }while (el != el0); return NULL; } define s_pr1(el,i) { vmessage("[%3d] %s",i,el.v); } define s_print(ls) { variable el0,el,i = 0; vmessage("List has %d elements",ls.ct); s_dofunc(ls,&s_pr1); message("List END -----------"); } define NC0_cmp(v,s) { return streq_i(v.nick,s);} define NC0_cmp_p(v,pfx) { return is_prefix_i(v.nick,pfx); }