commit 012a8a02d5e43c1d4698acf42da61f4429c3ac1f from: rsc date: Fri Oct 22 17:11:30 2004 UTC change md argument to number etc. (which acted only as a flag) to an actual flag. buffer underrun check in number add xdata file for exactly the addressed region save addr across opens commit - e63027eb68ff7252598003151d238dee8850ad34 commit + 012a8a02d5e43c1d4698acf42da61f4429c3ac1f blob - 04931905d53b80a7217c68a41859426164ed42e3 blob + 18765bcd92158afcfc6259e5db73764d5792aa52 --- src/cmd/acme/acme.c +++ src/cmd/acme/acme.c @@ -67,6 +67,11 @@ threadmain(int argc, char *argv[]) loadfile = nil; ARGBEGIN{ + case 'D': + {extern int _threaddebuglevel; + _threaddebuglevel = ~0; + } + break; case 'a': globalautoindent = TRUE; break; @@ -643,6 +648,21 @@ waitthread(void *v) alts[WCmd].op = CHANRCV; alts[NWALT].op = CHANEND; + /* + * BUG. Actually there's no bug here but this is the + * first place you'd look. When a program is run, + * it doesn't disappear from the main tag until the + * mouse is moved or keyboard is hit. This would + * suggest that the WWait case isn't working right, + * but what's actually going on is that the X11 code + * is running a select-based threading loop that + * doesn't get interrupted until there is data from X11. + * This was done to make acme work on Suns and + * other systems where our threading was sub-par. + * Now that we've gotten pthreads working (sort of), + * we might be able to fix this properly. + * But the bug is in libdraw and libthread, not here. + */ command = nil; for(;;){ switch(alt(alts)){ blob - 2a3447425ae922a13ab668783f87b869e6af212c blob + 4e31d6aef55064a1d64e72fbc4449e8546b471ba --- src/cmd/acme/addr.c +++ src/cmd/acme/addr.c @@ -49,7 +49,7 @@ isregexc(int r) } Range -number(Mntdir *md, Text *t, Range r, int line, int dir, int size, int *evalp) +number(uint showerr, Text *t, Range r, int line, int dir, int size, int *evalp) { uint q0, q1; @@ -82,7 +82,7 @@ number(Mntdir *md, Text *t, Range r, int line, int dir break; case Fore: if(q1 > 0) - while(textreadc(t, q1-1) != '\n') + while(q1file->b.nc && textreadc(t, q1-1) != '\n') q1++; q0 = q1; goto Forward; @@ -107,7 +107,7 @@ number(Mntdir *md, Text *t, Range r, int line, int dir return range(q0, q1); Rescue: - if(md != nil) + if(showerr) warning(nil, "address out of range\n"); *evalp = FALSE; return r; @@ -115,14 +115,15 @@ number(Mntdir *md, Text *t, Range r, int line, int dir Range -regexp(Mntdir *md, Text *t, Range lim, Range r, Rune *pat, int dir, int *foundp) +regexp(uint showerr, Text *t, Range lim, Range r, Rune *pat, int dir, int *foundp) { int found; Rangeset sel; int q; if(pat[0] == '\0' && rxnull()){ - warning(md, "no previous regular expression\n"); + if(showerr) + warning(nil, "no previous regular expression\n"); *foundp = FALSE; return r; } @@ -137,16 +138,17 @@ regexp(Mntdir *md, Text *t, Range lim, Range r, Rune * q = Infinity; else q = lim.q1; +warning(nil, "searching %d-%d\n", r.q1, q); found = rxexecute(t, nil, r.q1, q, &sel); } - if(!found && md==nil) + if(!found && showerr) warning(nil, "no match for regexp\n"); *foundp = found; return sel.r[0]; } Range -address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int (*getc)(void*, uint), int *evalp, uint *qp) +address(uint showerr, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int (*getc)(void*, uint), int *evalp, uint *qp) { int dir, size, npat; int prevc, c, nc, n; @@ -175,7 +177,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void if(q>=q1 && t!=nil && t->file!=nil) /* rhs defaults to $ */ r.q1 = t->file->b.nc; else{ - nr = address(md, t, lim, ar, a, q, q1, getc, evalp, &q); + nr = address(showerr, t, lim, ar, a, q, q1, getc, evalp, &q); r.q1 = nr.q1; } *qp = q; @@ -184,7 +186,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void case '-': if(*evalp && (prevc=='+' || prevc=='-')) if((nc=(*getc)(a, q))!='#' && nc!='/' && nc!='?') - r = number(md, t, r, 1, prevc, Line, evalp); /* do previous one */ + r = number(showerr, t, r, 1, prevc, Line, evalp); /* do previous one */ dir = c; break; case '.': @@ -222,7 +224,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void n = n*10+(c-'0'); } if(*evalp) - r = number(md, t, r, n, dir, size, evalp); + r = number(showerr, t, r, n, dir, size, evalp); dir = None; size = Line; break; @@ -255,7 +257,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void pat = runerealloc(pat, npat+1); pat[npat] = 0; if(*evalp) - r = regexp(md, t, lim, r, pat, dir, evalp); + r = regexp(showerr, t, lim, r, pat, dir, evalp); free(pat); dir = None; size = Line; @@ -263,7 +265,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void } } if(*evalp && dir != None) - r = number(md, t, r, 1, dir, Line, evalp); /* do previous one */ + r = number(showerr, t, r, 1, dir, Line, evalp); /* do previous one */ *qp = q; return r; } blob - fe4b060116e86ba1c0c733dbe2f0bc5997e77ffd blob + 48a57dd2ccb543b92a6eff51e3c6091694361a02 --- src/cmd/acme/dat.h +++ src/cmd/acme/dat.h @@ -19,6 +19,7 @@ enum QWrdsel, QWwrsel, QWtag, + QWxdata, QMAX, }; @@ -30,6 +31,7 @@ enum Infinity = 0x7FFFFFFF, /* huge value for regexp address */ }; +#define Buffer AcmeBuffer typedef struct Block Block; typedef struct Buffer Buffer; typedef struct Command Command; blob - 37d5edaef99f81d70e922c7197a0be61c31ef922 blob + 85ef69a5a236086eedd71c50818c41e66bc1b73c --- src/cmd/acme/exec.c +++ src/cmd/acme/exec.c @@ -342,7 +342,7 @@ delcol(Text *et, Text *_0, Text *_1, int _2, int _3, R return; for(i=0; inw; i++){ w = c->w[i]; - if(w->nopen[QWevent]+w->nopen[QWaddr]+w->nopen[QWdata] > 0){ + if(w->nopen[QWevent]+w->nopen[QWaddr]+w->nopen[QWdata]+w->nopen[QWxdata] > 0){ warning(nil, "can't delete column; %.*S is running an external command\n", w->body.file->nname, w->body.file->name); return; } @@ -1528,7 +1528,7 @@ Hard: if(ret >= 0){ if(cpid) sendul(cpid, ret); - threadexits(""); + threadexits(nil); } warning(nil, "exec rc: %r\n"); blob - 2257d681a094ea3569e7af968285b005d7bf5d21 blob + c61f96ecf1b98ca54e502ab525e08176d38f82c9 --- src/cmd/acme/fns.h +++ src/cmd/acme/fns.h @@ -81,7 +81,7 @@ int isregexc(int); void *emalloc(uint); void *erealloc(void*, uint); char *estrdup(char*); -Range address(Mntdir*, Text*, Range, Range, void*, uint, uint, int (*)(void*, uint), int*, uint*); +Range address(uint, Text*, Range, Range, void*, uint, uint, int (*)(void*, uint), int*, uint*); int rxexecute(Text*, Rune*, uint, uint, Rangeset*); int rxbexecute(Text*, uint, Rangeset*); Window* makenewwindow(Text *t); blob - 50e63411d4b39db2064990439f90fcdadadaa1df blob + a095529f8e2b49ce4320db78e2efe1686b4866dc --- src/cmd/acme/fsys.c +++ src/cmd/acme/fsys.c @@ -87,6 +87,7 @@ Dirtab dirtabw[]= { "rdsel", QTFILE, QWrdsel, 0400 }, { "wrsel", QTFILE, QWwrsel, 0200 }, { "tag", QTAPPEND, QWtag, 0600|DMAPPEND }, + { "xdata", QTFILE, QWxdata, 0600 }, { nil, } }; blob - f892640a27e28e1daceefd8555e14051fbafa9aa blob + d760745df6ff9e212145eb331c70e0b4fffa4b10 --- src/cmd/acme/look.c +++ src/cmd/acme/look.c @@ -591,7 +591,7 @@ expandfile(Text *t, uint q0, uint q1, Expand *e) e->u.at = t; e->a0 = amin+1; eval = FALSE; - address(nil, nil, range(-1,-1), range(0,0), t, e->a0, amax, tgetc, &eval, (uint*)&e->a1); + address(TRUE, nil, range(-1,-1), range(0,0), t, e->a0, amax, tgetc, &eval, (uint*)&e->a1); return TRUE; Isntfile: @@ -723,7 +723,7 @@ openfile(Text *t, Expand *e) eval = FALSE; else{ eval = TRUE; - r = address(nil, t, range(-1,-1), range(t->q0, t->q1), e->u.at, e->a0, e->a1, e->agetc, &eval, &dummy); + r = address(TRUE, t, range(-1,-1), range(t->q0, t->q1), e->u.at, e->a0, e->a1, e->agetc, &eval, &dummy); if(eval == FALSE) e->jump = FALSE; /* don't jump if invalid address */ } blob - 5fc4c5a5d24ba932dfef98cdf26fd08373973bb1 blob + 5a2723a435c39423ed578013eff80032c951f32b --- src/cmd/acme/xfid.c +++ src/cmd/acme/xfid.c @@ -103,13 +103,8 @@ xfidopen(Xfid *x) q = FILE(x->f->qid); switch(q){ case QWaddr: - if(w->nopen[q]++ == 0){ - w->addr = range(0,0); - w->limit = range(-1,-1); - } - break; - case QWdata: - w->nopen[q]++; + w->nopen[q]++; + w->limit = range(-1,-1); break; case QWevent: if(w->nopen[q]++ == 0){ @@ -214,12 +209,13 @@ xfidclose(Xfid *x) } break; case QWdata: + case QWxdata: w->nomark = FALSE; /* fall through */ case QWaddr: case QWevent: /* BUG: do we need to shut down Xfid? */ if(--w->nopen[q] == 0){ - if(q == QWdata) + if(q == QWdata || q == QWxdata) w->nomark = FALSE; if(q==QWevent && !w->isdir && w->col!=nil){ w->filemenu = TRUE; @@ -327,6 +323,15 @@ xfidread(Xfid *x) w->addr.q1 = w->addr.q0; break; + case QWxdata: + /* BUG: what should happen if q1 > q0? */ + if(w->addr.q0 > w->body.file->b.nc){ + respond(x, &fc, Eaddr); + break; + } + w->addr.q0 += xfidruneread(x, &w->body, w->addr.q0, w->addr.q1); + break; + case QWtag: xfidutfread(x, &w->tag, w->tag.file->b.nc, QWtag); break; @@ -398,7 +403,7 @@ xfidwrite(Xfid *x) t = &w->body; wincommit(w, t); eval = TRUE; - a = address(x->f->mntdir, t, w->limit, w->addr, r, 0, nr, rgetc, &eval, (uint*)&nb); + a = address(FALSE, t, w->limit, w->addr, r, 0, nr, rgetc, &eval, (uint*)&nb); free(r); if(nb < nr){ respond(x, &fc, Ebadaddr);