char* tksend(TkTop *t, char *arg, char **ret) { TkVar *v; char *var; USED(ret); var = mallocz(Tkmaxitem, 0); if(var == nil) return TkNomem; arg = tkword(t, arg, var, var+Tkmaxitem, nil); v = tkmkvar(t, var, 0); free(var); if(v == nil) return TkBadvr; if(v->type != TkVchan) return TkNotvt; arg = tkskip(arg, " \t"); if(tktolimbo(v->value, arg) == 0) return TkMovfw; return nil; }
char* tkvariable(TkTop *t, char *arg, char **ret) { TkVar *v; char *fmt, *e, *buf, *ebuf, *val; int l; l = strlen(arg) + 2; buf = malloc(l); if(buf == nil) return TkNomem; ebuf = buf+l; arg = tkword(t, arg, buf, ebuf, nil); arg = tkskip(arg, " \t"); if (*arg == '\0') { if(strcmp(buf, "lasterror") == 0) { free(buf); if(t->err == nil) return nil; fmt = "%s: %s"; if(strlen(t->errcmd) == sizeof(t->errcmd)-1) fmt = "%s...: %s"; e = tkvalue(ret, fmt, t->errcmd, t->err); t->err = nil; return e; } v = tkmkvar(t, buf, 0); free(buf); if(v == nil || v->value == nil) return nil; if(v->type != TkVstring) return TkNotvt; return tkvalue(ret, "%s", v->value); } val = buf+strlen(buf)+1; tkword(t, arg, val, ebuf, nil); e = tksetvar(t, buf, val); free(buf); return e; }
static char* tkentryget(Tk *tk, char *arg, char **val) { TkTop *top; TkEntry *tke; int first, last; char *e, *buf; tke = TKobj(TkEntry, tk); if(tke->text == nil) return nil; arg = tkskip(arg, " \t"); if(*arg == '\0') return tkvalue(val, "%.*S", tke->textlen, tke->text); top = tk->env->top; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; arg = tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &first); if(e != nil) { free(buf); return e; } last = first+1; tkword(top, arg, buf, buf+Tkmaxitem, nil); if(buf[0] != '\0') { e = tkentryparseindex(tk, buf, &last); if(e != nil) { free(buf); return e; } } free(buf); if(last <= first || tke->textlen == 0 || first == tke->textlen) return tkvalue(val, "%S", L""); return tkvalue(val, "%.*S", last-first, tke->text+first); }
char* tkbind(TkTop *t, char *arg, char **ret) { Rune r; Tk *tk; TkAction **ap; int i, mode, event; char *cmd, *tag, *seq; char *e; USED(ret); tag = mallocz(Tkmaxitem, 0); if(tag == nil) return TkNomem; seq = mallocz(Tkmaxitem, 0); if(seq == nil) { free(tag); return TkNomem; } arg = tkword(t, arg, tag, tag+Tkmaxitem, nil); if(tag[0] == '\0') { e = TkBadtg; goto err; } arg = tkword(t, arg, seq, seq+Tkmaxitem, nil); if(seq[0] == '<') { event = tkseqparse(seq+1); if(event == -1) { e = TkBadsq; goto err; } } else { chartorune(&r, seq); event = TkKey | r; } if(event == 0) { e = TkBadsq; goto err; } arg = tkskip(arg, " \t"); mode = TkArepl; if(*arg == '+') { mode = TkAadd; arg++; } else if(*arg == '-'){ mode = TkAsub; arg++; } if(*arg == '{') { cmd = tkskip(arg+1, " \t"); if(*cmd == '}') { tk = tklook(t, tag, 0); if(tk == nil) { for(i = 0; ; i++) { if(i >= TKwidgets) { e = TkBadwp; tkerr(t, tag); goto err; } if(strcmp(tag, tkmethod[i]->name) == 0) { ap = &(t->binds[i]); break; } } } else ap = &tk->binds; tkcancel(ap, event); } } tkword(t, arg, seq, seq+Tkmaxitem, nil); if(tag[0] == '.') { tk = tklook(t, tag, 0); if(tk == nil) { e = TkBadwp; tkerr(t, tag); goto err; } cmd = strdup(seq); if(cmd == nil) { e = TkNomem; goto err; } e = tkaction(&tk->binds, event, TkDynamic, cmd, mode); if(e != nil) goto err; /* tkaction does free(cmd) */ free(tag); free(seq); return nil; } /* documented but doesn't work */ if(strcmp(tag, "all") == 0) { for(tk = t->root; tk; tk = tk->next) { cmd = strdup(seq); if(cmd == nil) { e = TkNomem; goto err; } e = tkaction(&tk->binds, event, TkDynamic, cmd, mode); if(e != nil) goto err; } free(tag); free(seq); return nil; } /* undocumented, probably unused, and doesn't work consistently */ for(i = 0; i < TKwidgets; i++) { if(strcmp(tag, tkmethod[i]->name) == 0) { cmd = strdup(seq); if(cmd == nil) { e = TkNomem; goto err; } e = tkaction(t->binds + i,event, TkDynamic, cmd, mode); if(e != nil) goto err; free(tag); free(seq); return nil; } } e = TkBadtg; err: free(tag); free(seq); return e; }
static char* tkcvsbind(Tk *tk, char *arg, char **val) { Rune r; TkCtag *t; TkName *f; TkAction *a; TkCanvas *c; int event, mode; char *cmd, buf[Tkmaxitem]; char *e; c = TKobj(TkCanvas, tk); if (c->actions >= c->actlim) tksweepcanv(tk); arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); f = tkctaglook(tk, nil, buf); if(f == nil) { f = tkctaglook(tk, tkmkname(buf), buf); if(f == nil) return TkNomem; } arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '<') { event = tkseqparse(buf+1); if(event == -1) return TkBadsq; } else { chartorune(&r, buf); event = TkKey | r; } if(event == 0) return TkBadsq; arg = tkskip(arg, " \t"); if(*arg == '\0') { for(t = f->obj; t; t = t->taglist) { for(a = t->name->prop.binds; a; a = a->link) if(event == a->event) return tkvalue(val, "%s", a->arg); for(a = t->name->prop.binds; a; a = a->link) if(event & a->event) return tkvalue(val, "%s", a->arg); } return nil; } mode = TkArepl; if(*arg == '+') { mode = TkAadd; arg++; } else if(*arg == '-'){ mode = TkAsub; arg++; } tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); cmd = strdup(buf); if(cmd == nil) return TkNomem; e = tkaction(&f->prop.binds, event, TkDynamic, cmd, mode); if(e == nil) c->actions++; return e; }