static void zapf_assoc(char *botnick, char *code, char *par) { int idx = nextbot(botnick); char *s, *s1, *nick; int linking = 0, chan; if ((idx >= 0) && !(bot_flags(dcc[idx].user) & BOT_ISOLATE)) { if (!egg_strcasecmp(dcc[idx].nick, botnick)) linking = b_status(idx) & STAT_LINKING; s = newsplit(&par); chan = base64_to_int(s); if ((chan > 0) || (chan < GLOBAL_CHANS)) { nick = newsplit(&par); s1 = get_assoc_name(chan); if (linking && ((s1 == NULL) || (s1[0] == 0) || (((intptr_t) get_user(find_entry_type("BOTFL"), dcc[idx].user) & BOT_HUB)))) { add_assoc(par, chan); botnet_send_assoc(idx, chan, nick, par); chanout_but(-1, chan, ASSOC_CHNAME_NAMED, nick, par); } else if (par[0] == '0') { kill_assoc(chan); chanout_but(-1, chan, ASSOC_CHNAME_REM, botnick, nick); } else if (get_assoc(par) != chan) { /* New one i didn't know about -- pass it on */ s1 = get_assoc_name(chan); add_assoc(par, chan); chanout_but(-1, chan, ASSOC_CHNAME_NAMED2, botnick, nick, par); } } } }
/* Registers association in appropriate associations list and possibly in list * of active associations, which depends on association type and execution * environment. */ static void register_assoc(assoc_t assoc, int for_x, int in_x) { add_assoc(for_x ? &xfiletypes : &filetypes, assoc); if(!for_x || in_x) { add_assoc(&active_filetypes, assoc); } }
static void set_ext_programs(const char *extension, const char *programs, int for_x) { if(extension[0] == '\0') return; if(for_x) cfg.xfiletypes_num = add_assoc(&xfiletypes, cfg.xfiletypes_num, extension, programs); else cfg.filetypes_num = add_assoc(&filetypes, cfg.filetypes_num, extension, programs); if(!for_x || !curr_stats.is_console) nfiletypes = add_assoc(&all_filetypes, nfiletypes, extension, programs); }
/* Associates pattern with the list of viewers. */ static void assoc_viewers(matcher_t *matcher, const assoc_records_t *viewers) { const assoc_t assoc = { .matcher = matcher, .records = clone_assoc_records(viewers, matcher_get_expr(matcher), &fileviewers), }; add_assoc(&fileviewers, assoc); } /* Clones list of association records. Returns the clone. */ static assoc_records_t clone_assoc_records(const assoc_records_t *records, const char pattern[], const assoc_list_t *dst) { int i; assoc_records_t list = {}; for(i = 0; i < records->count; ++i) { if(!ft_assoc_exists(dst, pattern, records->list[i].command)) { ft_assoc_record_add(&list, records->list[i].command, records->list[i].description); } } return list; }
static void assoc_viewer(const char *pattern, const char *viewer) { int i; if(pattern[0] == '\0') { return; } for(i = 0; i < fileviewers.count; i++) { if(strcasecmp(fileviewers.list[i].pattern, pattern) == 0) { break; } } if(i == fileviewers.count) { assoc_t assoc = { .pattern = strdup(pattern), .records.list = NULL, .records.count = 0, }; add_assoc_record(&assoc.records, viewer, ""); add_assoc(&fileviewers, assoc); } else {
static bool pbind_vars(obj* vars, obj lt){ obj utype; switch(lt->type){ default: break; case tSymbol: if(vars) add_assoc(vars, lt, nil); return true; case tRef: assert(0); let(&(uref(lt)), nil); return true; case INT: assert(0); // return equal(lt,rt); case tOp: utype = search_assoc(curr_interp->types, ult(lt)); if(utype){ return pbind_vars(vars, urt(lt)); } pbind_vars(vars, ult(lt)); return pbind_vars(vars, urt(lt)); case LIST: list x=ul(lt); for(; (x); x=rest(x)){ pbind_vars(vars, first(x)); } return true; } print(lt); assert(0); return nil; }
static bool bind_vars(obj* vars, obj lt, obj rt){ obj utype; switch(lt->type){ default: break; case tSymbol: if(macromode){ if(obj rr = search_assoc(car(macro_env), lt)){ //macromode = false; if(vars) add_assoc(vars, rr, rt); //macromode = true; return true; } } if(vars) add_assoc(vars, lt, rt); return true; case tRef: let(&(uref(lt)), rt); return true; case INT: return equal(lt, rt); case tOp: utype = search_assoc(curr_interp->types, ult(lt)); if(utype){ if(vrInt(utype) != rt->type) return false; return bind_vars(vars, urt(lt), uref(rt)); } if(rt->type!=tOp) return false; if(! bind_vars(vars, ult(lt), ult(rt))) return false; return bind_vars(vars, urt(lt), urt(rt)); case LIST: if(rt->type!=LIST) return false; list x=ul(lt), a=ul(rt); for(; (x && a); x=rest(x),a=rest(a)){ if(!bind_vars(vars, first(x), first(a))) return false; } if(x||a) return false; return true; } print(lt); assert(0); return nil; }
static obj* lfind_var(obj id){ if(id->type==tRef) return &(uref(id)); if(env){ for(obj e=env; e; e=cdr(e)){ //if(e->refcount !=1) break; 140105 wrong because can't change enclosed vars obj* v = left_search(car(e), id); if (v) return v; } /*/ obj *v; obj e = lfind_local(env, id, &v); if(e) {release(env); env = e; return v;} if(v) return v; //*/ return add_assoc(&car(env), id, nil); //local } else { // when in global space obj* v = left_search(curr_interp->gl_vars, id);//global if(v) return v; return add_assoc(&(curr_interp->gl_vars), id, nil); //global } }
static void add_assoc(char *name, int chan) { assoc_t *a, *b, *old = NULL; for (a = assoc; a; a = a->next) { if (name[0] != 0 && !egg_strcasecmp(a->name, name)) { kill_assoc(a->channel); add_assoc(name, chan); return; } if (a->channel == chan) { strncpyz(a->name, name, sizeof a->name); return; } } /* Add in numerical order */ for (a = assoc; a; old = a, a = a->next) { if (a->channel > chan) { b = nmalloc(sizeof *b); b->next = a; b->channel = chan; strncpyz(b->name, name, sizeof b->name); if (old == NULL) assoc = b; else old->next = b; return; } } /* Add at the end */ b = nmalloc(sizeof *b); b->next = NULL; b->channel = chan; strncpyz(b->name, name, sizeof b->name); if (old == NULL) assoc = b; else old->next = b; }
static void set_ext_viewer(const char *extension, const char *viewer) { int x; if(extension[0] == '\0') return; for(x = 0; x < cfg.fileviewers_num; x++) if(strcasecmp(fileviewers[x].ext, extension) == 0) break; if(x == cfg.fileviewers_num) { cfg.fileviewers_num = add_assoc(&fileviewers, cfg.fileviewers_num, extension, viewer); } else { free(fileviewers[x].com); fileviewers[x].com = strdup(viewer); } }
static int cmd_assoc(struct userrec *u, int idx, char *par) { char *num; int chan; if (!par[0]) { putlog(LOG_CMDS, "*", "#%s# assoc", dcc[idx].nick); dump_assoc(idx); } else if (!u || !(u->flags & USER_BOTMAST)) dprintf(idx, "%s", MISC_NOSUCHCMD); else { num = newsplit(&par); if (num[0] == '*') { chan = GLOBAL_CHANS + atoi(num + 1); if ((chan < GLOBAL_CHANS) || (chan > 199999)) { dprintf(idx, "%s\n", ASSOC_LCHAN_RANGE); return 0; } } else { chan = atoi(num); if (chan == 0) { dprintf(idx, "%s\n", ASSOC_PARTYLINE); return 0; } else if ((chan < 1) || (chan >= GLOBAL_CHANS)) { dprintf(idx, "%s\n", ASSOC_CHAN_RANGE); return 0; } } if (!par[0]) { /* Remove an association */ if (get_assoc_name(chan) == NULL) { dprintf(idx, ASSOC_NONAME_CHAN, (chan < GLOBAL_CHANS) ? "" : "*", chan % GLOBAL_CHANS); return 0; } kill_assoc(chan); putlog(LOG_CMDS, "*", "#%s# assoc %d", dcc[idx].nick, chan); dprintf(idx, ASSOC_REMNAME_CHAN, (chan < GLOBAL_CHANS) ? "" : "*", chan % GLOBAL_CHANS); chanout_but(-1, chan, ASSOC_REMOUT_CHAN, dcc[idx].nick); if (chan < GLOBAL_CHANS) botnet_send_assoc(-1, chan, dcc[idx].nick, "0"); return 0; } if (strlen(par) > 20) { dprintf(idx, "%s\n", ASSOC_CHNAME_TOOLONG); return 0; } if ((par[0] >= '0') && (par[0] <= '9')) { dprintf(idx, "%s\n", ASSOC_CHNAME_FIRSTCHAR); return 0; } add_assoc(par, chan); putlog(LOG_CMDS, "*", "#%s# assoc %d %s", dcc[idx].nick, chan, par); dprintf(idx, ASSOC_NEWNAME_CHAN, (chan < GLOBAL_CHANS) ? "" : "*", chan % GLOBAL_CHANS, par); chanout_but(-1, chan, ASSOC_NEWOUT_CHAN, dcc[idx].nick, par); if (chan < GLOBAL_CHANS) botnet_send_assoc(-1, chan, dcc[idx].nick, par); } return 0; }
void newType(obj identifier){ static int uniq=tLast+1; add_assoc(&(curr_interp->types), identifier, Int(uniq)); uniq++; }
static void enclose0(obj v){ assert(!! v); switch(v->type){ case tSymbol: /* if( macromode) { for(obj e = macro_env; e; e = cdr(e)){ obj rr = search_assoc(car(e), v); if (v) { rr = v; break;} } //if(obj rr = search_assoc(car(macro_env), v)){ v=rr;} } //*/ if(is_in(penv, v)) return; if(search_pair(vto_close, car(v))) return; add_assoc(&vto_close, v, nil); return; case tAssign: enclose0(cdr(v)); if(is_in(penv, car(v))) return; if(search_pair(vto_close, car(v))) return; if(is_in(env, car(v))) { add_assoc(&vto_close, car(v), nil); return; } add_assoc(&car(penv), car(v), nil); // new assignment return; case tClosure: assert(0); case tArrow:{ obj vs = Assoc(); pbind_vars(&vs, em0(v)); penv = op(vs, penv); enclose0(em1(v)); release(pop(&penv)); return; } case tDefine: case tSyntaxDef: assert(0); case tArray: for(int i=0; i < uar(v).size; i++) enclose0(uar(v).v[i]); return; case LIST: //list case POW: case MULT: case DIVIDE: case ARITH: case CONDITION: case tIf: case tExec: case tAnd: for(list s=ul(v); s; s=rest(s)) enclose0(first(s)); return; case tReturn: if(!uref(v)) return; case tMinus: enclose0(uref(v)); return; case tInd: case tWhile: case tOp: enclose0(car(v)); enclose0(cdr(v)); return; case INT: case tDouble: case TOKEN: case tNull: case tLAVec: case tDblArray: case tIntArr: case tDblAr2: case IMAGE: case STRING: case tBreak: return; default: break; } print(v); assert(0); return; }
obj subs0(obj v, obj * vars){ assert(!! v); switch(v->type){ case tSymbol: if(vars){ // macro obj vp = search_assoc(*vars, v); if(vp) return vp; // vp = searchFunc(v, specials); // if(vp) {release(vp); return retain(v);} obj (*func)(obj) = searchFunc(v, specials); if(func) return retain(v); vp = find_var(v); if(vp) {release(vp); return retain(v);} assert(0); // return ref2var(add_assoc(*vars, v, Null())); } else { // quasi-quote obj vp = find_var(v); if(vp) return vp; return retain(v); } case tAssign:{ obj vp = search_assoc(*vars, car(v)); //macro-locals if(vp) goto nex; /* vp = searchFunc(car(v), specials); // not needed because cant assign to global if(vp) {release(vp); vp = retain(v); return vp;} vp = find_var(v); if(vp) {release(vp); vp = retain(v); return vp;} */ vp = ref2var(nil); add_assoc(vars, car(v), vp); nex: return operate(tAssign, vp, subs0(cdr(v), vars)); } case tArray:{ obj r = aArray(uar(v).size); for(int i=0; i < uar(v).size; i++) uar(r).v[i] = subs0(uar(v).v[i], vars); return r; } case LIST: //list case POW: case MULT: case DIVIDE: case ARITH: case CONDITION: case tIf: case tExec: { list l = phi(); for(list s=ul(v); s; s=rest(s)) l = cons(subs0(first(s), vars), l); return render(type(v), reverse(l)); } case tReturn: if(!uref(v)) return retain(v); case tMinus: return encap(v->type, subs0(uref(v), vars)); case tClosure: case tArrow: return render(type(v), list3(subs0(em0(v),vars), subs0(em1(v), vars), nil)); case tDefine: case tSyntaxDef: assert(0); case tInd: case tWhile: { obj st = subs0(cdr(v), vars); if(type(st)==LIST) st->type = tExec; return operate(v->type, subs0(car(v), vars), st); } case tOp: return operate(v->type, subs0(car(v), vars), subs0(cdr(v), vars)); case INT: case tDouble: case TOKEN: case tNull: case tLAVec: case tDblArray: case tIntArr: case tDblAr2: case IMAGE: case STRING: case tBreak: return retain(v); default: break; } print(v); assert(0); return v; }