#include "lib9.h"#include "kernel.h"#include "draw.h"#include "tk.h" #define O(t, e) ((long)(&((t*)0)->e)) static char* pdist(TkTop*, TkOption*, void*, char**, char*, char*);static char* pstab(TkTop*, TkOption*, void*, char**, char*, char*);static char* ptext(TkTop*, TkOption*, void*, char**, char*, char*);static char* pwinp(TkTop*, TkOption*, void*, char**, char*, char*);static char* pbmap(TkTop*, TkOption*, void*, char**, char*, char*);static char* pbool(TkTop*, TkOption*, void*, char**, char*, char*);static char* pfont(TkTop*, TkOption*, void*, char**, char*, char*);static char* pfrac(TkTop*, TkOption*, void*, char**, char*, char*);static char* pnnfrac(TkTop*, TkOption*, void*, char**, char*, char*);static char* pctag(TkTop*, TkOption*, void*, char**, char*, char*);static char* ptabs(TkTop*, TkOption*, void*, char**, char*, char*);static char* pcolr(TkTop*, TkOption*, void*, char**, char*, char*);static char* pimag(TkTop*, TkOption*, void*, char**, char*, char*);static char* psize(TkTop*, TkOption*, void*, char**, char*, char*);static char* pnndist(TkTop*, TkOption*, void*, char**, char*, char*);static char* pact(TkTop*, TkOption*, void*, char**, char*, char*);static char* pignore(TkTop*, TkOption*, void*, char**, char*, char*);static char* psticky(TkTop*, TkOption*, void*, char**, char*, char*);static char* plist(TkTop*, TkOption*, void*, char**, char*, char*); static char* (*oparse[])(TkTop*, TkOption*, void*, char**, char*, char*) ={ /* OPTdist */ pdist, /* OPTstab */ pstab, /* OPTtext */ ptext, /* OPTwinp */ pwinp, /* OPTflag */ pstab, /* OPTbmap */ pbmap, /* OPTbool */ pbool, /* OPTfont */ pfont, /* OPTfrac */ pfrac, /* OPTnnfrac */ pnnfrac, /* OPTctag */ pctag, /* OPTtabs */ ptabs, /* OPTcolr */ pcolr, /* OPTimag */ pimag, /* OPTsize */ psize, /* OPTnndist */ pnndist, /* OPTact */ pact, /* OPTignore */ pignore, /* OPTsticky */ psticky, /* OPTlist */ plist,}; char*tkskip(char *s, char *bl){ char *p; while(*s) { for(p = bl; *p; p++) if(*p == *s) break; if(*p == '\0') return s; s++; } return s;} /* XXX - Tad: error propagation? */char*tkword(TkTop *t, char *str, char *buf, char *ebuf, int *gotarg){ int c, lev, tmp; char *val, *e, *p, *cmd; if (gotarg == nil) gotarg = &tmp; /* * ebuf is one beyond last byte in buf; leave room for nul byte in * all cases. */ --ebuf; str = tkskip(str, " \t"); *gotarg = 1; lev = 1; switch(*str) { case '{': /* XXX - DBK: According to Ousterhout (p.37), while back= * slashed braces don't count toward finding the matching * closing braces, the backslashes should not be removed. * Presumably this also applies to other backslashed * characters: the backslash should not be removed. */ str++; while(*str && buf < ebuf) { c = *str++; if(c == '\\') { if(*str == '}' || *str == '{' || *str == '\\') c = *str++; } else if(c == '}') { lev--; if(lev == 0) break; } else if(c == '{') lev++; *buf++ = c; } break; case '[': /* XXX - DBK: According to Ousterhout (p. 33) command * substitution may occur anywhere within a word, not * only (as here) at the beginning. */ cmd = malloc(strlen(str)); /* not strlen+1 because the first character is skipped */ if ( cmd == nil ) { buf[0] = '\0'; /* DBK - Why not an error message? */ return str; } p = cmd; str++; while(*str) { c = *str++; if(c == '\\') { if(*str == ']' || *str == '[' || *str == '\\') c = *str++; } else if(c == ']') { lev--; if(lev == 0) break; } else if(c == '[') lev++; *p++ = c; } *p = '\0'; val = nil; e = tkexec(t, cmd, &val); free(cmd); /* XXX - Tad: is this appropriate behavior? * Am I sure that the error doesn't need to be * propagated back to the caller? */ if(e == nil && val != nil) { strncpy(buf, val, ebuf-buf); buf = ebuf; free(val); } break; case '\'': str++; while(*str && buf < ebuf) *buf++ = *str++; break; case '\0': *gotarg = 0; break; default: /* XXX - DBK: See comment above about command substitution. * Also, any backslashed character should be replaced by * itself (e.g. to put a space, tab, or [ into a word. * We assume that the C compiler has already done the * standard ANSI C substitutions. (But should we?) */ while(*str && *str != ' ' && *str != '\t' && buf < ebuf) *buf++ = *str++; } *buf = '\0'; return str;} static TkOption*Getopt(TkOption *o, char *buf){ while(o->o != nil) { if(strcmp(buf, o->o) == 0) return o; o++; } return nil;} TkName*tkmkname(char *name){ TkName *n; n = malloc(sizeof(struct TkName)+strlen(name)); if(n == nil) return nil; strcpy(n->name, name); n->link = nil; n->obj = nil; return n;} char*tkparse(TkTop *t, char *str, TkOptab *ot, TkName **nl){ int l; TkOptab *ft; TkOption *o; TkName *f, *n; char *e, *buf, *ebuf; l = strlen(str); if (l < Tkmaxitem) l = Tkmaxitem; buf = malloc(l + 1); if(buf == 0) return TkNomem; ebuf = buf + l + 1; e = nil; while(e == nil) { str = tkword(t, str, buf, ebuf, nil); switch(*buf) { case '\0': goto done; case '-': if (buf[1] != '\0') { for(ft = ot; ft->ptr; ft++) { o = Getopt(ft->optab, buf+1); if(o != nil) { e = oparse[o->type](t, o, ft->ptr, &str, buf, ebuf); break; } } if(ft->ptr == nil){ e = TkBadop; tkerr(t, buf); } break; } /* fall through if we've got a singleton '-' */ default: if(nl == nil) { e = TkBadop; tkerr(t, buf); break; } n = tkmkname(buf); if(n == nil) { e = TkNomem; break; } if(*nl == nil) *nl = n; else { for(f = *nl; f->link; f = f->link) ; f->link = n; } } } if(e != nil && nl != nil) tkfreename(*nl);done: free(buf); return e;} char*tkconflist(TkOptab *ot, char **val){ TkOption *o; char *f, *e; f = "-%s"; while(ot->ptr != nil) { o = ot->optab; while(o->o != nil) { e = tkvalue(val, f, o->o); if(e != nil) return e; f = " -%s"; o++; } ot++; } return nil;} char*tkgencget(TkOptab *ft, char *arg, char **val, TkTop *t){ Tk *w; char *c; Point g; TkEnv *e; TkStab *s; TkOption *o; int wh, con, i, n, flag, *v; char *r, *buf, *fmt; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; tkitem(buf, arg); r = buf; if(*r == '-') r++; o = nil; while(ft->ptr) { o = Getopt(ft->optab, r); if(o != nil) break; ft++; } if(o == nil) { tkerr(t, r); free(buf); return TkBadop; } switch(o->type) { default: tkerr(t, r); free(buf); return TkBadop; case OPTignore: return nil; case OPTact: w = ft->ptr; g = tkposn(w); n = g.y; if(o->aux == 0) n = g.x; free(buf); return tkvalue(val, "%d", n); case OPTdist: case OPTnndist: free(buf); return tkvalue(val, "%d", OPTION(ft->ptr, int, o->offset)); case OPTsize: w = ft->ptr; if(strcmp(r, "width") == 0) wh = w->req.width; else wh = w->req.height; free(buf); return tkvalue(val, "%d", wh); case OPTtext: c = OPTION(ft->ptr, char*, o->offset); if(c == nil) c = ""; free(buf); return tkvalue(val, "%s", c); case OPTwinp: w = OPTION(ft->ptr, Tk*, o->offset); if(w == nil || w->name == nil) c = ""; else c = w->name->name; free(buf); return tkvalue(val, "%s", c); case OPTstab: s = o->aux; c = ""; con = OPTION(ft->ptr, int, o->offset); while(s->val) { if(con == s->con) { c = s->val; break; } s++; } free(buf); return tkvalue(val, "%s", c); case OPTflag: con = OPTION(ft->ptr, int, o->offset); flag = 0; for (s = o->aux; s->val != nil; s++) flag |= s->con; c = ""; for (s = o->aux; s->val != nil; s++) { if ((con & flag) == s->con) { c = s->val; break; } } free(buf); return tkvalue(val, "%s", c); case OPTfont: e = OPTION(ft->ptr, TkEnv*, o->offset); free(buf); if (e->font != nil) return tkvalue(val, "%s", e->font->name); return nil; case OPTcolr: e = OPTION(ft->ptr, TkEnv*, o->offset); i = AUXI(o->aux); free(buf); return tkvalue(val, "#%.8lux", e->colors[i]); case OPTfrac: case OPTnnfrac: v = &OPTION(ft->ptr, int, o->offset); n = (int)o->aux; if(n == 0) n = 1; fmt = "%s"; for(i = 0; i < n; i++) { tkfprint(buf, *v++); r = tkvalue(val, fmt, buf); if(r != nil) { free(buf); return r; } fmt = " %s"; } free(buf); return nil; case OPTbmap: return tkvalue(val, "%d", OPTION(ft->ptr, Image*, o->offset) != nil); case OPTimag: return tkvalue(val, "%d", OPTION(ft->ptr, TkImg*, o->offset) != nil); }} static char*pact(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){ USED(buf); USED(ebuf); USED(str); USED(place); tkerr(t, o->o); return TkBadop;} static char*pignore(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){ char *p; USED(t); USED(o); USED(place); p = tkword(t, *str, buf, ebuf, nil); if(*buf == '\0') return TkOparg; *str = p; return nil;} static char*pdist(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){ int d; char *e; TkEnv *env; USED(buf); USED(ebuf); /* * this is a bit of a hack, as 0 is a valid option offset, * but a nil aux is commonly used when 'w' and 'h' suffixes * aren't appropriate. * just make sure that no structure placed in TkOptab->ptr * with an OPTdist element has a TkEnv as its first member. */ if (o->aux == nil) env = nil; else env = OPTION(place, TkEnv*, AUXI(o->aux)); e = tkfracword(t, str, &d, env); if(e != nil) return e; OPTION(place, int, o->offset) = TKF2I(d); return nil;} static char*pnndist(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){ char* e; int oldv; oldv = OPTION(place, int, o->offset); e = pdist(t, o, place, str, buf, ebuf); if(e == nil && OPTION(place, int, o->offset) < 0) { OPTION(place, int, o->offset) = oldv; return TkBadvl; } return e; } static char*psize(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){Lines 1–500 of 1165. Load more
#include "lib9.h" #include "kernel.h" #include "draw.h" #include "tk.h" #define O(t, e) ((long)(&((t*)0)->e)) static char* pdist(TkTop*, TkOption*, void*, char**, char*, char*); static char* pstab(TkTop*, TkOption*, void*, char**, char*, char*); static char* ptext(TkTop*, TkOption*, void*, char**, char*, char*); static char* pwinp(TkTop*, TkOption*, void*, char**, char*, char*); static char* pbmap(TkTop*, TkOption*, void*, char**, char*, char*); static char* pbool(TkTop*, TkOption*, void*, char**, char*, char*); static char* pfont(TkTop*, TkOption*, void*, char**, char*, char*); static char* pfrac(TkTop*, TkOption*, void*, char**, char*, char*); static char* pnnfrac(TkTop*, TkOption*, void*, char**, char*, char*); static char* pctag(TkTop*, TkOption*, void*, char**, char*, char*); static char* ptabs(TkTop*, TkOption*, void*, char**, char*, char*); static char* pcolr(TkTop*, TkOption*, void*, char**, char*, char*); static char* pimag(TkTop*, TkOption*, void*, char**, char*, char*); static char* psize(TkTop*, TkOption*, void*, char**, char*, char*); static char* pnndist(TkTop*, TkOption*, void*, char**, char*, char*); static char* pact(TkTop*, TkOption*, void*, char**, char*, char*); static char* pignore(TkTop*, TkOption*, void*, char**, char*, char*); static char* psticky(TkTop*, TkOption*, void*, char**, char*, char*); static char* plist(TkTop*, TkOption*, void*, char**, char*, char*); static char* (*oparse[])(TkTop*, TkOption*, void*, char**, char*, char*) = { /* OPTdist */ pdist, /* OPTstab */ pstab, /* OPTtext */ ptext, /* OPTwinp */ pwinp, /* OPTflag */ pstab, /* OPTbmap */ pbmap, /* OPTbool */ pbool, /* OPTfont */ pfont, /* OPTfrac */ pfrac, /* OPTnnfrac */ pnnfrac, /* OPTctag */ pctag, /* OPTtabs */ ptabs, /* OPTcolr */ pcolr, /* OPTimag */ pimag, /* OPTsize */ psize, /* OPTnndist */ pnndist, /* OPTact */ pact, /* OPTignore */ pignore, /* OPTsticky */ psticky, /* OPTlist */ plist, }; char* tkskip(char *s, char *bl) { char *p; while(*s) { for(p = bl; *p; p++) if(*p == *s) break; if(*p == '\0') return s; s++; } return s; } /* XXX - Tad: error propagation? */ char* tkword(TkTop *t, char *str, char *buf, char *ebuf, int *gotarg) { int c, lev, tmp; char *val, *e, *p, *cmd; if (gotarg == nil) gotarg = &tmp; /* * ebuf is one beyond last byte in buf; leave room for nul byte in * all cases. */ --ebuf; str = tkskip(str, " \t"); *gotarg = 1; lev = 1; switch(*str) { case '{': /* XXX - DBK: According to Ousterhout (p.37), while back= * slashed braces don't count toward finding the matching * closing braces, the backslashes should not be removed. * Presumably this also applies to other backslashed * characters: the backslash should not be removed. */ str++; while(*str && buf < ebuf) { c = *str++; if(c == '\\') { if(*str == '}' || *str == '{' || *str == '\\') c = *str++; } else if(c == '}') { lev--; if(lev == 0) break; } else if(c == '{') lev++; *buf++ = c; } break; case '[': /* XXX - DBK: According to Ousterhout (p. 33) command * substitution may occur anywhere within a word, not * only (as here) at the beginning. */ cmd = malloc(strlen(str)); /* not strlen+1 because the first character is skipped */ if ( cmd == nil ) { buf[0] = '\0'; /* DBK - Why not an error message? */ return str; } p = cmd; str++; while(*str) { c = *str++; if(c == '\\') { if(*str == ']' || *str == '[' || *str == '\\') c = *str++; } else if(c == ']') { lev--; if(lev == 0) break; } else if(c == '[') lev++; *p++ = c; } *p = '\0'; val = nil; e = tkexec(t, cmd, &val); free(cmd); /* XXX - Tad: is this appropriate behavior? * Am I sure that the error doesn't need to be * propagated back to the caller? */ if(e == nil && val != nil) { strncpy(buf, val, ebuf-buf); buf = ebuf; free(val); } break; case '\'': str++; while(*str && buf < ebuf) *buf++ = *str++; break; case '\0': *gotarg = 0; break; default: /* XXX - DBK: See comment above about command substitution. * Also, any backslashed character should be replaced by * itself (e.g. to put a space, tab, or [ into a word. * We assume that the C compiler has already done the * standard ANSI C substitutions. (But should we?) */ while(*str && *str != ' ' && *str != '\t' && buf < ebuf) *buf++ = *str++; } *buf = '\0'; return str; } static TkOption* Getopt(TkOption *o, char *buf) { while(o->o != nil) { if(strcmp(buf, o->o) == 0) return o; o++; } return nil; } TkName* tkmkname(char *name) { TkName *n; n = malloc(sizeof(struct TkName)+strlen(name)); if(n == nil) return nil; strcpy(n->name, name); n->link = nil; n->obj = nil; return n; } char* tkparse(TkTop *t, char *str, TkOptab *ot, TkName **nl) { int l; TkOptab *ft; TkOption *o; TkName *f, *n; char *e, *buf, *ebuf; l = strlen(str); if (l < Tkmaxitem) l = Tkmaxitem; buf = malloc(l + 1); if(buf == 0) return TkNomem; ebuf = buf + l + 1; e = nil; while(e == nil) { str = tkword(t, str, buf, ebuf, nil); switch(*buf) { case '\0': goto done; case '-': if (buf[1] != '\0') { for(ft = ot; ft->ptr; ft++) { o = Getopt(ft->optab, buf+1); if(o != nil) { e = oparse[o->type](t, o, ft->ptr, &str, buf, ebuf); break; } } if(ft->ptr == nil){ e = TkBadop; tkerr(t, buf); } break; } /* fall through if we've got a singleton '-' */ default: if(nl == nil) { e = TkBadop; tkerr(t, buf); break; } n = tkmkname(buf); if(n == nil) { e = TkNomem; break; } if(*nl == nil) *nl = n; else { for(f = *nl; f->link; f = f->link) ; f->link = n; } } } if(e != nil && nl != nil) tkfreename(*nl); done: free(buf); return e; } char* tkconflist(TkOptab *ot, char **val) { TkOption *o; char *f, *e; f = "-%s"; while(ot->ptr != nil) { o = ot->optab; while(o->o != nil) { e = tkvalue(val, f, o->o); if(e != nil) return e; f = " -%s"; o++; } ot++; } return nil; } char* tkgencget(TkOptab *ft, char *arg, char **val, TkTop *t) { Tk *w; char *c; Point g; TkEnv *e; TkStab *s; TkOption *o; int wh, con, i, n, flag, *v; char *r, *buf, *fmt; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; tkitem(buf, arg); r = buf; if(*r == '-') r++; o = nil; while(ft->ptr) { o = Getopt(ft->optab, r); if(o != nil) break; ft++; } if(o == nil) { tkerr(t, r); free(buf); return TkBadop; } switch(o->type) { default: tkerr(t, r); free(buf); return TkBadop; case OPTignore: return nil; case OPTact: w = ft->ptr; g = tkposn(w); n = g.y; if(o->aux == 0) n = g.x; free(buf); return tkvalue(val, "%d", n); case OPTdist: case OPTnndist: free(buf); return tkvalue(val, "%d", OPTION(ft->ptr, int, o->offset)); case OPTsize: w = ft->ptr; if(strcmp(r, "width") == 0) wh = w->req.width; else wh = w->req.height; free(buf); return tkvalue(val, "%d", wh); case OPTtext: c = OPTION(ft->ptr, char*, o->offset); if(c == nil) c = ""; free(buf); return tkvalue(val, "%s", c); case OPTwinp: w = OPTION(ft->ptr, Tk*, o->offset); if(w == nil || w->name == nil) c = ""; else c = w->name->name; free(buf); return tkvalue(val, "%s", c); case OPTstab: s = o->aux; c = ""; con = OPTION(ft->ptr, int, o->offset); while(s->val) { if(con == s->con) { c = s->val; break; } s++; } free(buf); return tkvalue(val, "%s", c); case OPTflag: con = OPTION(ft->ptr, int, o->offset); flag = 0; for (s = o->aux; s->val != nil; s++) flag |= s->con; c = ""; for (s = o->aux; s->val != nil; s++) { if ((con & flag) == s->con) { c = s->val; break; } } free(buf); return tkvalue(val, "%s", c); case OPTfont: e = OPTION(ft->ptr, TkEnv*, o->offset); free(buf); if (e->font != nil) return tkvalue(val, "%s", e->font->name); return nil; case OPTcolr: e = OPTION(ft->ptr, TkEnv*, o->offset); i = AUXI(o->aux); free(buf); return tkvalue(val, "#%.8lux", e->colors[i]); case OPTfrac: case OPTnnfrac: v = &OPTION(ft->ptr, int, o->offset); n = (int)o->aux; if(n == 0) n = 1; fmt = "%s"; for(i = 0; i < n; i++) { tkfprint(buf, *v++); r = tkvalue(val, fmt, buf); if(r != nil) { free(buf); return r; } fmt = " %s"; } free(buf); return nil; case OPTbmap: return tkvalue(val, "%d", OPTION(ft->ptr, Image*, o->offset) != nil); case OPTimag: return tkvalue(val, "%d", OPTION(ft->ptr, TkImg*, o->offset) != nil); } } static char* pact(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf) { USED(buf); USED(ebuf); USED(str); USED(place); tkerr(t, o->o); return TkBadop; } static char* pignore(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf) { char *p; USED(t); USED(o); USED(place); p = tkword(t, *str, buf, ebuf, nil); if(*buf == '\0') return TkOparg; *str = p; return nil; } static char* pdist(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf) { int d; char *e; TkEnv *env; USED(buf); USED(ebuf); /* * this is a bit of a hack, as 0 is a valid option offset, * but a nil aux is commonly used when 'w' and 'h' suffixes * aren't appropriate. * just make sure that no structure placed in TkOptab->ptr * with an OPTdist element has a TkEnv as its first member. */ if (o->aux == nil) env = nil; else env = OPTION(place, TkEnv*, AUXI(o->aux)); e = tkfracword(t, str, &d, env); if(e != nil) return e; OPTION(place, int, o->offset) = TKF2I(d); return nil; } static char* pnndist(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf) { char* e; int oldv; oldv = OPTION(place, int, o->offset); e = pdist(t, o, place, str, buf, ebuf); if(e == nil && OPTION(place, int, o->offset) < 0) { OPTION(place, int, o->offset) = oldv; return TkBadvl; } return e; } static char* psize(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf) {